diff --git a/3rdparty/3rdparty.pro b/3rdparty/3rdparty.pro index 7630102..75d28ff 100644 --- a/3rdparty/3rdparty.pro +++ b/3rdparty/3rdparty.pro @@ -1,6 +1,5 @@ -ZINT_PATH = $$PWD/zint-2.4.4/ -ZINT_VERSION = 2.4.4 -INCLUDEPATH += $${ZINT_PATH}/backend $${ZINT_PATH}/backend_qt4 -DEPENDPATH += $${ZINT_PATH}/backend $${ZINT_PATH}/backend_qt4 -include($${ZINT_PATH}/backend_qt4/Zint.pro) - +ZINT_PATH = $$PWD/zint-2.6.1/ +ZINT_VERSION = 2.6.1 +INCLUDEPATH += $${ZINT_PATH}/backend $${ZINT_PATH}/backend_qt +DEPENDPATH += $${ZINT_PATH}/backend $${ZINT_PATH}/backend_qt +include($${ZINT_PATH}/backend_qt/backend_qt.pro) diff --git a/3rdparty/dark_style_sheet/COPYING b/3rdparty/dark_style_sheet/COPYING new file mode 100644 index 0000000..49f878c --- /dev/null +++ b/3rdparty/dark_style_sheet/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) <2013-2017> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/Hmovetoolbar.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/Hmovetoolbar.png new file mode 100644 index 0000000..349b9f0 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/Hmovetoolbar.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/Hsepartoolbar.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/Hsepartoolbar.png new file mode 100644 index 0000000..70465de Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/Hsepartoolbar.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/Vmovetoolbar.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/Vmovetoolbar.png new file mode 100644 index 0000000..bc63f26 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/Vmovetoolbar.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/Vsepartoolbar.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/Vsepartoolbar.png new file mode 100644 index 0000000..14b9d13 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/Vsepartoolbar.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_closed-on.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_closed-on.png new file mode 100644 index 0000000..d081e9b Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_closed-on.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_closed.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_closed.png new file mode 100644 index 0000000..d652159 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_closed.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_open-on.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_open-on.png new file mode 100644 index 0000000..ec372b2 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_open-on.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_open.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_open.png new file mode 100644 index 0000000..66f8e1a Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/branch_open.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked.png new file mode 100644 index 0000000..830cfee Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked_disabled.png new file mode 100644 index 0000000..cb63cc2 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked_focus.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked_focus.png new file mode 100644 index 0000000..5b04d83 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_checked_focus.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate.png new file mode 100644 index 0000000..41024f7 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate_disabled.png new file mode 100644 index 0000000..abdc01d Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate_focus.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate_focus.png new file mode 100644 index 0000000..fea239d Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_indeterminate_focus.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked.png new file mode 100644 index 0000000..2159aca Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked_disabled.png new file mode 100644 index 0000000..ade721e Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked_focus.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked_focus.png new file mode 100644 index 0000000..c037864 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/checkbox_unchecked_focus.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/close-hover.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/close-hover.png new file mode 100644 index 0000000..fbd7463 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/close-hover.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/close-pressed.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/close-pressed.png new file mode 100644 index 0000000..937d005 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/close-pressed.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/close.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/close.png new file mode 100644 index 0000000..2a5f8ed Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/close.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/down_arrow.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/down_arrow.png new file mode 100644 index 0000000..e271f7f Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/down_arrow.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/down_arrow_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/down_arrow_disabled.png new file mode 100644 index 0000000..5805d98 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/down_arrow_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/extend.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/extend.png new file mode 100644 index 0000000..c5fd75a Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/extend.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/left_arrow.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/left_arrow.png new file mode 100644 index 0000000..f808d2d Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/left_arrow.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/left_arrow_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/left_arrow_disabled.png new file mode 100644 index 0000000..f5b9af8 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/left_arrow_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked.png new file mode 100644 index 0000000..235e6b0 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked_disabled.png new file mode 100644 index 0000000..bf0051e Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked_focus.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked_focus.png new file mode 100644 index 0000000..bea316d Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_checked_focus.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked.png new file mode 100644 index 0000000..9a4def6 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked_disabled.png new file mode 100644 index 0000000..6ece890 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked_focus.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked_focus.png new file mode 100644 index 0000000..b094c26 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/radio_unchecked_focus.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/right_arrow.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/right_arrow.png new file mode 100644 index 0000000..9b0a4e6 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/right_arrow.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/right_arrow_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/right_arrow_disabled.png new file mode 100644 index 0000000..5c0bee4 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/right_arrow_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/sizegrip.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/sizegrip.png new file mode 100644 index 0000000..350583a Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/sizegrip.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-branch-end.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-branch-end.png new file mode 100644 index 0000000..cb5d3b5 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-branch-end.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-branch-more.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-branch-more.png new file mode 100644 index 0000000..6271140 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-branch-more.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-vline.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-vline.png new file mode 100644 index 0000000..87536cc Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/stylesheet-vline.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/transparent.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/transparent.png new file mode 100644 index 0000000..483df25 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/transparent.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/undock-hover.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/undock-hover.png new file mode 100644 index 0000000..1dfd698 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/undock-hover.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/undock.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/undock.png new file mode 100644 index 0000000..a54c9f6 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/undock.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/up_arrow.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/up_arrow.png new file mode 100644 index 0000000..abcc724 Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/up_arrow.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/rc/up_arrow_disabled.png b/3rdparty/dark_style_sheet/qdarkstyle/rc/up_arrow_disabled.png new file mode 100644 index 0000000..b9c8e3b Binary files /dev/null and b/3rdparty/dark_style_sheet/qdarkstyle/rc/up_arrow_disabled.png differ diff --git a/3rdparty/dark_style_sheet/qdarkstyle/style.qrc b/3rdparty/dark_style_sheet/qdarkstyle/style.qrc new file mode 100644 index 0000000..6520860 --- /dev/null +++ b/3rdparty/dark_style_sheet/qdarkstyle/style.qrc @@ -0,0 +1,48 @@ + + + rc/up_arrow_disabled.png + rc/Hmovetoolbar.png + rc/stylesheet-branch-end.png + rc/branch_closed-on.png + rc/stylesheet-vline.png + rc/branch_closed.png + rc/branch_open-on.png + rc/transparent.png + rc/right_arrow_disabled.png + rc/sizegrip.png + rc/close.png + rc/close-hover.png + rc/close-pressed.png + rc/down_arrow.png + rc/Vmovetoolbar.png + rc/left_arrow.png + rc/stylesheet-branch-more.png + rc/up_arrow.png + rc/right_arrow.png + rc/left_arrow_disabled.png + rc/Hsepartoolbar.png + rc/branch_open.png + rc/Vsepartoolbar.png + rc/down_arrow_disabled.png + rc/undock.png + rc/checkbox_checked_disabled.png + rc/checkbox_checked_focus.png + rc/checkbox_checked.png + rc/checkbox_indeterminate.png + rc/checkbox_indeterminate_focus.png + rc/checkbox_unchecked_disabled.png + rc/checkbox_unchecked_focus.png + rc/checkbox_unchecked.png + rc/radio_checked_disabled.png + rc/radio_checked_focus.png + rc/radio_checked.png + rc/radio_unchecked_disabled.png + rc/radio_unchecked_focus.png + rc/radio_unchecked.png + rc/extend.png + rc/undock-hover.png + + + style.qss + + diff --git a/3rdparty/dark_style_sheet/qdarkstyle/style.qss b/3rdparty/dark_style_sheet/qdarkstyle/style.qss new file mode 100644 index 0000000..0140e4f --- /dev/null +++ b/3rdparty/dark_style_sheet/qdarkstyle/style.qss @@ -0,0 +1,1411 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) <2013-2014> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +QToolTip +{ + border: 1px solid #2b2b2b; + background-color: #383838; + color: white; +\\ padding: 5px; + +} + +QWidget +{ + color: #eff0f1; + background-color: #383838; + selection-background-color:#819a67; + selection-color: #eff0f1; + background-clip: border; + border-image: none; + border: 0px transparent black; + outline: 0; +} + +QWidget:item:hover +{ + background-color: #819a67; + color: #eff0f1; +} + +QWidget:item:selected +{ + background-color: #819a67; +} + +QCheckBox +{ + spacing: 5px; + outline: none; + color: #eff0f1; + margin-right: 2px; + +} + +QCheckBox::item{ + background-color: #404040; +} + +QCheckBox:disabled +{ + color: #494949; +} + +QCheckBox::indicator{ + width: 16px; + height: 16px; + color: #222222; +} + + +QCheckBox::indicator:unchecked +{ + image: url(:/qss_qdark_icons/rc/checkbox_unchecked.png); +} + +QCheckBox::indicator:unchecked:hover, +QCheckBox::indicator:unchecked:focus, +QCheckBox::indicator:unchecked:pressed, +QGroupBox::indicator:unchecked:hover, +QGroupBox::indicator:unchecked:focus, +QGroupBox::indicator:unchecked:pressed +{ + border: none; + image: url(:/qss_qdark_icons/rc/checkbox_unchecked_focus.png); +} + +QCheckBox::indicator:checked +{ + image: url(:/qss_qdark_icons/rc/checkbox_checked.png); +} + +QCheckBox::indicator:checked:hover, +QCheckBox::indicator:checked:focus, +QCheckBox::indicator:checked:pressed, +QGroupBox::indicator:checked:hover, +QGroupBox::indicator:checked:focus, +QGroupBox::indicator:checked:pressed +{ + border: none; + image: url(:/qss_qdark_icons/rc/checkbox_checked_focus.png); +} + + +QCheckBox::indicator:indeterminate +{ + image: url(:/qss_qdark_icons/rc/checkbox_indeterminate.png); +} + +QCheckBox::indicator:indeterminate:focus, +QCheckBox::indicator:indeterminate:hover, +QCheckBox::indicator:indeterminate:pressed +{ + image: url(:/qss_qdark_icons/rc/checkbox_indeterminate_focus.png); +} + +QCheckBox::indicator:checked:disabled, +QGroupBox::indicator:checked:disabled +{ + image: url(:/qss_qdark_icons/rc/checkbox_checked_disabled.png); +} + +QCheckBox::indicator:unchecked:disabled, +QGroupBox::indicator:unchecked:disabled +{ + image: url(:/qss_qdark_icons/rc/checkbox_unchecked_disabled.png); +} + +QGroupBox::indicator +{ + width: 18px; + height: 18px; +} +QGroupBox::indicator +{ + margin-left: 2px; +} + +QRadioButton +{ + spacing: 5px; + outline: none; + color: #eff0f1; + margin-bottom: 2px; +} + +QRadioButton:disabled +{ + color: #2b2b2b; +} + +QRadioButton::indicator +{ + width: 16px; + height: 16px; +} + +QRadioButton::indicator:unchecked +{ + image: url(:/qss_qdark_icons/rc/radio_unchecked.png); +} + +QRadioButton::indicator:unchecked:hover, +QRadioButton::indicator:unchecked:focus, +QRadioButton::indicator:unchecked:pressed +{ + border: none; + outline: none; + image: url(:/qss_qdark_icons/rc/radio_unchecked_focus.png); +} + +QRadioButton::indicator:checked +{ + border: none; + outline: none; + image: url(:/qss_qdark_icons/rc/radio_checked.png); +} + +QRadioButton::indicator:checked:hover, +QRadioButton::indicator:checked:focus, +QRadioButton::indicator:checked:pressed +{ + border: none; + outline: none; + image: url(:/qss_qdark_icons/rc/radio_checked_focus.png); +} + +QRadioButton::indicator:checked:disabled +{ + outline: none; + image: url(:/qss_qdark_icons/rc/radio_checked_disabled.png); +} + +QRadioButton::indicator:unchecked:disabled +{ + image: url(:/qss_qdark_icons/rc/radio_unchecked_disabled.png); +} + +QMenuBar +{ + background-color: #2f2f2f; + color: #eff0f1; + border-bottom: 1px solid #2b2b2b; +} + +QMenuBar::item +{ + background: transparent; +} + +QMenuBar::item:selected +{ + background: transparent; + background-color: #8fa876; + border: 1px solid #2b2b2b; +} + +QMenuBar::item:pressed +{ + border: 1px solid #2b2b2b; +\\ background-color: #2e2e2e; + background-color: #8fa876; + color: #eff0f1; + margin-bottom:-1px; + padding-bottom:1px; +} + +QMenu +{ + border: 1px solid #2b2b2b; + color: #eff0f1; + margin: 2px; +} + +QMenu::icon +{ + margin: 5px; +} + +QMenu::item +{ + padding: 5px 30px 5px 30px; + border: 1px solid transparent; /* reserve space for selection border */ +} + +QMenu::item:selected +{ + color: #eff0f1; +} + +QMenu::separator { + height: 2px; + background: lightblue; + margin-left: 10px; + margin-right: 5px; +} + +QMenu::indicator { + width: 18px; + height: 18px; + padding-left: 4px; +} + +/* non-exclusive indicator = check box style indicator + (see QActionGroup::setExclusive) */ +QMenu::indicator:non-exclusive:unchecked { + image: url(:/qss_qdark_icons/rc/checkbox_unchecked.png); +} + +QMenu::indicator:non-exclusive:unchecked:selected { + image: url(:/qss_qdark_icons/rc/checkbox_unchecked_disabled.png); +} + +QMenu::indicator:non-exclusive:checked { + image: url(:/qss_qdark_icons/rc/checkbox_checked.png); +} + +QMenu::indicator:non-exclusive:checked:selected { + image: url(:/qss_qdark_icons/rc/checkbox_checked_disabled.png); +} + +/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +QMenu::indicator:exclusive:unchecked { + image: url(:/qss_qdark_icons/rc/radio_unchecked.png); +} + +QMenu::indicator:exclusive:unchecked:selected { + image: url(:/qss_qdark_icons/rc/radio_unchecked_disabled.png); +} + +QMenu::indicator:exclusive:checked { + image: url(:/qss_qdark_icons/rc/radio_checked.png); +} + +QMenu::indicator:exclusive:checked:selected { + image: url(:/qss_qdark_icons/rc/radio_checked_disabled.png); +} + +QMenu::right-arrow { + margin: 5px; + image: url(:/qss_qdark_icons/rc/right_arrow.png) +} + + +QWidget:disabled +{ + color: #7a7a7a; + background-color: #404040; +} + +QAbstractItemView +{ + alternate-background-color: #383838; + color: #eff0f1; + border: 1px solid 3A3939; +\\ border-radius: 2px; +} + +QWidget:focus, QMenuBar:focus +{ + border: 1px solid #4b6807; +} + +QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus +{ + border: none; +} + +QLineEdit +{ + background-color: #232629; + padding-right: 5px; + padding-left: 5px; + padding-top: 1px; + padding-bottom: 1px; + margin: 1px; + border-style: solid; + border: 1px solid #2b2b2b; +\\ border-radius: 2px; + color: #eff0f1; +} + +QLineEdit[text=""] +{ + color: #fff; +} + +QLineEdit:disabled{ + color: #858585; +} + +QAbstractItemView QLineEdit +{ + padding: 0; +} + +QGroupBox { + margin-top: 1.5em; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + padding-left: 0px; + padding-right: 0px; + margin-top: 2px; + margin-bottom: 2px; +} + +QAbstractScrollArea +{ +\\ border-radius: 2px; + border: 1px solid #2b2b2b; + background-color: transparent; +} + +QScrollBar:horizontal +{ + height: 15px; + margin: 3px 15px 3px 15px; + border: 1px transparent #2A2929; + border-radius: 4px; + background-color: #2A2929; +} + +QScrollBar::handle:horizontal +{ + background-color: #605F5F; + min-width: 5px; + border-radius: 4px; +} + +QScrollBar::add-line:horizontal +{ + margin: 0px 3px 0px 3px; + border-image: url(:/qss_qdark_icons/rc/right_arrow_disabled.png); + width: 10px; + height: 10px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal +{ + margin: 0px 3px 0px 3px; + border-image: url(:/qss_qdark_icons/rc/left_arrow_disabled.png); + height: 10px; + width: 10px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on +{ + border-image: url(:/qss_qdark_icons/rc/right_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: right; + subcontrol-origin: margin; +} + + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on +{ + border-image: url(:/qss_qdark_icons/rc/left_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal +{ + background: none; +} + + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal +{ + background: none; +} + +QScrollBar:vertical +{ + background-color: #2A2929; + width: 15px; + margin: 15px 3px 15px 3px; + border: 1px transparent #2A2929; + border-radius: 4px; +} + +QScrollBar::handle:vertical +{ + background-color: #605F5F; + min-height: 5px; + border-radius: 4px; +} + +QScrollBar::sub-line:vertical +{ + margin: 3px 0px 3px 0px; + border-image: url(:/qss_qdark_icons/rc/up_arrow_disabled.png); + height: 10px; + width: 10px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical +{ + margin: 3px 0px 3px 0px; + border-image: url(:/qss_qdark_icons/rc/down_arrow_disabled.png); + height: 10px; + width: 10px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on +{ + + border-image: url(:/qss_qdark_icons/rc/up_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: top; + subcontrol-origin: margin; +} + + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on +{ + border-image: url(:/qss_qdark_icons/rc/down_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical +{ + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; +} + +QTextEdit +{ + background-color: #232629; + color: #eff0f1; + border: 1px solid #2b2b2b; +} + +QPlainTextEdit +{ + background-color: #232629;; + color: #eff0f1; +\\ border-radius: 2px; + border: 1px solid #2b2b2b; +} + +QHeaderView::section +{ + background-color: #2b2b2b; + color: #eff0f1; + padding: 5px; + border: 1px solid #2b2b2b; +} + +QSizeGrip { + image: url(:/qss_qdark_icons/rc/sizegrip.png); + width: 12px; + height: 12px; +} + + +QMainWindow::separator +{ + background-color: #383838; + color: white; + padding-left: 4px; + spacing: 2px; + border: 1px dashed #2b2b2b; +} + +QMainWindow::separator:hover +{ + + background-color: #787876; + color: white; + padding-left: 4px; + border: 1px solid #2b2b2b; + spacing: 2px; +} + + +QMenu::separator +{ + height: 1px; + background-color: #2b2b2b; + color: white; + padding-left: 4px; + margin-left: 10px; + margin-right: 5px; +} + + +QFrame +{ + border-radius: 0px; + border-top: 1px solid #2b2b2b; + border-left: 1px solid #2b2b2b; + border-bottom: 1px solid #494949; + border-right: 1px solid #494949; +} + +QFrame[frameShape="0"] +{ +\\ border-radius: 2px; + border: 1px transparent #2b2b2b; +} + +QStackedWidget +{ + border: 1px transparent black; +} + +QToolBar { +\\ border: 1px transparent #2b2b2b; +\\ background: #383838; + font-weight: bold; + border-bottom: 1px solid #2b2b2b; +} + +QToolBar:top{ + border-bottom: 1px solid #2b2b2b; +} + +QToolBar:left{ + border-right: 1px solid #2b2b2b; +} + +QToolBar:right{ + border-left: 1px solid #2b2b2b; +} + +QToolBar:bottom{ + border-top: 1px solid #2b2b2b; +} + +QToolBar::handle:horizontal { + image: url(:/qss_qdark_icons/rc/Hmovetoolbar.png); +} +QToolBar::handle:vertical { + image: url(:/qss_qdark_icons/rc/Vmovetoolbar.png); +} +QToolBar::separator:horizontal { + image: url(:/qss_qdark_icons/rc/Hsepartoolbar.png); +} +QToolBar::separator:vertical { + image: url(:/qss_qdark_icons/rc/Vsepartoolbar.png); +} + +QToolButton#qt_toolbar_ext_button { + background: transparent; + min-width: 8px; + width: 8px; + padding: 1px; + qproperty-icon: url(:/qss_qdark_icons/rc/extend.png); +} + +QPushButton +{ + color: #fff; + background-color: #404040; + border-width: 1px; + border-color: #2b2b2b; + border-style: solid; + padding: 5px; +\\ border-radius: 2px; + outline: none; +} + +QPushButton:disabled +{ + background-color: #383838; + border-width: 1px; + border-color: #454545; + border-style: solid; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 10px; + padding-right: 10px; +\\ border-radius: 2px; + color: #454545; +} + +QPushButton:focus { + background-color: #2e2e2e; + color: white; +} + +QPushButton:pressed +{ + background-color: #2e2e2e; + padding-top: -15px; + padding-bottom: -17px; +} + +QComboBox +{ + selection-background-color: #2e2e2e; + border-style: solid; + border: 1px solid #2b2b2b; +\\ border-radius: 2px; + padding-right: 5px; + padding-left: 5px; + padding-top: 1px; + padding-bottom: 1px; + margin: 1px; + min-width: 75px; +} + +QPushButton:checked{ + background-color: #2b2b2b; + border-color: #6A6969; +} + +QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover, +QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover, +QTableView:hover, QTableWidget::hover, QListWidget::hover +{ + border: 1px solid #4b6807; + color: #eff0f1; +} + +QComboBox:on +{ + padding-top: 3px; + padding-left: 4px; + selection-background-color: #4a4a4a; +} + +QComboBox QAbstractItemView +{ + background-color: #232629; +\\ border-radius: 2px; + border: 1px solid #2b2b2b; + selection-background-color: #89ae30; +} + +QComboBox::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + + border-left-width: 0px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +QComboBox::down-arrow +{ + image: url(:/qss_qdark_icons/rc/down_arrow_disabled.png); +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, +QComboBox::down-arrow:focus +{ + image: url(:/qss_qdark_icons/rc/down_arrow.png); +} + +QAbstractSpinBox { + padding-right: 5px; + padding-left: 5px; + padding-top: 1px; + padding-bottom: 1px; + margin: 1px; + border: 1px solid #2b2b2b; + background-color: #232629; + color: #eff0f1; +\\ border-radius: 2px; +} + +QAbstractSpinBox:up-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: top right; +} + +QAbstractSpinBox:down-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: bottom right; +} + +QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { + image: url(:/qss_qdark_icons/rc/up_arrow_disabled.png); + width: 10px; + height: 10px; +} +QAbstractSpinBox::up-arrow:hover +{ + image: url(:/qss_qdark_icons/rc/up_arrow.png); +} + + +QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off +{ + image: url(:/qss_qdark_icons/rc/down_arrow_disabled.png); + width: 10px; + height: 10px; +} +QAbstractSpinBox::down-arrow:hover +{ + image: url(:/qss_qdark_icons/rc/down_arrow.png); +} + + +QLabel +{ + border: 0px solid black; +} + +QTabWidget{ + border: 0px transparent black; +} + +QTabWidget::pane { + border: 1px solid #2b2b2b; + background-color: #404040; + padding: 5px; +} + +QTabWidget QWidget{ + background-color: #404040; +} + +QTabWidget::tab-bar { + left: 5px; /* move to the right by 5px */ +} + +QTabBar +{ + qproperty-drawBase: 0; + border-radius: 3px; +} + +QTabBar:focus +{ + border: 0px transparent black; +} + +QTabBar::close-button { + image: url(:/qss_qdark_icons/rc/close.png); + background: transparent; +} + +QTabBar::close-button:hover +{ + image: url(:/qss_qdark_icons/rc/close-hover.png); + background: transparent; +} + +QTabBar::close-button:pressed { + image: url(:/qss_qdark_icons/rc/close-pressed.png); + background: transparent; +} + +/* TOP TABS */ +QTabBar::tab:top { + color: #eff0f1; + border: 1px solid #2b2b2b; + border-bottom: 1px solid transparent; + background-color: #404040; + padding: 5px; + min-width: 10px; + margin-bottom: -1; +} + +QTabBar::tab:top:!selected +{ + color: #eff0f1; + background-color: #383838; + border: 1px solid transparent; +} + +QTabBar::tab:top:!selected:hover { + background-color: #2e2e2e; +} + +QTabBar::tab:top:!selected:hover { + background-color: #505050; +} + +QTabBar::tab::top:selected +{ + border-top: 2px solid #8fa876; + background-color: #2b2b2b; +} + +/* BOTTOM TABS */ +QTabBar::tab:bottom { + color: #eff0f1; + border: 1px solid #2b2b2b; + border-top: 1px solid #404040; + background-color: #404040; + padding: 5px; + min-width: 10px; + margin-top: -1; +} + +QTabBar::tab:bottom:!selected +{ + color: #eff0f1; + background-color: #383838; + border: 1px solid transparent; +} + +QTabBar::tab:bottom:!selected:hover { + background-color: #819a67; +} + +QTabBar::tab::bottom:selected +{ + border-bottom: 2px solid #8fa876; + background-color: #2b2b2b; +} + +/* LEFT TABS */ +QTabBar::tab:left { + color: #eff0f1; + border: 1px solid #2b2b2b; + border-left: 1px solid #404040; + background-color: #404040; + padding: 5px; + min-height: 10px; +} + +QTabBar::tab:left:!selected +{ + color: #eff0f1; + background-color: #383838; + border: 1px solid transparent; +} + +QTabBar::tab:left:!selected:hover { + background-color: #2e2e2e; +} + +QTabBar::tab:left:!selected:hover { + background-color: #505050; +} + +QTabBar::tab::left:selected +{ + border-left: 2px solid #8fa876; + background-color: #2b2b2b; +} + +/* RIGHT TABS */ +QTabBar::tab:right { + color: #eff0f1; + border: 1px solid #2b2b2b; + border-right: 1px solid #404040; + background-color: #404040; + padding: 5px; + min-height: 10px; +} + +QTabBar::tab:right:!selected +{ + color: #eff0f1; + background-color: #383838; + border: 1px solid transparent; +} + +QTabBar::tab:right:!selected:hover { + background-color: #2e2e2e; +} + +QTabBar::tab:right:!selected:hover { + background-color: #505050; +} + +QTabBar::tab::right:selected +{ + border-bottom: 2px solid #8fa876; + background-color: #2b2b2b; +} + +QTabBar QToolButton::right-arrow:enabled { + image: url(:/qss_qdark_icons/rc/right_arrow.png); +} + + QTabBar QToolButton::left-arrow:enabled { + image: url(:/qss_qdark_icons/rc/left_arrow.png); +} + +QTabBar QToolButton::right-arrow:disabled { + image: url(:/qss_qdark_icons/rc/right_arrow_disabled.png); +} + + QTabBar QToolButton::left-arrow:disabled { + image: url(:/qss_qdark_icons/rc/left_arrow_disabled.png); +} + +QDockWidget { + background: #383838; + border: 1px solid #403F3F; + titlebar-close-icon: url(:/qss_qdark_icons/rc/transparent.png); + titlebar-normal-icon: url(:/qss_qdark_icons/rc/transparent.png); +} + +QDockWidget::title{ + background: #383838; + padding-left: 5px; + padding-top: 4px; + margin-top: 4px; + icon-size: 16px; +} + +QDockWidget::close-button, QDockWidget::float-button { + border: 1px solid transparent; + border-radius: 2px; + background: transparent; +} + +QDockWidget::close-button { + subcontrol-position: top right; + subcontrol-origin: margin; + position: absolute; + top: 4px; left: 0px; bottom: 0px; right: 2px; + width: 16px; +} + +QDockWidget::float-button { + subcontrol-position: top right; + subcontrol-origin: margin; + position: absolute; + top: 4px; left: 0px; bottom: 0px; right: 18px; + width: 16px; +} + +QDockWidget::close-button:hover, QDockWidget::float-button:hover { +\\ background: rgba(255, 255, 255, 10); +} + +QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { + padding: 1px -1px -1px 1px; + background: rgba(255, 255, 255, 10); +} + +QDockWidget::close-button { + image: url(:/qss_qdark_icons/rc/close.png); +} + +QDockWidget::close-button:hover { + image: url(:/qss_qdark_icons/rc/close-hover.png); +} + +QDockWidget::float-button { + image: url(:/qss_qdark_icons/rc/undock.png); +} + +QDockWidget::float-button:hover { + image: url(:/qss_qdark_icons/rc/undock-hover.png); +} + +QLabel#limeReportLabel{ + color: #8fa876; +} + +QTreeView, QListView +{ + border-top: 1px solid #2b2b2b; + border-left: 1px solid #2b2b2b; + border-bottom: 1px solid #494949; + border-right: 1px solid #494949; + background-color: #404040; +} + +QTreeView::item, QListView::item{ + height: 25px; +} + +QTreeView::branch:selected{ + background-color: #819a67; +} + +QTreeView::branch:!selected:hover, QTreeView::item:!selected:hover{ +\\ background-color: #287399; + background-color: #819a67; +} + +QTreeView::branch:has-siblings:!adjoins-item { + border-image: url(:/qss_qdark_icons/rc/transparent.png); +} + +QTreeView::branch:has-siblings:adjoins-item { + border-image: url(:/qss_qdark_icons/rc/transparent.png); +} + +QTreeView::branch:!has-children:!has-siblings:adjoins-item { + border-image: url(:/qss_qdark_icons/rc/transparent.png); +} + +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings { + image: url(:/qss_qdark_icons/rc/branch_closed.png); +} + +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings { + image: url(:/qss_qdark_icons/rc/branch_open.png); +} + +QTreeView::branch:has-children:!has-siblings:closed:hover, +QTreeView::branch:closed:has-children:has-siblings:hover { + image: url(:/qss_qdark_icons/rc/branch_closed-on.png); +} + +QTreeView::branch:open:has-children:!has-siblings:hover, +QTreeView::branch:open:has-children:has-siblings:hover { + image: url(:/qss_qdark_icons/rc/branch_open-on.png); +} + +QSlider::groove:horizontal { + border: 1px solid #565a5e; + height: 4px; + background: #565a5e; + margin: 0px; + border-radius: 2px; +} + +QSlider::handle:horizontal { + background: #232629; + border: 1px solid #565a5e; + width: 16px; + height: 16px; + margin: -8px 0; + border-radius: 9px; +} + +QSlider::groove:vertical { + border: 1px solid #565a5e; + width: 4px; + background: #565a5e; + margin: 0px; + border-radius: 3px; +} + +QSlider::handle:vertical { + background: #232629; + border: 1px solid #565a5e; + width: 16px; + height: 16px; + margin: 0 -8px; + border-radius: 9px; +} + +QToolButton { + color : white; + border: 1px solid transparent; + margin: 2px; + padding: 2px; +} + +QToolButton:hover, QToolButton::menu-button:hover { + background-color: #2b2b2b; + border: 1px solid #8fa876; +} + +QToolButton:checked, QToolButton:pressed, + QToolButton::menu-button:pressed { + background-color: #2e2e2e; + border: 1px solid #8fa876; +} + +QToolButton:text{ + color: #ffffff; +} + +QToolButton:disabled{ + background-color: transparent; + border: 1px transparent #2b2b2b; +} + +\\ +\\QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ +\\ padding-right: 20px; /* make way for the popup button */ +\\ border: 1px #2b2b2b; +\\ border-radius: 5px; +\\} +\\ +\\QToolButton[popupMode="2"] { /* only for InstantPopup */ +\\ padding-right: 10px; /* make way for the popup button */ +\\ border: 1px #2b2b2b; +\\} +\\ +\\/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +\\QToolButton::menu-indicator { +\\ image: url(:/qss_qdark_icons/rc/down_arrow.png); +\\ top: -7px; left: -2px; /* shift it a bit */ +\\} +\\ +\\/* the subcontrols below are used only in the MenuButtonPopup mode */ +\\QToolButton::menu-button { +\\ border: 1px transparent #2b2b2b; +\\ border-top-right-radius: 6px; +\\ border-bottom-right-radius: 6px; +\\ /* 16px width + 4px for border = 20px allocated above */ +\\ width: 16px; +\\ outline: none; +\\} +\\ +\\QToolButton::menu-arrow { +\\ image: url(:/qss_qdark_icons/rc/down_arrow.png); +\\} +\\ +\\QToolButton::menu-arrow:open { +\\ border: 1px solid #2b2b2b; +\\} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + left: 8px; +} + +QTableView +{ + border: 1px solid #2b2b2b; + gridline-color: #383838; + background-color: #232629; +} + + +QTableView, QHeaderView +{ + border-radius: 0px; +} + +QTableView::item:pressed, QListView::item:pressed { + background: #819a67; + color: #eff0f1; +} + +QTableView::item:selected:active, QListView::item:selected:active { + background: #819a67; + color: #eff0f1; +} + +QTableView::focus{ + border: 1px solid #4b6807 +} + +QHeaderView +{ + background-color: #383838; + border: 1px transparent; + border-radius: 0px; + margin: 0px; + padding: 0px; + +} + +QHeaderView::section { + background-color: #383838; + color: #eff0f1; + padding: 5px; + border: 1px solid #2b2b2b; + border-radius: 0px; + text-align: center; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one +{ + border-top: 1px transparent #2b2b2b; +} + +QHeaderView::section::vertical +{ + border-top: transparent; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one +{ + border-left: 1px transparent #2b2b2b; +} + +QHeaderView::section::horizontal +{ + border-left: transparent; +} + + +QHeaderView::section:checked + { + color: white; + background-color: #334e5e; + } + + /* style the sort indicator */ +QHeaderView::down-arrow { + image: url(:/qss_qdark_icons/rc/down_arrow.png); +} + +QHeaderView::up-arrow { + image: url(:/qss_qdark_icons/rc/up_arrow.png); +} + + +QTableCornerButton::section { + background-color: #383838; + border: 1px transparent #2b2b2b; + border-radius: 0px; +} + +QToolBox { + padding: 5px; + border: 1px transparent black; +} + +QToolBox::tab { + color: #eff0f1; + font-weight: bold; + background-color: #383838; +\\ background-color: #2b2b2b; + border: 2px solid #d0d0d0; + border-top: 1px transparent #383838; + border-left: 1px transparent #383838; + border-right: 1px transparent #383838; +\\ border-bottom: 1px transparent #383838; +\\ border-top-left-radius: 5px; +\\ border-top-right-radius: 5px; +} + +QToolBox::tab:hover{ + background-color: #2b2b2b; + border-color: #8fa876; +} + +QToolBox::tab:selected { /* italicize selected tabs */ +\\ font: italic; + font-weight: bold; +\\ background-color: #383838; + background-color: #2b2b2b; + border-color: #8fa876; + } + +QStatusBar::item { + border: 0px transparent dark; + } + + +QFrame[height="3"], QFrame[width="3"] { + background-color: #2b2b2b; +} + + +QSplitter::handle { + border: 1px dashed #2b2b2b; +} + +QSplitter::handle:hover { + background-color: #787876; + border: 1px solid #2b2b2b; +} + +QSplitter::handle:horizontal { + width: 1px; +} + +QSplitter::handle:vertical { + height: 1px; +} + +QProgressBar { + border: 1px solid #2b2b2b; + border-radius: 5px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #05B8CC; +} + +QDateEdit +{ + selection-background-color: #2e2e2e; + border-style: solid; + border: 1px solid #3375A3; + border-radius: 2px; + padding: 1px; + min-width: 75px; +} + +QDateEdit:on +{ + padding-top: 3px; + padding-left: 4px; + selection-background-color: #4a4a4a; +} + +QDateEdit QAbstractItemView +{ + background-color: #232629; + border-radius: 2px; + border: 1px solid #3375A3; + selection-background-color: #2e2e2e; +} + +QDateEdit::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + border-left-width: 0px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +QDateEdit::down-arrow +{ + image: url(:/qss_qdark_icons/rc/down_arrow_disabled.png); +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, +QDateEdit::down-arrow:focus +{ + image: url(:/qss_qdark_icons/rc/down_arrow.png); +} diff --git a/3rdparty/dark_style_sheet/svg/checkbox_checked.svg b/3rdparty/dark_style_sheet/svg/checkbox_checked.svg new file mode 100644 index 0000000..a0f5045 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_checked.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_checked_disabled.svg b/3rdparty/dark_style_sheet/svg/checkbox_checked_disabled.svg new file mode 100644 index 0000000..79e23f2 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_checked_disabled.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_checked_focus.svg b/3rdparty/dark_style_sheet/svg/checkbox_checked_focus.svg new file mode 100644 index 0000000..2683c6b --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_checked_focus.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_indeterminate.svg b/3rdparty/dark_style_sheet/svg/checkbox_indeterminate.svg new file mode 100644 index 0000000..648734a --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_indeterminate.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_indeterminate_disabled.svg b/3rdparty/dark_style_sheet/svg/checkbox_indeterminate_disabled.svg new file mode 100644 index 0000000..79f9afb --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_indeterminate_disabled.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_indeterminate_focus.svg b/3rdparty/dark_style_sheet/svg/checkbox_indeterminate_focus.svg new file mode 100644 index 0000000..22d7337 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_indeterminate_focus.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_unchecked.svg b/3rdparty/dark_style_sheet/svg/checkbox_unchecked.svg new file mode 100644 index 0000000..b365e1b --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_unchecked.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_unchecked_disabled.svg b/3rdparty/dark_style_sheet/svg/checkbox_unchecked_disabled.svg new file mode 100644 index 0000000..a2a2059 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_unchecked_disabled.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/checkbox_unchecked_focus.svg b/3rdparty/dark_style_sheet/svg/checkbox_unchecked_focus.svg new file mode 100644 index 0000000..ffb2523 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/checkbox_unchecked_focus.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/radio_checked.svg b/3rdparty/dark_style_sheet/svg/radio_checked.svg new file mode 100644 index 0000000..062c7ec --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/radio_checked.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/radio_checked_disabled.svg b/3rdparty/dark_style_sheet/svg/radio_checked_disabled.svg new file mode 100644 index 0000000..c0d9720 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/radio_checked_disabled.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/radio_checked_focus.svg b/3rdparty/dark_style_sheet/svg/radio_checked_focus.svg new file mode 100644 index 0000000..458c051 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/radio_checked_focus.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/radio_unchecked.svg b/3rdparty/dark_style_sheet/svg/radio_unchecked.svg new file mode 100644 index 0000000..83db993 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/radio_unchecked.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/radio_unchecked_disabled.svg b/3rdparty/dark_style_sheet/svg/radio_unchecked_disabled.svg new file mode 100644 index 0000000..0297243 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/radio_unchecked_disabled.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/dark_style_sheet/svg/radio_unchecked_focus.svg b/3rdparty/dark_style_sheet/svg/radio_unchecked_focus.svg new file mode 100644 index 0000000..3f5e289 --- /dev/null +++ b/3rdparty/dark_style_sheet/svg/radio_unchecked_focus.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/easyprofiler/.gitignore b/3rdparty/easyprofiler/.gitignore new file mode 100644 index 0000000..83ccc54 --- /dev/null +++ b/3rdparty/easyprofiler/.gitignore @@ -0,0 +1,2 @@ +/build/ +/bin/ diff --git a/3rdparty/easyprofiler/CMakeCache.txt b/3rdparty/easyprofiler/CMakeCache.txt new file mode 100644 index 0000000..b48fae6 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeCache.txt @@ -0,0 +1,322 @@ +# This is the CMakeCache file. +# For build in directory: /home/alex/Work/C++Projects/easyprofiler +# It was generated by CMake: /usr/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//Build easy_profiler as shared library. +BUILD_SHARED_LIBS:BOOL=ON + +//Use std::chrono::high_resolution_clock as a timer +BUILD_WITH_CHRONO_HIGH_RESOLUTION_CLOCK:BOOL=OFF + +//Use std::chrono::steady_clock as a timer +BUILD_WITH_CHRONO_STEADY_CLOCK:BOOL=OFF + +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + +//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or +// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel. +CMAKE_BUILD_TYPE:STRING=Release + +//Enable/Disable color output during build. +CMAKE_COLOR_MAKEFILE:BOOL=ON + +//CXX compiler +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//Flags used by the compiler during all build types. +CMAKE_CXX_FLAGS:STRING= + +//Flags used by the compiler during debug builds. +CMAKE_CXX_FLAGS_DEBUG:STRING=-g + +//Flags used by the compiler during release builds for minimum +// size. +CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the compiler during release builds. +CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the compiler during release builds with debug info. +CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG + +//Flags used by the linker. +CMAKE_EXE_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Enable/Disable output of compile commands during generation. +CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF + +//Install path prefix, prepended onto install directories. +CMAKE_INSTALL_PREFIX:PATH=/usr/local + +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + +//Path to a program. +CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make + +//Flags used by the linker during the creation of modules. +CMAKE_MODULE_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=easy_profiler + +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + +//Flags used by the linker during the creation of dll's. +CMAKE_SHARED_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//If set, runtime paths are not added when installing shared libraries, +// but are added when building. +CMAKE_SKIP_INSTALL_RPATH:BOOL=NO + +//If set, runtime paths are not added when using shared libraries. +CMAKE_SKIP_RPATH:BOOL=NO + +//Flags used by the linker during the creation of static libraries. +CMAKE_STATIC_LINKER_FLAGS:STRING= + +//Flags used by the linker during debug builds. +CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during release minsize builds. +CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during release builds. +CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during Release with Debug Info builds. +CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + +//If this value is on, makefiles will be generated without the +// .SILENT directive, and all commands will be echoed to the console +// during the make. This is useful for debugging only. With Visual +// Studio IDE projects all commands are done without /nologo. +CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE + +//Default listening port +EASY_DEFAULT_PORT:STRING=28077 + +//Enable new threads registration when collecting context switch +// events +EASY_OPTION_IMPLICIT_THREAD_REGISTRATION:BOOL=ON + +//Enable automatic startListen on startup +EASY_OPTION_LISTEN:BOOL=OFF + +//Print errors to stderr +EASY_OPTION_LOG:BOOL=OFF + +//Use predefined set of colors (see profiler_colors.h). If you +// want to use your own colors palette you can turn this option +// OFF +EASY_OPTION_PREDEFINED_COLORS:BOOL=ON + +//Use pretty-printed function names with signature and argument +// types +EASY_OPTION_PRETTY_PRINT:BOOL=OFF + +//Enable self profiling (measure time for internal storage expand) +EASY_OPTION_PROFILE_SELF:BOOL=OFF + +//Storage expand default status (profiler::ON or profiler::OFF) +EASY_OPTION_PROFILE_SELF_BLOCKS_ON:BOOL=OFF + +//The directory containing a CMake configuration file for Qt5Core. +Qt5Core_DIR:PATH=/home/alex/Work/Qt/5.8/gcc_64/lib/cmake/Qt5Core + +//The directory containing a CMake configuration file for Qt5Gui. +Qt5Gui_DIR:PATH=/home/alex/Work/Qt/5.8/gcc_64/lib/cmake/Qt5Gui + +//The directory containing a CMake configuration file for Qt5Widgets. +Qt5Widgets_DIR:PATH=/home/alex/Work/Qt/5.8/gcc_64/lib/cmake/Qt5Widgets + +//Value Computed by CMake +easy_profiler_BINARY_DIR:STATIC=/home/alex/Work/C++Projects/easyprofiler + +//Dependencies for the target +easy_profiler_LIB_DEPENDS:STATIC=general;pthread; + +//Value Computed by CMake +easy_profiler_SOURCE_DIR:STATIC=/home/alex/Work/C++Projects/easyprofiler + + +######################## +# INTERNAL cache entries +######################## + +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/home/alex/Work/C++Projects/easyprofiler +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=5 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=1 +//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE +CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS +CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG +CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL +CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE +CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO +CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS +CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG +CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE +CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS +CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1 +//Name of external makefile project generator. +CMAKE_EXTRA_GENERATOR:INTERNAL= +//Name of generator. +CMAKE_GENERATOR:INTERNAL=Unix Makefiles +//Name of generator platform. +CMAKE_GENERATOR_PLATFORM:INTERNAL= +//Name of generator toolset. +CMAKE_GENERATOR_TOOLSET:INTERNAL= +//Source directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=/home/alex/Work/C++Projects/easyprofiler +//Install .so files without execute permission. +CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS +CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG +CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE +CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=5 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.5 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS +CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG +CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE +CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH +CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_RPATH +CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS +CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG +CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL +CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE +CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/bin/uname +//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE +CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 + diff --git a/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeCXXCompiler.cmake b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeCXXCompiler.cmake new file mode 100644 index 0000000..013ee92 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeCXXCompiler.cmake @@ -0,0 +1,68 @@ +set(CMAKE_CXX_COMPILER "/usr/bin/c++") +set(CMAKE_CXX_COMPILER_ARG1 "") +set(CMAKE_CXX_COMPILER_ID "GNU") +set(CMAKE_CXX_COMPILER_VERSION "5.4.0") +set(CMAKE_CXX_COMPILER_WRAPPER "") +set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "98") +set(CMAKE_CXX_COMPILE_FEATURES "cxx_template_template_parameters;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates") +set(CMAKE_CXX98_COMPILE_FEATURES "cxx_template_template_parameters") +set(CMAKE_CXX11_COMPILE_FEATURES "cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates") +set(CMAKE_CXX14_COMPILE_FEATURES "cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates") + +set(CMAKE_CXX_PLATFORM_ID "Linux") +set(CMAKE_CXX_SIMULATE_ID "") +set(CMAKE_CXX_SIMULATE_VERSION "") + +set(CMAKE_AR "/usr/bin/ar") +set(CMAKE_RANLIB "/usr/bin/ranlib") +set(CMAKE_LINKER "/usr/bin/ld") +set(CMAKE_COMPILER_IS_GNUCXX 1) +set(CMAKE_CXX_COMPILER_LOADED 1) +set(CMAKE_CXX_COMPILER_WORKS TRUE) +set(CMAKE_CXX_ABI_COMPILED TRUE) +set(CMAKE_COMPILER_IS_MINGW ) +set(CMAKE_COMPILER_IS_CYGWIN ) +if(CMAKE_COMPILER_IS_CYGWIN) + set(CYGWIN 1) + set(UNIX 1) +endif() + +set(CMAKE_CXX_COMPILER_ENV_VAR "CXX") + +if(CMAKE_COMPILER_IS_MINGW) + set(MINGW 1) +endif() +set(CMAKE_CXX_COMPILER_ID_RUN 1) +set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) +set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP) +set(CMAKE_CXX_LINKER_PREFERENCE 30) +set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) + +# Save compiler ABI information. +set(CMAKE_CXX_SIZEOF_DATA_PTR "8") +set(CMAKE_CXX_COMPILER_ABI "ELF") +set(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +if(CMAKE_CXX_SIZEOF_DATA_PTR) + set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") +endif() + +if(CMAKE_CXX_COMPILER_ABI) + set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") +endif() + +if(CMAKE_CXX_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +endif() + +set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "") +if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX) + set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}") +endif() + + + + +set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;c") +set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/5;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") +set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") diff --git a/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeDetermineCompilerABI_CXX.bin b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeDetermineCompilerABI_CXX.bin new file mode 100755 index 0000000..ccb7de9 Binary files /dev/null and b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeDetermineCompilerABI_CXX.bin differ diff --git a/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeSystem.cmake b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeSystem.cmake new file mode 100644 index 0000000..9b97c52 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CMakeSystem.cmake @@ -0,0 +1,15 @@ +set(CMAKE_HOST_SYSTEM "Linux-4.4.0-93-generic") +set(CMAKE_HOST_SYSTEM_NAME "Linux") +set(CMAKE_HOST_SYSTEM_VERSION "4.4.0-93-generic") +set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") + + + +set(CMAKE_SYSTEM "Linux-4.4.0-93-generic") +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_VERSION "4.4.0-93-generic") +set(CMAKE_SYSTEM_PROCESSOR "x86_64") + +set(CMAKE_CROSSCOMPILING "FALSE") + +set(CMAKE_SYSTEM_LOADED 1) diff --git a/3rdparty/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 0000000..e6d8536 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,533 @@ +/* This source file must have a .cpp extension so that all C++ compilers + recognize the extension without flags. Borland does not know .cxx for + example. */ +#ifndef __cplusplus +# error "A C compiler has been selected for C++." +#endif + + +/* Version number components: V=Version, R=Revision, P=Patch + Version date components: YYYY=Year, MM=Month, DD=Day */ + +#if defined(__COMO__) +# define COMPILER_ID "Comeau" + /* __COMO_VERSION__ = VRR */ +# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100) +# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100) + +#elif defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif + /* __INTEL_COMPILER = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# if defined(__INTEL_COMPILER_UPDATE) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) +# else +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# endif +# if defined(__INTEL_COMPILER_BUILD_DATE) + /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif + +#elif defined(__PATHCC__) +# define COMPILER_ID "PathScale" +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif + +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__WATCOMC__) +# define COMPILER_ID "OpenWatcom" + /* __WATCOMC__ = VVRP + 1100 */ +# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__SUNPRO_CC) +# define COMPILER_ID "SunPro" +# if __SUNPRO_CC >= 0x5100 + /* __SUNPRO_CC = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# else + /* __SUNPRO_CC = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# endif + +#elif defined(__HP_aCC) +# define COMPILER_ID "HP" + /* __HP_aCC = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100) + +#elif defined(__DECCXX) +# define COMPILER_ID "Compaq" + /* __DECCXX_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000) + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800 +# define COMPILER_ID "XL" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800 +# define COMPILER_ID "VisualAge" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version) +# define COMPILER_ID "Fujitsu" + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__clang__) && defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) + +#elif defined(__clang__) +# define COMPILER_ID "Clang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# if defined(__GNUC_MINOR__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) +# define COMPILER_ID "ADSP" +#if defined(__VISUALDSPVERSION__) + /* __VISUALDSPVERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24) +# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF) +#endif + +#elif defined(__IAR_SYSTEMS_ICC__ ) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" + +#elif defined(__ARMCC_VERSION) +# define COMPILER_ID "ARMCC" +#if __ARMCC_VERSION >= 1000000 + /* __ARMCC_VERSION = VRRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#else + /* __ARMCC_VERSION = VRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#endif + + +#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) +# define COMPILER_ID "MIPSpro" +# if defined(_SGI_COMPILER_VERSION) + /* _SGI_COMPILER_VERSION = VRP */ +# define COMPILER_VERSION_MAJOR DEC(_SGI_COMPILER_VERSION/100) +# define COMPILER_VERSION_MINOR DEC(_SGI_COMPILER_VERSION/10 % 10) +# define COMPILER_VERSION_PATCH DEC(_SGI_COMPILER_VERSION % 10) +# else + /* _COMPILER_VERSION = VRP */ +# define COMPILER_VERSION_MAJOR DEC(_COMPILER_VERSION/100) +# define COMPILER_VERSION_MINOR DEC(_COMPILER_VERSION/10 % 10) +# define COMPILER_VERSION_PATCH DEC(_COMPILER_VERSION % 10) +# endif + + +/* These compilers are either not known or too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__sgi) +# define COMPILER_ID "MIPSpro" + +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif + +#ifdef __QNXNTO__ +char const* qnxnto = "INFO" ":" "qnxnto[]"; +#endif + +#if defined(__CRAYXE) || defined(__CRAYXC) +char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; +#endif + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) +# define PLATFORM_ID "IRIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#elif defined(__WATCOMC__) +# if defined(__LINUX__) +# define PLATFORM_ID "Linux" + +# elif defined(__DOS__) +# define PLATFORM_ID "DOS" + +# elif defined(__OS2__) +# define PLATFORM_ID "OS2" + +# elif defined(__WINDOWS__) +# define PLATFORM_ID "Windows3x" + +# else /* unknown platform */ +# define PLATFORM_ID "" +# endif + +#else /* unknown platform */ +# define PLATFORM_ID "" + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM) +# if _M_ARM == 4 +# define ARCHITECTURE_ID "ARMV4I" +# elif _M_ARM == 5 +# define ARCHITECTURE_ID "ARMV5I" +# else +# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) +# endif + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__WATCOMC__) +# if defined(_M_I86) +# define ARCHITECTURE_ID "I86" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID "" +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number components. */ +#ifdef COMPILER_VERSION_MAJOR +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct a string literal encoding the version number components. */ +#ifdef SIMULATE_VERSION_MAJOR +char const info_simulate_version[] = { + 'I', 'N', 'F', 'O', ':', + 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', + SIMULATE_VERSION_MAJOR, +# ifdef SIMULATE_VERSION_MINOR + '.', SIMULATE_VERSION_MINOR, +# ifdef SIMULATE_VERSION_PATCH + '.', SIMULATE_VERSION_PATCH, +# ifdef SIMULATE_VERSION_TWEAK + '.', SIMULATE_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + + +const char* info_language_dialect_default = "INFO" ":" "dialect_default[" +#if __cplusplus >= 201402L + "14" +#elif __cplusplus >= 201103L + "11" +#else + "98" +#endif +"]"; + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif +#if defined(__CRAYXE) || defined(__CRAYXC) + require += info_cray[argc]; +#endif + require += info_language_dialect_default[argc]; + (void)argv; + return require; +} diff --git a/3rdparty/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/a.out b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/a.out new file mode 100755 index 0000000..b677508 Binary files /dev/null and b/3rdparty/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/a.out differ diff --git a/3rdparty/easyprofiler/CMakeFiles/CMakeDirectoryInformation.cmake b/3rdparty/easyprofiler/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..9ecfcf5 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/alex/Work/C++Projects/easyprofiler") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/alex/Work/C++Projects/easyprofiler") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/3rdparty/easyprofiler/CMakeFiles/CMakeOutput.log b/3rdparty/easyprofiler/CMakeFiles/CMakeOutput.log new file mode 100644 index 0000000..d37f64b --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/CMakeOutput.log @@ -0,0 +1,356 @@ +The system is: Linux - 4.4.0-93-generic - x86_64 +Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded. +Compiler: /usr/bin/c++ +Build flags: +Id flags: + +The output was: +0 + + +Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out" + +The CXX compiler identification is GNU, found in "/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/3.5.1/CompilerIdCXX/a.out" + +Determining if the CXX compiler works passed with the following output: +Change Dir: /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp + +Run Build Command:"/usr/bin/make" "cmTC_56b63/fast" +/usr/bin/make -f CMakeFiles/cmTC_56b63.dir/build.make CMakeFiles/cmTC_56b63.dir/build +make[1]: Entering directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_56b63.dir/testCXXCompiler.cxx.o +/usr/bin/c++ -o CMakeFiles/cmTC_56b63.dir/testCXXCompiler.cxx.o -c /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp/testCXXCompiler.cxx +Linking CXX executable cmTC_56b63 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_56b63.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTC_56b63.dir/testCXXCompiler.cxx.o -o cmTC_56b63 -rdynamic +make[1]: Leaving directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' + + +Detecting CXX compiler ABI info compiled with the following output: +Change Dir: /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp + +Run Build Command:"/usr/bin/make" "cmTC_aa90b/fast" +/usr/bin/make -f CMakeFiles/cmTC_aa90b.dir/build.make CMakeFiles/cmTC_aa90b.dir/build +make[1]: Entering directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o +/usr/bin/c++ -o CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-3.5/Modules/CMakeCXXCompilerABI.cpp +Linking CXX executable cmTC_aa90b +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_aa90b.dir/link.txt --verbose=1 +/usr/bin/c++ -v CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_aa90b -rdynamic +Using built-in specs. +COLLECT_GCC=/usr/bin/c++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.6' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.6) +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_aa90b' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=x86-64' + /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccL6oSX7.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o cmTC_aa90b /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o +make[1]: Leaving directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' + + +Parsed CXX implicit link information from above output: + link line regex: [^( *|.*[/\])(ld|([^/\]+-)?ld|collect2)[^/\]*( |$)] + ignore line: [Change Dir: /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp] + ignore line: [] + ignore line: [Run Build Command:"/usr/bin/make" "cmTC_aa90b/fast"] + ignore line: [/usr/bin/make -f CMakeFiles/cmTC_aa90b.dir/build.make CMakeFiles/cmTC_aa90b.dir/build] + ignore line: [make[1]: Entering directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp'] + ignore line: [Building CXX object CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o] + ignore line: [/usr/bin/c++ -o CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-3.5/Modules/CMakeCXXCompilerABI.cpp] + ignore line: [Linking CXX executable cmTC_aa90b] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_aa90b.dir/link.txt --verbose=1] + ignore line: [/usr/bin/c++ -v CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_aa90b -rdynamic ] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.6' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu] + ignore line: [Thread model: posix] + ignore line: [gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.6) ] + ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_aa90b' '-rdynamic' '-shared-libgcc' '-mtune=generic' '-march=x86-64'] + link line: [ /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccL6oSX7.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o cmTC_aa90b /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/5/collect2] ==> ignore + arg [-plugin] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so] ==> ignore + arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper] ==> ignore + arg [-plugin-opt=-fresolution=/tmp/ccL6oSX7.res] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [--sysroot=/] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [--as-needed] ==> ignore + arg [-export-dynamic] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTC_aa90b] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o] ==> ignore + arg [-L/usr/lib/gcc/x86_64-linux-gnu/5] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/5] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/5/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/5/../../..] + arg [CMakeFiles/cmTC_aa90b.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore + arg [-lstdc++] ==> lib [stdc++] + arg [-lm] ==> lib [m] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [-lc] ==> lib [c] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [/usr/lib/gcc/x86_64-linux-gnu/5/crtend.o] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o] ==> ignore + remove lib [gcc_s] + remove lib [gcc] + remove lib [gcc_s] + remove lib [gcc] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/5] ==> [/usr/lib/gcc/x86_64-linux-gnu/5] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/5/../../..] ==> [/usr/lib] + implicit libs: [stdc++;m;c] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/5;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + implicit fwks: [] + + + + +Detecting CXX [-std=c++14] compiler features compiled with the following output: +Change Dir: /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp + +Run Build Command:"/usr/bin/make" "cmTC_46192/fast" +/usr/bin/make -f CMakeFiles/cmTC_46192.dir/build.make CMakeFiles/cmTC_46192.dir/build +make[1]: Entering directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_46192.dir/feature_tests.cxx.o +/usr/bin/c++ -std=c++14 -o CMakeFiles/cmTC_46192.dir/feature_tests.cxx.o -c /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/feature_tests.cxx +Linking CXX executable cmTC_46192 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_46192.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTC_46192.dir/feature_tests.cxx.o -o cmTC_46192 -rdynamic +make[1]: Leaving directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' + + + Feature record: CXX_FEATURE:1cxx_aggregate_default_initializers + Feature record: CXX_FEATURE:1cxx_alias_templates + Feature record: CXX_FEATURE:1cxx_alignas + Feature record: CXX_FEATURE:1cxx_alignof + Feature record: CXX_FEATURE:1cxx_attributes + Feature record: CXX_FEATURE:1cxx_attribute_deprecated + Feature record: CXX_FEATURE:1cxx_auto_type + Feature record: CXX_FEATURE:1cxx_binary_literals + Feature record: CXX_FEATURE:1cxx_constexpr + Feature record: CXX_FEATURE:1cxx_contextual_conversions + Feature record: CXX_FEATURE:1cxx_decltype + Feature record: CXX_FEATURE:1cxx_decltype_auto + Feature record: CXX_FEATURE:1cxx_decltype_incomplete_return_types + Feature record: CXX_FEATURE:1cxx_default_function_template_args + Feature record: CXX_FEATURE:1cxx_defaulted_functions + Feature record: CXX_FEATURE:1cxx_defaulted_move_initializers + Feature record: CXX_FEATURE:1cxx_delegating_constructors + Feature record: CXX_FEATURE:1cxx_deleted_functions + Feature record: CXX_FEATURE:1cxx_digit_separators + Feature record: CXX_FEATURE:1cxx_enum_forward_declarations + Feature record: CXX_FEATURE:1cxx_explicit_conversions + Feature record: CXX_FEATURE:1cxx_extended_friend_declarations + Feature record: CXX_FEATURE:1cxx_extern_templates + Feature record: CXX_FEATURE:1cxx_final + Feature record: CXX_FEATURE:1cxx_func_identifier + Feature record: CXX_FEATURE:1cxx_generalized_initializers + Feature record: CXX_FEATURE:1cxx_generic_lambdas + Feature record: CXX_FEATURE:1cxx_inheriting_constructors + Feature record: CXX_FEATURE:1cxx_inline_namespaces + Feature record: CXX_FEATURE:1cxx_lambdas + Feature record: CXX_FEATURE:1cxx_lambda_init_captures + Feature record: CXX_FEATURE:1cxx_local_type_template_args + Feature record: CXX_FEATURE:1cxx_long_long_type + Feature record: CXX_FEATURE:1cxx_noexcept + Feature record: CXX_FEATURE:1cxx_nonstatic_member_init + Feature record: CXX_FEATURE:1cxx_nullptr + Feature record: CXX_FEATURE:1cxx_override + Feature record: CXX_FEATURE:1cxx_range_for + Feature record: CXX_FEATURE:1cxx_raw_string_literals + Feature record: CXX_FEATURE:1cxx_reference_qualified_functions + Feature record: CXX_FEATURE:1cxx_relaxed_constexpr + Feature record: CXX_FEATURE:1cxx_return_type_deduction + Feature record: CXX_FEATURE:1cxx_right_angle_brackets + Feature record: CXX_FEATURE:1cxx_rvalue_references + Feature record: CXX_FEATURE:1cxx_sizeof_member + Feature record: CXX_FEATURE:1cxx_static_assert + Feature record: CXX_FEATURE:1cxx_strong_enums + Feature record: CXX_FEATURE:1cxx_template_template_parameters + Feature record: CXX_FEATURE:1cxx_thread_local + Feature record: CXX_FEATURE:1cxx_trailing_return_types + Feature record: CXX_FEATURE:1cxx_unicode_literals + Feature record: CXX_FEATURE:1cxx_uniform_initialization + Feature record: CXX_FEATURE:1cxx_unrestricted_unions + Feature record: CXX_FEATURE:1cxx_user_literals + Feature record: CXX_FEATURE:1cxx_variable_templates + Feature record: CXX_FEATURE:1cxx_variadic_macros + Feature record: CXX_FEATURE:1cxx_variadic_templates + + +Detecting CXX [-std=c++11] compiler features compiled with the following output: +Change Dir: /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp + +Run Build Command:"/usr/bin/make" "cmTC_270c0/fast" +/usr/bin/make -f CMakeFiles/cmTC_270c0.dir/build.make CMakeFiles/cmTC_270c0.dir/build +make[1]: Entering directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_270c0.dir/feature_tests.cxx.o +/usr/bin/c++ -std=c++11 -o CMakeFiles/cmTC_270c0.dir/feature_tests.cxx.o -c /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/feature_tests.cxx +Linking CXX executable cmTC_270c0 +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_270c0.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTC_270c0.dir/feature_tests.cxx.o -o cmTC_270c0 -rdynamic +make[1]: Leaving directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' + + + Feature record: CXX_FEATURE:0cxx_aggregate_default_initializers + Feature record: CXX_FEATURE:1cxx_alias_templates + Feature record: CXX_FEATURE:1cxx_alignas + Feature record: CXX_FEATURE:1cxx_alignof + Feature record: CXX_FEATURE:1cxx_attributes + Feature record: CXX_FEATURE:0cxx_attribute_deprecated + Feature record: CXX_FEATURE:1cxx_auto_type + Feature record: CXX_FEATURE:0cxx_binary_literals + Feature record: CXX_FEATURE:1cxx_constexpr + Feature record: CXX_FEATURE:0cxx_contextual_conversions + Feature record: CXX_FEATURE:1cxx_decltype + Feature record: CXX_FEATURE:0cxx_decltype_auto + Feature record: CXX_FEATURE:1cxx_decltype_incomplete_return_types + Feature record: CXX_FEATURE:1cxx_default_function_template_args + Feature record: CXX_FEATURE:1cxx_defaulted_functions + Feature record: CXX_FEATURE:1cxx_defaulted_move_initializers + Feature record: CXX_FEATURE:1cxx_delegating_constructors + Feature record: CXX_FEATURE:1cxx_deleted_functions + Feature record: CXX_FEATURE:0cxx_digit_separators + Feature record: CXX_FEATURE:1cxx_enum_forward_declarations + Feature record: CXX_FEATURE:1cxx_explicit_conversions + Feature record: CXX_FEATURE:1cxx_extended_friend_declarations + Feature record: CXX_FEATURE:1cxx_extern_templates + Feature record: CXX_FEATURE:1cxx_final + Feature record: CXX_FEATURE:1cxx_func_identifier + Feature record: CXX_FEATURE:1cxx_generalized_initializers + Feature record: CXX_FEATURE:0cxx_generic_lambdas + Feature record: CXX_FEATURE:1cxx_inheriting_constructors + Feature record: CXX_FEATURE:1cxx_inline_namespaces + Feature record: CXX_FEATURE:1cxx_lambdas + Feature record: CXX_FEATURE:0cxx_lambda_init_captures + Feature record: CXX_FEATURE:1cxx_local_type_template_args + Feature record: CXX_FEATURE:1cxx_long_long_type + Feature record: CXX_FEATURE:1cxx_noexcept + Feature record: CXX_FEATURE:1cxx_nonstatic_member_init + Feature record: CXX_FEATURE:1cxx_nullptr + Feature record: CXX_FEATURE:1cxx_override + Feature record: CXX_FEATURE:1cxx_range_for + Feature record: CXX_FEATURE:1cxx_raw_string_literals + Feature record: CXX_FEATURE:1cxx_reference_qualified_functions + Feature record: CXX_FEATURE:0cxx_relaxed_constexpr + Feature record: CXX_FEATURE:0cxx_return_type_deduction + Feature record: CXX_FEATURE:1cxx_right_angle_brackets + Feature record: CXX_FEATURE:1cxx_rvalue_references + Feature record: CXX_FEATURE:1cxx_sizeof_member + Feature record: CXX_FEATURE:1cxx_static_assert + Feature record: CXX_FEATURE:1cxx_strong_enums + Feature record: CXX_FEATURE:1cxx_template_template_parameters + Feature record: CXX_FEATURE:1cxx_thread_local + Feature record: CXX_FEATURE:1cxx_trailing_return_types + Feature record: CXX_FEATURE:1cxx_unicode_literals + Feature record: CXX_FEATURE:1cxx_uniform_initialization + Feature record: CXX_FEATURE:1cxx_unrestricted_unions + Feature record: CXX_FEATURE:1cxx_user_literals + Feature record: CXX_FEATURE:0cxx_variable_templates + Feature record: CXX_FEATURE:1cxx_variadic_macros + Feature record: CXX_FEATURE:1cxx_variadic_templates + + +Detecting CXX [-std=c++98] compiler features compiled with the following output: +Change Dir: /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp + +Run Build Command:"/usr/bin/make" "cmTC_aba3e/fast" +/usr/bin/make -f CMakeFiles/cmTC_aba3e.dir/build.make CMakeFiles/cmTC_aba3e.dir/build +make[1]: Entering directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' +Building CXX object CMakeFiles/cmTC_aba3e.dir/feature_tests.cxx.o +/usr/bin/c++ -std=c++98 -o CMakeFiles/cmTC_aba3e.dir/feature_tests.cxx.o -c /home/alex/Work/C++Projects/easyprofiler/CMakeFiles/feature_tests.cxx +Linking CXX executable cmTC_aba3e +/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_aba3e.dir/link.txt --verbose=1 +/usr/bin/c++ CMakeFiles/cmTC_aba3e.dir/feature_tests.cxx.o -o cmTC_aba3e -rdynamic +make[1]: Leaving directory '/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/CMakeTmp' + + + Feature record: CXX_FEATURE:0cxx_aggregate_default_initializers + Feature record: CXX_FEATURE:0cxx_alias_templates + Feature record: CXX_FEATURE:0cxx_alignas + Feature record: CXX_FEATURE:0cxx_alignof + Feature record: CXX_FEATURE:0cxx_attributes + Feature record: CXX_FEATURE:0cxx_attribute_deprecated + Feature record: CXX_FEATURE:0cxx_auto_type + Feature record: CXX_FEATURE:0cxx_binary_literals + Feature record: CXX_FEATURE:0cxx_constexpr + Feature record: CXX_FEATURE:0cxx_contextual_conversions + Feature record: CXX_FEATURE:0cxx_decltype + Feature record: CXX_FEATURE:0cxx_decltype_auto + Feature record: CXX_FEATURE:0cxx_decltype_incomplete_return_types + Feature record: CXX_FEATURE:0cxx_default_function_template_args + Feature record: CXX_FEATURE:0cxx_defaulted_functions + Feature record: CXX_FEATURE:0cxx_defaulted_move_initializers + Feature record: CXX_FEATURE:0cxx_delegating_constructors + Feature record: CXX_FEATURE:0cxx_deleted_functions + Feature record: CXX_FEATURE:0cxx_digit_separators + Feature record: CXX_FEATURE:0cxx_enum_forward_declarations + Feature record: CXX_FEATURE:0cxx_explicit_conversions + Feature record: CXX_FEATURE:0cxx_extended_friend_declarations + Feature record: CXX_FEATURE:0cxx_extern_templates + Feature record: CXX_FEATURE:0cxx_final + Feature record: CXX_FEATURE:0cxx_func_identifier + Feature record: CXX_FEATURE:0cxx_generalized_initializers + Feature record: CXX_FEATURE:0cxx_generic_lambdas + Feature record: CXX_FEATURE:0cxx_inheriting_constructors + Feature record: CXX_FEATURE:0cxx_inline_namespaces + Feature record: CXX_FEATURE:0cxx_lambdas + Feature record: CXX_FEATURE:0cxx_lambda_init_captures + Feature record: CXX_FEATURE:0cxx_local_type_template_args + Feature record: CXX_FEATURE:0cxx_long_long_type + Feature record: CXX_FEATURE:0cxx_noexcept + Feature record: CXX_FEATURE:0cxx_nonstatic_member_init + Feature record: CXX_FEATURE:0cxx_nullptr + Feature record: CXX_FEATURE:0cxx_override + Feature record: CXX_FEATURE:0cxx_range_for + Feature record: CXX_FEATURE:0cxx_raw_string_literals + Feature record: CXX_FEATURE:0cxx_reference_qualified_functions + Feature record: CXX_FEATURE:0cxx_relaxed_constexpr + Feature record: CXX_FEATURE:0cxx_return_type_deduction + Feature record: CXX_FEATURE:0cxx_right_angle_brackets + Feature record: CXX_FEATURE:0cxx_rvalue_references + Feature record: CXX_FEATURE:0cxx_sizeof_member + Feature record: CXX_FEATURE:0cxx_static_assert + Feature record: CXX_FEATURE:0cxx_strong_enums + Feature record: CXX_FEATURE:1cxx_template_template_parameters + Feature record: CXX_FEATURE:0cxx_thread_local + Feature record: CXX_FEATURE:0cxx_trailing_return_types + Feature record: CXX_FEATURE:0cxx_unicode_literals + Feature record: CXX_FEATURE:0cxx_uniform_initialization + Feature record: CXX_FEATURE:0cxx_unrestricted_unions + Feature record: CXX_FEATURE:0cxx_user_literals + Feature record: CXX_FEATURE:0cxx_variable_templates + Feature record: CXX_FEATURE:0cxx_variadic_macros + Feature record: CXX_FEATURE:0cxx_variadic_templates diff --git a/3rdparty/easyprofiler/CMakeFiles/CMakeRuleHashes.txt b/3rdparty/easyprofiler/CMakeFiles/CMakeRuleHashes.txt new file mode 100644 index 0000000..5275219 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/CMakeRuleHashes.txt @@ -0,0 +1,2 @@ +# Hashes of file build rules. +74e55f76d310972c5aad534ac6b85d71 profiler_gui/CMakeFiles/profiler_gui_automoc diff --git a/3rdparty/easyprofiler/CMakeFiles/TargetDirectories.txt b/3rdparty/easyprofiler/CMakeFiles/TargetDirectories.txt new file mode 100644 index 0000000..afc5f57 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/TargetDirectories.txt @@ -0,0 +1,36 @@ +/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/install.dir +/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/list_install_components.dir +/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/install/strip.dir +/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/install/local.dir +/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/rebuild_cache.dir +/home/alex/Work/C++Projects/easyprofiler/CMakeFiles/edit_cache.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/install.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/list_install_components.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/rebuild_cache.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/install/strip.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/install/local.dir +/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/edit_cache.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/install.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/list_install_components.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/rebuild_cache.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/install/strip.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/install/local.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/edit_cache.dir +/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/install.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/list_install_components.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/rebuild_cache.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/edit_cache.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/profiler_sample.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/install/strip.dir +/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/install/local.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/install.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/list_install_components.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/rebuild_cache.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/profiler_reader.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/install/local.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/install/strip.dir +/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/edit_cache.dir diff --git a/3rdparty/easyprofiler/CMakeFiles/cmake.check_cache b/3rdparty/easyprofiler/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/3rdparty/easyprofiler/CMakeFiles/feature_tests.bin b/3rdparty/easyprofiler/CMakeFiles/feature_tests.bin new file mode 100755 index 0000000..9fe5cc8 Binary files /dev/null and b/3rdparty/easyprofiler/CMakeFiles/feature_tests.bin differ diff --git a/3rdparty/easyprofiler/CMakeFiles/feature_tests.cxx b/3rdparty/easyprofiler/CMakeFiles/feature_tests.cxx new file mode 100644 index 0000000..b93418c --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/feature_tests.cxx @@ -0,0 +1,405 @@ + + const char features[] = {"\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L +"1" +#else +"0" +#endif +"cxx_aggregate_default_initializers\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_alias_templates\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_alignas\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_alignof\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_attributes\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_attribute_deprecated\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_auto_type\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_binary_literals\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_constexpr\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_contextual_conversions\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_decltype\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_decltype_auto\n" +"CXX_FEATURE:" +#if ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40801) && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_decltype_incomplete_return_types\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_default_function_template_args\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_defaulted_functions\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_defaulted_move_initializers\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_delegating_constructors\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_deleted_functions\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_digit_separators\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_enum_forward_declarations\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_explicit_conversions\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_extended_friend_declarations\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_extern_templates\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_final\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_func_identifier\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_generalized_initializers\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_generic_lambdas\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_inheriting_constructors\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_inline_namespaces\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_lambdas\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_lambda_init_captures\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_local_type_template_args\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_long_long_type\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_noexcept\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_nonstatic_member_init\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_nullptr\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_override\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_range_for\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_raw_string_literals\n" +"CXX_FEATURE:" +#if ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40801) && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_reference_qualified_functions\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L +"1" +#else +"0" +#endif +"cxx_relaxed_constexpr\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L +"1" +#else +"0" +#endif +"cxx_return_type_deduction\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_right_angle_brackets\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_rvalue_references\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_sizeof_member\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_static_assert\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_strong_enums\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && __cplusplus +"1" +#else +"0" +#endif +"cxx_template_template_parameters\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_thread_local\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_trailing_return_types\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_unicode_literals\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_uniform_initialization\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_unrestricted_unions\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && __cplusplus >= 201103L +"1" +#else +"0" +#endif +"cxx_user_literals\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L +"1" +#else +"0" +#endif +"cxx_variable_templates\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_variadic_macros\n" +"CXX_FEATURE:" +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__)) +"1" +#else +"0" +#endif +"cxx_variadic_templates\n" + +}; + +int main(int argc, char** argv) { (void)argv; return features[argc]; } diff --git a/3rdparty/easyprofiler/CMakeFiles/progress.marks b/3rdparty/easyprofiler/CMakeFiles/progress.marks new file mode 100644 index 0000000..8f92bfd --- /dev/null +++ b/3rdparty/easyprofiler/CMakeFiles/progress.marks @@ -0,0 +1 @@ +35 diff --git a/3rdparty/easyprofiler/CMakeLists.txt b/3rdparty/easyprofiler/CMakeLists.txt new file mode 100644 index 0000000..4fe44a4 --- /dev/null +++ b/3rdparty/easyprofiler/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.0) +project(easy_profiler CXX) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set(EASY_PROGRAM_VERSION_MAJOR 1) +set(EASY_PROGRAM_VERSION_MINOR 3) +set(EASY_PROGRAM_VERSION_PATCH 0) +set(EASY_PRODUCT_VERSION_STRING "${EASY_PROGRAM_VERSION_MAJOR}.${EASY_PROGRAM_VERSION_MINOR}.${EASY_PROGRAM_VERSION_PATCH}") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) + +# set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/sdk) + +macro(easy_define_target_option TARGET SOURCE_OPTION TARGET_DEFINITION) + if (${SOURCE_OPTION}) + set(_VALUE 1) + else () + set(_VALUE 0) + endif () + target_compile_options(${TARGET} PUBLIC -D${TARGET_DEFINITION}=${_VALUE}) +endmacro() + +SET(CMAKE_INSTALL_RPATH "$ORIGIN") + +add_subdirectory(easy_profiler_core) +add_subdirectory(profiler_gui) + +if (NOT EASY_PROFILER_NO_SAMPLES) + add_subdirectory(sample) + add_subdirectory(reader) +endif () diff --git a/3rdparty/easyprofiler/LICENSE.APACHE b/3rdparty/easyprofiler/LICENSE.APACHE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/3rdparty/easyprofiler/LICENSE.APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/3rdparty/easyprofiler/LICENSE.MIT b/3rdparty/easyprofiler/LICENSE.MIT new file mode 100644 index 0000000..3840145 --- /dev/null +++ b/3rdparty/easyprofiler/LICENSE.MIT @@ -0,0 +1,18 @@ +Copyright (c) 2017 Sergey Yagovtsev, Victor Zarubkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/3rdparty/easyprofiler/README.md b/3rdparty/easyprofiler/README.md new file mode 100644 index 0000000..634e463 --- /dev/null +++ b/3rdparty/easyprofiler/README.md @@ -0,0 +1,224 @@ +# easy_profiler [![1.3.0](https://img.shields.io/badge/version-1.3.0-009688.svg)](https://github.com/yse/easy_profiler/releases) + +[![Build Status](https://travis-ci.org/yse/easy_profiler.svg?branch=develop)](https://travis-ci.org/yse/easy_profiler) +[![Build Status](https://ci.appveyor.com/api/projects/status/github/yse/easy_profiler?branch=develop&svg=true)](https://ci.appveyor.com/project/yse/easy-profiler/branch/develop) + +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + + +1. [About](#about) +2. [Key features](#key-features) +3. [Usage](#usage) + - [Prepare build system](#prepare-build-system) + - [General build system](#general) + - [CMake](#build-with-cmake) + - [Add profiling blocks](#add-profiling-blocks) + - [Collect blocks](#collect-blocks) + - [Collect via network](#collect-via-network) + - [Collect via file](#collect-via-file) + - [Note about context-switch](#note-about-context-switch) +4. [Build](#build) + - [Linux](#linux) + - [Windows](#windows) +5. [License](#license) + +# About +Lightweight cross-platform profiler library for c++ + +You can profile any function in you code. Furthermore this library provide measuring time of any block of code. +For example, information for 12 millions of blocks is using less than 300Mb of memory. +Working profiler slows your application execution for only 1-2%. + +![Block time](https://hsto.org/files/3e4/afe/8b7/3e4afe8b77ac4ad3a6f8c805be4b7f13.png) +_Average overhead per block is about 15ns/block (tested on Intel Core i7-5930K 3.5GHz, Win7)_ + +Disabled profiler will not affect your application execution in any way. You can leave it in your Release build +and enable it at run-time at any moment during application launch to see what is happening at the moment. + +Also the library can capture system's context switch events between threads. Context switch information includes +duration, target thread id, thread owner process id, thread owner process name. + +You can see the results of measuring in simple GUI application which provides full statistics and renders beautiful time-line. + +![GUI screenshot](https://cloud.githubusercontent.com/assets/1775230/24852044/a0b1edd0-1dde-11e7-8736-7052b840ad06.png) +_Profiling CryEngine SDK example_ + +# Key features + +- Extremely low overhead +- Low additional memory usage +- Cross-platform +- Measuring over network +- Capture thread context-switch events +- Fully remove integration via defines +- GUI could be connected to an application which is already profiling (so you can profile initialization of your application) +- Monitor main thread fps at real-time in GUI even if profiling is disabled or draw your own HUD/fps-plot directly in your application using data provided by profiler +- Configurable timer type with CMakeLists or defines + +# Usage + +## Prepare build system + +### General + +First of all you can specify path to include directory which contains `include/profiler` directory and define macro `BUILD_WITH_EASY_PROFILER`. +For linking with easy_profiler you can specify path to library. + +### Build with cmake + +If you are using `cmake` set `CMAKE_PREFIX_PATH` to `lib/cmake/easy_profiler` directory (from [release](https://github.com/yse/easy_profiler/releases) package) and use function `find_package(easy_profiler)` with `target_link_libraries(... easy_profiler)`. Example: + +``` cmake +project(app_for_profiling) + +set(SOURCES + main.cpp +) + +#CMAKE_PREFIX_PATH should be set to /lib/cmake/easy_profiler +find_package(easy_profiler REQUIRED) + +add_executable(app_for_profiling ${SOURCES}) + +target_link_libraries(app_for_profiling easy_profiler) +``` + +## Add profiling blocks + +Example of usage. + +This code snippet will generate block with function name and Magenta color: +```cpp +#include + +void frame() { + EASY_FUNCTION(profiler::colors::Magenta); // Magenta block with name "frame" + prepareRender(); + calculatePhysics(); +} +``` + +To profile any block you may do this as following. +You can specify these blocks also with Google material design colors or just set name of the block +(in this case it will have default color which is `Amber100`): +```cpp +#include + +void foo() { + // some code + EASY_BLOCK("Calculating sum"); // Block with default color + int sum = 0; + for (int i = 0; i < 10; ++i) { + EASY_BLOCK("Addition", profiler::colors::Red); // Scoped red block (no EASY_END_BLOCK needed) + sum += i; + } + EASY_END_BLOCK; // This ends "Calculating sum" block + + EASY_BLOCK("Calculating multiplication", profiler::colors::Blue500); // Blue block + int mul = 1; + for (int i = 1; i < 11; ++i) + mul *= i; + //EASY_END_BLOCK; // This is not needed because all blocks are ended on destructor when closing braces met +} +``` + +You can also use your own colors. easy_profiler is using standard 32-bit ARGB color format. +Example: +```cpp +#include + +void bar() { + EASY_FUNCTION(0xfff080aa); // Function block with custom color + // some code +} +``` +## Collect blocks + +There are two ways to cature blocks + +### Collect via network + +It's most prefered and convenient approach in many case. + +1. Initialize listening by `profiler::startListen()`. It's start new thread to listen on `28077` port the start-capture-signal from gui-application. +2. To stop listening you can call `profiler::stopListen()` function. + +### Collect via file + +1. Enable profiler by `EASY_PROFILER_ENABLE` macro +2. Dump blocks to file in any place you want by `profiler::dumpBlocksToFile("test_profile.prof")` function + +Example: +```cpp +int main() +{ + EASY_PROFILER_ENABLE; + /* do work*/ + profiler::dumpBlocksToFile("test_profile.prof"); +} +``` + +### Note about context-switch + +To capture a thread context-switch event you need: + +- On Windows: run profiling application "as administrator" +- On linux: you can run special `systemtap` script with root privileges as follow (example on Fedora): +```bash +#stap -o /tmp/cs_profiling_info.log scripts/context_switch_logger.stp name APPLICATION_NAME +``` +APPLICATION_NAME - name of profiling application + +# Build + +## Prerequisites + +* CMake 3.0 or higher +* Compiler with c++11 support + * for Unix systems: compiler with `thread_local` support is **highly recommended**: _GCC >=4.8_, _Clang >=3.3_ + +Additional requirements for GUI: +* Qt 5.3.0 or higher + +## Linux + +```bash +$ mkdir build +$ cd build +$ cmake -DCMAKE_BUILD_TYPE="Release" .. +$ make +``` + +## Windows + +If you are using QtCreator IDE you can just open `CMakeLists.txt` file in root directory. +If you are using Visual Studio you can generate solution by cmake generator command. +Examples shows how to generate Win64 solution for Visual Studio 2013. To generate for another version use proper cmake generator (-G "name of generator"). + +### Way 1 +Specify path to cmake scripts in Qt5 dir (usually in lib/cmake subdir) and execute cmake generator command, +for example: +```batch +$ mkdir build +$ cd build +$ cmake -DCMAKE_PREFIX_PATH="C:\Qt\5.3\msvc2013_64\lib\cmake" .. -G "Visual Studio 12 2013 Win64" +``` + +### Way 2 +Create system variable "Qt5Widgets_DIR" and set it's value to "[path-to-Qt5-binaries]\lib\cmake\Qt5Widgets". +For example, "C:\Qt\5.3\msvc2013_64\lib\cmake\Qt5Widgets". +And then run cmake generator as follows: +```batch +$ mkdir build +$ cd build +$ cmake .. -G "Visual Studio 12 2013 Win64" +``` + +# License + +Licensed under either of +- MIT license ([LICENSE.MIT](LICENSE.MIT) or http://opensource.org/licenses/MIT) +- Apache License, Version 2.0, ([LICENSE.APACHE](LICENSE.APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + +at your option. diff --git a/3rdparty/easyprofiler/appveyor.bat b/3rdparty/easyprofiler/appveyor.bat new file mode 100644 index 0000000..5f78678 --- /dev/null +++ b/3rdparty/easyprofiler/appveyor.bat @@ -0,0 +1,6 @@ +mkdir build_msvc +cd build_msvc +cmake -G "%GENERATOR%" ../ +cmake --build . --config Release + +goto :EOF diff --git a/3rdparty/easyprofiler/appveyor.yml b/3rdparty/easyprofiler/appveyor.yml new file mode 100644 index 0000000..6a7708f --- /dev/null +++ b/3rdparty/easyprofiler/appveyor.yml @@ -0,0 +1,19 @@ +platform: + - Win64 + +configuration: + - Release + +environment: + matrix: + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 + Qt5Widgets_DIR: "C:\\Qt\\5.5\\msvc2013_64\\lib\\cmake\\Qt5Widgets" + GENERATOR: "Visual Studio 12 2013 Win64" + +test: off + +build_script: + - CALL appveyor.bat + +skip_commits: + message: /.*\[skip appveyor\].*/ diff --git a/3rdparty/easyprofiler/cmake_install.cmake b/3rdparty/easyprofiler/cmake_install.cmake new file mode 100644 index 0000000..94c87df --- /dev/null +++ b/3rdparty/easyprofiler/cmake_install.cmake @@ -0,0 +1,53 @@ +# Install script for directory: /home/alex/Work/C++Projects/easyprofiler + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +if(NOT CMAKE_INSTALL_LOCAL_ONLY) + # Include the install script for each subdirectory. + include("/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/cmake_install.cmake") + include("/home/alex/Work/C++Projects/easyprofiler/profiler_gui/cmake_install.cmake") + include("/home/alex/Work/C++Projects/easyprofiler/sample/cmake_install.cmake") + include("/home/alex/Work/C++Projects/easyprofiler/reader/cmake_install.cmake") + +endif() + +if(CMAKE_INSTALL_COMPONENT) + set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") +else() + set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +endif() + +string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT + "${CMAKE_INSTALL_MANIFEST_FILES}") +file(WRITE "/home/alex/Work/C++Projects/easyprofiler/${CMAKE_INSTALL_MANIFEST}" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/CMakeDirectoryInformation.cmake b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..9ecfcf5 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/alex/Work/C++Projects/easyprofiler") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/alex/Work/C++Projects/easyprofiler") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets-release.cmake b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets-release.cmake new file mode 100644 index 0000000..09cbb89 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets-release.cmake @@ -0,0 +1,19 @@ +#---------------------------------------------------------------- +# Generated CMake target import file for configuration "Release". +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Import target "easy_profiler" for configuration "Release" +set_property(TARGET easy_profiler APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) +set_target_properties(easy_profiler PROPERTIES + IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/libeasy_profiler.so" + IMPORTED_SONAME_RELEASE "libeasy_profiler.so" + ) + +list(APPEND _IMPORT_CHECK_TARGETS easy_profiler ) +list(APPEND _IMPORT_CHECK_FILES_FOR_easy_profiler "${_IMPORT_PREFIX}/bin/libeasy_profiler.so" ) + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets.cmake b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets.cmake new file mode 100644 index 0000000..5f95653 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets.cmake @@ -0,0 +1,95 @@ +# Generated by CMake 3.5.1 + +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5) + message(FATAL_ERROR "CMake >= 2.6.0 required") +endif() +cmake_policy(PUSH) +cmake_policy(VERSION 2.6) +#---------------------------------------------------------------- +# Generated CMake target import file. +#---------------------------------------------------------------- + +# Commands may need to know the format version. +set(CMAKE_IMPORT_FILE_VERSION 1) + +# Protect against multiple inclusion, which would fail when already imported targets are added once more. +set(_targetsDefined) +set(_targetsNotDefined) +set(_expectedTargets) +foreach(_expectedTarget easy_profiler) + list(APPEND _expectedTargets ${_expectedTarget}) + if(NOT TARGET ${_expectedTarget}) + list(APPEND _targetsNotDefined ${_expectedTarget}) + endif() + if(TARGET ${_expectedTarget}) + list(APPEND _targetsDefined ${_expectedTarget}) + endif() +endforeach() +if("${_targetsDefined}" STREQUAL "${_expectedTargets}") + set(CMAKE_IMPORT_FILE_VERSION) + cmake_policy(POP) + return() +endif() +if(NOT "${_targetsDefined}" STREQUAL "") + message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n") +endif() +unset(_targetsDefined) +unset(_targetsNotDefined) +unset(_expectedTargets) + + +# Compute the installation prefix relative to this file. +get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) +get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) + +# Create imported target easy_profiler +add_library(easy_profiler SHARED IMPORTED) + +set_target_properties(easy_profiler PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "EASY_PROFILER_VERSION_MAJOR=1;EASY_PROFILER_VERSION_MINOR=3;EASY_PROFILER_VERSION_PATCH=0;EASY_DEFAULT_PORT=28077;BUILD_WITH_EASY_PROFILER=1" + INTERFACE_COMPILE_OPTIONS "-DEASY_CHRONO_STEADY_CLOCK=0;-DEASY_CHRONO_HIGHRES_CLOCK=0;-DEASY_OPTION_START_LISTEN_ON_STARTUP=0;-DEASY_OPTION_MEASURE_STORAGE_EXPAND=0;-DEASY_OPTION_STORAGE_EXPAND_BLOCKS_ON=0;-DEASY_OPTION_IMPLICIT_THREAD_REGISTRATION=1;-DEASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS=0;-DEASY_OPTION_LOG_ENABLED=0;-DEASY_OPTION_PRETTY_PRINT_FUNCTIONS=0;-DEASY_OPTION_BUILTIN_COLORS=1;-std=gnu++11" + INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include" + INTERFACE_LINK_LIBRARIES "pthread" +) + +if(CMAKE_VERSION VERSION_LESS 2.8.12) + message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.") +endif() + +# Load information for each installed configuration. +get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +file(GLOB CONFIG_FILES "${_DIR}/easy_profilerTargets-*.cmake") +foreach(f ${CONFIG_FILES}) + include(${f}) +endforeach() + +# Cleanup temporary variables. +set(_IMPORT_PREFIX) + +# Loop over all imported files and verify that they actually exist +foreach(target ${_IMPORT_CHECK_TARGETS} ) + foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} ) + if(NOT EXISTS "${file}" ) + message(FATAL_ERROR "The imported target \"${target}\" references the file + \"${file}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty and contained + \"${CMAKE_CURRENT_LIST_FILE}\" +but not all the files it references. +") + endif() + endforeach() + unset(_IMPORT_CHECK_FILES_FOR_${target}) +endforeach() +unset(_IMPORT_CHECK_TARGETS) + +# This file does not depend on other imported targets which have +# been exported from the same project but in a separate export set. + +# Commands beyond this point should not need to know the version. +set(CMAKE_IMPORT_FILE_VERSION) +cmake_policy(POP) diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake new file mode 100644 index 0000000..56e0950 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake @@ -0,0 +1,37 @@ +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +set(CMAKE_DEPENDS_CHECK_CXX + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/block.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/easy_socket.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/event_trace_win.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/nonscoped_block.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/profile_manager.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/reader.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/thread_storage.cpp" "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o" + ) +set(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +set(CMAKE_TARGET_DEFINITIONS_CXX + "BUILD_WITH_EASY_PROFILER=1" + "EASY_DEFAULT_PORT=28077" + "EASY_PROFILER_VERSION_MAJOR=1" + "EASY_PROFILER_VERSION_MINOR=3" + "EASY_PROFILER_VERSION_PATCH=0" + "_BUILD_PROFILER=1" + ) + +# The include file search paths: +set(CMAKE_CXX_TARGET_INCLUDE_PATH + "easy_profiler_core/include" + ) + +# Targets to which this target links. +set(CMAKE_TARGET_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make new file mode 100644 index 0000000..2b3b823 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make @@ -0,0 +1,275 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/alex/Work/C++Projects/easyprofiler + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/alex/Work/C++Projects/easyprofiler + +# Include any dependencies generated for this target. +include easy_profiler_core/CMakeFiles/easy_profiler.dir/depend.make + +# Include the progress variables for this target. +include easy_profiler_core/CMakeFiles/easy_profiler.dir/progress.make + +# Include the compile flags for this target's objects. +include easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make + +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o: easy_profiler_core/block.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/block.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/block.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/block.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/block.cpp > CMakeFiles/easy_profiler.dir/block.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/block.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/block.cpp -o CMakeFiles/easy_profiler.dir/block.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o + + +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o: easy_profiler_core/easy_socket.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/easy_socket.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/easy_socket.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/easy_socket.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/easy_socket.cpp > CMakeFiles/easy_profiler.dir/easy_socket.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/easy_socket.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/easy_socket.cpp -o CMakeFiles/easy_profiler.dir/easy_socket.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o + + +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o: easy_profiler_core/event_trace_win.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/event_trace_win.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/event_trace_win.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/event_trace_win.cpp > CMakeFiles/easy_profiler.dir/event_trace_win.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/event_trace_win.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/event_trace_win.cpp -o CMakeFiles/easy_profiler.dir/event_trace_win.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o + + +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o: easy_profiler_core/nonscoped_block.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/nonscoped_block.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/nonscoped_block.cpp > CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/nonscoped_block.cpp -o CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o + + +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o: easy_profiler_core/profile_manager.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_5) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/profile_manager.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/profile_manager.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/profile_manager.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/profile_manager.cpp > CMakeFiles/easy_profiler.dir/profile_manager.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/profile_manager.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/profile_manager.cpp -o CMakeFiles/easy_profiler.dir/profile_manager.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o + + +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o: easy_profiler_core/reader.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_6) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/reader.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/reader.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/reader.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/reader.cpp > CMakeFiles/easy_profiler.dir/reader.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/reader.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/reader.cpp -o CMakeFiles/easy_profiler.dir/reader.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o + + +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o: easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o: easy_profiler_core/thread_storage.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_7) "Building CXX object easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/easy_profiler.dir/thread_storage.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/thread_storage.cpp + +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/easy_profiler.dir/thread_storage.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/thread_storage.cpp > CMakeFiles/easy_profiler.dir/thread_storage.cpp.i + +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/easy_profiler.dir/thread_storage.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/thread_storage.cpp -o CMakeFiles/easy_profiler.dir/thread_storage.cpp.s + +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.requires: + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.provides: easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.requires + $(MAKE) -f easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.provides.build +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.provides + +easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.provides.build: easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o + + +# Object files for target easy_profiler +easy_profiler_OBJECTS = \ +"CMakeFiles/easy_profiler.dir/block.cpp.o" \ +"CMakeFiles/easy_profiler.dir/easy_socket.cpp.o" \ +"CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o" \ +"CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o" \ +"CMakeFiles/easy_profiler.dir/profile_manager.cpp.o" \ +"CMakeFiles/easy_profiler.dir/reader.cpp.o" \ +"CMakeFiles/easy_profiler.dir/thread_storage.cpp.o" + +# External object files for target easy_profiler +easy_profiler_EXTERNAL_OBJECTS = + +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/build.make +bin/libeasy_profiler.so: easy_profiler_core/CMakeFiles/easy_profiler.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_8) "Linking CXX shared library ../bin/libeasy_profiler.so" + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/easy_profiler.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +easy_profiler_core/CMakeFiles/easy_profiler.dir/build: bin/libeasy_profiler.so + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/build + +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/block.cpp.o.requires +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/easy_socket.cpp.o.requires +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o.requires +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o.requires +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/profile_manager.cpp.o.requires +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/reader.cpp.o.requires +easy_profiler_core/CMakeFiles/easy_profiler.dir/requires: easy_profiler_core/CMakeFiles/easy_profiler.dir/thread_storage.cpp.o.requires + +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/requires + +easy_profiler_core/CMakeFiles/easy_profiler.dir/clean: + cd /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core && $(CMAKE_COMMAND) -P CMakeFiles/easy_profiler.dir/cmake_clean.cmake +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/clean + +easy_profiler_core/CMakeFiles/easy_profiler.dir/depend: + cd /home/alex/Work/C++Projects/easyprofiler && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : easy_profiler_core/CMakeFiles/easy_profiler.dir/depend + diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/cmake_clean.cmake b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/cmake_clean.cmake new file mode 100644 index 0000000..27eab83 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/cmake_clean.cmake @@ -0,0 +1,16 @@ +file(REMOVE_RECURSE + "CMakeFiles/easy_profiler.dir/block.cpp.o" + "CMakeFiles/easy_profiler.dir/easy_socket.cpp.o" + "CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o" + "CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o" + "CMakeFiles/easy_profiler.dir/profile_manager.cpp.o" + "CMakeFiles/easy_profiler.dir/reader.cpp.o" + "CMakeFiles/easy_profiler.dir/thread_storage.cpp.o" + "../bin/libeasy_profiler.pdb" + "../bin/libeasy_profiler.so" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/easy_profiler.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/depend.make b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/depend.make new file mode 100644 index 0000000..be24553 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for easy_profiler. +# This may be replaced when dependencies are built. diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make new file mode 100644 index 0000000..a91ba6d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -O3 -DNDEBUG -fPIC -DEASY_CHRONO_STEADY_CLOCK=0 -DEASY_CHRONO_HIGHRES_CLOCK=0 -DEASY_OPTION_START_LISTEN_ON_STARTUP=0 -DEASY_OPTION_MEASURE_STORAGE_EXPAND=0 -DEASY_OPTION_STORAGE_EXPAND_BLOCKS_ON=0 -DEASY_OPTION_IMPLICIT_THREAD_REGISTRATION=1 -DEASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS=0 -DEASY_OPTION_LOG_ENABLED=0 -DEASY_OPTION_PRETTY_PRINT_FUNCTIONS=0 -DEASY_OPTION_BUILTIN_COLORS=1 -Wall -Wno-long-long -Wno-reorder -Wno-braced-scalar-init -pedantic -std=gnu++11 -std=gnu++11 + +CXX_DEFINES = -DBUILD_WITH_EASY_PROFILER=1 -DEASY_DEFAULT_PORT=28077 -DEASY_PROFILER_VERSION_MAJOR=1 -DEASY_PROFILER_VERSION_MINOR=3 -DEASY_PROFILER_VERSION_PATCH=0 -D_BUILD_PROFILER=1 -Deasy_profiler_EXPORTS + +CXX_INCLUDES = -I/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include + diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/link.txt b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/link.txt new file mode 100644 index 0000000..55b5e85 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fPIC -O3 -DNDEBUG -shared -Wl,-soname,libeasy_profiler.so -o ../bin/libeasy_profiler.so CMakeFiles/easy_profiler.dir/block.cpp.o CMakeFiles/easy_profiler.dir/easy_socket.cpp.o CMakeFiles/easy_profiler.dir/event_trace_win.cpp.o CMakeFiles/easy_profiler.dir/nonscoped_block.cpp.o CMakeFiles/easy_profiler.dir/profile_manager.cpp.o CMakeFiles/easy_profiler.dir/reader.cpp.o CMakeFiles/easy_profiler.dir/thread_storage.cpp.o -lpthread -Wl,-rpath,::::::: diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/progress.make b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/progress.make new file mode 100644 index 0000000..5b29368 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/progress.make @@ -0,0 +1,9 @@ +CMAKE_PROGRESS_1 = 1 +CMAKE_PROGRESS_2 = 2 +CMAKE_PROGRESS_3 = 3 +CMAKE_PROGRESS_4 = 4 +CMAKE_PROGRESS_5 = 5 +CMAKE_PROGRESS_6 = 6 +CMAKE_PROGRESS_7 = 7 +CMAKE_PROGRESS_8 = 8 + diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/progress.marks b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/progress.marks new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeFiles/progress.marks @@ -0,0 +1 @@ +8 diff --git a/3rdparty/easyprofiler/easy_profiler_core/CMakeLists.txt b/3rdparty/easyprofiler/easy_profiler_core/CMakeLists.txt new file mode 100644 index 0000000..e41a7d9 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/CMakeLists.txt @@ -0,0 +1,309 @@ +message(STATUS "") +message(STATUS "EASY_PROFILER.Core version = ${EASY_PRODUCT_VERSION_STRING}") +message(STATUS "") + + + +##################################################################### +# Checking c++11 thread_local support +if (NOT WIN32) + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8") + set(NO_CXX11_THREAD_LOCAL_SUPPORT TRUE) + endif () + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.3") + set(NO_CXX11_THREAD_LOCAL_SUPPORT TRUE) + endif () + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.0") + set(NO_CXX11_THREAD_LOCAL_SUPPORT TRUE) + endif () + endif () + + # TODO: Check thread_local keyword support for other compilers for Unix + + if (NO_CXX11_THREAD_LOCAL_SUPPORT) + message(WARNING " Your compiler does not support C++11 thread_local feature.") + message(WARNING " Without C++11 thread_local feature you may face to possible memory leak or application crash if using implicit thread registration and using EASY_THREAD instead of EASY_THREAD_SCOPE.") + endif () +endif () +##################################################################### + + + +########################################################### +# EasyProfiler options: +set(EASY_OPTION_IMPLICIT_THREAD_REGISTER_TEXT "Enable new threads registration when collecting context switch events") +set(EASY_DEFAULT_PORT 28077 CACHE STRING "Default listening port") +set(EASY_OPTION_LISTEN OFF CACHE BOOL "Enable automatic startListen on startup") +set(EASY_OPTION_PROFILE_SELF OFF CACHE BOOL "Enable self profiling (measure time for internal storage expand)") +set(EASY_OPTION_PROFILE_SELF_BLOCKS_ON OFF CACHE BOOL "Storage expand default status (profiler::ON or profiler::OFF)") +set(EASY_OPTION_LOG OFF CACHE BOOL "Print errors to stderr") +set(EASY_OPTION_PRETTY_PRINT OFF CACHE BOOL "Use pretty-printed function names with signature and argument types") +set(EASY_OPTION_PREDEFINED_COLORS ON CACHE BOOL "Use predefined set of colors (see profiler_colors.h). If you want to use your own colors palette you can turn this option OFF") +set(BUILD_SHARED_LIBS ON CACHE BOOL "Build easy_profiler as shared library.") +if (WIN32) + set(EASY_OPTION_IMPLICIT_THREAD_REGISTRATION ON CACHE BOOL ${EASY_OPTION_IMPLICIT_THREAD_REGISTER_TEXT}) + set(EASY_OPTION_EVENT_TRACING ON CACHE BOOL "Enable event tracing by default") + set(EASY_OPTION_LOW_PRIORITY_EVENT_TRACING ON CACHE BOOL "Set low priority for event tracing thread") +else () + if (NO_CXX11_THREAD_LOCAL_SUPPORT) + set(EASY_OPTION_IMPLICIT_THREAD_REGISTRATION OFF CACHE BOOL ${EASY_OPTION_IMPLICIT_THREAD_REGISTER_TEXT}) + set(EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS OFF CACHE BOOL "Enable easy_profiler to remove empty unguarded threads. This fixes potential memory leak on Unix systems, but may lead to an application crash! This is used when C++11 thread_local is unavailable.") + else () + set(EASY_OPTION_IMPLICIT_THREAD_REGISTRATION ON CACHE BOOL ${EASY_OPTION_IMPLICIT_THREAD_REGISTER_TEXT}) + endif () +endif () +set(BUILD_WITH_CHRONO_STEADY_CLOCK OFF CACHE BOOL "Use std::chrono::steady_clock as a timer" ) +set(BUILD_WITH_CHRONO_HIGH_RESOLUTION_CLOCK OFF CACHE BOOL "Use std::chrono::high_resolution_clock as a timer") +# End EasyProfiler options. +########################################################### + + + +##################################################################### +# Print EasyProfiler options status: +message(STATUS "-------- EASY_PROFILER OPTIONS: --------") +if (BUILD_WITH_CHRONO_STEADY_CLOCK) + message(STATUS " Use std::chrono::steady_clock as a timer") +elseif (BUILD_WITH_CHRONO_HIGH_RESOLUTION_CLOCK) + message(STATUS " Use std::chrono::high_resolution_clock as a timer") +else () + if (WIN32) + message(STATUS " Use QueryPerformanceCounter as a timer") + else () + message(STATUS " Use rtdsc as a timer") + endif () +endif () + +message(STATUS " Default listening port = ${EASY_DEFAULT_PORT}") +message(STATUS " Auto-start listening = ${EASY_OPTION_LISTEN}") +message(STATUS " Profile self = ${EASY_OPTION_PROFILE_SELF}") +message(STATUS " Profile self blocks initial status = ${EASY_OPTION_PROFILE_SELF_BLOCKS_ON}") +message(STATUS " Implicit thread registration = ${EASY_OPTION_IMPLICIT_THREAD_REGISTRATION}") +if (WIN32) + message(STATUS " Event tracing = ${EASY_OPTION_EVENT_TRACING}") + message(STATUS " Event tracing has low priority = ${EASY_OPTION_LOW_PRIORITY_EVENT_TRACING}") +elseif (NO_CXX11_THREAD_LOCAL_SUPPORT) + if (EASY_OPTION_IMPLICIT_THREAD_REGISTRATION) + message(STATUS " WARNING! Implicit thread registration for Unix systems can lead to memory leak") + message(STATUS " because there is no possibility to check if thread is alive and remove dead threads.") + endif () + message(STATUS " Removing empty unguarded threads = ${EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS}") + if (EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS) + message(STATUS " WARNING! Removing empty unguarded threads may lead to an application crash!") + message(STATUS " But fixes potential memory leak on Unix systems.") + else () + message(STATUS " WARNING! There is a possibility of memory leak without removing empty unguarded threads.") + endif () +endif () +message(STATUS " Log messages = ${EASY_OPTION_LOG}") +message(STATUS " Function names pretty-print = ${EASY_OPTION_PRETTY_PRINT}") +message(STATUS " Use EasyProfiler colors palette = ${EASY_OPTION_PREDEFINED_COLORS}") +message(STATUS " Shared library: ${BUILD_SHARED_LIBS}") +message(STATUS "------ END EASY_PROFILER OPTIONS -------") +message(STATUS "") +# End printing EasyProfiler options status. +##################################################################### + + + +################################################# +# Add source files: +set(CPP_FILES + block.cpp + easy_socket.cpp + event_trace_win.cpp + nonscoped_block.cpp + profile_manager.cpp + reader.cpp + thread_storage.cpp +) + +set(H_FILES + chunk_allocator.h + current_time.h + current_thread.h + event_trace_win.h + nonscoped_block.h + profile_manager.h + thread_storage.h + spin_lock.h + stack_buffer.h +) + +set(INCLUDE_FILES + include/easy/arbitrary_value.h + include/easy/easy_net.h + include/easy/easy_socket.h + include/easy/profiler.h + include/easy/reader.h + include/easy/serialized_block.h + include/easy/details/arbitrary_value_aux.h + include/easy/details/arbitrary_value_public_types.h + include/easy/details/easy_compiler_support.h + include/easy/details/profiler_aux.h + include/easy/details/profiler_colors.h + include/easy/details/profiler_public_types.h +) + +source_group(include FILES ${INCLUDE_FILES}) + +set(SOURCES + ${CPP_FILES} + ${H_FILES} + ${INCLUDE_FILES} +) + +add_library(easy_profiler ${SOURCES} resources.rc) +# End adding source files. +################################################# + + + +target_include_directories(easy_profiler PUBLIC + $ + $ # /include +) +target_compile_definitions(easy_profiler PRIVATE + -D_BUILD_PROFILER=1 + #-DEASY_PROFILER_API_DISABLED # uncomment this to disable profiler api only (you will have to rebuild only easy_profiler) +) +if (NOT BUILD_SHARED_LIBS) + target_compile_definitions(easy_profiler PUBLIC -DEASY_PROFILER_STATIC=1) +endif () +target_compile_definitions(easy_profiler PUBLIC + -DEASY_PROFILER_VERSION_MAJOR=${EASY_PROGRAM_VERSION_MAJOR} + -DEASY_PROFILER_VERSION_MINOR=${EASY_PROGRAM_VERSION_MINOR} + -DEASY_PROFILER_VERSION_PATCH=${EASY_PROGRAM_VERSION_PATCH} + -DEASY_DEFAULT_PORT=${EASY_DEFAULT_PORT} + -DBUILD_WITH_EASY_PROFILER=1 +) + + + +##################################################################### +# Add EasyProfiler options definitions: +easy_define_target_option(easy_profiler BUILD_WITH_CHRONO_STEADY_CLOCK EASY_CHRONO_STEADY_CLOCK) +easy_define_target_option(easy_profiler BUILD_WITH_CHRONO_HIGH_RESOLUTION_CLOCK EASY_CHRONO_HIGHRES_CLOCK) +easy_define_target_option(easy_profiler EASY_OPTION_LISTEN EASY_OPTION_START_LISTEN_ON_STARTUP) +easy_define_target_option(easy_profiler EASY_OPTION_PROFILE_SELF EASY_OPTION_MEASURE_STORAGE_EXPAND) +easy_define_target_option(easy_profiler EASY_OPTION_PROFILE_SELF_BLOCKS_ON EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON) +easy_define_target_option(easy_profiler EASY_OPTION_IMPLICIT_THREAD_REGISTRATION EASY_OPTION_IMPLICIT_THREAD_REGISTRATION) +if (WIN32) + easy_define_target_option(easy_profiler EASY_OPTION_EVENT_TRACING EASY_OPTION_EVENT_TRACING_ENABLED) + easy_define_target_option(easy_profiler EASY_OPTION_LOW_PRIORITY_EVENT_TRACING EASY_OPTION_LOW_PRIORITY_EVENT_TRACING) +else () + easy_define_target_option(easy_profiler EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS) +endif () +easy_define_target_option(easy_profiler EASY_OPTION_LOG EASY_OPTION_LOG_ENABLED) +easy_define_target_option(easy_profiler EASY_OPTION_PRETTY_PRINT EASY_OPTION_PRETTY_PRINT_FUNCTIONS) +easy_define_target_option(easy_profiler EASY_OPTION_PREDEFINED_COLORS EASY_OPTION_BUILTIN_COLORS) +# End adding EasyProfiler options definitions. +##################################################################### + + + +############################################################################### +# Add platform specific compile options: +if (UNIX) + target_compile_options(easy_profiler PRIVATE -Wall -Wno-long-long -Wno-reorder -Wno-braced-scalar-init -pedantic) + target_link_libraries(easy_profiler pthread) +elseif (WIN32) + target_compile_definitions(easy_profiler PRIVATE -D_WIN32_WINNT=0x0600 -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS) + target_link_libraries(easy_profiler ws2_32 psapi) +endif () + +if (MINGW) + target_compile_definitions(easy_profiler PRIVATE -DSTRSAFE_NO_DEPRECATE) +endif () + +if (MSVC) + target_compile_options(easy_profiler PRIVATE /WX) +endif () + +if (APPLE) + target_compile_options(easy_profiler PUBLIC -std=gnu++11) +else () + if (CMAKE_VERSION VERSION_LESS "3.1") + if (NOT MSVC) + target_compile_options(easy_profiler PUBLIC $<$:-std=gnu++11>) + endif () + else () + if (NOT MSVC) + target_compile_options(easy_profiler PUBLIC -std=gnu++11) + endif () + set_target_properties(easy_profiler PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON) + endif () +endif () +# End adding platform specific compile options. +############################################################################### + + + +######################################################################################### +# Installation: +set(config_install_dir "lib/cmake/${PROJECT_NAME}") +set(include_install_dir "include") + +set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") + +# Configuration +set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake") +set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake") +set(targets_export_name "${PROJECT_NAME}Targets") + +include(CMakePackageConfigHelpers) +include(InstallRequiredSystemLibraries) + +write_basic_package_version_file( + "${version_config}" + VERSION + ${EASY_PRODUCT_VERSION_STRING} + COMPATIBILITY + SameMajorVersion +) + +configure_package_config_file( + "cmake/config.cmake.in" + "${project_config}" + INSTALL_DESTINATION "${config_install_dir}" +) + +install( + FILES "${project_config}" "${version_config}" + DESTINATION "${config_install_dir}" +) + +install( + FILES + ${INCLUDE_FILES} + DESTINATION + include/easy +) + +install( + FILES + LICENSE.MIT + LICENSE.APACHE + DESTINATION + . +) + +install( + TARGETS + easy_profiler + EXPORT + ${targets_export_name} + DESTINATION + bin + INCLUDES DESTINATION "${include_install_dir}" +) + +install( + EXPORT "${targets_export_name}" + DESTINATION "${config_install_dir}" +) + +target_compile_definitions(easy_profiler PUBLIC ) diff --git a/3rdparty/easyprofiler/easy_profiler_core/LICENSE.APACHE b/3rdparty/easyprofiler/easy_profiler_core/LICENSE.APACHE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/LICENSE.APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/3rdparty/easyprofiler/easy_profiler_core/LICENSE.MIT b/3rdparty/easyprofiler/easy_profiler_core/LICENSE.MIT new file mode 100644 index 0000000..3840145 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/LICENSE.MIT @@ -0,0 +1,18 @@ +Copyright (c) 2017 Sergey Yagovtsev, Victor Zarubkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/3rdparty/easyprofiler/easy_profiler_core/block.cpp b/3rdparty/easyprofiler/easy_profiler_core/block.cpp new file mode 100644 index 0000000..de0b7b7 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/block.cpp @@ -0,0 +1,241 @@ +/************************************************************************ +* file name : block.cpp +* ----------------- : +* creation time : 2016/02/16 +* authors : Sergey Yagovtsev, Victor Zarubkin +* emails : yse.sey@gmail.com, v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of profiling blocks +* : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include "profile_manager.h" +#include "current_time.h" + +using namespace profiler; + +#ifndef EASY_PROFILER_API_DISABLED +Event::Event(timestamp_t _begin_time) EASY_NOEXCEPT : m_begin(_begin_time), m_end(0) +{ + +} + +Event::Event(timestamp_t _begin_time, timestamp_t _end_time) EASY_NOEXCEPT : m_begin(_begin_time), m_end(_end_time) +{ + +} + +BaseBlockData::BaseBlockData(timestamp_t _begin_time, block_id_t _descriptor_id) EASY_NOEXCEPT + : Event(_begin_time) + , m_id(_descriptor_id) +{ + +} + +BaseBlockData::BaseBlockData(timestamp_t _begin_time, timestamp_t _end_time, block_id_t _descriptor_id) EASY_NOEXCEPT + : Event(_begin_time, _end_time) + , m_id(_descriptor_id) +{ + +} + +Block::Block(Block&& that) EASY_NOEXCEPT + : BaseBlockData(that.m_begin, that.m_id) + , m_name(that.m_name) + , m_status(that.m_status) + , m_isScoped(that.m_isScoped) +{ + m_end = that.m_end; + that.m_end = that.m_begin; +} + +Block::Block(timestamp_t _begin_time, block_id_t _descriptor_id, const char* _runtimeName) EASY_NOEXCEPT + : BaseBlockData(_begin_time, _descriptor_id) + , m_name(_runtimeName) + , m_status(::profiler::ON) + , m_isScoped(true) +{ + +} + +Block::Block(timestamp_t _begin_time, timestamp_t _end_time, block_id_t _descriptor_id, const char* _runtimeName) EASY_NOEXCEPT + : BaseBlockData(_begin_time, _end_time, _descriptor_id) + , m_name(_runtimeName) + , m_status(::profiler::ON) + , m_isScoped(true) +{ + +} + +Block::Block(const BaseBlockDescriptor* _descriptor, const char* _runtimeName, bool _scoped) EASY_NOEXCEPT + : BaseBlockData(1ULL, _descriptor->id()) + , m_name(_runtimeName) + , m_status(_descriptor->status()) + , m_isScoped(_scoped) +{ + +} + +void Block::start() +{ + m_begin = getCurrentTime(); +} + +void Block::start(timestamp_t _time) EASY_NOEXCEPT +{ + m_begin = _time; +} + +void Block::finish() +{ + m_end = getCurrentTime(); +} + +void Block::finish(timestamp_t _time) EASY_NOEXCEPT +{ + m_end = _time; +} + +Block::~Block() +{ + if (!finished()) + ::profiler::endBlock(); +} +#else +Event::Event(timestamp_t) EASY_NOEXCEPT : m_begin(0), m_end(0) +{ + +} + +Event::Event(timestamp_t, timestamp_t) EASY_NOEXCEPT : m_begin(0), m_end(0) +{ + +} + +BaseBlockData::BaseBlockData(timestamp_t, block_id_t) EASY_NOEXCEPT + : Event(0, 0) + , m_id(~0U) +{ + +} + +BaseBlockData::BaseBlockData(timestamp_t, timestamp_t, block_id_t) EASY_NOEXCEPT + : Event(0, 0) + , m_id(~0U) +{ + +} + +Block::Block(Block&& that) EASY_NOEXCEPT + : BaseBlockData(0, ~0U) + , m_name("") + , m_status(::profiler::OFF) + , m_isScoped(that.m_isScoped) +{ +} + +Block::Block(timestamp_t, block_id_t, const char*) EASY_NOEXCEPT + : BaseBlockData(0, ~0U) + , m_name("") + , m_status(::profiler::OFF) + , m_isScoped(true) +{ + +} + +Block::Block(timestamp_t, timestamp_t, block_id_t, const char*) EASY_NOEXCEPT + : BaseBlockData(0, ~0U) + , m_name("") + , m_status(::profiler::OFF) + , m_isScoped(true) +{ + +} + +Block::Block(const BaseBlockDescriptor*, const char*, bool _scoped) EASY_NOEXCEPT + : BaseBlockData(0, ~0U) + , m_name("") + , m_status(::profiler::OFF) + , m_isScoped(_scoped) +{ + +} + +void Block::start() +{ +} + +void Block::start(timestamp_t) EASY_NOEXCEPT +{ +} + +void Block::finish() +{ +} + +void Block::finish(timestamp_t) EASY_NOEXCEPT +{ +} + +Block::~Block() +{ +} +#endif + +////////////////////////////////////////////////////////////////////////// + +CSwitchEvent::CSwitchEvent(timestamp_t _begin_time, thread_id_t _tid) EASY_NOEXCEPT + : Event(_begin_time) + , m_thread_id(_tid) +{ + +} + +CSwitchBlock::CSwitchBlock(timestamp_t _begin_time, thread_id_t _tid, const char* _runtimeName) EASY_NOEXCEPT + : CSwitchEvent(_begin_time, _tid) + , m_name(_runtimeName) +{ + +} + +////////////////////////////////////////////////////////////////////////// diff --git a/3rdparty/easyprofiler/easy_profiler_core/chunk_allocator.h b/3rdparty/easyprofiler/easy_profiler_core/chunk_allocator.h new file mode 100644 index 0000000..c189cf3 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/chunk_allocator.h @@ -0,0 +1,509 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_CHUNK_ALLOCATOR_H +#define EASY_PROFILER_CHUNK_ALLOCATOR_H + +#include +#include +#include +#include +#include "outstream.h" + +////////////////////////////////////////////////////////////////////////// + +#ifndef EASY_ENABLE_ALIGNMENT +# define EASY_ENABLE_ALIGNMENT 0 +#endif + +#ifndef EASY_ALIGNMENT_SIZE +# define EASY_ALIGNMENT_SIZE alignof(std::max_align_t) +#endif + +#if EASY_ENABLE_ALIGNMENT == 0 +# define EASY_ALIGNED(TYPE, VAR, A) TYPE VAR +# define EASY_MALLOC(MEMSIZE, A) malloc(MEMSIZE) +# define EASY_FREE(MEMPTR) free(MEMPTR) +#else +// MSVC and GNUC aligned versions of malloc are defined in malloc.h +# include +# if defined(_MSC_VER) +# define EASY_ALIGNED(TYPE, VAR, A) __declspec(align(A)) TYPE VAR +# define EASY_MALLOC(MEMSIZE, A) _aligned_malloc(MEMSIZE, A) +# define EASY_FREE(MEMPTR) _aligned_free(MEMPTR) +# elif defined(__GNUC__) +# define EASY_ALIGNED(TYPE, VAR, A) TYPE VAR __attribute__((aligned(A))) +# define EASY_MALLOC(MEMSIZE, A) memalign(A, MEMSIZE) +# define EASY_FREE(MEMPTR) free(MEMPTR) +# else +# define EASY_ALIGNED(TYPE, VAR, A) TYPE VAR +# define EASY_MALLOC(MEMSIZE, A) malloc(MEMSIZE) +# define EASY_FREE(MEMPTR) free(MEMPTR) +# endif +#endif + +////////////////////////////////////////////////////////////////////////// + +//! Checks if a pointer is aligned. +//! \param ptr The pointer to check. +//! \param alignment The alignement (must be a power of 2) +//! \returns true if the memory is aligned. +//! +template +EASY_FORCE_INLINE bool is_aligned(void* ptr) +{ + static_assert(ALIGNMENT % 2 == 0, "Alignment must be a power of two."); + return ((uintptr_t)ptr & (ALIGNMENT-1)) == 0; +} + +EASY_FORCE_INLINE void unaligned_zero16(void* ptr) +{ +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *(uint16_t*)ptr = 0; +#else + ((char*)ptr)[0] = 0; + ((char*)ptr)[1] = 0; +#endif +} + +EASY_FORCE_INLINE void unaligned_zero32(void* ptr) +{ +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *(uint32_t*)ptr = 0; +#else + ((char*)ptr)[0] = 0; + ((char*)ptr)[1] = 0; + ((char*)ptr)[2] = 0; + ((char*)ptr)[3] = 0; +#endif +} + +EASY_FORCE_INLINE void unaligned_zero64(void* ptr) +{ +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *(uint64_t*)ptr = 0; +#else + // Assume unaligned is more common. + if (!is_aligned(ptr)) { + ((char*)ptr)[0] = 0; + ((char*)ptr)[1] = 0; + ((char*)ptr)[2] = 0; + ((char*)ptr)[3] = 0; + ((char*)ptr)[4] = 0; + ((char*)ptr)[5] = 0; + ((char*)ptr)[6] = 0; + ((char*)ptr)[7] = 0; + } + else { + *(uint64_t*)ptr = 0; + } +#endif +} + +template +EASY_FORCE_INLINE void unaligned_store16(void* ptr, T val) +{ + static_assert(sizeof(T) == 2, "16 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *(T*)ptr = val; +#else + const char* const temp = (char*)&val; + ((char*)ptr)[0] = temp[0]; + ((char*)ptr)[1] = temp[1]; +#endif +} + +template +EASY_FORCE_INLINE void unaligned_store32(void* ptr, T val) +{ + static_assert(sizeof(T) == 4, "32 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *(T*)ptr = val; +#else + const char* const temp = (char*)&val; + ((char*)ptr)[0] = temp[0]; + ((char*)ptr)[1] = temp[1]; + ((char*)ptr)[2] = temp[2]; + ((char*)ptr)[3] = temp[3]; +#endif +} + +template +EASY_FORCE_INLINE void unaligned_store64(void* ptr, T val) +{ + static_assert(sizeof(T) == 8, "64 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *(T*)ptr = val; +#else + const char* const temp = (char*)&val; + // Assume unaligned is more common. + if (!is_aligned(ptr)) { + ((char*)ptr)[0] = temp[0]; + ((char*)ptr)[1] = temp[1]; + ((char*)ptr)[2] = temp[2]; + ((char*)ptr)[3] = temp[3]; + ((char*)ptr)[4] = temp[4]; + ((char*)ptr)[5] = temp[5]; + ((char*)ptr)[6] = temp[6]; + ((char*)ptr)[7] = temp[7]; + } + else { + *(T*)ptr = val; + } +#endif +} + +template +EASY_FORCE_INLINE T unaligned_load16(const void* ptr) +{ + static_assert(sizeof(T) == 2, "16 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + return *(T*)ptr; +#else + T value; + ((char*)&value)[0] = ((char*)ptr)[0]; + ((char*)&value)[1] = ((char*)ptr)[1]; + return value; +#endif +} + +template +EASY_FORCE_INLINE T unaligned_load16(const void* ptr, T* val) +{ + static_assert(sizeof(T) == 2, "16 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *val = *(T*)ptr; + return *val; +#else + ((char*)val)[0] = ((char*)ptr)[0]; + ((char*)val)[1] = ((char*)ptr)[1]; + return *val; +#endif +} + +template +EASY_FORCE_INLINE T unaligned_load32(const void* ptr) +{ + static_assert(sizeof(T) == 4, "32 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + return *(T*)ptr; +#else + T value; + ((char*)&value)[0] = ((char*)ptr)[0]; + ((char*)&value)[1] = ((char*)ptr)[1]; + ((char*)&value)[2] = ((char*)ptr)[2]; + ((char*)&value)[3] = ((char*)ptr)[3]; + return value; +#endif +} + +template +EASY_FORCE_INLINE T unaligned_load32(const void* ptr, T* val) +{ + static_assert(sizeof(T) == 4, "32 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *val = *(T*)ptr; +#else + ((char*)&val)[0] = ((char*)ptr)[0]; + ((char*)&val)[1] = ((char*)ptr)[1]; + ((char*)&val)[2] = ((char*)ptr)[2]; + ((char*)&val)[3] = ((char*)ptr)[3]; + return *val; +#endif +} + +template +EASY_FORCE_INLINE T unaligned_load64(const void* ptr) +{ + static_assert(sizeof(T) == 8, "64 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + return *(T*)ptr; +#else + if (!is_aligned(ptr)) { + T value; + ((char*)&value)[0] = ((char*)ptr)[0]; + ((char*)&value)[1] = ((char*)ptr)[1]; + ((char*)&value)[2] = ((char*)ptr)[2]; + ((char*)&value)[3] = ((char*)ptr)[3]; + ((char*)&value)[4] = ((char*)ptr)[4]; + ((char*)&value)[5] = ((char*)ptr)[5]; + ((char*)&value)[6] = ((char*)ptr)[6]; + ((char*)&value)[7] = ((char*)ptr)[7]; + return value; + } + else { + return *(T*)ptr; + } +#endif +} + +template +EASY_FORCE_INLINE T unaligned_load64(const void* ptr, T* val) +{ + static_assert(sizeof(T) == 8, "64 bit type required."); +#ifndef EASY_ENABLE_STRICT_ALIGNMENT + *val = *(T*)ptr; +#else + if (!is_aligned(ptr)) { + ((char*)&val)[0] = ((char*)ptr)[0]; + ((char*)&val)[1] = ((char*)ptr)[1]; + ((char*)&val)[2] = ((char*)ptr)[2]; + ((char*)&val)[3] = ((char*)ptr)[3]; + ((char*)&val)[4] = ((char*)ptr)[4]; + ((char*)&val)[5] = ((char*)ptr)[5]; + ((char*)&val)[6] = ((char*)ptr)[6]; + ((char*)&val)[7] = ((char*)ptr)[7]; + return *val; + } + else { + *val = *(T*)ptr; + return *val; + } +#endif +} + +////////////////////////////////////////////////////////////////////////// + +template +class chunk_allocator +{ + struct chunk { EASY_ALIGNED(char, data[N], EASY_ALIGNMENT_SIZE); chunk* prev = nullptr; }; + + struct chunk_list + { + chunk* last; + + chunk_list() : last(nullptr) + { + static_assert(sizeof(char) == 1, "easy_profiler logic error: sizeof(char) != 1 for this platform! Please, contact easy_profiler authors to resolve your problem."); + emplace_back(); + } + + ~chunk_list() + { + do free_last(); while (last != nullptr); + } + + void clear_all_except_last() + { + while (last->prev != nullptr) + free_last(); + zero_last_chunk_size(); + } + + void emplace_back() + { + auto prev = last; + last = ::new (EASY_MALLOC(sizeof(chunk), EASY_ALIGNMENT_SIZE)) chunk(); + last->prev = prev; + zero_last_chunk_size(); + } + + /** Invert current chunks list to enable to iterate over chunks list in direct order. + + This method is used by serialize(). + */ + void invert() + { + chunk* next = nullptr; + + while (last->prev != nullptr) { + auto p = last->prev; + last->prev = next; + next = last; + last = p; + } + + last->prev = next; + } + + private: + + chunk_list(const chunk_list&) = delete; + chunk_list(chunk_list&&) = delete; + + void free_last() + { + auto p = last; + last = last->prev; + EASY_FREE(p); + } + + void zero_last_chunk_size() + { + // Although there is no need for unaligned access stuff b/c a new chunk will + // usually be at least 8 byte aligned (and we only need 2 byte alignment), + // this is the only way I have been able to get rid of the GCC strict-aliasing warning + // without using std::memset. It's an extra line, but is just as fast as *(uint16_t*)last->data = 0; + char* const data = last->data; + *(uint16_t*)data = (uint16_t)0; + } + }; + + // Used in serialize(): workaround for no constexpr support in MSVC 2013. + static const int_fast32_t MAX_CHUNK_OFFSET = N - sizeof(uint16_t); + static const uint16_t N_MINUS_ONE = N - 1; + + chunk_list m_chunks; ///< List of chunks. + uint32_t m_size; ///< Number of elements stored(# of times allocate() has been called.) + uint16_t m_chunkOffset; ///< Number of bytes used in the current chunk. + +public: + + chunk_allocator() : m_size(0), m_chunkOffset(0) + { + } + + /** Allocate n bytes. + + Automatically checks if there is enough preserved memory to store additional n bytes + and allocates additional buffer if needed. + */ + void* allocate(uint16_t n) + { + ++m_size; + + if (!need_expand(n)) + { + // Temp to avoid extra load due to this* aliasing. + uint16_t chunkOffset = m_chunkOffset; + char* data = m_chunks.last->data + chunkOffset; + chunkOffset += n + sizeof(uint16_t); + m_chunkOffset = chunkOffset; + + unaligned_store16(data, n); + data += sizeof(uint16_t); + + // If there is enough space for at least another payload size, + // set it to zero. + if (chunkOffset < N_MINUS_ONE) + unaligned_zero16(data + n); + + return data; + } + + m_chunkOffset = n + sizeof(uint16_t); + m_chunks.emplace_back(); + + char* data = m_chunks.last->data; + unaligned_store16(data, n); + data += sizeof(uint16_t); + + // We assume here that it takes more than one element to fill a chunk. + unaligned_zero16(data + n); + + return data; + } + + /** Check if current storage is not enough to store additional n bytes. + */ + bool need_expand(uint16_t n) const + { + return (m_chunkOffset + n + sizeof(uint16_t)) > N; + } + + uint32_t size() const + { + return m_size; + } + + bool empty() const + { + return m_size == 0; + } + + void clear() + { + m_size = 0; + m_chunkOffset = 0; + m_chunks.clear_all_except_last(); // There is always at least one chunk + } + + /** Serialize data to stream. + + \warning Data will be cleared after serialization. + */ + void serialize(profiler::OStream& _outputStream) + { + // Chunks are stored in reversed order (stack). + // To be able to iterate them in direct order we have to invert the chunks list. + m_chunks.invert(); + + // Each chunk is an array of N bytes that can hold between + // 1(if the list isn't empty) and however many elements can fit in a chunk, + // where an element consists of a payload size + a payload as follows: + // elementStart[0..1]: size as a uint16_t + // elementStart[2..size-1]: payload. + + // The maximum chunk offset is N-sizeof(uint16_t) b/c, if we hit that (or go past), + // there is either no space left, 1 byte left, or 2 bytes left, all of which are + // too small to cary more than a zero-sized element. + + chunk* current = m_chunks.last; + do { + const char* data = current->data; + int_fast32_t chunkOffset = 0; // signed int so overflow is not checked. + uint16_t payloadSize = unaligned_load16(data); + while (chunkOffset < MAX_CHUNK_OFFSET && payloadSize != 0) { + const uint16_t chunkSize = sizeof(uint16_t) + payloadSize; + _outputStream.write(data, chunkSize); + data += chunkSize; + chunkOffset += chunkSize; + unaligned_load16(data, &payloadSize); + } + + current = current->prev; + } while (current != nullptr); + + clear(); + } + +private: + + chunk_allocator(const chunk_allocator&) = delete; + chunk_allocator(chunk_allocator&&) = delete; + +}; // END of class chunk_allocator. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_CHUNK_ALLOCATOR_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/cmake/config.cmake.in b/3rdparty/easyprofiler/easy_profiler_core/cmake/config.cmake.in new file mode 100644 index 0000000..9b4c9ee --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/cmake/config.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/3rdparty/easyprofiler/easy_profiler_core/cmake_install.cmake b/3rdparty/easyprofiler/easy_profiler_core/cmake_install.cmake new file mode 100644 index 0000000..89b2d40 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/cmake_install.cmake @@ -0,0 +1,104 @@ +# Install script for directory: /home/alex/Work/C++Projects/easyprofiler/easy_profiler_core + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler" TYPE FILE FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/generated/easy_profilerConfig.cmake" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/generated/easy_profilerConfigVersion.cmake" + ) +endif() + +if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include/easy" TYPE FILE FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/arbitrary_value.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/easy_net.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/easy_socket.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/profiler.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/reader.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/serialized_block.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_aux.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_public_types.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/details/easy_compiler_support.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/details/profiler_aux.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/details/profiler_colors.h" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include/easy/details/profiler_public_types.h" + ) +endif() + +if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/." TYPE FILE FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/LICENSE.MIT" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/LICENSE.APACHE" + ) +endif() + +if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so") + file(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so" + RPATH "$ORIGIN") + endif() + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE SHARED_LIBRARY FILES "/home/alex/Work/C++Projects/easyprofiler/bin/libeasy_profiler.so") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so") + file(RPATH_CHANGE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so" + OLD_RPATH ":::::::" + NEW_RPATH "$ORIGIN") + if(CMAKE_INSTALL_DO_STRIP) + execute_process(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/libeasy_profiler.so") + endif() + endif() +endif() + +if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler/easy_profilerTargets.cmake") + file(DIFFERENT EXPORT_FILE_CHANGED FILES + "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler/easy_profilerTargets.cmake" + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets.cmake") + if(EXPORT_FILE_CHANGED) + file(GLOB OLD_CONFIG_FILES "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler/easy_profilerTargets-*.cmake") + if(OLD_CONFIG_FILES) + message(STATUS "Old export file \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler/easy_profilerTargets.cmake\" will be replaced. Removing files [${OLD_CONFIG_FILES}].") + file(REMOVE ${OLD_CONFIG_FILES}) + endif() + endif() + endif() + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler" TYPE FILE FILES "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets.cmake") + if("${CMAKE_INSTALL_CONFIG_NAME}" MATCHES "^([Rr][Ee][Ll][Ee][Aa][Ss][Ee])$") + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/easy_profiler" TYPE FILE FILES "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/Export/lib/cmake/easy_profiler/easy_profilerTargets-release.cmake") + endif() +endif() + diff --git a/3rdparty/easyprofiler/easy_profiler_core/current_thread.h b/3rdparty/easyprofiler/easy_profiler_core/current_thread.h new file mode 100644 index 0000000..816979c --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/current_thread.h @@ -0,0 +1,79 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_CURRENT_THREAD_H +#define EASY_PROFILER_CURRENT_THREAD_H + +#include + +#ifdef _WIN32 +# include +#elif defined(__APPLE__) +# include +# include +#else +# include +# include +# include +#endif + +inline profiler::thread_id_t getCurrentThreadId() +{ +#ifdef _WIN32 + return (profiler::thread_id_t)::GetCurrentThreadId(); +#elif defined(__APPLE__) +# if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6) || \ + (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0) + EASY_THREAD_LOCAL static uint64_t _id = 0; + if (!_id) + pthread_threadid_np(NULL, &_id); + return (profiler::thread_id_t)_id; +# else + return (profiler::thread_id_t)pthread_self(); +# endif +#else + EASY_THREAD_LOCAL static const profiler::thread_id_t _id = (profiler::thread_id_t)syscall(__NR_gettid); + return _id; +#endif +} + +#endif // EASY_PROFILER_CURRENT_THREAD_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/current_time.h b/3rdparty/easyprofiler/easy_profiler_core/current_time.h new file mode 100644 index 0000000..b08224e --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/current_time.h @@ -0,0 +1,174 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_CURRENT_TIME_H +#define EASY_PROFILER_CURRENT_TIME_H + +#include + +#if defined(_MSC_VER) && _MSC_VER <= 1800 +// std::chrono for MSVC2013 is broken - it has very low resolution of 16ms +// restrict usage of std::chrono +# if EASY_CHRONO_HIGHRES_CLOCK +# undef EASY_CHRONO_HIGHRES_CLOCK +# endif +# if EASY_CHRONO_STEADY_CLOCK +# undef EASY_CHRONO_STEADY_CLOCK +# endif +#endif + +#if EASY_CHRONO_HIGHRES_CLOCK +# include +# define EASY_CHRONO_CLOCK std::chrono::high_resolution_clock +#elif EASY_CHRONO_STEADY_CLOCK +# include +# define EASY_CHRONO_CLOCK std::chrono::steady_clock +#elif defined(_WIN32) +# include +#else +# include +# include +# ifdef __ARM_ARCH +# include +# endif//__ARM_ARCH +#endif + +static inline profiler::timestamp_t getCurrentTime() +{ +#if EASY_CHRONO_HIGHRES_CLOCK || EASY_CHRONO_STEADY_CLOCK + return (profiler::timestamp_t)EASY_CHRONO_CLOCK::now().time_since_epoch().count(); +#elif defined(_WIN32) + //see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx + LARGE_INTEGER elapsedMicroseconds; + if (!QueryPerformanceCounter(&elapsedMicroseconds)) + return 0; + return (profiler::timestamp_t)elapsedMicroseconds.QuadPart; +#else// not _WIN32 + +#if (defined(__GNUC__) || defined(__ICC)) + + // part of code from google/benchmark library (Licensed under the Apache License, Version 2.0) + // see https://github.com/google/benchmark/blob/master/src/cycleclock.h#L111 + #if defined(__i386__) + int64_t ret; + __asm__ volatile("rdtsc" : "=A"(ret)); + return ret; + #elif defined(__x86_64__) || defined(__amd64__) + uint64_t low, high; + __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); + return (high << 32) | low; + #elif defined(__powerpc__) || defined(__ppc__) + // This returns a time-base, which is not always precisely a cycle-count. + int64_t tbl, tbu0, tbu1; + asm("mftbu %0" : "=r"(tbu0)); + asm("mftb %0" : "=r"(tbl)); + asm("mftbu %0" : "=r"(tbu1)); + tbl &= -static_cast(tbu0 == tbu1); + // high 32 bits in tbu1; low 32 bits in tbl (tbu0 is garbage) + return (tbu1 << 32) | tbl; + #elif defined(__sparc__) + int64_t tick; + asm(".byte 0x83, 0x41, 0x00, 0x00"); + asm("mov %%g1, %0" : "=r"(tick)); + return tick; + #elif defined(__ia64__) + int64_t itc; + asm("mov %0 = ar.itc" : "=r"(itc)); + return itc; + #elif defined(COMPILER_MSVC) && defined(_M_IX86) + // Older MSVC compilers (like 7.x) don't seem to support the + // __rdtsc intrinsic properly, so I prefer to use _asm instead + // when I know it will work. Otherwise, I'll use __rdtsc and hope + // the code is being compiled with a non-ancient compiler. + _asm rdtsc + #elif defined(COMPILER_MSVC) + return __rdtsc(); + #elif defined(__aarch64__) + // System timer of ARMv8 runs at a different frequency than the CPU's. + // The frequency is fixed, typically in the range 1-50MHz. It can be + // read at CNTFRQ special register. We assume the OS has set up + // the virtual timer properly. + int64_t virtual_timer_value; + asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); + return virtual_timer_value; + #elif defined(__ARM_ARCH) + #if (__ARM_ARCH >= 6) // V6 is the earliest arch that has a standard cyclecount + uint32_t pmccntr; + uint32_t pmuseren; + uint32_t pmcntenset; + // Read the user mode perf monitor counter access permissions. + asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren)); + if (pmuseren & 1) { // Allows reading perfmon counters for user mode code. + asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset)); + if (pmcntenset & 0x80000000ul) { // Is it counting? + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr)); + // The counter is set up to count every 64th cycle + return static_cast(pmccntr) * 64; // Should optimize to << 6 + } + } + #endif + struct timeval tv; + gettimeofday(&tv, nullptr); + return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; + #elif defined(__mips__) + // mips apparently only allows rdtsc for superusers, so we fall + // back to gettimeofday. It's possible clock_gettime would be better. + struct timeval tv; + gettimeofday(&tv, nullptr); + return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; + #else + #warning You need to define fast getCurrentTime() for your OS and CPU + return std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #define EASY_CHRONO_CLOCK std::chrono::high_resolution_clock + #endif + +#else // not _WIN32, __GNUC__, __ICC + #warning You need to define fast getCurrentTime() for your OS and CPU + return std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #define EASY_CHRONO_CLOCK std::chrono::high_resolution_clock +#endif + +#endif +} + + +#endif // EASY_PROFILER_CURRENT_TIME_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/easy_socket.cpp b/3rdparty/easyprofiler/easy_profiler_core/easy_socket.cpp new file mode 100644 index 0000000..05f6308 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/easy_socket.cpp @@ -0,0 +1,431 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of +* MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); +You may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +**/ + +#include +#include +#include +#include + +#if defined(_WIN32) +# pragma comment (lib, "Ws2_32.lib") +# pragma comment (lib, "Mswsock.lib") +# pragma comment (lib, "AdvApi32.lib") +# ifdef max +# undef max +# endif +#else +# include +# include +#endif + +///////////////////////////////////////////////////////////////// + +#if defined(_WIN32) +const int SOCK_ABORTED = WSAECONNABORTED; +const int SOCK_RESET = WSAECONNRESET; +const int SOCK_IN_PROGRESS = WSAEINPROGRESS; +#else +const int SOCK_ABORTED = ECONNABORTED; +const int SOCK_RESET = ECONNRESET; +const int SOCK_IN_PROGRESS = EINPROGRESS; +const int SOCK_BROKEN_PIPE = EPIPE; +const int SOCK_ENOENT = ENOENT; +#endif + +const int SEND_BUFFER_SIZE = 64 * 1024 * 1024; + +///////////////////////////////////////////////////////////////// + +static int closeSocket(EasySocket::socket_t s) +{ +#if defined(_WIN32) + return ::closesocket(s); +#else + return ::close(s); +#endif +} + +///////////////////////////////////////////////////////////////// + +bool EasySocket::checkSocket(socket_t s) const +{ + return s > 0; +} + +void EasySocket::setBlocking(EasySocket::socket_t s, bool blocking) +{ +#if defined(_WIN32) + u_long iMode = blocking ? 0 : 1;//0 - blocking, 1 - non blocking + ::ioctlsocket(s, FIONBIO, &iMode); +#else + int iMode = blocking ? 0 : 1;//0 - blocking, 1 - non blocking + ::ioctl(s, FIONBIO, (char*)&iMode); +#endif +} + +int EasySocket::bind(uint16_t port) +{ + if (!checkSocket(m_socket)) + return -1; + + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(port); + auto res = ::bind(m_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); + + return res; +} + +void EasySocket::flush() +{ + if (m_socket) + closeSocket(m_socket); + + if (m_replySocket != m_socket) + closeSocket(m_replySocket); + +#if defined(_WIN32) + m_socket = 0; + m_replySocket = 0; +#else + m_wsaret = 0; +#endif +} + +void EasySocket::checkResult(int result) +{ + if (result >= 0) + { + m_state = ConnectionState::Connected; + return; + } + + if (result == -1) // is this check necessary? + { +#if defined(_WIN32) + const int error_code = WSAGetLastError(); +#else + const int error_code = errno; +#endif + + switch (error_code) + { + case SOCK_ABORTED: + case SOCK_RESET: +#if !defined(_WIN32) + case SOCK_BROKEN_PIPE: + case SOCK_ENOENT: +#endif + m_state = ConnectionState::Disconnected; + break; + + case SOCK_IN_PROGRESS: + m_state = ConnectionState::Connecting; + break; + + default: + break; + } + } +} + +void EasySocket::init() +{ + if (m_wsaret != 0) + return; + +#if !defined(_WIN32) + const int protocol = 0; +#else + const int protocol = IPPROTO_TCP; +#endif + + m_socket = ::socket(AF_INET, SOCK_STREAM, protocol); + if (!checkSocket(m_socket)) + return; + + setBlocking(m_socket, true); + +#if !defined(_WIN32) + m_wsaret = 1; +#endif + + const int opt = 1; + ::setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(int)); +} + +EasySocket::ConnectionState EasySocket::state() const +{ + return m_state; +} + +bool EasySocket::isDisconnected() const +{ + return static_cast(m_state) <= 0; +} + +bool EasySocket::isConnected() const +{ + return m_state == ConnectionState::Connected; +} + +EasySocket::EasySocket() +{ +#if defined(_WIN32) + WSADATA wsaData; + m_wsaret = WSAStartup(0x101, &wsaData); +#else + m_wsaret = 0; +#endif + + init(); +} + +EasySocket::~EasySocket() +{ + flush(); + +#if defined(_WIN32) + if (m_wsaret == 0) + WSACleanup(); +#endif +} + +void EasySocket::setReceiveTimeout(int milliseconds) +{ + if (!isConnected() || !checkSocket(m_replySocket)) + return; + + if (milliseconds <= 0) + milliseconds = std::numeric_limits::max() / 1000; + +#if defined(_WIN32) + const DWORD timeout = static_cast(milliseconds); + ::setsockopt(m_replySocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(DWORD)); +#else + struct timeval tv; + if (milliseconds >= 1000) + { + const int s = milliseconds / 1000; + const int us = (milliseconds - s * 1000) * 1000; + tv.tv_sec = s; + tv.tv_usec = us; + } + else + { + tv.tv_sec = 0; + tv.tv_usec = milliseconds * 1000; + } + + ::setsockopt(m_replySocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof (struct timeval)); +#endif +} + +int EasySocket::send(const void* buffer, size_t nbytes) +{ + if (!checkSocket(m_replySocket)) + return -1; + +#if defined(_WIN32) || defined(__APPLE__) + const int res = ::send(m_replySocket, (const char*)buffer, (int)nbytes, 0); +#else + const int res = (int)::send(m_replySocket, buffer, nbytes, MSG_NOSIGNAL); +#endif + + checkResult(res); + + return res; +} + +int EasySocket::receive(void* buffer, size_t nbytes) +{ + if (!checkSocket(m_replySocket)) + return -1; + +#if defined(_WIN32) + const int res = ::recv(m_replySocket, (char*)buffer, (int)nbytes, 0); +#else + const int res = (int)::read(m_replySocket, buffer, nbytes); +#endif + + checkResult(res); + if (res == 0) + m_state = ConnectionState::Disconnected; + + return res; +} + +int EasySocket::listen(int count) +{ + if (!checkSocket(m_socket)) + return -1; + + const int res = ::listen(m_socket, count); + checkResult(res); + + return res; +} + +int EasySocket::accept() +{ + if (!checkSocket(m_socket)) + return -1; + + fd_set fdread; + FD_ZERO (&fdread); + FD_SET (m_socket, &fdread); + + fd_set fdwrite = fdread; + fd_set fdexcl = fdread; + + struct timeval tv { 0, 500 }; + const int rc = ::select((int)m_socket + 1, &fdread, &fdwrite, &fdexcl, &tv); + if (rc <= 0) + return -1; // there is no connection for accept + + m_replySocket = ::accept(m_socket, nullptr, nullptr); + checkResult((int)m_replySocket); + + if (checkSocket(m_replySocket)) + { + ::setsockopt(m_replySocket, SOL_SOCKET, SO_SNDBUF, (char*)&SEND_BUFFER_SIZE, sizeof(int)); + + //const int flag = 1; + //const int result = setsockopt(m_replySocket,IPPROTO_TCP,TCP_NODELAY,(char *)&flag,sizeof(int)); + +#if defined(__APPLE__) + // Apple doesn't have MSG_NOSIGNAL, work around it + const int value = 1; + ::setsockopt(m_replySocket, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)); +#endif + + //setBlocking(m_replySocket,true); + } + + return (int)m_replySocket; +} + +bool EasySocket::setAddress(const char* address, uint16_t port) +{ + m_server = ::gethostbyname(address); + if (m_server == nullptr) + return false; + + memset((char*)&m_serverAddress, 0, sizeof(m_serverAddress)); + m_serverAddress.sin_family = AF_INET; + memcpy((char*)&m_serverAddress.sin_addr.s_addr, (char*)m_server->h_addr, (size_t)m_server->h_length); + + m_serverAddress.sin_port = htons(port); + + return true; +} + +int EasySocket::connect() +{ + if (m_server == nullptr || m_socket <= 0) + return -1; + + int res = 0; + //TODO: more intelligence +#if !defined(_WIN32) + setBlocking(m_socket, false); + + const int sleepMs = 20; + const int waitSec = 1; + const int waitMs = waitSec * 1000 / sleepMs; + + for (int counter = 0; counter++ < waitMs;) + { + res = ::connect(m_socket, (struct sockaddr*)&m_serverAddress, sizeof(m_serverAddress)); + +#if defined(__APPLE__) + // on Apple, treat EISCONN error as success + if (res == -1 && errno == EISCONN) + { + res = 0; + break; + } +#endif + + checkResult(res); + if (res == 0) + { + break; + } + + if (m_state == ConnectionState::Connecting) + { + std::this_thread::sleep_for(std::chrono::milliseconds(sleepMs)); + continue; + } + + if (isDisconnected()) + { + break; + } + } + + setBlocking(m_socket, true); +#else + res = ::connect(m_socket, (struct sockaddr*)&m_serverAddress, sizeof(m_serverAddress)); + checkResult(res); +#endif + + if (res == 0) + { + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + ::setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(struct timeval)); + +#if defined(__APPLE__) + // Apple doesn't have MSG_NOSIGNAL, work around it + const int value = 1; + setsockopt(m_socket, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)); +#endif + + m_replySocket = m_socket; + } + + return res; +} diff --git a/3rdparty/easyprofiler/easy_profiler_core/event_trace_status.h b/3rdparty/easyprofiler/easy_profiler_core/event_trace_status.h new file mode 100644 index 0000000..12c4476 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/event_trace_status.h @@ -0,0 +1,27 @@ + + + +#ifndef EASY_PROFILER__EVENT_TRACE_STATUS__H_ +#define EASY_PROFILER__EVENT_TRACE_STATUS__H_ + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + enum EventTracingEnableStatus : unsigned char + { + EVENT_TRACING_LAUNCHED_SUCCESSFULLY = 0, + EVENT_TRACING_NOT_ENOUGH_ACCESS_RIGHTS, + EVENT_TRACING_WAS_LAUNCHED_BY_SOMEBODY_ELSE, + EVENT_TRACING_BAD_PROPERTIES_SIZE, + EVENT_TRACING_OPEN_TRACE_ERROR, + EVENT_TRACING_MISTERIOUS_ERROR, + }; + +} // END of namespace profiler. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER__EVENT_TRACE_STATUS__H_ diff --git a/3rdparty/easyprofiler/easy_profiler_core/event_trace_win.cpp b/3rdparty/easyprofiler/easy_profiler_core/event_trace_win.cpp new file mode 100644 index 0000000..871a797 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/event_trace_win.cpp @@ -0,0 +1,550 @@ +/************************************************************************ +* file name : event_trace_win.cpp +* ----------------- : +* creation time : 2016/09/04 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyEventTracer class used for tracing +* : Windows system events to get context switches. +* ----------------- : +* change log : * 2016/09/04 Victor Zarubkin: initial commit. +* : +* : * 2016/09/13 Victor Zarubkin: get process id and process name +* : of the owner of thread with id == CSwitch::NewThreadId. +* : +* : * 2016/09/17 Victor Zarubkin: added log messages printing. +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifdef _WIN32 +#include +#include +#include +#include +#include "profile_manager.h" +#include "current_time.h" + +#include "event_trace_win.h" +#include + +#ifdef __MINGW32__ +#include +#endif + +//#include + +#if EASY_OPTION_LOG_ENABLED != 0 +# include + +# ifndef EASY_ERRORLOG +# define EASY_ERRORLOG ::std::cerr +# endif + +# ifndef EASY_LOG +# define EASY_LOG ::std::cerr +# endif + +# ifndef EASY_ERROR +# define EASY_ERROR(LOG_MSG) EASY_ERRORLOG << "EasyProfiler ERROR: " << LOG_MSG +# endif + +# ifndef EASY_WARNING +# define EASY_WARNING(LOG_MSG) EASY_ERRORLOG << "EasyProfiler WARNING: " << LOG_MSG +# endif + +# ifndef EASY_LOGMSG +# define EASY_LOGMSG(LOG_MSG) EASY_LOG << "EasyProfiler INFO: " << LOG_MSG +# endif + +# ifndef EASY_LOG_ONLY +# define EASY_LOG_ONLY(CODE) CODE +# endif + +#else + +# ifndef EASY_ERROR +# define EASY_ERROR(LOG_MSG) +# endif + +# ifndef EASY_WARNING +# define EASY_WARNING(LOG_MSG) +# endif + +# ifndef EASY_LOGMSG +# define EASY_LOGMSG(LOG_MSG) +# endif + +# ifndef EASY_LOG_ONLY +# define EASY_LOG_ONLY(CODE) +# endif + +#endif + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +//extern ProfileManager& MANAGER; +#define MANAGER ProfileManager::instance() + +extern const ::profiler::color_t EASY_COLOR_INTERNAL_EVENT; + +#ifdef __MINGW32__ +::std::atomic TRACING_END_TIME = ATOMIC_VAR_INIT(~0ULL); +char KERNEL_LOGGER[] = KERNEL_LOGGER_NAME; +#else +::std::atomic_uint64_t TRACING_END_TIME = ATOMIC_VAR_INIT(~0ULL); +#endif + +namespace profiler { + + const decltype(EVENT_DESCRIPTOR::Opcode) SWITCH_CONTEXT_OPCODE = 36; + const int RAW_TIMESTAMP_TIME_TYPE = 1; + + ////////////////////////////////////////////////////////////////////////// + + struct ProcessInfo { + std::string name; + processid_t id = 0; + int8_t valid = 0; + }; + + ////////////////////////////////////////////////////////////////////////// + + // CSwitch class + // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa964744(v=vs.85).aspx + // EventType = 36 + struct CSwitch + { + uint32_t NewThreadId; + uint32_t OldThreadId; + int8_t NewThreadPriority; + int8_t OldThreadPriority; + uint8_t PreviousCState; + int8_t SpareByte; + int8_t OldThreadWaitReason; + int8_t OldThreadWaitMode; + int8_t OldThreadState; + int8_t OldThreadWaitIdealProcessor; + uint32_t NewThreadWaitTime; + uint32_t Reserved; + }; + + ////////////////////////////////////////////////////////////////////////// + + struct do_not_calc_hash { + template inline size_t operator()(T _value) const { + return static_cast(_value); + } + }; + + typedef ::std::unordered_map thread_process_info_map; + typedef ::std::unordered_map process_info_map; + + // Using static is safe because processTraceEvent() is called from one thread + process_info_map PROCESS_INFO_TABLE; + thread_process_info_map THREAD_PROCESS_INFO_TABLE = ([](){ thread_process_info_map initial; initial[0U] = nullptr; return ::std::move(initial); })(); + + ////////////////////////////////////////////////////////////////////////// + + void WINAPI processTraceEvent(PEVENT_RECORD _traceEvent) + { + if (_traceEvent->EventHeader.EventDescriptor.Opcode != SWITCH_CONTEXT_OPCODE) + return; + + if (sizeof(CSwitch) != _traceEvent->UserDataLength) + return; + + EASY_FUNCTION(EASY_COLOR_INTERNAL_EVENT, ::profiler::OFF); + + auto _contextSwitchEvent = reinterpret_cast(_traceEvent->UserData); + const auto time = static_cast<::profiler::timestamp_t>(_traceEvent->EventHeader.TimeStamp.QuadPart); + if (time > TRACING_END_TIME.load(::std::memory_order_acquire)) + return; + + DWORD pid = 0; + const char* process_name = ""; + + // Trying to get target process name and id + auto it = THREAD_PROCESS_INFO_TABLE.find(_contextSwitchEvent->NewThreadId); + if (it == THREAD_PROCESS_INFO_TABLE.end()) + { + auto hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, _contextSwitchEvent->NewThreadId); + if (hThread != nullptr) + { + pid = GetProcessIdOfThread(hThread); + auto pinfo = &PROCESS_INFO_TABLE[pid]; + + if (pinfo->valid == 0) + { + if (pinfo->name.empty()) + { + static char numbuf[128] = {}; + sprintf(numbuf, "%u", pid); + pinfo->name = numbuf; + pinfo->id = pid; + } + + /* + According to documentation, using GetModuleBaseName() requires + PROCESS_QUERY_INFORMATION | PROCESS_VM_READ access rights. + But it works fine with PROCESS_QUERY_LIMITED_INFORMATION instead of PROCESS_QUERY_INFORMATION. + + See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683196(v=vs.85).aspx + */ + + //auto hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + //if (hProc == nullptr) + auto hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (hProc != nullptr) + { + static TCHAR buf[MAX_PATH] = {}; // Using static is safe because processTraceEvent() is called from one thread + auto len = GetModuleBaseName(hProc, 0, buf, MAX_PATH); + + if (len != 0) + { + pinfo->name.reserve(pinfo->name.size() + 2 + len); + pinfo->name.append(" ", 1); + pinfo->name.append(buf, len); + pinfo->valid = 1; + } + + CloseHandle(hProc); + } + else + { + //auto err = GetLastError(); + //printf("OpenProcess(%u) fail: GetLastError() == %u\n", pid, err); + pinfo->valid = -1; + + if (pid == 4) { + pinfo->name.reserve(pinfo->name.size() + 8); + pinfo->name.append(" System", 7); + } + } + } + + process_name = pinfo->name.c_str(); + THREAD_PROCESS_INFO_TABLE[_contextSwitchEvent->NewThreadId] = pinfo; + + CloseHandle(hThread); + } + else + { + //printf("Can not OpenThread(%u);\n", _contextSwitchEvent->NewThreadId); + THREAD_PROCESS_INFO_TABLE[_contextSwitchEvent->NewThreadId] = nullptr; + } + } + else + { + auto pinfo = it->second; + if (pinfo != nullptr) + process_name = pinfo->name.c_str(); + else if (it->first == 0) + process_name = "System Idle"; + else if (it->first == 4) + process_name = "System"; + } + + MANAGER.beginContextSwitch(_contextSwitchEvent->OldThreadId, time, _contextSwitchEvent->NewThreadId, process_name); + MANAGER.endContextSwitch(_contextSwitchEvent->NewThreadId, pid, time); + } + + ////////////////////////////////////////////////////////////////////////// + +#ifndef EASY_MAGIC_STATIC_AVAILABLE + class EasyEventTracerInstance { + friend EasyEventTracer; + EasyEventTracer instance; + } EASY_EVENT_TRACER; +#endif + + EasyEventTracer& EasyEventTracer::instance() + { +#ifndef EASY_MAGIC_STATIC_AVAILABLE + return EASY_EVENT_TRACER.instance; +#else + static EasyEventTracer tracer; + return tracer; +#endif + } + + EasyEventTracer::EasyEventTracer() + { + m_lowPriority = ATOMIC_VAR_INIT(EASY_OPTION_LOW_PRIORITY_EVENT_TRACING); + } + + EasyEventTracer::~EasyEventTracer() + { + disable(); + } + + bool EasyEventTracer::isLowPriority() const + { + return m_lowPriority.load(::std::memory_order_acquire); + } + + void EasyEventTracer::setLowPriority(bool _value) + { + m_lowPriority.store(_value, ::std::memory_order_release); + } + + bool setPrivilege(HANDLE hToken, LPCSTR _privelegeName) + { + bool success = false; + + if (hToken) + { + LUID privilegyId; + if (LookupPrivilegeValue(NULL, _privelegeName, &privilegyId)) + { + TOKEN_PRIVILEGES tokenPrivilege; + tokenPrivilege.PrivilegeCount = 1; + tokenPrivilege.Privileges[0].Luid = privilegyId; + tokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + success = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivilege, sizeof(TOKEN_PRIVILEGES), NULL, NULL) != FALSE; + } + } + + EASY_LOG_ONLY( + if (!success) + EASY_WARNING("Failed to set " << _privelegeName << " privelege for the application.\n"); + ) + + return success; + } + + void EasyEventTracer::setProcessPrivileges() + { + static bool alreadySet = false; + if (alreadySet) + return; + + alreadySet = true; + + HANDLE hToken = nullptr; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + { +#if EASY_OPTION_LOG_ENABLED != 0 + const bool success = setPrivilege(hToken, SE_DEBUG_NAME); + if (!success) + EASY_WARNING("Some context switch events could not get process name.\n"); +#else + setPrivilege(hToken, SE_DEBUG_NAME); +#endif + + CloseHandle(hToken); + } + EASY_LOG_ONLY( + else { + EASY_WARNING("Failed to open process to adjust priveleges.\n"); + } + ) + } + + ::profiler::EventTracingEnableStatus EasyEventTracer::startTrace(bool _force, int _step) + { + auto startTraceResult = StartTrace(&m_sessionHandle, KERNEL_LOGGER_NAME, props()); + switch (startTraceResult) + { + case ERROR_SUCCESS: + return EVENT_TRACING_LAUNCHED_SUCCESSFULLY; + + case ERROR_ALREADY_EXISTS: + { + if (_force) + { + // Try to stop another event tracing session to force launch self session. + + if (_step == 0) + { + /* + According to https://msdn.microsoft.com/en-us/library/windows/desktop/aa363696(v=vs.85).aspx + SessionHandle is ignored (and could be NULL) if SessionName is not NULL, + and you only need to set the Wnode.BufferSize, Wnode.Guid, LoggerNameOffset, and LogFileNameOffset + in EVENT_TRACE_PROPERTIES structure if ControlCode is EVENT_TRACE_CONTROL_STOP. + All data is already set for m_properties to the moment. Simply copy m_properties and use the copy. + + This method supposed to be faster than launching console window and executing shell command, + but if that would not work, return to using shell command "logman stop". + */ + + // static is safe because we are guarded by spin-lock m_spin + static Properties p = ([]{ Properties prp; strncpy(prp.sessionName, KERNEL_LOGGER_NAME, sizeof(prp.sessionName)); return prp; })(); + p.base = m_properties.base; // Use copy of m_properties to make sure m_properties will not be changed + + // Stop another session + ControlTrace((TRACEHANDLE)NULL, KERNEL_LOGGER_NAME, reinterpret_cast(&p), EVENT_TRACE_CONTROL_STOP); + + // Console window variant: + //if (32 >= (int)ShellExecute(NULL, NULL, "logman", "stop \"" KERNEL_LOGGER_NAME "\" -ets", NULL, SW_HIDE)) + // return EVENT_TRACING_WAS_LAUNCHED_BY_SOMEBODY_ELSE; + } + + if (_step < 4) + { + // Command executed successfully. Wait for a few time until tracing session finish. + ::std::this_thread::sleep_for(::std::chrono::milliseconds(500)); + return startTrace(true, ++_step); + } + } + + EASY_ERROR("Event tracing not launched: ERROR_ALREADY_EXISTS. To stop another session execute cmd: logman stop \"" << KERNEL_LOGGER_NAME << "\" -ets\n"); + return EVENT_TRACING_WAS_LAUNCHED_BY_SOMEBODY_ELSE; + } + + case ERROR_ACCESS_DENIED: + EASY_ERROR("Event tracing not launched: ERROR_ACCESS_DENIED. Try to launch your application as Administrator.\n"); + return EVENT_TRACING_NOT_ENOUGH_ACCESS_RIGHTS; + + case ERROR_BAD_LENGTH: + EASY_ERROR("Event tracing not launched: ERROR_BAD_LENGTH. It seems that your KERNEL_LOGGER_NAME differs from \"" << m_properties.sessionName << "\". Try to re-compile easy_profiler or contact EasyProfiler developers.\n"); + return EVENT_TRACING_BAD_PROPERTIES_SIZE; + } + + EASY_ERROR("Event tracing not launched: StartTrace() returned " << startTraceResult << ::std::endl); + + return EVENT_TRACING_MISTERIOUS_ERROR; + } + + ::profiler::EventTracingEnableStatus EasyEventTracer::enable(bool _force) + { + ::profiler::guard_lock<::profiler::spin_lock> lock(m_spin); + if (m_bEnabled) + return EVENT_TRACING_LAUNCHED_SUCCESSFULLY; + + /* + Trying to set debug privilege for current process + to be able to get other process information (process name). + */ + EasyEventTracer::setProcessPrivileges(); + + // Clear properties + memset(&m_properties, 0, sizeof(m_properties)); + m_properties.base.Wnode.BufferSize = sizeof(m_properties); + m_properties.base.Wnode.Flags = WNODE_FLAG_TRACED_GUID; + m_properties.base.Wnode.ClientContext = RAW_TIMESTAMP_TIME_TYPE; + m_properties.base.Wnode.Guid = SystemTraceControlGuid; + m_properties.base.LoggerNameOffset = sizeof(m_properties.base); + m_properties.base.EnableFlags = EVENT_TRACE_FLAG_CSWITCH; + m_properties.base.LogFileMode = EVENT_TRACE_REAL_TIME_MODE; + + // Start event tracing + auto res = startTrace(_force); + if (res != EVENT_TRACING_LAUNCHED_SUCCESSFULLY) + return res; + + memset(&m_trace, 0, sizeof(m_trace)); +#ifdef __MINGW32__ + m_trace.LoggerName = KERNEL_LOGGER; +#else + m_trace.LoggerName = KERNEL_LOGGER_NAME; +#endif + m_trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP; + m_trace.EventRecordCallback = ::profiler::processTraceEvent; + + m_openedHandle = OpenTrace(&m_trace); + if (m_openedHandle == INVALID_PROCESSTRACE_HANDLE) + { + EASY_ERROR("Event tracing not launched: OpenTrace() returned invalid handle.\n"); + return EVENT_TRACING_OPEN_TRACE_ERROR; + } + + /* + Have to launch a thread to process events because according to MSDN documentation: + + The ProcessTrace function blocks the thread until it delivers all events, the BufferCallback function returns FALSE, + or you call CloseTrace. If the consumer is consuming events in real time, the ProcessTrace function returns after + the controller stops the trace session. (Note that there may be a several-second delay before the function returns.) + + https://msdn.microsoft.com/en-us/library/windows/desktop/aa364093(v=vs.85).aspx + */ + m_processThread = ::std::thread([this](bool _lowPriority) + { + if (_lowPriority) // Set low priority for event tracing thread + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + EASY_THREAD_SCOPE("EasyProfiler.ETW"); + ProcessTrace(&m_openedHandle, 1, 0, 0); + + }, m_lowPriority.load(::std::memory_order_acquire)); + + m_bEnabled = true; + + EASY_LOGMSG("Event tracing launched\n"); + return EVENT_TRACING_LAUNCHED_SUCCESSFULLY; + } + + void EasyEventTracer::disable() + { + ::profiler::guard_lock<::profiler::spin_lock> lock(m_spin); + if (!m_bEnabled) + return; + + EASY_LOGMSG("Event tracing is stopping...\n"); + + TRACING_END_TIME.store(getCurrentTime(), ::std::memory_order_release); + + ControlTrace(m_openedHandle, KERNEL_LOGGER_NAME, props(), EVENT_TRACE_CONTROL_STOP); + CloseTrace(m_openedHandle); + + // Wait for ProcessTrace to finish to make sure no processTraceEvent() will be called later. + if (m_processThread.joinable()) + m_processThread.join(); + + m_bEnabled = false; + + // processTraceEvent() is not called anymore. Clean static maps is safe. + PROCESS_INFO_TABLE.clear(); + THREAD_PROCESS_INFO_TABLE.clear(); + THREAD_PROCESS_INFO_TABLE[0U] = nullptr; + + TRACING_END_TIME.store(~0ULL, ::std::memory_order_release); + + EASY_LOGMSG("Event tracing stopped\n"); + } + +} // END of namespace profiler. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // _WIN32 diff --git a/3rdparty/easyprofiler/easy_profiler_core/event_trace_win.h b/3rdparty/easyprofiler/easy_profiler_core/event_trace_win.h new file mode 100644 index 0000000..cb3c01b --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/event_trace_win.h @@ -0,0 +1,129 @@ +/************************************************************************ +* file name : event_trace_win.h +* ----------------- : +* creation time : 2016/09/04 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyEventTracer class used for tracing +* : Windows system events to get context switches. +* ----------------- : +* change log : * 2016/09/04 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER_EVENT_TRACE_WINDOWS_H +#define EASY_PROFILER_EVENT_TRACE_WINDOWS_H +#ifdef _WIN32 + +#define INITGUID // This is to enable using SystemTraceControlGuid in evntrace.h. +#include +#include +#include +#include +#include +#include +#include +#include "event_trace_status.h" +#include "spin_lock.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + class EasyEventTracer EASY_FINAL + { +#ifndef EASY_MAGIC_STATIC_AVAILABLE + friend class EasyEventTracerInstance; +#endif + +#pragma pack(push, 1) + struct Properties { + EVENT_TRACE_PROPERTIES base; + char sessionName[sizeof(KERNEL_LOGGER_NAME)]; + }; +#pragma pack(pop) + + ::std::thread m_processThread; + Properties m_properties; + EVENT_TRACE_LOGFILE m_trace; + ::profiler::spin_lock m_spin; + ::std::atomic_bool m_lowPriority; + TRACEHANDLE m_sessionHandle = INVALID_PROCESSTRACE_HANDLE; + TRACEHANDLE m_openedHandle = INVALID_PROCESSTRACE_HANDLE; + bool m_bEnabled = false; + + public: + + static EasyEventTracer& instance(); + ~EasyEventTracer(); + + bool isLowPriority() const; + + ::profiler::EventTracingEnableStatus enable(bool _force = false); + void disable(); + void setLowPriority(bool _value); + static void setProcessPrivileges(); + + private: + + EasyEventTracer(); + + inline EVENT_TRACE_PROPERTIES* props() + { + return reinterpret_cast(&m_properties); + } + + ::profiler::EventTracingEnableStatus startTrace(bool _force, int _step = 0); + + }; // END of class EasyEventTracer. + +} // END of namespace profiler. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // _WIN32 +#endif // EASY_PROFILER_EVENT_TRACE_WINDOWS_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/generated/easy_profilerConfig.cmake b/3rdparty/easyprofiler/easy_profiler_core/generated/easy_profilerConfig.cmake new file mode 100644 index 0000000..75ba62d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/generated/easy_profilerConfig.cmake @@ -0,0 +1,28 @@ + +####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### +####### Any changes to this file will be overwritten by the next CMake run #### +####### The input file was config.cmake.in ######## + +get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +macro(set_and_check _var _file) + set(${_var} "${_file}") + if(NOT EXISTS "${_file}") + message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") + endif() +endmacro() + +macro(check_required_components _NAME) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(NOT ${_NAME}_${comp}_FOUND) + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME}_FOUND FALSE) + endif() + endif() + endforeach() +endmacro() + +#################################################################################### + +include("${CMAKE_CURRENT_LIST_DIR}/easy_profilerTargets.cmake") +check_required_components("easy_profiler") diff --git a/3rdparty/easyprofiler/easy_profiler_core/generated/easy_profilerConfigVersion.cmake b/3rdparty/easyprofiler/easy_profiler_core/generated/easy_profilerConfigVersion.cmake new file mode 100644 index 0000000..4f2f941 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/generated/easy_profilerConfigVersion.cmake @@ -0,0 +1,46 @@ +# This is a basic version file for the Config-mode of find_package(). +# It is used by write_basic_package_version_file() as input file for configure_file() +# to create a version-file which can be installed along a config.cmake file. +# +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, +# but only if the requested major version is the same as the current one. +# The variable CVF_VERSION must be set before calling configure_file(). + + +set(PACKAGE_VERSION "1.3.0") + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + + if("1.3.0" MATCHES "^([0-9]+)\\.") + set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") + else() + set(CVF_VERSION_MAJOR "1.3.0") + endif() + + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() + + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") + return() +endif() + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") + math(EXPR installedBits "8 * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() diff --git a/3rdparty/easyprofiler/easy_profiler_core/hashed_cstr.h b/3rdparty/easyprofiler/easy_profiler_core/hashed_cstr.h new file mode 100644 index 0000000..075f2b1 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/hashed_cstr.h @@ -0,0 +1,298 @@ +/************************************************************************ +* file name : hashed_str.h +* ----------------- : +* creation time : 2016/09/11 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains definition of C-strings with calculated hash-code. +* : These strings may be used as optimized keys for std::unordered_map. +* ----------------- : +* change log : * 2016/09/11 Victor Zarubkin: Initial commit. Moved sources from reader.cpp +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER__HASHED_CSTR__H_ +#define EASY_PROFILER__HASHED_CSTR__H_ + +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#if 0 == 1//defined(_MSC_VER)// && _MSC_VER >= 1800 +# define EASY_PROFILER_HASHED_CSTR_DEFINED + +namespace profiler { + + /** \brief Simple C-string pointer with length. + + It is used as base class for a key in std::unordered_map. + It is used to get better performance than std::string. + It simply stores a pointer and a length, there is no + any memory allocation and copy. + + \warning Make sure you know what you are doing. You have to be sure that + pointed C-string will exist until you finish using this cstring. + + \ingroup profiler + */ + class cstring + { + protected: + + const char* m_str; + size_t m_len; + + public: + + cstring(const char* _str) : m_str(_str), m_len(strlen(_str)) + { + } + + cstring(const char* _str, size_t _len) : m_str(_str), m_len(_len) + { + } + + cstring(const cstring&) = default; + cstring& operator = (const cstring&) = default; + + inline bool operator == (const cstring& _other) const + { + return m_len == _other.m_len && !strncmp(m_str, _other.m_str, m_len); + } + + inline bool operator != (const cstring& _other) const + { + return !operator == (_other); + } + + inline bool operator < (const cstring& _other) const + { + if (m_len == _other.m_len) + { + return strncmp(m_str, _other.m_str, m_len) < 0; + } + + return m_len < _other.m_len; + } + + inline const char* c_str() const + { + return m_str; + } + + inline size_t size() const + { + return m_len; + } + + }; // END of class cstring. + + /** \brief cstring with precalculated hash. + + This is used to calculate hash for C-string and to cache it + to be used in the future without recurring hash calculatoin. + + \note This class is used as a key in std::unordered_map. + + \ingroup profiler + */ + class hashed_cstr : public cstring + { + typedef cstring Parent; + + size_t m_hash; + + public: + + hashed_cstr(const char* _str) : Parent(_str), m_hash(0) + { + m_hash = ::std::_Hash_seq((const unsigned char *)m_str, m_len); + } + + hashed_cstr(const char* _str, size_t _hash_code) : Parent(_str), m_hash(_hash_code) + { + } + + hashed_cstr(const char* _str, size_t _len, size_t _hash_code) : Parent(_str, _len), m_hash(_hash_code) + { + } + + hashed_cstr(const hashed_cstr&) = default; + hashed_cstr& operator = (const hashed_cstr&) = default; + + inline bool operator == (const hashed_cstr& _other) const + { + return m_hash == _other.m_hash && Parent::operator == (_other); + } + + inline bool operator != (const hashed_cstr& _other) const + { + return !operator == (_other); + } + + inline size_t hcode() const + { + return m_hash; + } + + }; // END of class hashed_cstr. + +} // END of namespace profiler. + +namespace std { + + /** \brief Simply returns precalculated hash of a C-string. */ + template <> struct hash<::profiler::hashed_cstr> { + typedef ::profiler::hashed_cstr argument_type; + typedef size_t result_type; + inline size_t operator () (const ::profiler::hashed_cstr& _str) const { + return _str.hcode(); + } + }; + +} // END of namespace std. + +#else //////////////////////////////////////////////////////////////////// + +// TODO: Create hashed_cstr for Linux (need to use Linux version of std::_Hash_seq) + +#endif + +namespace profiler { + + class hashed_stdstring + { + ::std::string m_str; + size_t m_hash; + + public: + + hashed_stdstring(const char* _str) : m_str(_str), m_hash(::std::hash<::std::string>()(m_str)) + { + } + + hashed_stdstring(const ::std::string& _str) : m_str(_str), m_hash(::std::hash<::std::string>()(m_str)) + { + } + + hashed_stdstring(::std::string&& _str) : m_str(::std::forward<::std::string&&>(_str)), m_hash(::std::hash<::std::string>()(m_str)) + { + } + + hashed_stdstring(hashed_stdstring&& _other) : m_str(::std::move(_other.m_str)), m_hash(_other.m_hash) + { + } + + hashed_stdstring(const char* _str, size_t _hash_code) : m_str(_str), m_hash(_hash_code) + { + } + + hashed_stdstring(const ::std::string& _str, size_t _hash_code) : m_str(_str), m_hash(_hash_code) + { + } + + hashed_stdstring(::std::string&& _str, size_t _hash_code) : m_str(::std::forward<::std::string&&>(_str)), m_hash(_hash_code) + { + } + + hashed_stdstring(const hashed_stdstring&) = default; + hashed_stdstring& operator = (const hashed_stdstring&) = default; + + hashed_stdstring& operator = (hashed_stdstring&& _other) + { + m_str = ::std::move(_other.m_str); + m_hash = _other.m_hash; + return *this; + } + + inline bool operator == (const hashed_stdstring& _other) const + { + return m_hash == _other.m_hash && m_str == _other.m_str; + } + + inline bool operator != (const hashed_stdstring& _other) const + { + return !operator == (_other); + } + + inline size_t hcode() const + { + return m_hash; + } + + inline const char* c_str() const + { + return m_str.c_str(); + } + + inline size_t size() const + { + return m_str.size(); + } + + }; // END of class hashed_stdstring. + +} // END of namespace profiler. + +namespace std { + + /** \brief Simply returns precalculated hash of a std::string. */ + template <> struct hash<::profiler::hashed_stdstring> { + typedef ::profiler::hashed_stdstring argument_type; + typedef size_t result_type; + inline size_t operator () (const ::profiler::hashed_stdstring& _str) const { + return _str.hcode(); + } + }; + +} // END of namespace std. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER__HASHED_CSTR__H_ diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/arbitrary_value.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/arbitrary_value.h new file mode 100644 index 0000000..9e1305b --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/arbitrary_value.h @@ -0,0 +1,308 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_ARBITRARY_VALUE_H +#define EASY_PROFILER_ARBITRARY_VALUE_H + +#include + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" +#endif + +#ifdef USING_EASY_PROFILER + +/** Macro used to create a unique Value Identification Number. + +Use this if you want to change the same value from different places in your code. +Otherwise do not mind. + +\code +struct A { + int someCount; +}; + +void foo(const A& a) { + EASY_VALUE("foo count", a.someCount); // Value ID is automatically set to (uint64_t)&a.someCount + + // This notation is completely the same as EASY_VALUE("foo count", a.someCount, EASY_VIN(a.someCount)); +} + +void bar(const A& b) { + EASY_VALUE("bar count", b.someCount); // Same ID as for "foo count" if &b == &a (and different ID otherwise) +} + +void baz(const A& c) { + EASY_VALUE("baz count", c.someCount, EASY_VIN(EASY_FUNC_NAME)); // Different ID from "foo count" and "bar count" + EASY_VALUE("qux count", 100500, EASY_VIN(EASY_FUNC_NAME)); // Same ID as for "baz count" +} +\endcode + +\ingroup profiler +*/ +# define EASY_VIN(member) ::profiler::ValueId(member) + +/** Macro used to identify global value which would be recognized by it's name in GUI. + +\code +struct A { + int someCount; +}; + +struct B { + int someOtherCount; +}; + +void foo(const A& a) { + EASY_VALUE("Count", a.someCount, EASY_GLOBAL_VIN); +} + +void bar(const B& b) { + EASY_VALUE("Count", b.someOtherCount, EASY_GLOBAL_VIN); // Same ID as for foo::"Count" despite of &b != &a +} +\endcode + +\ingroup profiler +*/ +# define EASY_GLOBAL_VIN ::profiler::ValueId() + +/** Macro used to identify unique value. + +\code +struct A { + int someCount; +}; + +void foo(const A& a) { + // All these values would have different IDs despite of names, pointers and values are the same + EASY_VALUE("foo count", a.someCount, EASY_UNIQUE_VIN); + EASY_VALUE("foo count", a.someCount, EASY_UNIQUE_VIN); + EASY_VALUE("foo count", a.someCount, EASY_UNIQUE_VIN); +} +\endcode + +\ingroup profiler +*/ +# define EASY_UNIQUE_VIN ::profiler::ValueId(EASY_UNIQUE_DESC(__LINE__)) + +/** Macro used to store single arbitrary value. + +\note Also stores a time-stamp of it's occurrence like an Event. + +\note To store an array, please, use EASY_ARRAY macro. + +\note Currently arbitrary values support only compile-time names. + +\sa EASY_ARRAY, EASY_TEXT, EASY_STRING + +\ingroup profiler +*/ +# define EASY_VALUE(name, value, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Value, ::profiler::extract_color(__VA_ARGS__), false));\ + ::profiler::setValue(EASY_UNIQUE_DESC(__LINE__), value, ::profiler::extract_value_id(value, ## __VA_ARGS__)); + +/** Macro used to store an array of arbitrary values. + +\note Also stores a time-stamp of it's occurrence like an Event. + +\note Currently arbitrary values support only compile-time names. + +\sa EASY_VALUE, EASY_TEXT, EASY_STRING + +\ingroup profiler +*/ +# define EASY_ARRAY(name, value, size, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Value, ::profiler::extract_color(__VA_ARGS__), false));\ + ::profiler::setValue(EASY_UNIQUE_DESC(__LINE__), value, ::profiler::extract_value_id(value, ## __VA_ARGS__), size); + +/** Macro used to store custom text. + +Could be C-string or std::string. + +\note Also stores a time-stamp of it's occurrence like an Event. + +\note Currently arbitrary values support only compile-time names. + +\sa EASY_VALUE, EASY_ARRAY, EASY_STRING + +\ingroup profiler +*/ +# define EASY_TEXT(name, text, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Value, ::profiler::extract_color(__VA_ARGS__), false));\ + ::profiler::setText(EASY_UNIQUE_DESC(__LINE__), text, ::profiler::extract_value_id(text , ## __VA_ARGS__)); + +/** Macro used to store custom text of specified length. + +Same as EASY_TEXT, but with explicitly specified length. +Use this for C-strings of known length (compile-time or run-time). + +\note Recommendation (not a requirement): Take into account a zero-terminator '\0' symbol (e.g. strlen("BlaBla") + 1). + +\note Also stores a time-stamp of it's occurrence like an Event. + +\note Currently arbitrary values support only compile-time names. + +\sa EASY_VALUE, EASY_ARRAY, EASY_TEXT + +\ingroup profiler +*/ +# define EASY_STRING(name, text, size, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Value, ::profiler::extract_color(__VA_ARGS__), false));\ + ::profiler::setText(EASY_UNIQUE_DESC(__LINE__), text, ::profiler::extract_value_id(text, ## __VA_ARGS__), size); + +namespace profiler +{ + + EASY_CONSTEXPR uint16_t MaxArbitraryValuesArraySize = 65535; + + extern "C" PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, + size_t _size, bool _isArray, ValueId _vin); + + template + inline void setValue(const BaseBlockDescriptor* _desc, T _value, ValueId _vin) + { + static_assert(!::std::is_pointer::value, + "You should not pass pointers into EASY_VALUE. Pass a reference instead."); + + using Type = typename ::std::remove_reference::type>::type; + + static_assert(StdToDataType::data_type != DataType::TypesCount, + "You should use standard builtin scalar types as profiler::Value type!"); + + storeValue(_desc, StdToDataType::data_type, &_value, sizeof(Type), false, _vin); + } + + template + inline void setValue(const BaseBlockDescriptor* _desc, const T* _valueArray, ValueId _vin, uint16_t _arraySize) + { + static_assert(StdToDataType::data_type != DataType::TypesCount, + "You should use standard builtin scalar types as profiler::Value type!"); + + storeValue(_desc, StdToDataType::data_type, _valueArray, sizeof(T) * _arraySize, true, _vin); + } + + template + inline void setValue(const BaseBlockDescriptor* _desc, const T (&_value)[N], ValueId _vin) + { + static_assert(StdToDataType::data_type != DataType::TypesCount, + "You should use standard builtin scalar types as profiler::Value type!"); + + static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 65535."); + + storeValue(_desc, StdToDataType::data_type, _value, sizeof(_value), true, _vin); + } + + inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin, uint16_t _textLength) + { + storeValue(_desc, DataType::String, _text, _textLength, true, _vin); + } + + inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin) + { + storeValue(_desc, DataType::String, _text, strlen(_text) + 1, true, _vin); + } + + inline void setText(const BaseBlockDescriptor* _desc, const ::std::string& _text, ValueId _vin) + { + storeValue(_desc, DataType::String, _text.c_str(), _text.size() + 1, true, _vin); + } + + template + inline void setText(const BaseBlockDescriptor* _desc, const char (&_text)[N], ValueId _vin) + { + static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 65535."); + storeValue(_desc, DataType::String, &_text[0], N, true, _vin); + } + +} // end of namespace profiler. + +#else + +# define EASY_GLOBAL_VIN +# define EASY_UNIQUE_VIN +# define EASY_VIN(member) +# define EASY_VALUE(...) +# define EASY_ARRAY(...) +# define EASY_TEXT(...) +# define EASY_STRING(...) + +namespace profiler +{ + + inline void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool, ValueId) {} + + template + inline void setValue(const BaseBlockDescriptor*, T, ValueId) {} + + template + inline void setValue(const BaseBlockDescriptor*, const T*, ValueId, uint16_t) {} + + template + inline void setValue(const BaseBlockDescriptor*, const T (&)[N], ValueId) {} + + inline void setText(const BaseBlockDescriptor*, const char*, ValueId, uint16_t) {} + + inline void setText(const BaseBlockDescriptor*, const char*, ValueId) {} + + inline void setText(const BaseBlockDescriptor*, const ::std::string&, ValueId) {} + + template + inline void setText(const BaseBlockDescriptor*, const char (&)[N], ValueId) {} + +} // end of namespace profiler. + +#endif // USING_EASY_PROFILER + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#endif // EASY_PROFILER_ARBITRARY_VALUE_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_aux.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_aux.h new file mode 100644 index 0000000..2f8506e --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_aux.h @@ -0,0 +1,130 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_ARBITRARY_VALUE_AUX_H +#define EASY_PROFILER_ARBITRARY_VALUE_AUX_H + +#include +#include + +namespace profiler +{ + + using vin_t = uint64_t; + + class ValueId EASY_FINAL + { + friend ::ThreadStorage; + vin_t m_id; + + public: + +#if defined(_MSC_VER) && _MSC_VER <= 1800 + inline EASY_CONSTEXPR_FCN ValueId(const ValueId& _another) : m_id(_another.m_id) {} + inline EASY_CONSTEXPR_FCN ValueId(ValueId&& _another) : m_id(_another.m_id) {} +#else + inline EASY_CONSTEXPR_FCN ValueId(const ValueId&) = default; + inline EASY_CONSTEXPR_FCN ValueId(ValueId&&) = default; +#endif + + explicit inline EASY_CONSTEXPR_FCN ValueId() : m_id(0) {} + explicit inline EASY_CONSTEXPR_FCN ValueId(const void* _member) : m_id(reinterpret_cast(_member)) {} + + template + explicit inline EASY_CONSTEXPR_FCN ValueId(const T& _member) : m_id(reinterpret_cast(&_member)) {} + + template + explicit inline EASY_CONSTEXPR_FCN ValueId(const T (&_member)[N]) : m_id(reinterpret_cast((void*)_member)) {} + + ValueId& operator = (const ValueId&) = delete; + ValueId& operator = (ValueId&&) = delete; + }; + + namespace { + template + inline EASY_CONSTEXPR_FCN bool subextract_value_id(TArgs...); + + template <> + inline EASY_CONSTEXPR_FCN bool subextract_value_id<>() { return false; } + + template + inline EASY_CONSTEXPR_FCN bool subextract_value_id(T) { return false; } + + inline EASY_CONSTEXPR_FCN ValueId subextract_value_id(ValueId _value) { return _value; } + + template + inline EASY_CONSTEXPR_FCN ValueId subextract_value_id(ValueId _value, TArgs...) { return _value; } + + template + inline EASY_CONSTEXPR_FCN auto subextract_value_id(T, TArgs... _args) -> decltype(subextract_value_id(_args...)) { + return subextract_value_id(_args...); + } + + struct GetFirst { + template + static EASY_CONSTEXPR_FCN ValueId get(const T& _first, TArgs...) { return ValueId(_first); } + + template + static EASY_CONSTEXPR_FCN ValueId get(const T (&_first)[N], TArgs...) { return ValueId(_first); } + }; + + struct GetRest { + template + static EASY_CONSTEXPR_FCN ValueId get(const T&, TArgs... _args) { return subextract_value_id(_args...); } + }; + } // end of noname namespace. + + template + inline EASY_CONSTEXPR_FCN ValueId extract_value_id(const T& _first, TArgs... _args) { + return ::std::conditional<::std::is_same::value, GetRest, GetFirst> + ::type::get(_first, _args...); + } + + template + inline EASY_CONSTEXPR_FCN ValueId extract_value_id(const T (&_first)[N], TArgs... _args) { + return ::std::conditional<::std::is_same::value, GetRest, GetFirst> + ::type::get(_first, _args...); + } + +} // end of namespace profiler. + +#endif // EASY_PROFILER_ARBITRARY_VALUE_AUX_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_public_types.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_public_types.h new file mode 100644 index 0000000..c2851cb --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/arbitrary_value_public_types.h @@ -0,0 +1,102 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_ARBITRARY_VALUE_PUBLIC_TYPES_H +#define EASY_PROFILER_ARBITRARY_VALUE_PUBLIC_TYPES_H + +#include +#include +#include + +namespace profiler +{ + + enum class DataType : uint8_t + { + Bool = 0, + Char, + Int8, + Uint8, + Int16, + Uint16, + Int32, + Uint32, + Int64, + Uint64, + Float, + Double, + String, + + TypesCount + }; // end of enum class DataType. + + template struct StdType; + + template struct StdToDataType EASY_FINAL { + EASY_STATIC_CONSTEXPR auto data_type = DataType::TypesCount; + }; + +# define EASY_DATATYPE_CONVERSION(DataTypeName, StdTypeName)\ + template <> struct StdType EASY_FINAL { using value_type = StdTypeName; };\ + template <> struct StdToDataType EASY_FINAL { EASY_STATIC_CONSTEXPR auto data_type = DataTypeName; } + + EASY_DATATYPE_CONVERSION(DataType::Bool , bool ); + EASY_DATATYPE_CONVERSION(DataType::Char , char ); + EASY_DATATYPE_CONVERSION(DataType::Int8 , int8_t ); + EASY_DATATYPE_CONVERSION(DataType::Uint8 , uint8_t ); + EASY_DATATYPE_CONVERSION(DataType::Int16 , int16_t ); + EASY_DATATYPE_CONVERSION(DataType::Uint16, uint16_t); + EASY_DATATYPE_CONVERSION(DataType::Int32 , int32_t ); + EASY_DATATYPE_CONVERSION(DataType::Uint32, uint32_t); + EASY_DATATYPE_CONVERSION(DataType::Int64 , int64_t ); + EASY_DATATYPE_CONVERSION(DataType::Uint64, uint64_t); + EASY_DATATYPE_CONVERSION(DataType::Float , float ); + EASY_DATATYPE_CONVERSION(DataType::Double, double ); + +# undef EASY_DATATYPE_CONVERSION + + template <> struct StdType EASY_FINAL { using value_type = char; }; + template <> struct StdToDataType EASY_FINAL { EASY_STATIC_CONSTEXPR auto data_type = DataType::String; }; + +} // end of namespace profiler. + +#endif //EASY_PROFILER_ARBITRARY_VALUE_PUBLIC_TYPES_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/easy_compiler_support.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/easy_compiler_support.h new file mode 100644 index 0000000..6d9fe8d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/easy_compiler_support.h @@ -0,0 +1,224 @@ +/************************************************************************ +* file name : easy_compiler_support.h +* ----------------- : +* creation time : 2016/09/22 +* authors : Victor Zarubkin, Sergey Yagovtsev +* emails : v.s.zarubkin@gmail.com, yse.sey@gmail.com +* ----------------- : +* description : This file contains auxiliary profiler macros for different compiler support. +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER_COMPILER_SUPPORT_H +#define EASY_PROFILER_COMPILER_SUPPORT_H + +#include + +#if defined(_WIN32) && !defined(EASY_PROFILER_STATIC) +// Visual Studio and MinGW +# ifdef _BUILD_PROFILER +# define PROFILER_API __declspec(dllexport) +# else +# define PROFILER_API __declspec(dllimport) +# endif +#endif + + + +#if defined(_MSC_VER) +////////////////////////////////////////////////////////////////////////// +// Visual Studio + +# if defined(EASY_OPTION_PRETTY_PRINT_FUNCTIONS) && EASY_OPTION_PRETTY_PRINT_FUNCTIONS != 0 +# define EASY_FUNC_NAME __FUNCSIG__ +# else +# define EASY_FUNC_NAME __FUNCTION__ +# endif + +# if _MSC_VER <= 1800 +// There is no support for C++11 thread_local keyword prior to Visual Studio 2015. Use __declspec(thread) instead. +// There is also no support for C++11 magic statics feature :( So it becomes slightly harder to initialize static vars - additional "if" for each profiler block. +# define EASY_THREAD_LOCAL __declspec(thread) +# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer)\ + __declspec(thread) static VarType VarName = 0;\ + if (!VarName)\ + VarName = VarInitializer + +// No constexpr support before Visual Studio 2015 +# define EASY_CONSTEXPR const +# define EASY_STATIC_CONSTEXPR static const +# define EASY_CONSTEXPR_FCN + +// No noexcept support before Visual Studio 2015 +# define EASY_NOEXCEPT throw() +# endif + +# define EASY_FORCE_INLINE __forceinline + +#elif defined(__clang__) +////////////////////////////////////////////////////////////////////////// +// Clang Compiler + +# define EASY_COMPILER_VERSION (__clang_major__ * 10 + __clang_minor__) + +# if EASY_COMPILER_VERSION < 33 || (defined(__APPLE_CC__) && __APPLE_CC__ < 8000) +// There is no support for C++11 thread_local keyword prior to Clang v3.3 and Apple LLVM clang 8.0. Use __thread instead. +# define EASY_THREAD_LOCAL __thread +# endif + +# if EASY_COMPILER_VERSION < 31 +// No constexpr support before Clang v3.1 +# define EASY_CONSTEXPR const +# define EASY_STATIC_CONSTEXPR static const +# define EASY_CONSTEXPR_FCN +# endif + +# if EASY_COMPILER_VERSION < 29 +// There is no support for C++11 magic statics feature prior to clang 2.9. It becomes slightly harder to initialize static vars - additional "if" for each profiler block. +# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer)\ + EASY_THREAD_LOCAL static VarType VarName = 0;\ + if (!VarName)\ + VarName = VarInitializer + +// There is no support for C++11 final keyword prior to Clang v2.9 +# define EASY_FINAL +# endif + +# define EASY_FORCE_INLINE inline __attribute__((always_inline)) +# undef EASY_COMPILER_VERSION + +#elif defined(__GNUC__) +////////////////////////////////////////////////////////////////////////// +// GNU Compiler + +# define EASY_COMPILER_VERSION (__GNUC__ * 10 + __GNUC_MINOR__) + +# if EASY_COMPILER_VERSION < 48 +// There is no support for C++11 thread_local keyword prior to gcc 4.8. Use __thread instead. +# define EASY_THREAD_LOCAL __thread +# endif + +# if EASY_COMPILER_VERSION < 46 +// No constexpr support before GCC v4.6 +# define EASY_CONSTEXPR const +# define EASY_STATIC_CONSTEXPR static const +# define EASY_CONSTEXPR_FCN + +// No noexcept support before GCC v4.6 +# define EASY_NOEXCEPT throw() +# endif + +# if EASY_COMPILER_VERSION < 43 +// There is no support for C++11 magic statics feature prior to gcc 4.3. It becomes slightly harder to initialize static vars - additional "if" for each profiler block. +# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer)\ + EASY_THREAD_LOCAL static VarType VarName = 0;\ + if (!VarName)\ + VarName = VarInitializer +# endif + +# if EASY_COMPILER_VERSION < 47 +// There is no support for C++11 final keyword prior to gcc 4.7 +# define EASY_FINAL +# endif + +# define EASY_FORCE_INLINE inline __attribute__((always_inline)) +# undef EASY_COMPILER_VERSION + +#else +////////////////////////////////////////////////////////////////////////// +// TODO: Add other compilers support + +static_assert(false, "EasyProfiler is not configured for using your compiler type. Please, contact developers."); +#endif +// END +////////////////////////////////////////////////////////////////////////// + + + +////////////////////////////////////////////////////////////////////////// +// Default values + +#ifndef EASY_FUNC_NAME +# if defined(EASY_OPTION_PRETTY_PRINT_FUNCTIONS) && EASY_OPTION_PRETTY_PRINT_FUNCTIONS != 0 +# define EASY_FUNC_NAME __PRETTY_FUNCTION__ +# else +# define EASY_FUNC_NAME __func__ +# endif +#endif + +#ifndef EASY_THREAD_LOCAL +# define EASY_THREAD_LOCAL thread_local +# define EASY_CXX11_TLS_AVAILABLE +#endif + +#ifndef EASY_LOCAL_STATIC_PTR +# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer) static VarType VarName = VarInitializer +# define EASY_MAGIC_STATIC_AVAILABLE +#endif + +#ifndef EASY_FINAL +# define EASY_FINAL final +#endif + +#ifndef EASY_FORCE_INLINE +# define EASY_FORCE_INLINE inline +#endif + +#ifndef EASY_CONSTEXPR +# define EASY_CONSTEXPR constexpr +# define EASY_STATIC_CONSTEXPR static constexpr +# define EASY_CONSTEXPR_FCN constexpr +# define EASY_CONSTEXPR_AVAILABLE +#endif + +#ifndef EASY_NOEXCEPT +# define EASY_NOEXCEPT noexcept +# define EASY_NOEXCEPT_AVAILABLE +#endif + +#ifndef PROFILER_API +# define PROFILER_API +#endif + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_COMPILER_SUPPORT_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_aux.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_aux.h new file mode 100644 index 0000000..9b8da6c --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_aux.h @@ -0,0 +1,214 @@ +/************************************************************************ +* file name : profiler_aux.h +* ----------------- : +* creation time : 2016/06/11 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : This file contains auxiliary profiler macros and funcitons. +* ----------------- : +* change log : * 2016/06/11 Victor Zarubkin: Moved sources from profiler.h +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER_AUX_H +#define EASY_PROFILER_AUX_H + +#include + +#include +#include + +////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + enum EasyBlockStatus : uint8_t { + OFF = 0, ///< The block is OFF + ON = 1, ///< The block is ON (but if it's parent block is off recursively then this block will be off too) + FORCE_ON = ON | 2, ///< The block is ALWAYS ON (even if it's parent has turned off all children) + OFF_RECURSIVE = 4, ///< The block is OFF and all of it's children by call-stack are also OFF. + ON_WITHOUT_CHILDREN = ON | OFF_RECURSIVE, ///< The block is ON but all of it's children are OFF. + FORCE_ON_WITHOUT_CHILDREN = FORCE_ON | OFF_RECURSIVE, ///< The block is ALWAYS ON but all of it's children are OFF. + }; + +} + +////////////////////////////////////////////////////////////////////////// + +#include +#include + +# define EASY_STRINGIFY(a) #a +# define EASY_STRINGIFICATION(a) EASY_STRINGIFY(a) +# define EASY_TOKEN_JOIN(x, y) x ## y +# define EASY_TOKEN_CONCATENATE(x, y) EASY_TOKEN_JOIN(x, y) +# define EASY_UNIQUE_BLOCK(x) EASY_TOKEN_CONCATENATE(unique_profiler_mark_name_, x) +# define EASY_UNIQUE_FRAME_COUNTER(x) EASY_TOKEN_CONCATENATE(unique_profiler_frame_mark_name_, x) +# define EASY_UNIQUE_DESC(x) EASY_TOKEN_CONCATENATE(unique_profiler_descriptor_, x) + +#ifdef BUILD_WITH_EASY_PROFILER + +namespace profiler { + + template struct NameSwitch; + + class ForceConstStr EASY_FINAL { + friend NameSwitch; + friend NameSwitch; + + const char* c_str; + + public: + + ForceConstStr() = delete; + ForceConstStr(const ForceConstStr&) = delete; + ForceConstStr(ForceConstStr&&) = delete; + ForceConstStr& operator = (const ForceConstStr&) = delete; + ForceConstStr& operator = (ForceConstStr&&) = delete; + + explicit EASY_CONSTEXPR_FCN ForceConstStr(const char* _str) : c_str(_str) {} + explicit ForceConstStr(const ::std::string& _str) : c_str(_str.c_str()) {} + }; + + template struct NameSwitch EASY_FINAL { + static const char* runtime_name(const char* name) { return name; } + static const char* runtime_name(const ::std::string& name) { return name.c_str(); } + static EASY_CONSTEXPR_FCN const char* runtime_name(const ForceConstStr&) { return ""; } + + template + static EASY_CONSTEXPR_FCN const char* compiletime_name(const T&, const char* autoGeneratedName) { return autoGeneratedName; } + static EASY_CONSTEXPR_FCN const char* compiletime_name(const char*, const char* autoGeneratedName) { return autoGeneratedName; } + static EASY_CONSTEXPR_FCN const char* compiletime_name(const ForceConstStr& name, const char*) { return name.c_str; } + }; + + template <> struct NameSwitch EASY_FINAL { + static EASY_CONSTEXPR_FCN const char* runtime_name(const char*) { return ""; } + static EASY_CONSTEXPR_FCN const char* runtime_name(const ForceConstStr&) { return ""; } + static const char* runtime_name(const ::std::string& name) { return name.c_str(); } + + template + static EASY_CONSTEXPR_FCN const char* compiletime_name(const T&, const char* autoGeneratedName) { return autoGeneratedName; } + static EASY_CONSTEXPR_FCN const char* compiletime_name(const char* name, const char*) { return name; } + static EASY_CONSTEXPR_FCN const char* compiletime_name(const ForceConstStr& name, const char*) { return name.c_str; } + }; + + //*********************************************** + + template + inline EASY_CONSTEXPR_FCN color_t extract_color(TArgs...); + + template <> + inline EASY_CONSTEXPR_FCN color_t extract_color<>() { + return ::profiler::colors::Default; + } + + template + inline EASY_CONSTEXPR_FCN color_t extract_color(T) { + return ::profiler::colors::Default; + } + + template <> + inline EASY_CONSTEXPR_FCN color_t extract_color(color_t _color) { + return _color; + } + + template + inline EASY_CONSTEXPR_FCN color_t extract_color(color_t _color, TArgs...) { + return _color; + } + + template + inline EASY_CONSTEXPR_FCN color_t extract_color(T, TArgs... _args) { + return extract_color(_args...); + } + + //*********************************************** + + template + inline EASY_CONSTEXPR_FCN EasyBlockStatus extract_enable_flag(TArgs...); + + template <> + inline EASY_CONSTEXPR_FCN EasyBlockStatus extract_enable_flag<>() { + return ::profiler::ON; + } + + template + inline EASY_CONSTEXPR_FCN EasyBlockStatus extract_enable_flag(T) { + return ::profiler::ON; + } + + template <> + inline EASY_CONSTEXPR_FCN EasyBlockStatus extract_enable_flag(EasyBlockStatus _flag) { + return _flag; + } + + template + inline EASY_CONSTEXPR_FCN EasyBlockStatus extract_enable_flag(EasyBlockStatus _flag, TArgs...) { + return _flag; + } + + template + inline EASY_CONSTEXPR_FCN EasyBlockStatus extract_enable_flag(T, TArgs... _args) { + return extract_enable_flag(_args...); + } + + //*********************************************** + +} // END of namespace profiler. + +# define EASY_UNIQUE_LINE_ID __FILE__ ":" EASY_STRINGIFICATION(__LINE__) +# define EASY_COMPILETIME_NAME(name) ::profiler::NameSwitch<::std::is_reference::value>::compiletime_name(name, EASY_UNIQUE_LINE_ID) +# define EASY_RUNTIME_NAME(name) ::profiler::NameSwitch<::std::is_reference::value>::runtime_name(name) +# define EASY_CONST_NAME(name) ::profiler::ForceConstStr(name) + +#else + +# define EASY_CONST_NAME(name) + +#endif // BUILD_WITH_EASY_PROFILER + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_AUX_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_colors.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_colors.h new file mode 100644 index 0000000..61e8b5b --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_colors.h @@ -0,0 +1,413 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_COLORS_H +#define EASY_PROFILER_COLORS_H + +#include +#include + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +namespace profiler { + + using color_t = uint32_t; // Standard four-byte ARGB color format + + namespace colors { + + ///< Change alpha for color. Only 8 major bytes (0xff000000) used from alpha. + inline EASY_CONSTEXPR_FCN color_t modify_alpha32(color_t _color, color_t _alpha) { + return (_alpha & 0xff000000) | (_color & 0x00ffffff); + } + + ///< Change alpha for color. + inline EASY_CONSTEXPR_FCN color_t modify_alpha8(color_t _color, uint8_t _alpha) { + return (static_cast(_alpha) << 24) | (_color & 0x00ffffff); + } + + ///< Create color from ARGB components. + inline EASY_CONSTEXPR_FCN color_t color(uint8_t _red, uint8_t _green, uint8_t _blue, uint8_t _alpha = 0xff) { + return (static_cast(_alpha) << 24) | (static_cast(_red) << 16) | (static_cast(_green) << 8) | static_cast(_blue); + } + +#if !defined(EASY_OPTION_BUILTIN_COLORS) || EASY_OPTION_BUILTIN_COLORS != 0 + // Google Material Design colors + // See https://material.google.com/style/color.html + + EASY_CONSTEXPR color_t Red50 = 0xffffebee; + EASY_CONSTEXPR color_t Red100 = 0xffffcdd2; + EASY_CONSTEXPR color_t Red200 = 0xffef9a9a; + EASY_CONSTEXPR color_t Red300 = 0xffe57373; + EASY_CONSTEXPR color_t Red400 = 0xffef5350; + EASY_CONSTEXPR color_t Red500 = 0xfff44336; + EASY_CONSTEXPR color_t Red600 = 0xffe53935; + EASY_CONSTEXPR color_t Red700 = 0xffd32f2f; + EASY_CONSTEXPR color_t Red800 = 0xffc62828; + EASY_CONSTEXPR color_t Red900 = 0xffb71c1c; + EASY_CONSTEXPR color_t RedA100 = 0xffff8a80; + EASY_CONSTEXPR color_t RedA200 = 0xffff5252; + EASY_CONSTEXPR color_t RedA400 = 0xffff1744; + EASY_CONSTEXPR color_t RedA700 = 0xffd50000; + + EASY_CONSTEXPR color_t Pink50 = 0xfffce4ec; + EASY_CONSTEXPR color_t Pink100 = 0xfff8bbd0; + EASY_CONSTEXPR color_t Pink200 = 0xfff48fb1; + EASY_CONSTEXPR color_t Pink300 = 0xfff06292; + EASY_CONSTEXPR color_t Pink400 = 0xffec407a; + EASY_CONSTEXPR color_t Pink500 = 0xffe91e63; + EASY_CONSTEXPR color_t Pink600 = 0xffd81b60; + EASY_CONSTEXPR color_t Pink700 = 0xffc2185b; + EASY_CONSTEXPR color_t Pink800 = 0xffad1457; + EASY_CONSTEXPR color_t Pink900 = 0xff880e4f; + EASY_CONSTEXPR color_t PinkA100 = 0xffff80ab; + EASY_CONSTEXPR color_t PinkA200 = 0xffff4081; + EASY_CONSTEXPR color_t PinkA400 = 0xfff50057; + EASY_CONSTEXPR color_t PinkA700 = 0xffc51162; + + EASY_CONSTEXPR color_t Purple50 = 0xfff3e5f5; + EASY_CONSTEXPR color_t Purple100 = 0xffe1bee7; + EASY_CONSTEXPR color_t Purple200 = 0xffce93d8; + EASY_CONSTEXPR color_t Purple300 = 0xffba68c8; + EASY_CONSTEXPR color_t Purple400 = 0xffab47bc; + EASY_CONSTEXPR color_t Purple500 = 0xff9c27b0; + EASY_CONSTEXPR color_t Purple600 = 0xff8e24aa; + EASY_CONSTEXPR color_t Purple700 = 0xff7b1fa2; + EASY_CONSTEXPR color_t Purple800 = 0xff6a1b9a; + EASY_CONSTEXPR color_t Purple900 = 0xff4a148c; + EASY_CONSTEXPR color_t PurpleA100 = 0xffea80fc; + EASY_CONSTEXPR color_t PurpleA200 = 0xffe040fb; + EASY_CONSTEXPR color_t PurpleA400 = 0xffd500f9; + EASY_CONSTEXPR color_t PurpleA700 = 0xffaa00ff; + + EASY_CONSTEXPR color_t DeepPurple50 = 0xffede7f6; + EASY_CONSTEXPR color_t DeepPurple100 = 0xffd1c4e9; + EASY_CONSTEXPR color_t DeepPurple200 = 0xffb39ddb; + EASY_CONSTEXPR color_t DeepPurple300 = 0xff9575cd; + EASY_CONSTEXPR color_t DeepPurple400 = 0xff7e57c2; + EASY_CONSTEXPR color_t DeepPurple500 = 0xff673ab7; + EASY_CONSTEXPR color_t DeepPurple600 = 0xff5e35b1; + EASY_CONSTEXPR color_t DeepPurple700 = 0xff512da8; + EASY_CONSTEXPR color_t DeepPurple800 = 0xff4527a0; + EASY_CONSTEXPR color_t DeepPurple900 = 0xff311b92; + EASY_CONSTEXPR color_t DeepPurpleA100 = 0xffb388ff; + EASY_CONSTEXPR color_t DeepPurpleA200 = 0xff7c4dff; + EASY_CONSTEXPR color_t DeepPurpleA400 = 0xff651fff; + EASY_CONSTEXPR color_t DeepPurpleA700 = 0xff6200ea; + + EASY_CONSTEXPR color_t Indigo50 = 0xffe8eaf6; + EASY_CONSTEXPR color_t Indigo100 = 0xffc5cae9; + EASY_CONSTEXPR color_t Indigo200 = 0xff9fa8da; + EASY_CONSTEXPR color_t Indigo300 = 0xff7986cb; + EASY_CONSTEXPR color_t Indigo400 = 0xff5c6bc0; + EASY_CONSTEXPR color_t Indigo500 = 0xff3f51b5; + EASY_CONSTEXPR color_t Indigo600 = 0xff3949ab; + EASY_CONSTEXPR color_t Indigo700 = 0xff303f9f; + EASY_CONSTEXPR color_t Indigo800 = 0xff283593; + EASY_CONSTEXPR color_t Indigo900 = 0xff1a237e; + EASY_CONSTEXPR color_t IndigoA100 = 0xff8c9eff; + EASY_CONSTEXPR color_t IndigoA200 = 0xff536dfe; + EASY_CONSTEXPR color_t IndigoA400 = 0xff3d5afe; + EASY_CONSTEXPR color_t IndigoA700 = 0xff304ffe; + + EASY_CONSTEXPR color_t Blue50 = 0xffe3f2fd; + EASY_CONSTEXPR color_t Blue100 = 0xffbbdefb; + EASY_CONSTEXPR color_t Blue200 = 0xff90caf9; + EASY_CONSTEXPR color_t Blue300 = 0xff64b5f6; + EASY_CONSTEXPR color_t Blue400 = 0xff42a5f5; + EASY_CONSTEXPR color_t Blue500 = 0xff2196f3; + EASY_CONSTEXPR color_t Blue600 = 0xff1e88e5; + EASY_CONSTEXPR color_t Blue700 = 0xff1976d2; + EASY_CONSTEXPR color_t Blue800 = 0xff1565c0; + EASY_CONSTEXPR color_t Blue900 = 0xff0d47a1; + EASY_CONSTEXPR color_t BlueA100 = 0xff82b1ff; + EASY_CONSTEXPR color_t BlueA200 = 0xff448aff; + EASY_CONSTEXPR color_t BlueA400 = 0xff2979ff; + EASY_CONSTEXPR color_t BlueA700 = 0xff2962ff; + + EASY_CONSTEXPR color_t LightBlue50 = 0xffe1f5fe; + EASY_CONSTEXPR color_t LightBlue100 = 0xffb3e5fc; + EASY_CONSTEXPR color_t LightBlue200 = 0xff81d4fa; + EASY_CONSTEXPR color_t LightBlue300 = 0xff4fc3f7; + EASY_CONSTEXPR color_t LightBlue400 = 0xff29b6f6; + EASY_CONSTEXPR color_t LightBlue500 = 0xff03a9f4; + EASY_CONSTEXPR color_t LightBlue600 = 0xff039be5; + EASY_CONSTEXPR color_t LightBlue700 = 0xff0288d1; + EASY_CONSTEXPR color_t LightBlue800 = 0xff0277bd; + EASY_CONSTEXPR color_t LightBlue900 = 0xff01579b; + EASY_CONSTEXPR color_t LightBlueA100 = 0xff80d8ff; + EASY_CONSTEXPR color_t LightBlueA200 = 0xff40c4ff; + EASY_CONSTEXPR color_t LightBlueA400 = 0xff00b0ff; + EASY_CONSTEXPR color_t LightBlueA700 = 0xff0091ea; + + EASY_CONSTEXPR color_t Cyan50 = 0xffe0f7fa; + EASY_CONSTEXPR color_t Cyan100 = 0xffb2ebf2; + EASY_CONSTEXPR color_t Cyan200 = 0xff80deea; + EASY_CONSTEXPR color_t Cyan300 = 0xff4dd0e1; + EASY_CONSTEXPR color_t Cyan400 = 0xff26c6da; + EASY_CONSTEXPR color_t Cyan500 = 0xff00bcd4; + EASY_CONSTEXPR color_t Cyan600 = 0xff00acc1; + EASY_CONSTEXPR color_t Cyan700 = 0xff0097a7; + EASY_CONSTEXPR color_t Cyan800 = 0xff00838f; + EASY_CONSTEXPR color_t Cyan900 = 0xff006064; + EASY_CONSTEXPR color_t CyanA100 = 0xff84ffff; + EASY_CONSTEXPR color_t CyanA200 = 0xff18ffff; + EASY_CONSTEXPR color_t CyanA400 = 0xff00e5ff; + EASY_CONSTEXPR color_t CyanA700 = 0xff00b8d4; + + EASY_CONSTEXPR color_t Teal50 = 0xffe0f2f1; + EASY_CONSTEXPR color_t Teal100 = 0xffb2dfdb; + EASY_CONSTEXPR color_t Teal200 = 0xff80cbc4; + EASY_CONSTEXPR color_t Teal300 = 0xff4db6ac; + EASY_CONSTEXPR color_t Teal400 = 0xff26a69a; + EASY_CONSTEXPR color_t Teal500 = 0xff009688; + EASY_CONSTEXPR color_t Teal600 = 0xff00897b; + EASY_CONSTEXPR color_t Teal700 = 0xff00796b; + EASY_CONSTEXPR color_t Teal800 = 0xff00695c; + EASY_CONSTEXPR color_t Teal900 = 0xff004d40; + EASY_CONSTEXPR color_t TealA100 = 0xffa7ffeb; + EASY_CONSTEXPR color_t TealA200 = 0xff64ffda; + EASY_CONSTEXPR color_t TealA400 = 0xff1de9b6; + EASY_CONSTEXPR color_t TealA700 = 0xff00bfa5; + + EASY_CONSTEXPR color_t Green50 = 0xffe8f5e9; + EASY_CONSTEXPR color_t Green100 = 0xffc8e6c9; + EASY_CONSTEXPR color_t Green200 = 0xffa5d6a7; + EASY_CONSTEXPR color_t Green300 = 0xff81c784; + EASY_CONSTEXPR color_t Green400 = 0xff66bb6a; + EASY_CONSTEXPR color_t Green500 = 0xff4caf50; + EASY_CONSTEXPR color_t Green600 = 0xff43a047; + EASY_CONSTEXPR color_t Green700 = 0xff388e3c; + EASY_CONSTEXPR color_t Green800 = 0xff2e7d32; + EASY_CONSTEXPR color_t Green900 = 0xff1b5e20; + EASY_CONSTEXPR color_t GreenA100 = 0xffb9f6ca; + EASY_CONSTEXPR color_t GreenA200 = 0xff69f0ae; + EASY_CONSTEXPR color_t GreenA400 = 0xff00e676; + EASY_CONSTEXPR color_t GreenA700 = 0xff00c853; + + EASY_CONSTEXPR color_t LightGreen50 = 0xfff1f8e9; + EASY_CONSTEXPR color_t LightGreen100 = 0xffdcedc8; + EASY_CONSTEXPR color_t LightGreen200 = 0xffc5e1a5; + EASY_CONSTEXPR color_t LightGreen300 = 0xffaed581; + EASY_CONSTEXPR color_t LightGreen400 = 0xff9ccc65; + EASY_CONSTEXPR color_t LightGreen500 = 0xff8bc34a; + EASY_CONSTEXPR color_t LightGreen600 = 0xff7cb342; + EASY_CONSTEXPR color_t LightGreen700 = 0xff689f38; + EASY_CONSTEXPR color_t LightGreen800 = 0xff558b2f; + EASY_CONSTEXPR color_t LightGreen900 = 0xff33691e; + EASY_CONSTEXPR color_t LightGreenA100 = 0xffccff90; + EASY_CONSTEXPR color_t LightGreenA200 = 0xffb2ff59; + EASY_CONSTEXPR color_t LightGreenA400 = 0xff76ff03; + EASY_CONSTEXPR color_t LightGreenA700 = 0xff64dd17; + + EASY_CONSTEXPR color_t Lime50 = 0xfff9ebe7; + EASY_CONSTEXPR color_t Lime100 = 0xfff0f4c3; + EASY_CONSTEXPR color_t Lime200 = 0xffe6ee9c; + EASY_CONSTEXPR color_t Lime300 = 0xffdce775; + EASY_CONSTEXPR color_t Lime400 = 0xffd4e157; + EASY_CONSTEXPR color_t Lime500 = 0xffcddc39; + EASY_CONSTEXPR color_t Lime600 = 0xffc0ca33; + EASY_CONSTEXPR color_t Lime700 = 0xffafb42b; + EASY_CONSTEXPR color_t Lime800 = 0xff9e9d24; + EASY_CONSTEXPR color_t Lime900 = 0xff827717; + EASY_CONSTEXPR color_t LimeA100 = 0xfff4ff81; + EASY_CONSTEXPR color_t LimeA200 = 0xffeeff41; + EASY_CONSTEXPR color_t LimeA400 = 0xffc6ff00; + EASY_CONSTEXPR color_t LimeA700 = 0xffaeea00; + + EASY_CONSTEXPR color_t Yellow50 = 0xfffffde7; + EASY_CONSTEXPR color_t Yellow100 = 0xfffff9c4; + EASY_CONSTEXPR color_t Yellow200 = 0xfffff59d; + EASY_CONSTEXPR color_t Yellow300 = 0xfffff176; + EASY_CONSTEXPR color_t Yellow400 = 0xffffee58; + EASY_CONSTEXPR color_t Yellow500 = 0xffffeb3b; + EASY_CONSTEXPR color_t Yellow600 = 0xfffdd835; + EASY_CONSTEXPR color_t Yellow700 = 0xfffbc02d; + EASY_CONSTEXPR color_t Yellow800 = 0xfff9a825; + EASY_CONSTEXPR color_t Yellow900 = 0xfff57f17; + EASY_CONSTEXPR color_t YellowA100 = 0xffffff8d; + EASY_CONSTEXPR color_t YellowA200 = 0xffffff00; + EASY_CONSTEXPR color_t YellowA400 = 0xffffea00; + EASY_CONSTEXPR color_t YellowA700 = 0xffffd600; + + EASY_CONSTEXPR color_t Amber50 = 0xfffff8e1; + EASY_CONSTEXPR color_t Amber100 = 0xffffecb3; + EASY_CONSTEXPR color_t Amber200 = 0xffffe082; + EASY_CONSTEXPR color_t Amber300 = 0xffffd54f; + EASY_CONSTEXPR color_t Amber400 = 0xffffca28; + EASY_CONSTEXPR color_t Amber500 = 0xffffc107; + EASY_CONSTEXPR color_t Amber600 = 0xffffb300; + EASY_CONSTEXPR color_t Amber700 = 0xffffa000; + EASY_CONSTEXPR color_t Amber800 = 0xffff8f00; + EASY_CONSTEXPR color_t Amber900 = 0xffff6f00; + EASY_CONSTEXPR color_t AmberA100 = 0xffffe57f; + EASY_CONSTEXPR color_t AmberA200 = 0xffffd740; + EASY_CONSTEXPR color_t AmberA400 = 0xffffc400; + EASY_CONSTEXPR color_t AmberA700 = 0xffffab00; + + EASY_CONSTEXPR color_t Orange50 = 0xfffff3e0; + EASY_CONSTEXPR color_t Orange100 = 0xffffe0b2; + EASY_CONSTEXPR color_t Orange200 = 0xffffcc80; + EASY_CONSTEXPR color_t Orange300 = 0xffffb74d; + EASY_CONSTEXPR color_t Orange400 = 0xffffa726; + EASY_CONSTEXPR color_t Orange500 = 0xffff9800; + EASY_CONSTEXPR color_t Orange600 = 0xfffb8c00; + EASY_CONSTEXPR color_t Orange700 = 0xfff57c00; + EASY_CONSTEXPR color_t Orange800 = 0xffef6c00; + EASY_CONSTEXPR color_t Orange900 = 0xffe65100; + EASY_CONSTEXPR color_t OrangeA100 = 0xffffd180; + EASY_CONSTEXPR color_t OrangeA200 = 0xffffab40; + EASY_CONSTEXPR color_t OrangeA400 = 0xffff9100; + EASY_CONSTEXPR color_t OrangeA700 = 0xffff6d00; + + EASY_CONSTEXPR color_t DeepOrange50 = 0xfffbe9e7; + EASY_CONSTEXPR color_t DeepOrange100 = 0xffffccbc; + EASY_CONSTEXPR color_t DeepOrange200 = 0xffffab91; + EASY_CONSTEXPR color_t DeepOrange300 = 0xffff8a65; + EASY_CONSTEXPR color_t DeepOrange400 = 0xffff7043; + EASY_CONSTEXPR color_t DeepOrange500 = 0xffff5722; + EASY_CONSTEXPR color_t DeepOrange600 = 0xfff4511e; + EASY_CONSTEXPR color_t DeepOrange700 = 0xffe64a19; + EASY_CONSTEXPR color_t DeepOrange800 = 0xffd84315; + EASY_CONSTEXPR color_t DeepOrange900 = 0xffbf360c; + EASY_CONSTEXPR color_t DeepOrangeA100 = 0xffff9e80; + EASY_CONSTEXPR color_t DeepOrangeA200 = 0xffff6e40; + EASY_CONSTEXPR color_t DeepOrangeA400 = 0xffff3d00; + EASY_CONSTEXPR color_t DeepOrangeA700 = 0xffdd2c00; + + EASY_CONSTEXPR color_t Brown50 = 0xffefebe9; + EASY_CONSTEXPR color_t Brown100 = 0xffd7ccc8; + EASY_CONSTEXPR color_t Brown200 = 0xffbcaaa4; + EASY_CONSTEXPR color_t Brown300 = 0xffa1887f; + EASY_CONSTEXPR color_t Brown400 = 0xff8d6e63; + EASY_CONSTEXPR color_t Brown500 = 0xff795548; + EASY_CONSTEXPR color_t Brown600 = 0xff6d4c41; + EASY_CONSTEXPR color_t Brown700 = 0xff5d4037; + EASY_CONSTEXPR color_t Brown800 = 0xff4e342e; + EASY_CONSTEXPR color_t Brown900 = 0xff3e2723; + + EASY_CONSTEXPR color_t Grey50 = 0xfffafafa; + EASY_CONSTEXPR color_t Grey100 = 0xfff5f5f5; + EASY_CONSTEXPR color_t Grey200 = 0xffeeeeee; + EASY_CONSTEXPR color_t Grey300 = 0xffe0e0e0; + EASY_CONSTEXPR color_t Grey400 = 0xffbdbdbd; + EASY_CONSTEXPR color_t Grey500 = 0xff9e9e9e; + EASY_CONSTEXPR color_t Grey600 = 0xff757575; + EASY_CONSTEXPR color_t Grey700 = 0xff616161; + EASY_CONSTEXPR color_t Grey800 = 0xff424242; + EASY_CONSTEXPR color_t Grey900 = 0xff212121; + + EASY_CONSTEXPR color_t BlueGrey50 = 0xffeceff1; + EASY_CONSTEXPR color_t BlueGrey100 = 0xffcfd8dc; + EASY_CONSTEXPR color_t BlueGrey200 = 0xffb0bec5; + EASY_CONSTEXPR color_t BlueGrey300 = 0xff90a4ae; + EASY_CONSTEXPR color_t BlueGrey400 = 0xff78909c; + EASY_CONSTEXPR color_t BlueGrey500 = 0xff607d8b; + EASY_CONSTEXPR color_t BlueGrey600 = 0xff546e7a; + EASY_CONSTEXPR color_t BlueGrey700 = 0xff455a64; + EASY_CONSTEXPR color_t BlueGrey800 = 0xff37474f; + EASY_CONSTEXPR color_t BlueGrey900 = 0xff263238; + + EASY_CONSTEXPR color_t Black = 0xff000000; + EASY_CONSTEXPR color_t White = 0xffffffff; + EASY_CONSTEXPR color_t Null = 0x00000000; + + + EASY_CONSTEXPR color_t Red = Red500; + EASY_CONSTEXPR color_t DarkRed = Red900; + EASY_CONSTEXPR color_t Coral = Red200; + EASY_CONSTEXPR color_t RichRed = 0xffff0000; + EASY_CONSTEXPR color_t Pink = Pink500; + EASY_CONSTEXPR color_t Rose = PinkA100; + EASY_CONSTEXPR color_t Purple = Purple500; + EASY_CONSTEXPR color_t Magenta = PurpleA200; + EASY_CONSTEXPR color_t DarkMagenta = PurpleA700; + EASY_CONSTEXPR color_t DeepPurple = DeepPurple500; + EASY_CONSTEXPR color_t Indigo = Indigo500; + EASY_CONSTEXPR color_t Blue = Blue500; + EASY_CONSTEXPR color_t DarkBlue = Blue900; + EASY_CONSTEXPR color_t RichBlue = 0xff0000ff; + EASY_CONSTEXPR color_t LightBlue = LightBlue500; + EASY_CONSTEXPR color_t SkyBlue = LightBlueA100; + EASY_CONSTEXPR color_t Navy = LightBlue800; + EASY_CONSTEXPR color_t Cyan = Cyan500; + EASY_CONSTEXPR color_t DarkCyan = Cyan900; + EASY_CONSTEXPR color_t Teal = Teal500; + EASY_CONSTEXPR color_t DarkTeal = Teal900; + EASY_CONSTEXPR color_t Green = Green500; + EASY_CONSTEXPR color_t DarkGreen = Green900; + EASY_CONSTEXPR color_t RichGreen = 0xff00ff00; + EASY_CONSTEXPR color_t LightGreen = LightGreen500; + EASY_CONSTEXPR color_t Mint = LightGreen900; + EASY_CONSTEXPR color_t Lime = Lime500; + EASY_CONSTEXPR color_t Olive = Lime900; + EASY_CONSTEXPR color_t Yellow = Yellow500; + EASY_CONSTEXPR color_t RichYellow = YellowA200; + EASY_CONSTEXPR color_t Amber = Amber500; + EASY_CONSTEXPR color_t Gold = Amber300; + EASY_CONSTEXPR color_t PaleGold = AmberA100; + EASY_CONSTEXPR color_t Orange = Orange500; + EASY_CONSTEXPR color_t Skin = Orange100; + EASY_CONSTEXPR color_t DeepOrange = DeepOrange500; + EASY_CONSTEXPR color_t Brick = DeepOrange900; + EASY_CONSTEXPR color_t Brown = Brown500; + EASY_CONSTEXPR color_t DarkBrown = Brown900; + EASY_CONSTEXPR color_t CreamWhite = Orange50; + EASY_CONSTEXPR color_t Wheat = Amber100; + EASY_CONSTEXPR color_t Grey = Grey500; + EASY_CONSTEXPR color_t Dark = Grey900; + EASY_CONSTEXPR color_t Silver = Grey300; + EASY_CONSTEXPR color_t BlueGrey = BlueGrey500; + + EASY_CONSTEXPR color_t Default = Wheat; +#else + EASY_CONSTEXPR color_t Default = 0xffffecb3; +#endif // #if !defined(EASY_OPTION_BUILTIN_COLORS) || EASY_OPTION_BUILTIN_COLORS == 0 + + } // END of namespace colors. + +} // END of namespace profiler. + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_COLORS_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_public_types.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_public_types.h new file mode 100644 index 0000000..d19af70 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/details/profiler_public_types.h @@ -0,0 +1,203 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_PUBLIC_TYPES_H +#define EASY_PROFILER_PUBLIC_TYPES_H + +#include + +class NonscopedBlock; +class ProfileManager; +struct ThreadStorage; + +namespace profiler { + + using timestamp_t = uint64_t; + using thread_id_t = uint64_t; + using block_id_t = uint32_t; + + enum class BlockType : uint8_t + { + Event = 0, + Block, + Value, + + TypesCount + }; + using block_type_t = BlockType; + + enum Duration : uint8_t + { + TICKS = 0, ///< CPU ticks + MICROSECONDS ///< Microseconds + }; + + //*********************************************** + +#pragma pack(push,1) + class PROFILER_API BaseBlockDescriptor + { + friend ::ProfileManager; + friend ::ThreadStorage; + + protected: + + block_id_t m_id; ///< This descriptor id (We can afford this spending because there are much more blocks than descriptors) + int32_t m_line; ///< Line number in the source file + color_t m_color; ///< Color of the block packed into 1-byte structure + block_type_t m_type; ///< Type of the block (See BlockType) + EasyBlockStatus m_status; ///< If false then blocks with such id() will not be stored by profiler during profile session + + explicit BaseBlockDescriptor(block_id_t _id, EasyBlockStatus _status, int _line, block_type_t _block_type, color_t _color) EASY_NOEXCEPT; + + public: + + BaseBlockDescriptor() = delete; + + inline block_id_t id() const EASY_NOEXCEPT { return m_id; } + inline int32_t line() const EASY_NOEXCEPT { return m_line; } + inline color_t color() const EASY_NOEXCEPT { return m_color; } + inline block_type_t type() const EASY_NOEXCEPT { return m_type; } + inline EasyBlockStatus status() const EASY_NOEXCEPT { return m_status; } + + }; // END of class BaseBlockDescriptor. + + //*********************************************** + + class PROFILER_API Event + { + friend ::ProfileManager; + + protected: + + timestamp_t m_begin; + timestamp_t m_end; + + public: + + Event() = delete; + + Event(const Event&) = default; + explicit Event(timestamp_t _begin_time) EASY_NOEXCEPT; + explicit Event(timestamp_t _begin_time, timestamp_t _end_time) EASY_NOEXCEPT; + + inline timestamp_t begin() const EASY_NOEXCEPT { return m_begin; } + inline timestamp_t end() const EASY_NOEXCEPT { return m_end; } + inline timestamp_t duration() const EASY_NOEXCEPT { return m_end - m_begin; } + + }; // END class Event. + + class PROFILER_API BaseBlockData : public Event + { + friend ::ProfileManager; + + protected: + + block_id_t m_id; + + public: + + BaseBlockData() = delete; + + BaseBlockData(const BaseBlockData&) = default; + explicit BaseBlockData(timestamp_t _begin_time, block_id_t _id) EASY_NOEXCEPT; + explicit BaseBlockData(timestamp_t _begin_time, timestamp_t _end_time, block_id_t _id) EASY_NOEXCEPT; + + inline block_id_t id() const EASY_NOEXCEPT { return m_id; } + inline void setId(block_id_t _id) EASY_NOEXCEPT { m_id = _id; } + + }; // END of class BaseBlockData. +#pragma pack(pop) + + //*********************************************** + + class PROFILER_API Block : public BaseBlockData + { + friend ::ProfileManager; + friend ::ThreadStorage; + friend ::NonscopedBlock; + + const char* m_name; + EasyBlockStatus m_status; + bool m_isScoped; + + private: + + void start(); + void start(timestamp_t _time) EASY_NOEXCEPT; + void finish(); + void finish(timestamp_t _time) EASY_NOEXCEPT; + inline bool finished() const EASY_NOEXCEPT { return m_end >= m_begin; } + inline EasyBlockStatus status() const EASY_NOEXCEPT { return m_status; } + inline void setStatus(EasyBlockStatus _status) EASY_NOEXCEPT { m_status = _status; } + + public: + + Block(const Block&) = delete; + Block& operator = (const Block&) = delete; + + Block(Block&& that) EASY_NOEXCEPT; + Block(const BaseBlockDescriptor* _desc, const char* _runtimeName, bool _scoped = true) EASY_NOEXCEPT; + Block(timestamp_t _begin_time, block_id_t _id, const char* _runtimeName) EASY_NOEXCEPT; + Block(timestamp_t _begin_time, timestamp_t _end_time, block_id_t _id, const char* _runtimeName) EASY_NOEXCEPT; + ~Block(); + + inline const char* name() const EASY_NOEXCEPT { return m_name; } + + }; // END of class Block. + + //*********************************************** + + class PROFILER_API ThreadGuard EASY_FINAL + { + friend ::ProfileManager; + thread_id_t m_id = 0; + + public: + + ~ThreadGuard(); + + }; // END of class ThreadGuard. + +} // END of namespace profiler. + +#endif // EASY_PROFILER_PUBLIC_TYPES_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/easy_net.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/easy_net.h new file mode 100644 index 0000000..cf2d092 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/easy_net.h @@ -0,0 +1,161 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_NET_H +#define EASY_NET_H + +#include +#include + +namespace profiler { namespace net { + +EASY_CONSTEXPR uint32_t EASY_MESSAGE_SIGN = 20160909; + +#pragma pack(push,1) + +enum class MessageType : uint8_t +{ + Undefined = 0, + + Request_Start_Capture, + Reply_Capturing_Started, + Request_Stop_Capture, + + Reply_Blocks, + Reply_Blocks_End, + + Connection_Accepted, + + Request_Blocks_Description, + Reply_Blocks_Description, + Reply_Blocks_Description_End, + + Change_Block_Status, + Change_Event_Tracing_Status, + Change_Event_Tracing_Priority, + + Ping, + + Request_MainThread_FPS, + Reply_MainThread_FPS, +}; + +struct Message +{ + uint32_t magic_number = EASY_MESSAGE_SIGN; + MessageType type = MessageType::Undefined; + + bool isEasyNetMessage() const EASY_NOEXCEPT { + return EASY_MESSAGE_SIGN == magic_number; + } + + explicit Message(MessageType _t) EASY_NOEXCEPT : type(_t) { } + + Message() = default; +}; + +struct DataMessage : public Message +{ + uint32_t size = 0; // bytes + + explicit DataMessage(MessageType _t = MessageType::Reply_Blocks) : Message(_t) {} + explicit DataMessage(uint32_t _s, MessageType _t = MessageType::Reply_Blocks) : Message(_t), size(_s) {} + + const char* data() const { return reinterpret_cast(this) + sizeof(DataMessage); } +}; + +struct BlockStatusMessage : public Message +{ + uint32_t id; + uint8_t status; + + explicit BlockStatusMessage(uint32_t _id, uint8_t _status) + : Message(MessageType::Change_Block_Status), id(_id), status(_status) { } + + BlockStatusMessage() = delete; +}; + +struct EasyProfilerStatus : public Message +{ + bool isProfilerEnabled; + bool isEventTracingEnabled; + bool isLowPriorityEventTracing; + + explicit EasyProfilerStatus(bool _enabled, bool _ETenabled, bool _ETlowp) + : Message(MessageType::Connection_Accepted) + , isProfilerEnabled(_enabled) + , isEventTracingEnabled(_ETenabled) + , isLowPriorityEventTracing(_ETlowp) + { + } + + EasyProfilerStatus() = delete; +}; + +struct BoolMessage : public Message +{ + bool flag = false; + + explicit BoolMessage(MessageType _t, bool _flag = false) + : Message(_t), flag(_flag) { } + + BoolMessage() = default; +}; + +struct TimestampMessage : public Message +{ + uint32_t maxValue = 0; + uint32_t avgValue = 0; + + explicit TimestampMessage(MessageType _t, uint32_t _maxValue, uint32_t _avgValue) + : Message(_t), maxValue(_maxValue), avgValue(_avgValue) { } + + TimestampMessage() = default; +}; + +#pragma pack(pop) + +}//net + +}//profiler + +#endif // EASY_NET_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/easy_socket.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/easy_socket.h new file mode 100644 index 0000000..064ba6a --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/easy_socket.h @@ -0,0 +1,130 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ +#ifndef EASY_PROFILER_SOCKET_H +#define EASY_PROFILER_SOCKET_H + +#include +#include + +#ifndef _WIN32 + +// Unix +# include +# include +# include +# include +# include +# include +# include //for android-build + +#else + +// Windows +# define WIN32_LEAN_AND_MEAN +# include +# include +# include +# include + +#endif + +class PROFILER_API EasySocket EASY_FINAL +{ +public: + +#ifdef _WIN32 + typedef SOCKET socket_t; +#else + typedef int socket_t; +#endif + + enum class ConnectionState : int8_t + { + Disconnected = -1, + Unknown, + Connected, + Connecting + }; + +private: + + socket_t m_socket = 0; + socket_t m_replySocket = 0; + int m_wsaret = -1; + + struct hostent* m_server = nullptr; + struct sockaddr_in m_serverAddress; + + ConnectionState m_state = ConnectionState::Unknown; + +public: + + EasySocket(); + ~EasySocket(); + + void setReceiveTimeout(int milliseconds); + + int send(const void* buf, size_t nbyte); + int receive(void* buf, size_t nbyte); + int listen(int count = 5); + int accept(); + int bind(uint16_t portno); + + bool setAddress(const char* serv, uint16_t port); + int connect(); + + void flush(); + void init(); + + ConnectionState state() const; + bool isDisconnected() const; + bool isConnected() const; + +private: + + void checkResult(int result); + bool checkSocket(socket_t s) const; + void setBlocking(socket_t s, bool blocking); + +}; // end of class EasySocket. + +#endif // EASY_PROFILER_SOCKET_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/profiler.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/profiler.h new file mode 100644 index 0000000..dffc525 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/profiler.h @@ -0,0 +1,910 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_H +#define EASY_PROFILER_H + +#include + +#if defined ( __clang__ ) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" +#endif + +// +// BUILD_WITH_EASY_PROFILER is defined in CMakeLists.txt if your project is linked to easy_profiler. +// + +// +// DISABLE_EASY_PROFILER may be defined manually in source-file before #include +// to disable profiler for certain source-file or project. +// + +#if defined(BUILD_WITH_EASY_PROFILER) && !defined(DISABLE_EASY_PROFILER) + +/** +\defgroup profiler EasyProfiler +*/ + + +/** Indicates that EasyProfiler is used. + +\ingroup profiler +*/ +#define USING_EASY_PROFILER + + +// EasyProfiler core API: + +/** Macro for beginning of a scoped block with custom name and color. + +\code + #include + void foo() + { + // some code ... + + EASY_BLOCK("Check something", profiler::OFF); // Disabled block (There is possibility to enable this block later via GUI) + if(something){ + EASY_BLOCK("Calling bar()"); // Block with default color + bar(); + } + else{ + EASY_BLOCK("Calling baz()", profiler::colors::Red); // Red block + baz(); + } + EASY_END_BLOCK; // End of "Check something" block (Even if "Check something" is disabled, this EASY_END_BLOCK will not end any other block). + + EASY_BLOCK("Some another block", profiler::colors::Blue, profiler::ON_WITHOUT_CHILDREN); // Block with Blue color without + // some another code... + EASY_BLOCK("Calculate sum"); // This block will not be profiled because it's parent is ON_WITHOUT_CHILDREN + int sum = 0; + for (int i = 0; i < 10; ++i) + sum += i; + EASY_END_BLOCK; // End of "Calculate sum" block + } +\endcode + +Block will be automatically completed by destructor. + +\ingroup profiler +*/ +# define EASY_BLOCK(name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(::profiler::extract_enable_flag(__VA_ARGS__),\ + EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name), __FILE__, __LINE__, ::profiler::BlockType::Block, ::profiler::extract_color(__VA_ARGS__),\ + ::std::is_base_of<::profiler::ForceConstStr, decltype(name)>::value));\ + ::profiler::Block EASY_UNIQUE_BLOCK(__LINE__)(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name));\ + ::profiler::beginBlock(EASY_UNIQUE_BLOCK(__LINE__)); + +/** Macro for beginning of a non-scoped block with custom name and color. + +You must end such block manually with EASY_END_BLOCK. + +\code + #include + void foo() { + EASY_NONSCOPED_BLOCK("Callback"); // Begin block which would not be finished when function returns. + + // some code ... + } + + void bar() { + // some another code... + + EASY_END_BLOCK; // This, as always, ends last opened block. You have to take care about blocks order by yourself. + } + + void baz() { + foo(); // non-scoped block begins here + + // some code... + + bar(); // non-scoped block ends here + } +\endcode + +Block will be automatically completed by destructor. + +\ingroup profiler +*/ +#define EASY_NONSCOPED_BLOCK(name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(::profiler::extract_enable_flag(__VA_ARGS__),\ + EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name), __FILE__, __LINE__, ::profiler::BlockType::Block, ::profiler::extract_color(__VA_ARGS__),\ + ::std::is_base_of<::profiler::ForceConstStr, decltype(name)>::value));\ + ::profiler::beginNonScopedBlock(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name)); + +/** Macro for beginning of a block with function name and custom color. + +\code + #include + void foo(){ + EASY_FUNCTION(); // Block with name="foo" and default color + //some code... + } + + void bar(){ + EASY_FUNCTION(profiler::colors::Green); // Green block with name="bar" + //some code... + } + + void baz(){ + EASY_FUNCTION(profiler::FORCE_ON); // Force enabled block with name="baz" and default color (This block will be profiled even if it's parent is OFF_RECURSIVE) + // som code... + } +\endcode + +Name of the block automatically created with function name. + +\ingroup profiler +*/ +# define EASY_FUNCTION(...) EASY_BLOCK(EASY_FUNC_NAME, ## __VA_ARGS__) + +/** Macro for completion of last opened block explicitly. + +\code +#include +int foo() +{ + // some code ... + + int sum = 0; + EASY_BLOCK("Calculating sum"); + for (int i = 0; i < 10; ++i){ + sum += i; + } + EASY_END_BLOCK; + + // some antoher code here ... + + return sum; +} +\endcode + +\ingroup profiler +*/ +# define EASY_END_BLOCK ::profiler::endBlock(); + +/** Macro for creating event marker with custom name and color. + +Event marker is a block with zero duration and special type. + +\warning Event marker ends immidiately and calling EASY_END_BLOCK after EASY_EVENT +will end previously opened EASY_BLOCK or EASY_FUNCTION. + +\ingroup profiler +*/ +# define EASY_EVENT(name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), ::profiler::registerDescription(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Event, ::profiler::extract_color(__VA_ARGS__),\ + ::std::is_base_of<::profiler::ForceConstStr, decltype(name)>::value));\ + ::profiler::storeEvent(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name)); + +/** Macro for enabling profiler. + +\ingroup profiler +*/ +# define EASY_PROFILER_ENABLE ::profiler::setEnabled(true); + +/** Macro for disabling profiler. + +\ingroup profiler +*/ +# define EASY_PROFILER_DISABLE ::profiler::setEnabled(false); + +/** Macro for current thread registration. + +\note If this thread has been already registered then nothing happens. + +\ingroup profiler +*/ +# define EASY_THREAD(name)\ + EASY_THREAD_LOCAL static const char* EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = 0;\ + if (!EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__))\ + EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = ::profiler::registerThread(name); + +/** Macro for current thread registration and creating a thread guard object. + +\note If this thread has been already registered then nothing happens. + +\note Also creates thread guard which marks thread as "expired" on it's destructor +and creates "ThreadFinished" profiler event. + +\ingroup profiler +*/ +# define EASY_THREAD_SCOPE(name)\ + EASY_THREAD_LOCAL static const char* EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = 0;\ + ::profiler::ThreadGuard EASY_TOKEN_CONCATENATE(unique_profiler_thread_guard, __LINE__);\ + if (!EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__))\ + EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = ::profiler::registerThreadScoped(name,\ + EASY_TOKEN_CONCATENATE(unique_profiler_thread_guard, __LINE__)); + +/** Macro for main thread registration. + +This is just for user's comfort. There is no difference for EasyProfiler GUI between different threads. + +\ingroup profiler +*/ +# define EASY_MAIN_THREAD EASY_THREAD("Main") + +/** Enable or disable event tracing (context switch events). + +\note Default value is controlled by EASY_OPTION_EVENT_TRACING_ENABLED macro. + +\note Change will take effect on the next call to EASY_PROFILER_ENABLE. + +\sa EASY_PROFILER_ENABLE, EASY_OPTION_EVENT_TRACING_ENABLED + +\ingroup profiler +*/ +# define EASY_SET_EVENT_TRACING_ENABLED(isEnabled) ::profiler::setEventTracingEnabled(isEnabled); + +/** Set event tracing thread priority (low or normal). + +Event tracing with low priority will affect your application performance much more less, but +it can be late to gather information about thread/process (thread could be finished to the moment +when event tracing thread will be awaken) and you will not see process name and process id +information in GUI for such threads. You will still be able to see all context switch events. + +Event tracing with normal priority could gather more information about processes but potentially +it could affect performance as it has more work to do. Usually you will not notice any performance +breakdown, but if you care about that then you change set event tracing priority level to low. + +\sa EASY_OPTION_LOW_PRIORITY_EVENT_TRACING + +\ingroup profiler +*/ +# define EASY_SET_LOW_PRIORITY_EVENT_TRACING(isLowPriority) ::profiler::setLowPriorityEventTracing(isLowPriority); + +/** Macro for setting temporary log-file path for Unix event tracing system. + +\note Default value is "/tmp/cs_profiling_info.log". + +\ingroup profiler +*/ +# define EASY_EVENT_TRACING_SET_LOG(filename) ::profiler::setContextSwitchLogFilename(filename); + +/** Macro returning current path to the temporary log-file for Unix event tracing system. + +\ingroup profiler +*/ +# define EASY_EVENT_TRACING_LOG ::profiler::getContextSwitchLogFilename(); + +// EasyProfiler settings: + +/** If != 0 then EasyProfiler will measure time for blocks storage expansion. +If 0 then EasyProfiler will be compiled without blocks of code responsible +for measuring these events. + +These are "EasyProfiler.ExpandStorage" blocks on a diagram. + +\ingroup profiler +*/ +# ifndef EASY_OPTION_MEASURE_STORAGE_EXPAND +# define EASY_OPTION_MEASURE_STORAGE_EXPAND 0 +# endif + +# if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 +/** If true then "EasyProfiler.ExpandStorage" blocks are enabled by default and will be +writed to output file or translated over the net. +If false then you need to enable these blocks via GUI if you want to see them. + +\ingroup profiler +*/ +# ifndef EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON +# define EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON true +# endif + +# endif // EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 + +/** If true then EasyProfiler event tracing is enabled by default +and will be turned on and off when you call profiler::setEnabled(). +Otherwise, it have to be turned on via GUI and then it will be +turned on/off with next calls of profiler::setEnabled(). + +\ingroup profiler +*/ +# ifndef EASY_OPTION_EVENT_TRACING_ENABLED +# define EASY_OPTION_EVENT_TRACING_ENABLED true +# endif + +/** If true then EasyProfiler.ETW thread (Event tracing for Windows) will have low priority by default. + +\sa EASY_SET_LOW_PRIORITY_EVENT_TRACING + +\note You can always change priority level via GUI or API while profiling session is not launched. +You don't need to rebuild or restart your application for that. + +\ingroup profiler +*/ +# ifndef EASY_OPTION_LOW_PRIORITY_EVENT_TRACING +# define EASY_OPTION_LOW_PRIORITY_EVENT_TRACING true +# endif + + +/** If != 0 then EasyProfiler will print error messages into stderr. +Otherwise, no log messages will be printed. + +\ingroup profiler +*/ +# ifndef EASY_OPTION_LOG_ENABLED +# define EASY_OPTION_LOG_ENABLED 0 +# endif + +/** If != 0 then EasyProfiler will start listening thread immidiately on ProfileManager initialization. + +\sa startListen + +\ingroup profiler +*/ +# ifndef EASY_OPTION_START_LISTEN_ON_STARTUP +# define EASY_OPTION_START_LISTEN_ON_STARTUP 0 +# endif + +#else // #ifdef BUILD_WITH_EASY_PROFILER + +# define EASY_BLOCK(...) +# define EASY_NONSCOPED_BLOCK(...) +# define EASY_FUNCTION(...) +# define EASY_END_BLOCK +# define EASY_PROFILER_ENABLE +# define EASY_PROFILER_DISABLE +# define EASY_EVENT(...) +# define EASY_THREAD(...) +# define EASY_THREAD_SCOPE(...) +# define EASY_MAIN_THREAD +# define EASY_SET_EVENT_TRACING_ENABLED(isEnabled) +# define EASY_SET_LOW_PRIORITY_EVENT_TRACING(isLowPriority) + +# ifndef _WIN32 +# define EASY_EVENT_TRACING_SET_LOG(filename) +# define EASY_EVENT_TRACING_LOG "" +# endif + +# ifndef EASY_OPTION_MEASURE_STORAGE_EXPAND +# define EASY_OPTION_MEASURE_STORAGE_EXPAND 0 +# endif + +# ifndef EASY_OPTION_EVENT_TRACING_ENABLED +# define EASY_OPTION_EVENT_TRACING_ENABLED false +# endif + +# ifndef EASY_OPTION_LOW_PRIORITY_EVENT_TRACING +# define EASY_OPTION_LOW_PRIORITY_EVENT_TRACING true +# endif + +# ifndef EASY_OPTION_LOG_ENABLED +# define EASY_OPTION_LOG_ENABLED 0 +# endif + +# ifndef EASY_OPTION_START_LISTEN_ON_STARTUP +# define EASY_OPTION_START_LISTEN_ON_STARTUP 0 +# endif + +#endif // #ifndef BUILD_WITH_EASY_PROFILER + +# ifndef EASY_DEFAULT_PORT +# define EASY_DEFAULT_PORT 28077 +# endif + +/** Alias for EASY_PROFILER_ENABLE. + +Added for clarification. + +\sa EASY_PROFILER_ENABLE + +\ingroup profiler +*/ +#define EASY_START_CAPTURE EASY_PROFILER_ENABLE + +/** Alias for EASY_PROFILER_DISABLE. + +Added for clarification. + +\sa EASY_PROFILER_DISABLE + +\ingroup profiler +*/ +#define EASY_STOP_CAPTURE EASY_PROFILER_DISABLE + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + EASY_CONSTEXPR uint16_t DEFAULT_PORT = EASY_DEFAULT_PORT; + + ////////////////////////////////////////////////////////////////////// + // Core API + // Note: It is better to use macros defined above than a direct calls to API. + // But some API functions does not have macro wrappers... + +#ifdef USING_EASY_PROFILER + extern "C" { + + /** Returns current time in ticks. + + You can use it if you want to store block explicitly. + + \retval Current CPU time in ticks. + + \ingroup profiler + */ + PROFILER_API timestamp_t currentTime(); + + /** Convert ticks to nanoseconds. + + \retval _ticks converted to nanoseconds. + + \ingroup profiler + */ + PROFILER_API timestamp_t toNanoseconds(timestamp_t _ticks); + + /** Convert ticks to microseconds. + + \retval _ticks converted to microseconds. + + \ingroup profiler + */ + PROFILER_API timestamp_t toMicroseconds(timestamp_t _ticks); + + /** Registers static description of a block. + + It is general information which is common for all such blocks. + Includes color, block type (see BlockType), file-name, line-number, compile-time name of a block and enable-flag. + + \note This API function is used by EASY_EVENT, EASY_BLOCK, EASY_FUNCTION macros. + There is no need to invoke this function explicitly. + + \retval Pointer to registered block description. + + \ingroup profiler + */ + PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _compiletimeName, const char* _filename, int _line, block_type_t _block_type, color_t _color, bool _copyName = false); + + /** Stores event in the blocks list. + + An event ends instantly and has zero duration. + + \note There is no need to invoke this function explicitly - use EASY_EVENT macro instead. + + \param _desc Reference to the previously registered description. + \param _runtimeName Standard zero-terminated string which will be copied to the events buffer. + + \note _runtimeName must be an empty string ("") if you do not want to set name to the event at run-time. + + \ingroup profiler + */ + PROFILER_API void storeEvent(const BaseBlockDescriptor* _desc, const char* _runtimeName = ""); + + /** Stores block explicitly in the blocks list. + + Use this function for additional flexibility if you want to set block duration manually. + + \param _desc Reference to the previously registered description. + \param _runtimeName Standard zero-terminated string which will be copied to the events buffer. + \param _beginTime begin time of the block + \param _endTime end time of the block + + \note _runtimeName must be an empty string ("") if you do not want to set name to the block at run-time. + + \ingroup profiler + */ + PROFILER_API void storeBlock(const BaseBlockDescriptor* _desc, const char* _runtimeName, timestamp_t _beginTime, timestamp_t _endTime); + + /** Begins scoped block. + + \ingroup profiler + */ + PROFILER_API void beginBlock(Block& _block); + + /** Begins non-scoped block. + + \param _desc Reference to the previously registered description (see registerDescription). + \param _runtimeName Standard zero-terminated string which will be copied to the block buffer when block will end. + + \note There is no need to invoke this function explicitly - use EASY_NONSCOPED_BLOCK macro instead. + EASY_NONSCOPED_BLOCK macro could be used for higher flexibility if you have to begin block in one + function and end it in another one. + + \note _runtimeName must be an empty string ("") if you do not want to set name to the block at run-time. + \note _runtimeName is copied only when block ends so you must ensure it's validity until block end. + + \warning You have to end this block explicitly. + + \ingroup profiler + */ + PROFILER_API void beginNonScopedBlock(const BaseBlockDescriptor* _desc, const char* _runtimeName = ""); + + /** Ends last started block. + + Use this only if you want to finish block explicitly. + + \ingroup profiler + */ + PROFILER_API void endBlock(); + + /** Enable or disable profiler. + + AKA start or stop profiling (capturing blocks). + + \ingroup profiler + */ + PROFILER_API void setEnabled(bool _isEnable); + PROFILER_API bool isEnabled(); + + /** Save all gathered blocks into file. + + \note This also disables profiler. + + \retval Number of saved blocks. If 0 then nothing was profiled or an error occured. + + \ingroup profiler + */ + PROFILER_API uint32_t dumpBlocksToFile(const char* _filename); + + /** Register current thread and give it a name. + + Also creates a scoped ThreadGuard which would unregister thread on it's destructor. + This helps for memory management while using an old compiler whitout thread_local support. + + \note Only first call of registerThread() for the current thread will have an effect. + + \note Use this function if you want to build your source code with an old compiler (MSVC < 2013, GCC < 4.8, Clang < 3.3). + Otherwise there is no need in this function because a thread_local ThreadGuard created inside. + + \retval Registered name of the thread. It may differ from _name if the thread was registered before. + + \sa registerThread, ThreadGuard + + \ingroup profiler + */ + PROFILER_API const char* registerThreadScoped(const char* _name, ThreadGuard&); + + /** Register current thread and give it a name. + + \note Only first call of registerThread() for the current thread will have an effect. + + \retval Registered name of the thread. It may differ from _name if the thread was registered before. + + \ingroup profiler + */ + PROFILER_API const char* registerThread(const char* _name); + + /** Enable or disable event tracing. + + \note This change will take an effect on the next call of setEnabled(true); + + \sa setEnabled, EASY_SET_EVENT_TRACING_ENABLED + + \ingroup profiler + */ + PROFILER_API void setEventTracingEnabled(bool _isEnable); + PROFILER_API bool isEventTracingEnabled(); + + /** Set event tracing thread priority (low or normal). + + \note This change will take effect on the next call of setEnabled(true); + + \sa setEnabled, EASY_SET_LOW_PRIORITY_EVENT_TRACING + + \ingroup profiler + */ + PROFILER_API void setLowPriorityEventTracing(bool _isLowPriority); + PROFILER_API bool isLowPriorityEventTracing(); + + /** Set temporary log-file path for Unix event tracing system. + + \note Default value is "/tmp/cs_profiling_info.log". + + \ingroup profiler + */ + PROFILER_API void setContextSwitchLogFilename(const char* _name); + + /** Returns current path to the temporary log-file for Unix event tracing system. + + \ingroup profiler + */ + PROFILER_API const char* getContextSwitchLogFilename(); + + /** Start listening for network commands. + + Launches a separate listening thread which would listen to the network commands (start, stop, etc.). + The listening thread sends all profiled blocks via network after receiving network command 'stop'. + + \ingroup profiler + */ + PROFILER_API void startListen(uint16_t _port = ::profiler::DEFAULT_PORT); + + /** Stops listening thread. + + \note This would be invoked automatically on application exit. + + \note Does not send any messages to the network, just stops thread. + + \ingroup profiler + */ + PROFILER_API void stopListen(); + + /** Check if listening thread launched. + + \ingroup profiler + */ + PROFILER_API bool isListening(); + + /** Returns current major version. + + \ingroup profiler + */ + PROFILER_API uint8_t versionMajor(); + + /** Returns current minor version. + + \ingroup profiler + */ + PROFILER_API uint8_t versionMinor(); + + /** Returns current version patch. + + \ingroup profiler + */ + PROFILER_API uint16_t versionPatch(); + + /** Returns current version in 32-bit integer format. + + \note Format is: 0x MAJ-MAJ MIN-MIN PATCH-PATCH-PATCH-PATCH + For example v1.3.0 is: 0x01030000 + + \ingroup profiler + */ + PROFILER_API uint32_t version(); + + /** Returns current version string. + + Example: "v1.3.0" + + \ingroup profiler + */ + PROFILER_API const char* versionName(); + + /** Returns true if current thread has been marked as Main. + Otherwise, returns false. + + \ingroup profiler + */ + PROFILER_API bool isMainThread(); + + /** Returns last frame duration for current thread. + + \param _durationCast desired duration units (could be cpu-ticks or microseconds) + + \ingroup profiler + */ + PROFILER_API timestamp_t this_thread_frameTime(Duration _durationCast = ::profiler::MICROSECONDS); + + /** Returns local max of frame duration for current thread. + + Local max is maximum frame duration since last frameTimeLocalMax() call. + + \param _durationCast desired duration units (could be cpu-ticks or microseconds) + + \ingroup profiler + */ + PROFILER_API timestamp_t this_thread_frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS); + + /** Returns local average of frame duration for current thread. + + Local average is average frame duration since last frameTimeLocalAvg() call. + + \param _durationCast desired duration units (could be cpu-ticks or microseconds) + + \ingroup profiler + */ + PROFILER_API timestamp_t this_thread_frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS); + + /** Returns last frame duration for main thread. + + \param _durationCast desired duration units (could be cpu-ticks or microseconds) + + \ingroup profiler + */ + PROFILER_API timestamp_t main_thread_frameTime(Duration _durationCast = ::profiler::MICROSECONDS); + + /** Returns local max of frame duration for main thread. + + Local max is maximum frame duration since last frameTimeLocalMax() call. + + \param _durationCast desired duration units (could be cpu-ticks or microseconds) + + \ingroup profiler + */ + PROFILER_API timestamp_t main_thread_frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS); + + /** Returns local average of frame duration for main thread. + + Local average is average frame duration since last frameTimeLocalAvg() call. + + \param _durationCast desired duration units (could be cpu-ticks or microseconds) + + \ingroup profiler + */ + PROFILER_API timestamp_t main_thread_frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS); + + } +#else + inline timestamp_t currentTime() { return 0; } + inline timestamp_t toNanoseconds(timestamp_t) { return 0; } + inline timestamp_t toMicroseconds(timestamp_t) { return 0; } + inline const BaseBlockDescriptor* registerDescription(EasyBlockStatus, const char*, const char*, const char*, int, block_type_t, color_t, bool = false) + { return reinterpret_cast(0xbad); } + inline void endBlock() { } + inline void setEnabled(bool) { } + inline bool isEnabled() { return false; } + inline void storeEvent(const BaseBlockDescriptor*, const char* = "") { } + inline void storeBlock(const BaseBlockDescriptor*, const char*, timestamp_t, timestamp_t) { } + inline void beginBlock(Block&) { } + inline void beginNonScopedBlock(const BaseBlockDescriptor*, const char* = "") { } + inline uint32_t dumpBlocksToFile(const char*) { return 0; } + inline const char* registerThreadScoped(const char*, ThreadGuard&) { return ""; } + inline const char* registerThread(const char*) { return ""; } + inline void setEventTracingEnabled(bool) { } + inline bool isEventTracingEnabled() { return false; } + inline void setLowPriorityEventTracing(bool) { } + inline bool isLowPriorityEventTracing() { return false; } + inline void setContextSwitchLogFilename(const char*) { } + inline const char* getContextSwitchLogFilename() { return ""; } + inline void startListen(uint16_t = ::profiler::DEFAULT_PORT) { } + inline void stopListen() { } + inline bool isListening() { return false; } + inline uint8_t versionMajor() { return 0; } + inline uint8_t versionMinor() { return 0; } + inline uint16_t versionPatch() { return 0; } + inline uint32_t version() { return 0; } + inline const char* versionName() { return "v0.0.0_disabled"; } + inline bool isMainThread() { return false; } + inline timestamp_t this_thread_frameTime(Duration = ::profiler::MICROSECONDS) { return 0; } + inline timestamp_t this_thread_frameTimeLocalMax(Duration = ::profiler::MICROSECONDS) { return 0; } + inline timestamp_t this_thread_frameTimeLocalAvg(Duration = ::profiler::MICROSECONDS) { return 0; } + inline timestamp_t main_thread_frameTime(Duration = ::profiler::MICROSECONDS) { return 0; } + inline timestamp_t main_thread_frameTimeLocalMax(Duration = ::profiler::MICROSECONDS) { return 0; } + inline timestamp_t main_thread_frameTimeLocalAvg(Duration = ::profiler::MICROSECONDS) { return 0; } +#endif + + /** API functions binded to current thread. + + \ingroup profiler + */ + namespace this_thread { + + inline const char* registrate(const char* _name) { + return ::profiler::registerThread(_name); + } + + inline const char* registrate(const char* _name, ThreadGuard& _threadGuard) { + return ::profiler::registerThreadScoped(_name, _threadGuard); + } + + inline timestamp_t frameTime(Duration _durationCast = ::profiler::MICROSECONDS) { + return ::profiler::this_thread_frameTime(_durationCast); + } + + inline timestamp_t frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS) { + return ::profiler::this_thread_frameTimeLocalMax(_durationCast); + } + + inline timestamp_t frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS) { + return ::profiler::this_thread_frameTimeLocalAvg(_durationCast); + } + + inline bool isMain() { + return ::profiler::isMainThread(); + } + + } // END of namespace this_thread. + + /** API functions binded to main thread. + + Could be called from any thread. + + \ingroup profiler + */ + namespace main_thread { + + inline timestamp_t frameTime(Duration _durationCast = ::profiler::MICROSECONDS) { + return ::profiler::main_thread_frameTime(_durationCast); + } + + inline timestamp_t frameTimeLocalMax(Duration _durationCast = ::profiler::MICROSECONDS) { + return ::profiler::main_thread_frameTimeLocalMax(_durationCast); + } + + inline timestamp_t frameTimeLocalAvg(Duration _durationCast = ::profiler::MICROSECONDS) { + return ::profiler::main_thread_frameTimeLocalAvg(_durationCast); + } + + /** Always returns true. + */ + inline EASY_CONSTEXPR_FCN bool isMain() { + return true; + } + + } // END of namespace main_thread. + + /** Alias for isEnabled(). + + Added for clarification. + + \sa isEnabled + + \ingroup profiler + */ + EASY_FORCE_INLINE bool isCapturing() { return isEnabled(); } + + /** Alias for EASY_PROFILER_ENABLE. + + Added for clarification. + + \sa EASY_PROFILER_ENABLE + + \ingroup profiler + */ + EASY_FORCE_INLINE void startCapture() { EASY_PROFILER_ENABLE; } + + /** Alias for EASY_PROFILER_DISABLE. + + Added for clarification. + + \sa EASY_PROFILER_DISABLE + + \ingroup profiler + */ + EASY_FORCE_INLINE void stopCapture() { EASY_PROFILER_DISABLE; } + + ////////////////////////////////////////////////////////////////////// + +} // END of namespace profiler. + +#if defined ( __clang__ ) +# pragma clang diagnostic pop +#endif + +#endif // EASY_PROFILER_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/reader.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/reader.h new file mode 100644 index 0000000..cbfe414 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/reader.h @@ -0,0 +1,428 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef PROFILER_READER____H +#define PROFILER_READER____H + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + using calls_number_t = uint32_t; + using block_index_t = uint32_t; + +#pragma pack(push, 1) + struct BlockStatistics EASY_FINAL + { + ::profiler::timestamp_t total_duration; ///< Total duration of all block calls + ::profiler::timestamp_t total_children_duration; ///< Total duration of all children of all block calls + ::profiler::block_index_t min_duration_block; ///< Will be used in GUI to jump to the block with min duration + ::profiler::block_index_t max_duration_block; ///< Will be used in GUI to jump to the block with max duration + ::profiler::block_index_t parent_block; ///< Index of block which is "parent" for "per_parent_stats" or "frame" for "per_frame_stats" or thread-id for "per_thread_stats" + ::profiler::calls_number_t calls_number; ///< Block calls number + + explicit BlockStatistics(::profiler::timestamp_t _duration, ::profiler::block_index_t _block_index, ::profiler::block_index_t _parent_index) + : total_duration(_duration) + , total_children_duration(0) + , min_duration_block(_block_index) + , max_duration_block(_block_index) + , parent_block(_parent_index) + , calls_number(1) + { + } + + //BlockStatistics() = default; + + inline ::profiler::timestamp_t average_duration() const + { + return total_duration / calls_number; + } + + }; // END of struct BlockStatistics. +#pragma pack(pop) + + extern "C" PROFILER_API void release_stats(BlockStatistics*& _stats); + + ////////////////////////////////////////////////////////////////////////// + + class BlocksTree EASY_FINAL + { + using This = BlocksTree; + + public: + + using blocks_t = ::std::vector; + using children_t = ::std::vector<::profiler::block_index_t>; + + children_t children; ///< List of children blocks. May be empty. + + union { + ::profiler::SerializedBlock* node; ///< Pointer to serialized data for regular block (id, name, begin, end etc.) + ::profiler::SerializedCSwitch* cs; ///< Pointer to serialized data for context switch (thread_id, name, begin, end etc.) + ::profiler::ArbitraryValue* value; ///< Pointer to serialized data for arbitrary value + }; + + ::profiler::BlockStatistics* per_parent_stats; ///< Pointer to statistics for this block within the parent (may be nullptr for top-level blocks) + ::profiler::BlockStatistics* per_frame_stats; ///< Pointer to statistics for this block within the frame (may be nullptr for top-level blocks) + ::profiler::BlockStatistics* per_thread_stats; ///< Pointer to statistics for this block within the bounds of all frames per current thread + uint8_t depth; ///< Maximum number of sublevels (maximum children depth) + + BlocksTree(const This&) = delete; + This& operator = (const This&) = delete; + + BlocksTree() EASY_NOEXCEPT + : node(nullptr) + , per_parent_stats(nullptr) + , per_frame_stats(nullptr) + , per_thread_stats(nullptr) + , depth(0) + { + + } + + BlocksTree(This&& that) EASY_NOEXCEPT + : BlocksTree() + { + make_move(::std::forward(that)); + } + + This& operator = (This&& that) EASY_NOEXCEPT + { + make_move(::std::forward(that)); + return *this; + } + + ~BlocksTree() EASY_NOEXCEPT + { + release_stats(per_thread_stats); + release_stats(per_parent_stats); + release_stats(per_frame_stats); + } + + bool operator < (const This& other) const EASY_NOEXCEPT + { + if (node == nullptr || other.node == nullptr) + return false; + return node->begin() < other.node->begin(); + } + + void shrink_to_fit() EASY_NOEXCEPT + { + //for (auto& child : children) + // child.shrink_to_fit(); + + // shrink version 1: + //children.shrink_to_fit(); + + // shrink version 2: + //children_t new_children; + //new_children.reserve(children.size()); + //::std::move(children.begin(), children.end(), ::std::back_inserter(new_children)); + //new_children.swap(children); + } + + private: + + void make_move(This&& that) EASY_NOEXCEPT + { + if (per_thread_stats != that.per_thread_stats) + release_stats(per_thread_stats); + + if (per_parent_stats != that.per_parent_stats) + release_stats(per_parent_stats); + + if (per_frame_stats != that.per_frame_stats) + release_stats(per_frame_stats); + + children = ::std::move(that.children); + node = that.node; + per_parent_stats = that.per_parent_stats; + per_frame_stats = that.per_frame_stats; + per_thread_stats = that.per_thread_stats; + depth = that.depth; + + that.node = nullptr; + that.per_parent_stats = nullptr; + that.per_frame_stats = nullptr; + that.per_thread_stats = nullptr; + } + + }; // END of class BlocksTree. + + ////////////////////////////////////////////////////////////////////////// + + class BlocksTreeRoot EASY_FINAL + { + using This = BlocksTreeRoot; + + public: + + BlocksTree::children_t children; ///< List of children indexes + BlocksTree::children_t sync; ///< List of context-switch events + BlocksTree::children_t events; ///< List of events indexes + std::string thread_name; ///< Name of this thread + ::profiler::timestamp_t profiled_time; ///< Profiled time of this thread (sum of all children duration) + ::profiler::timestamp_t wait_time; ///< Wait time of this thread (sum of all context switches) + ::profiler::thread_id_t thread_id; ///< System Id of this thread + ::profiler::block_index_t frames_number; ///< Total frames number (top-level blocks) + ::profiler::block_index_t blocks_number; ///< Total blocks number including their children + uint8_t depth; ///< Maximum stack depth (number of levels) + + BlocksTreeRoot(const This&) = delete; + This& operator = (const This&) = delete; + + BlocksTreeRoot() EASY_NOEXCEPT + : profiled_time(0), wait_time(0), thread_id(0), frames_number(0), blocks_number(0), depth(0) + { + } + + BlocksTreeRoot(This&& that) EASY_NOEXCEPT + : children(::std::move(that.children)) + , sync(::std::move(that.sync)) + , events(::std::move(that.events)) + , thread_name(::std::move(that.thread_name)) + , profiled_time(that.profiled_time) + , wait_time(that.wait_time) + , thread_id(that.thread_id) + , frames_number(that.frames_number) + , blocks_number(that.blocks_number) + , depth(that.depth) + { + } + + This& operator = (This&& that) EASY_NOEXCEPT + { + children = ::std::move(that.children); + sync = ::std::move(that.sync); + events = ::std::move(that.events); + thread_name = ::std::move(that.thread_name); + profiled_time = that.profiled_time; + wait_time = that.wait_time; + thread_id = that.thread_id; + frames_number = that.frames_number; + blocks_number = that.blocks_number; + depth = that.depth; + return *this; + } + + inline bool got_name() const EASY_NOEXCEPT + { + return !thread_name.empty(); + } + + inline const char* name() const EASY_NOEXCEPT + { + return thread_name.c_str(); + } + + bool operator < (const This& other) const EASY_NOEXCEPT + { + return thread_id < other.thread_id; + } + + }; // END of class BlocksTreeRoot. + + using blocks_t = ::profiler::BlocksTree::blocks_t; + using thread_blocks_tree_t = ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot, ::estd::hash<::profiler::thread_id_t> >; + + ////////////////////////////////////////////////////////////////////////// + + class PROFILER_API SerializedData EASY_FINAL + { + char* m_data; + size_t m_size; + + public: + + SerializedData(const SerializedData&) = delete; + SerializedData& operator = (const SerializedData&) = delete; + + SerializedData() : m_data(nullptr), m_size(0) + { + } + + SerializedData(SerializedData&& that) : m_data(that.m_data), m_size(that.m_size) + { + that.m_data = nullptr; + that.m_size = 0; + } + + ~SerializedData() + { + clear(); + } + + void set(uint64_t _size); + void extend(uint64_t _size); + + SerializedData& operator = (SerializedData&& that) + { + set(that.m_data, that.m_size); + that.m_data = nullptr; + that.m_size = 0; + return *this; + } + + char* operator [] (uint64_t i) + { + return m_data + i; + } + + const char* operator [] (uint64_t i) const + { + return m_data + i; + } + + bool empty() const + { + return m_size == 0; + } + + uint64_t size() const + { + return m_size; + } + + char* data() + { + return m_data; + } + + const char* data() const + { + return m_data; + } + + void clear() + { + set(nullptr, 0); + } + + void swap(SerializedData& other) + { + char* d = other.m_data; + uint64_t sz = other.m_size; + + other.m_data = m_data; + other.m_size = m_size; + + m_data = d; + m_size = (size_t)sz; + } + + private: + + void set(char* _data, uint64_t _size); + + }; // END of class SerializedData. + + ////////////////////////////////////////////////////////////////////////// + + using descriptors_list_t = ::std::vector; + +} // END of namespace profiler. + +extern "C" { + + PROFILER_API ::profiler::block_index_t fillTreesFromFile(::std::atomic& progress, const char* filename, + ::profiler::SerializedData& serialized_blocks, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::profiler::blocks_t& _blocks, + ::profiler::thread_blocks_tree_t& threaded_trees, + uint32_t& total_descriptors_number, + uint32_t& version, + bool gather_statistics, + ::std::stringstream& _log); + + PROFILER_API ::profiler::block_index_t fillTreesFromStream(::std::atomic& progress, ::std::stringstream& str, + ::profiler::SerializedData& serialized_blocks, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::profiler::blocks_t& _blocks, + ::profiler::thread_blocks_tree_t& threaded_trees, + uint32_t& total_descriptors_number, + uint32_t& version, + bool gather_statistics, + ::std::stringstream& _log); + + PROFILER_API bool readDescriptionsFromStream(::std::atomic& progress, ::std::stringstream& str, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::std::stringstream& _log); +} + +inline ::profiler::block_index_t fillTreesFromFile(const char* filename, ::profiler::SerializedData& serialized_blocks, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, ::profiler::blocks_t& _blocks, + ::profiler::thread_blocks_tree_t& threaded_trees, + uint32_t& total_descriptors_number, + uint32_t& version, + bool gather_statistics, + ::std::stringstream& _log) +{ + ::std::atomic progress = ATOMIC_VAR_INIT(0); + return fillTreesFromFile(progress, filename, serialized_blocks, serialized_descriptors, descriptors, _blocks, threaded_trees, total_descriptors_number, version, gather_statistics, _log); +} + +inline bool readDescriptionsFromStream(::std::stringstream& str, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::std::stringstream& _log) +{ + ::std::atomic progress = ATOMIC_VAR_INIT(0); + return readDescriptionsFromStream(progress, str, serialized_descriptors, descriptors, _log); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif // PROFILER_READER____H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/serialized_block.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/serialized_block.h new file mode 100644 index 0000000..dd07711 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/serialized_block.h @@ -0,0 +1,289 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_SERIALIZED_BLOCK_H +#define EASY_PROFILER_SERIALIZED_BLOCK_H + +#include +#include + +class CSwitchBlock; + +namespace profiler { + + template + struct Value; + + template + struct Value; + + ////////////////////////////////////////////////////////////////////////// + + class PROFILER_API SerializedBlock EASY_FINAL : public BaseBlockData + { + friend ::ProfileManager; + friend ::ThreadStorage; + + public: + + inline const char* data() const { return reinterpret_cast(this); } + + ///< Run-time block name is stored right after main BaseBlockData data + inline const char* name() const { return data() + sizeof(BaseBlockData); } + + SerializedBlock(const SerializedBlock&) = delete; + SerializedBlock& operator = (const SerializedBlock&) = delete; + SerializedBlock(SerializedBlock&&) = delete; + SerializedBlock& operator = (SerializedBlock&&) = delete; + ~SerializedBlock() = delete; + + private: + + explicit SerializedBlock(const Block& block, uint16_t name_length); + + }; // END of SerializedBlock. + + ////////////////////////////////////////////////////////////////////////// + +#pragma pack(push, 1) + class PROFILER_API CSwitchEvent : public Event + { + thread_id_t m_thread_id; + + public: + + CSwitchEvent() = default; + CSwitchEvent(const CSwitchEvent&) = default; + explicit CSwitchEvent(timestamp_t _begin_time, thread_id_t _tid) EASY_NOEXCEPT; + + inline thread_id_t tid() const EASY_NOEXCEPT { return m_thread_id; } + + }; // END of class CSwitchEvent. +#pragma pack(pop) + + class PROFILER_API SerializedCSwitch EASY_FINAL : public CSwitchEvent + { + friend ::ProfileManager; + friend ::ThreadStorage; + + public: + + inline const char* data() const { return reinterpret_cast(this); } + + ///< Run-time block name is stored right after main CSwitchEvent data + inline const char* name() const { return data() + sizeof(CSwitchEvent); } + + SerializedCSwitch(const SerializedCSwitch&) = delete; + SerializedCSwitch& operator = (const SerializedCSwitch&) = delete; + SerializedCSwitch(SerializedCSwitch&&) = delete; + SerializedCSwitch& operator = (SerializedCSwitch&&) = delete; + ~SerializedCSwitch() = delete; + + private: + + explicit SerializedCSwitch(const CSwitchBlock& block, uint16_t name_length); + + }; // END of SerializedCSwitch. + + ////////////////////////////////////////////////////////////////////////// + +#pragma pack(push, 1) + class PROFILER_API SerializedBlockDescriptor EASY_FINAL : public BaseBlockDescriptor + { + uint16_t m_nameLength; ///< Length of the name including trailing '\0' sybmol + + public: + + inline const char* data() const { + return reinterpret_cast(this); + } + + ///< Name is stored right after m_nameLength + inline const char* name() const { + static const auto shift = sizeof(BaseBlockDescriptor) + sizeof(decltype(m_nameLength)); + return data() + shift; + } + + ///< File name is stored right after the name + inline const char* file() const { + return name() + m_nameLength; + } + + inline void setStatus(EasyBlockStatus _status) EASY_NOEXCEPT { + m_status = _status; + } + + // Instances of this class can not be created or destroyed directly + SerializedBlockDescriptor() = delete; + SerializedBlockDescriptor(const SerializedBlockDescriptor&) = delete; + SerializedBlockDescriptor& operator = (const SerializedBlockDescriptor&) = delete; + SerializedBlockDescriptor(SerializedBlockDescriptor&&) = delete; + SerializedBlockDescriptor& operator = (SerializedBlockDescriptor&&) = delete; + ~SerializedBlockDescriptor() = delete; + + }; // END of SerializedBlockDescriptor. +//#pragma pack(pop) + + ////////////////////////////////////////////////////////////////////////// + +//#pragma pack(push, 1) + class PROFILER_API ArbitraryValue : protected BaseBlockData + { + friend ::ThreadStorage; + + protected: + + char m_nameStub; ///< Artificial padding which is used to imitate SerializedBlock::name() == 0 behavior + char m_padding; ///< Padding to the bound of 2 bytes + uint16_t m_size; + DataType m_type; + bool m_isArray; + vin_t m_value_id; + + explicit ArbitraryValue(timestamp_t _timestamp, vin_t _vin, block_id_t _id, + uint16_t _size, DataType _type, bool _isArray) + : BaseBlockData(_timestamp, _timestamp, _id) + , m_nameStub(0) + , m_padding(0) + , m_size(_size) + , m_type(_type) + , m_isArray(_isArray) + , m_value_id(_vin) + { + } + + public: + + using BaseBlockData::id; + using Event::begin; + + ~ArbitraryValue() = delete; + + const char* data() const { + return reinterpret_cast(this) + sizeof(ArbitraryValue); + } + + vin_t value_id() const { + return m_value_id; + } + + DataType type() const { + return m_type; + } + + bool isArray() const { + return m_isArray; + } + + template + const Value* toValue() const { + return m_type == dataType ? static_cast*>(this) : nullptr; + } + + template + const Value::data_type, false>* toValue() const { + static_assert(StdToDataType::data_type != DataType::TypesCount, + "You should use standard builtin scalar types as profiler::Value type!"); + return toValue::data_type>(); + } + + template + const Value* toArray() const { + return m_isArray && m_type == dataType ? static_cast*>(this) : nullptr; + } + + template + const Value::data_type, true>* toArray() const { + static_assert(StdToDataType::data_type != DataType::TypesCount, + "You should use standard builtin scalar types as profiler::Value type!"); + return toArray::data_type>(); + } + }; // end of class ArbitraryValue. +#pragma pack(pop) + + ////////////////////////////////////////////////////////////////////////// + + template + struct Value EASY_FINAL : public ArbitraryValue { + using value_type = typename StdType::value_type; + value_type value() const { return *reinterpret_cast(data()); } + ~Value() = delete; + }; + + + template + struct Value EASY_FINAL : public ArbitraryValue { + using value_type = typename StdType::value_type; + const value_type* value() const { return reinterpret_cast(data()); } + uint16_t size() const { return m_size / sizeof(value_type); } + value_type operator [] (int i) const { return value()[i]; } + value_type at(int i) const { return value()[i]; } + ~Value() = delete; + }; + + + template <> + struct Value EASY_FINAL : public ArbitraryValue { + using value_type = char; + const char* value() const { return data(); } + uint16_t size() const { return m_size; } + char operator [] (int i) const { return data()[i]; } + char at(int i) const { return data()[i]; } + const char* c_str() const { return data(); } + ~Value() = delete; + }; + + ////////////////////////////////////////////////////////////////////////// + + template + using SingleValue = Value; + + template + using ArrayValue = Value; + + using StringValue = Value; + + ////////////////////////////////////////////////////////////////////////// + +} // END of namespace profiler. + +#endif // EASY_PROFILER_SERIALIZED_BLOCK_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/include/easy/utility.h b/3rdparty/easyprofiler/easy_profiler_core/include/easy/utility.h new file mode 100644 index 0000000..167e17d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/include/easy/utility.h @@ -0,0 +1,63 @@ + + +#ifndef EASY_PROFILER_UTILITY_H +#define EASY_PROFILER_UTILITY_H + +#include +#include +#include +#include + +namespace estd { + +////////////////////////////////////////////////////////////////////////// + + namespace detail { + template struct hasher { + using type = const T&; + EASY_FORCE_INLINE size_t operator () (type value) const { return ::std::hash {}(value); } }; + + template struct hasher { + using type = T; + EASY_FORCE_INLINE size_t operator () (type value) const { return static_cast(value); } }; + } + + template struct hash EASY_FINAL : public ::estd::detail::hasher sizeof(void*))> { + using ::estd::detail::hasher sizeof(void*))>::operator(); + }; + + template struct hash EASY_FINAL { + EASY_FORCE_INLINE size_t operator () (const T* value) const { return reinterpret_cast(value); } }; + + template struct hash EASY_FINAL { + EASY_FORCE_INLINE size_t operator () (const T* value) const { return reinterpret_cast(value); } }; + +////////////////////////////////////////////////////////////////////////// + + template + inline EASY_CONSTEXPR_FCN Q clamp(T min_value, Q value, W max_value) { + return static_cast(min_value < value ? (value < max_value ? value : max_value) : min_value); + } + + template + EASY_FORCE_INLINE EASY_CONSTEXPR_FCN T sqr(T value) { + return value * value; + } + + template + EASY_FORCE_INLINE EASY_CONSTEXPR_FCN int sign(T value) { return value < 0 ? -1 : 1; } + + template + inline EASY_CONSTEXPR_FCN T absmin(T a, T b) { return abs(a) < abs(b) ? a : b; } + + template + inline T logn(T value) { + EASY_STATIC_CONSTEXPR double div = 1.0 / log2((double)N); + return log2(value) * div; + } + +////////////////////////////////////////////////////////////////////////// + +} // end of namespace estd. + +#endif // EASY_PROFILER_UTILITY_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/nonscoped_block.cpp b/3rdparty/easyprofiler/easy_profiler_core/nonscoped_block.cpp new file mode 100644 index 0000000..6fa5d77 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/nonscoped_block.cpp @@ -0,0 +1,92 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#include "nonscoped_block.h" +#include +#include + +NonscopedBlock::NonscopedBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, bool) + : profiler::Block(_desc, _runtimeName, false), m_runtimeName(nullptr) +{ + +} + +NonscopedBlock::~NonscopedBlock() +{ + // Actually destructor should not be invoked because StackBuffer do manual memory management + + m_end = m_begin; // to restrict profiler::Block to invoke profiler::endBlock() on destructor. + free(m_runtimeName); +} + +void NonscopedBlock::copyname() +{ + // Here we need to copy m_name to m_runtimeName to ensure that + // it would be alive to the moment we will serialize the block + + if ((m_status & profiler::ON) == 0) + return; + + if (*m_name != 0) + { + auto len = strlen(m_name); + m_runtimeName = static_cast(malloc(len + 1)); + + // memcpy should be faster than strncpy because we know + // actual bytes number and both strings have the same size + memcpy(m_runtimeName, m_name, len); + + m_runtimeName[len] = 0; + m_name = m_runtimeName; + } + else + { + m_name = ""; + } +} + +void NonscopedBlock::destroy() +{ + // free memory used by m_runtimeName + free(m_runtimeName); + m_name = ""; +} diff --git a/3rdparty/easyprofiler/easy_profiler_core/nonscoped_block.h b/3rdparty/easyprofiler/easy_profiler_core/nonscoped_block.h new file mode 100644 index 0000000..5655f5a --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/nonscoped_block.h @@ -0,0 +1,73 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_NONSCOPED_BLOCK_H +#define EASY_PROFILER_NONSCOPED_BLOCK_H + +#include + +class NonscopedBlock : public profiler::Block +{ + char* m_runtimeName; ///< A copy of _runtimeName to make it safe to begin block in one function and end it in another + +public: + + NonscopedBlock() = delete; + NonscopedBlock(const NonscopedBlock&) = delete; + NonscopedBlock(NonscopedBlock&&) = delete; + NonscopedBlock& operator = (const NonscopedBlock&) = delete; + NonscopedBlock& operator = (NonscopedBlock&&) = delete; + + NonscopedBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, bool = false); + ~NonscopedBlock(); + + /** Copy string from m_name to m_runtimeName to make it safe to end block in another function. + + Performs any work if block is ON and m_name != "" + */ + void copyname(); + + void destroy(); + +}; // END of class NonscopedBlock. + +#endif // EASY_PROFILER_NONSCOPED_BLOCK_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/outstream.h b/3rdparty/easyprofiler/easy_profiler_core/outstream.h new file mode 100644 index 0000000..f27762d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/outstream.h @@ -0,0 +1,115 @@ +/************************************************************************ +* file name : outstream.h +* ----------------- : +* creation time : 2016/09/11 +* authors : Sergey Yagovtsev, Victor Zarubkin +* emails : yse.sey@gmail.com, v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains definition of output stream helpers. +* ----------------- : +* change log : * 2016/09/11 Victor Zarubkin: Initial commit. Moved sources from profiler_manager.h/.cpp +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER__OUTPUT_STREAM__H_ +#define EASY_PROFILER__OUTPUT_STREAM__H_ + +#include +#include + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + class OStream + { + ::std::stringstream m_stream; + + public: + + explicit OStream() : m_stream(std::ios_base::out | std::ios_base::binary) + { + + } + + template void write(const char* _data, T _size) + { + m_stream.write(_data, _size); + } + + template void write(const T& _data) + { + m_stream.write((const char*)&_data, sizeof(T)); + } + + ::std::stringstream& stream() + { + return m_stream; + } + + const ::std::stringstream& stream() const + { + return m_stream; + } + + void clear() + { +#if defined(__GNUC__) && __GNUC__ < 5 + // gcc 4 has a known bug which has been solved in gcc 5: + // std::stringstream has no swap() method :( + m_stream.str(::std::string()); +#else + ::std::stringstream().swap(m_stream); +#endif + } + + }; // END of class OStream. + +} // END of namespace profiler. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER__OUTPUT_STREAM__H_ diff --git a/3rdparty/easyprofiler/easy_profiler_core/profile_manager.cpp b/3rdparty/easyprofiler/easy_profiler_core/profile_manager.cpp new file mode 100644 index 0000000..d61246d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/profile_manager.cpp @@ -0,0 +1,2015 @@ +/************************************************************************ +* file name : profile_manager.cpp +* ----------------- : +* creation time : 2016/02/16 +* authors : Sergey Yagovtsev, Victor Zarubkin +* emails : yse.sey@gmail.com, v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of Profile manager and implement access c-function +* : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include "profile_manager.h" + +#include +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +#include "event_trace_win.h" +#include "current_time.h" +#include "current_thread.h" + +#ifdef __APPLE__ +#include +#include +#endif + +#if EASY_OPTION_LOG_ENABLED != 0 +# include + +# ifndef EASY_ERRORLOG +# define EASY_ERRORLOG ::std::cerr +# endif + +# ifndef EASY_LOG +# define EASY_LOG ::std::cerr +# endif + +# ifndef EASY_ERROR +# define EASY_ERROR(LOG_MSG) EASY_ERRORLOG << "EasyProfiler ERROR: " << LOG_MSG +# endif + +# ifndef EASY_WARNING +# define EASY_WARNING(LOG_MSG) EASY_ERRORLOG << "EasyProfiler WARNING: " << LOG_MSG +# endif + +# ifndef EASY_LOGMSG +# define EASY_LOGMSG(LOG_MSG) EASY_LOG << "EasyProfiler INFO: " << LOG_MSG +# endif + +# ifndef EASY_LOG_ONLY +# define EASY_LOG_ONLY(CODE) CODE +# endif + +#else + +# ifndef EASY_ERROR +# define EASY_ERROR(LOG_MSG) +# endif + +# ifndef EASY_WARNING +# define EASY_WARNING(LOG_MSG) +# endif + +# ifndef EASY_LOGMSG +# define EASY_LOGMSG(LOG_MSG) +# endif + +# ifndef EASY_LOG_ONLY +# define EASY_LOG_ONLY(CODE) +# endif + +#endif + +#ifdef min +# undef min +#endif + +#ifndef EASY_ENABLE_BLOCK_STATUS +# define EASY_ENABLE_BLOCK_STATUS 1 +#endif + +#if !defined(_WIN32) && !defined(EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS) +# define EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS 0 +#endif + +#ifndef EASY_OPTION_IMPLICIT_THREAD_REGISTRATION +# define EASY_OPTION_IMPLICIT_THREAD_REGISTRATION 0 +#endif + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +using namespace profiler; + +////////////////////////////////////////////////////////////////////////// + +#if !defined(EASY_PROFILER_VERSION_MAJOR) || !defined(EASY_PROFILER_VERSION_MINOR) || !defined(EASY_PROFILER_VERSION_PATCH) +# ifdef _WIN32 +# error EASY_PROFILER_VERSION_MAJOR and EASY_PROFILER_VERSION_MINOR and EASY_PROFILER_VERSION_PATCH macros must be defined +# else +# error "EASY_PROFILER_VERSION_MAJOR and EASY_PROFILER_VERSION_MINOR and EASY_PROFILER_VERSION_PATCH macros must be defined" +# endif +#endif + +# define EASY_PROFILER_PRODUCT_VERSION "v" EASY_STRINGIFICATION(EASY_PROFILER_VERSION_MAJOR) "." \ + EASY_STRINGIFICATION(EASY_PROFILER_VERSION_MINOR) "." \ + EASY_STRINGIFICATION(EASY_PROFILER_VERSION_PATCH) + +# define EASY_VERSION_INT(v_major, v_minor, v_patch) ((static_cast(v_major) << 24) | (static_cast(v_minor) << 16) | static_cast(v_patch)) +extern const uint32_t PROFILER_SIGNATURE = ('E' << 24) | ('a' << 16) | ('s' << 8) | 'y'; +extern const uint32_t EASY_CURRENT_VERSION = EASY_VERSION_INT(EASY_PROFILER_VERSION_MAJOR, EASY_PROFILER_VERSION_MINOR, EASY_PROFILER_VERSION_PATCH); +# undef EASY_VERSION_INT + +////////////////////////////////////////////////////////////////////////// + +# define EASY_PROF_DISABLED 0 +# define EASY_PROF_ENABLED 1 +# define EASY_PROF_DUMP 2 + +////////////////////////////////////////////////////////////////////////// + +//auto& MANAGER = ProfileManager::instance(); +# define MANAGER ProfileManager::instance() +EASY_CONSTEXPR uint8_t FORCE_ON_FLAG = profiler::FORCE_ON & ~profiler::ON; + +#if defined(EASY_CHRONO_CLOCK) +#include +const int64_t CPU_FREQUENCY = EASY_CHRONO_CLOCK::period::den / EASY_CHRONO_CLOCK::period::num; +# define TICKS_TO_US(ticks) ticks * 1000000LL / CPU_FREQUENCY +#elif defined(_WIN32) +const decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; })(); +# define TICKS_TO_US(ticks) ticks * 1000000LL / CPU_FREQUENCY +#else +# ifndef __APPLE__ +# include +# endif +int64_t calculate_cpu_frequency() +{ + double g_TicksPerNanoSec; + uint64_t begin = 0, end = 0; +#ifdef __APPLE__ + clock_serv_t cclock; + mach_timespec_t begints, endts; + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); + clock_get_time(cclock, &begints); +#else + struct timespec begints, endts; + clock_gettime(CLOCK_MONOTONIC, &begints); +#endif + begin = getCurrentTime(); + volatile uint64_t i; + for (i = 0; i < 100000000; i++); /* must be CPU intensive */ + end = getCurrentTime(); +#ifdef __APPLE__ + clock_get_time(cclock, &endts); + mach_port_deallocate(mach_task_self(), cclock); +#else + clock_gettime(CLOCK_MONOTONIC, &endts); +#endif + struct timespec tmpts; + const int NANO_SECONDS_IN_SEC = 1000000000; + tmpts.tv_sec = endts.tv_sec - begints.tv_sec; + tmpts.tv_nsec = endts.tv_nsec - begints.tv_nsec; + if (tmpts.tv_nsec < 0) + { + tmpts.tv_sec--; + tmpts.tv_nsec += NANO_SECONDS_IN_SEC; + } + + uint64_t nsecElapsed = tmpts.tv_sec * 1000000000LL + tmpts.tv_nsec; + g_TicksPerNanoSec = (double)(end - begin) / (double)nsecElapsed; + + int64_t cpu_frequency = int(g_TicksPerNanoSec * 1000000); + + return cpu_frequency; +} + +static std::atomic CPU_FREQUENCY = ATOMIC_VAR_INIT(1); +# define TICKS_TO_US(ticks) ticks * 1000 / CPU_FREQUENCY.load(std::memory_order_acquire) +#endif + +extern const profiler::color_t EASY_COLOR_INTERNAL_EVENT = 0xffffffff; // profiler::colors::White +EASY_CONSTEXPR profiler::color_t EASY_COLOR_THREAD_END = 0xff212121; // profiler::colors::Dark +EASY_CONSTEXPR profiler::color_t EASY_COLOR_START = 0xff4caf50; // profiler::colors::Green +EASY_CONSTEXPR profiler::color_t EASY_COLOR_END = 0xfff44336; // profiler::colors::Red + +////////////////////////////////////////////////////////////////////////// + +EASY_THREAD_LOCAL static ::ThreadStorage* THIS_THREAD = nullptr; +EASY_THREAD_LOCAL static bool THIS_THREAD_IS_MAIN = false; + +EASY_THREAD_LOCAL static profiler::timestamp_t THIS_THREAD_FRAME_T_MAX = 0ULL; +EASY_THREAD_LOCAL static profiler::timestamp_t THIS_THREAD_FRAME_T_CUR = 0ULL; +EASY_THREAD_LOCAL static profiler::timestamp_t THIS_THREAD_FRAME_T_ACC = 0ULL; +EASY_THREAD_LOCAL static uint32_t THIS_THREAD_N_FRAMES = 0; +EASY_THREAD_LOCAL static bool THIS_THREAD_FRAME_T_RESET_MAX = false; +EASY_THREAD_LOCAL static bool THIS_THREAD_FRAME_T_RESET_AVG = false; + +#ifdef EASY_CXX11_TLS_AVAILABLE +thread_local static profiler::ThreadGuard THIS_THREAD_GUARD; // thread guard for monitoring thread life time +#endif + +////////////////////////////////////////////////////////////////////////// + +#ifdef BUILD_WITH_EASY_PROFILER +# define EASY_EVENT_RES(res, name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), MANAGER.addBlockDescriptor(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Event, ::profiler::extract_color(__VA_ARGS__)));\ + res = MANAGER.storeBlock(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name)) + +# define EASY_FORCE_EVENT(timestamp, name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), addBlockDescriptor(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Event, ::profiler::extract_color(__VA_ARGS__)));\ + storeBlockForce(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name), timestamp) + +# define EASY_FORCE_EVENT2(timestamp, name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), addBlockDescriptor(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Event, ::profiler::extract_color(__VA_ARGS__)));\ + storeBlockForce2(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name), timestamp) + +# define EASY_FORCE_EVENT3(ts, timestamp, name, ...)\ + EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), addBlockDescriptor(\ + ::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\ + __FILE__, __LINE__, ::profiler::BlockType::Event, ::profiler::extract_color(__VA_ARGS__)));\ + storeBlockForce2(ts, EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name), timestamp) +#else +# ifndef EASY_PROFILER_API_DISABLED +# define EASY_PROFILER_API_DISABLED +# endif +# define EASY_EVENT_RES(res, name, ...) +# define EASY_FORCE_EVENT(timestamp, name, ...) +# define EASY_FORCE_EVENT2(timestamp, name, ...) +# define EASY_FORCE_EVENT3(ts, timestamp, name, ...) +#endif + +////////////////////////////////////////////////////////////////////////// + +extern "C" { + +#if !defined(EASY_PROFILER_API_DISABLED) + PROFILER_API timestamp_t currentTime() + { + return getCurrentTime(); + } + + PROFILER_API timestamp_t toNanoseconds(timestamp_t _ticks) + { +#if defined(EASY_CHRONO_CLOCK) || defined(_WIN32) + return _ticks * 1000000000LL / CPU_FREQUENCY; +#else + return _ticks / CPU_FREQUENCY.load(std::memory_order_acquire); +#endif + } + + PROFILER_API timestamp_t toMicroseconds(timestamp_t _ticks) + { + return TICKS_TO_US(_ticks); + } + + PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color, bool _copyName) + { + return MANAGER.addBlockDescriptor(_status, _autogenUniqueId, _name, _filename, _line, _block_type, _color, _copyName); + } + + PROFILER_API void endBlock() + { + MANAGER.endBlock(); + } + + PROFILER_API void setEnabled(bool isEnable) + { + MANAGER.setEnabled(isEnable); + } + + PROFILER_API bool isEnabled() + { + return MANAGER.isEnabled(); + } + + PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin) + { + MANAGER.storeValue(_desc, _type, _data, _size, _isArray, _vin); + } + + PROFILER_API void storeEvent(const BaseBlockDescriptor* _desc, const char* _runtimeName) + { + MANAGER.storeBlock(_desc, _runtimeName); + } + + PROFILER_API void storeBlock(const BaseBlockDescriptor* _desc, const char* _runtimeName, timestamp_t _beginTime, timestamp_t _endTime) + { + MANAGER.storeBlock(_desc, _runtimeName, _beginTime, _endTime); + } + + PROFILER_API void beginBlock(Block& _block) + { + MANAGER.beginBlock(_block); + } + + PROFILER_API void beginNonScopedBlock(const BaseBlockDescriptor* _desc, const char* _runtimeName) + { + MANAGER.beginNonScopedBlock(_desc, _runtimeName); + } + + PROFILER_API uint32_t dumpBlocksToFile(const char* filename) + { + return MANAGER.dumpBlocksToFile(filename); + } + + PROFILER_API const char* registerThreadScoped(const char* name, ThreadGuard& threadGuard) + { + return MANAGER.registerThread(name, threadGuard); + } + + PROFILER_API const char* registerThread(const char* name) + { + return MANAGER.registerThread(name); + } + + PROFILER_API void setEventTracingEnabled(bool _isEnable) + { + MANAGER.setEventTracingEnabled(_isEnable); + } + + PROFILER_API bool isEventTracingEnabled() + { + return MANAGER.isEventTracingEnabled(); + } + +# ifdef _WIN32 + PROFILER_API void setLowPriorityEventTracing(bool _isLowPriority) + { + EasyEventTracer::instance().setLowPriority(_isLowPriority); + } + + PROFILER_API bool isLowPriorityEventTracing() + { + return EasyEventTracer::instance().isLowPriority(); + } +# else + PROFILER_API void setLowPriorityEventTracing(bool) { } + PROFILER_API bool isLowPriorityEventTracing() { return false; } +# endif + + PROFILER_API void setContextSwitchLogFilename(const char* name) + { + return MANAGER.setContextSwitchLogFilename(name); + } + + PROFILER_API const char* getContextSwitchLogFilename() + { + return MANAGER.getContextSwitchLogFilename(); + } + + PROFILER_API void startListen(uint16_t _port) + { + return MANAGER.startListen(_port); + } + + PROFILER_API void stopListen() + { + return MANAGER.stopListen(); + } + + PROFILER_API bool isListening() + { + return MANAGER.isListening(); + } + + PROFILER_API bool isMainThread() + { + return THIS_THREAD_IS_MAIN; + } + + PROFILER_API timestamp_t this_thread_frameTime(Duration _durationCast) + { + if (_durationCast == profiler::TICKS) + return THIS_THREAD_FRAME_T_CUR; + return TICKS_TO_US(THIS_THREAD_FRAME_T_CUR); + } + + PROFILER_API timestamp_t this_thread_frameTimeLocalMax(Duration _durationCast) + { + THIS_THREAD_FRAME_T_RESET_MAX = true; + if (_durationCast == profiler::TICKS) + return THIS_THREAD_FRAME_T_MAX; + return TICKS_TO_US(THIS_THREAD_FRAME_T_MAX); + } + + PROFILER_API timestamp_t this_thread_frameTimeLocalAvg(Duration _durationCast) + { + THIS_THREAD_FRAME_T_RESET_AVG = true; + auto avgDuration = THIS_THREAD_N_FRAMES > 0 ? THIS_THREAD_FRAME_T_ACC / THIS_THREAD_N_FRAMES : 0; + if (_durationCast == profiler::TICKS) + return avgDuration; + return TICKS_TO_US(avgDuration); + } + + PROFILER_API timestamp_t main_thread_frameTime(Duration _durationCast) + { + const auto ticks = THIS_THREAD_IS_MAIN ? THIS_THREAD_FRAME_T_CUR : MANAGER.curFrameDuration(); + if (_durationCast == profiler::TICKS) + return ticks; + return TICKS_TO_US(ticks); + } + + PROFILER_API timestamp_t main_thread_frameTimeLocalMax(Duration _durationCast) + { + if (THIS_THREAD_IS_MAIN) + { + THIS_THREAD_FRAME_T_RESET_MAX = true; + if (_durationCast == profiler::TICKS) + return THIS_THREAD_FRAME_T_MAX; + return TICKS_TO_US(THIS_THREAD_FRAME_T_MAX); + } + + if (_durationCast == profiler::TICKS) + return MANAGER.maxFrameDuration(); + return TICKS_TO_US(MANAGER.maxFrameDuration()); + } + + PROFILER_API timestamp_t main_thread_frameTimeLocalAvg(Duration _durationCast) + { + if (THIS_THREAD_IS_MAIN) + { + THIS_THREAD_FRAME_T_RESET_AVG = true; + auto avgDuration = THIS_THREAD_N_FRAMES > 0 ? THIS_THREAD_FRAME_T_ACC / THIS_THREAD_N_FRAMES : 0; + if (_durationCast == profiler::TICKS) + return avgDuration; + return TICKS_TO_US(avgDuration); + } + + if (_durationCast == profiler::TICKS) + return MANAGER.avgFrameDuration(); + return TICKS_TO_US(MANAGER.avgFrameDuration()); + } + +#else + PROFILER_API timestamp_t currentTime() { return 0; } + PROFILER_API timestamp_t toNanoseconds(timestamp_t) { return 0; } + PROFILER_API timestamp_t toMicroseconds(timestamp_t) { return 0; } + PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus, const char*, const char*, const char*, int, block_type_t, color_t, bool) { return reinterpret_cast(0xbad); } + PROFILER_API void endBlock() { } + PROFILER_API void setEnabled(bool) { } + PROFILER_API bool isEnabled() { return false; } + PROFILER_API void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool, ValueId) {} + PROFILER_API void storeEvent(const BaseBlockDescriptor*, const char*) { } + PROFILER_API void storeBlock(const BaseBlockDescriptor*, const char*, timestamp_t, timestamp_t) { } + PROFILER_API void beginBlock(Block&) { } + PROFILER_API void beginNonScopedBlock(const BaseBlockDescriptor*, const char*) { } + PROFILER_API uint32_t dumpBlocksToFile(const char*) { return 0; } + PROFILER_API const char* registerThreadScoped(const char*, ThreadGuard&) { return ""; } + PROFILER_API const char* registerThread(const char*) { return ""; } + PROFILER_API void setEventTracingEnabled(bool) { } + PROFILER_API bool isEventTracingEnabled() { return false; } + PROFILER_API void setLowPriorityEventTracing(bool) { } + PROFILER_API bool isLowPriorityEventTracing(bool) { return false; } + PROFILER_API void setContextSwitchLogFilename(const char*) { } + PROFILER_API const char* getContextSwitchLogFilename() { return ""; } + PROFILER_API void startListen(uint16_t) { } + PROFILER_API void stopListen() { } + PROFILER_API bool isListening() { return false; } + + PROFILER_API bool isMainThread() { return false; } + PROFILER_API timestamp_t this_thread_frameTime(Duration) { return 0; } + PROFILER_API timestamp_t this_thread_frameTimeLocalMax(Duration) { return 0; } + PROFILER_API timestamp_t this_thread_frameTimeLocalAvg(Duration) { return 0; } + PROFILER_API timestamp_t main_thread_frameTime(Duration) { return 0; } + PROFILER_API timestamp_t main_thread_frameTimeLocalMax(Duration) { return 0; } + PROFILER_API timestamp_t main_thread_frameTimeLocalAvg(Duration) { return 0; } +#endif + + PROFILER_API uint8_t versionMajor() + { + static_assert(0 <= EASY_PROFILER_VERSION_MAJOR && EASY_PROFILER_VERSION_MAJOR <= 255, "EASY_PROFILER_VERSION_MAJOR must be defined in range [0, 255]"); + return EASY_PROFILER_VERSION_MAJOR; + } + + PROFILER_API uint8_t versionMinor() + { + static_assert(0 <= EASY_PROFILER_VERSION_MINOR && EASY_PROFILER_VERSION_MINOR <= 255, "EASY_PROFILER_VERSION_MINOR must be defined in range [0, 255]"); + return EASY_PROFILER_VERSION_MINOR; + } + + PROFILER_API uint16_t versionPatch() + { + static_assert(0 <= EASY_PROFILER_VERSION_PATCH && EASY_PROFILER_VERSION_PATCH <= 65535, "EASY_PROFILER_VERSION_PATCH must be defined in range [0, 65535]"); + return EASY_PROFILER_VERSION_PATCH; + } + + PROFILER_API uint32_t version() + { + return EASY_CURRENT_VERSION; + } + + PROFILER_API const char* versionName() + { + return EASY_PROFILER_PRODUCT_VERSION +#ifdef EASY_PROFILER_API_DISABLED + "_disabled" +#endif + ; + } + +} + +////////////////////////////////////////////////////////////////////////// + +SerializedBlock::SerializedBlock(const Block& block, uint16_t name_length) + : BaseBlockData(block) +{ + char* pName = const_cast(name()); + if (name_length) strncpy(pName, block.name(), name_length); + pName[name_length] = 0; +} + +SerializedCSwitch::SerializedCSwitch(const CSwitchBlock& block, uint16_t name_length) + : CSwitchEvent(block) +{ + char* pName = const_cast(name()); + if (name_length) strncpy(pName, block.name(), name_length); + pName[name_length] = 0; +} + +////////////////////////////////////////////////////////////////////////// + +BaseBlockDescriptor::BaseBlockDescriptor(block_id_t _id, EasyBlockStatus _status, int _line, + block_type_t _block_type, color_t _color) EASY_NOEXCEPT + : m_id(_id) + , m_line(_line) + , m_type(_block_type) + , m_color(_color) + , m_status(_status) +{ + +} + +////////////////////////////////////////////////////////////////////////// + +#ifndef EASY_BLOCK_DESC_FULL_COPY +# define EASY_BLOCK_DESC_FULL_COPY 1 +#endif + +#if EASY_BLOCK_DESC_FULL_COPY == 0 +# define EASY_BLOCK_DESC_STRING const char* +# define EASY_BLOCK_DESC_STRING_LEN(s) static_cast(strlen(s) + 1) +# define EASY_BLOCK_DESC_STRING_VAL(s) s +#else +# define EASY_BLOCK_DESC_STRING std::string +# define EASY_BLOCK_DESC_STRING_LEN(s) static_cast(s.size() + 1) +# define EASY_BLOCK_DESC_STRING_VAL(s) s.c_str() +#endif + +class BlockDescriptor : public BaseBlockDescriptor +{ + friend ProfileManager; + + EASY_BLOCK_DESC_STRING m_filename; ///< Source file name where this block is declared + EASY_BLOCK_DESC_STRING m_name; ///< Static name of all blocks of the same type (blocks can have dynamic name) which is, in pair with descriptor id, a unique block identifier + +public: + + BlockDescriptor(block_id_t _id, EasyBlockStatus _status, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color) + : BaseBlockDescriptor(_id, _status, _line, _block_type, _color) + , m_filename(_filename) + , m_name(_name) + { + } + + const char* name() const { + return EASY_BLOCK_DESC_STRING_VAL(m_name); + } + + const char* filename() const { + return EASY_BLOCK_DESC_STRING_VAL(m_filename); + } + + uint16_t nameSize() const { + return EASY_BLOCK_DESC_STRING_LEN(m_name); + } + + uint16_t filenameSize() const { + return EASY_BLOCK_DESC_STRING_LEN(m_filename); + } + +}; // END of class BlockDescriptor. + +////////////////////////////////////////////////////////////////////////// + +ThreadGuard::~ThreadGuard() +{ +#ifndef EASY_PROFILER_API_DISABLED + if (m_id != 0 && THIS_THREAD != nullptr && THIS_THREAD->id == m_id) + { + bool isMarked = false; + EASY_EVENT_RES(isMarked, "ThreadFinished", EASY_COLOR_THREAD_END, ::profiler::FORCE_ON); + THIS_THREAD->profiledFrameOpened.store(false, std::memory_order_release); + THIS_THREAD->expired.store(isMarked ? 2 : 1, std::memory_order_release); + THIS_THREAD = nullptr; + } +#endif +} + +////////////////////////////////////////////////////////////////////////// + +ProfileManager::ProfileManager() : +#ifdef _WIN32 + m_processId(GetProcessId(GetCurrentProcess())) +#else + m_processId((processid_t)getpid()) +#endif + , m_usedMemorySize(0) + , m_beginTime(0) + , m_endTime(0) +{ + m_profilerStatus = ATOMIC_VAR_INIT(EASY_PROF_DISABLED); + m_isEventTracingEnabled = ATOMIC_VAR_INIT(EASY_OPTION_EVENT_TRACING_ENABLED); + m_isAlreadyListening = ATOMIC_VAR_INIT(false); + m_stopDumping = ATOMIC_VAR_INIT(false); + m_stopListen = ATOMIC_VAR_INIT(false); + + m_mainThreadId = ATOMIC_VAR_INIT(0); + m_frameMax = ATOMIC_VAR_INIT(0); + m_frameAvg = ATOMIC_VAR_INIT(0); + m_frameCur = ATOMIC_VAR_INIT(0); + m_frameMaxReset = ATOMIC_VAR_INIT(false); + m_frameAvgReset = ATOMIC_VAR_INIT(false); + +#if !defined(EASY_PROFILER_API_DISABLED) && EASY_OPTION_START_LISTEN_ON_STARTUP != 0 + startListen(profiler::DEFAULT_PORT); +#endif + +#if !defined(EASY_PROFILER_API_DISABLED) && !defined(EASY_CHRONO_CLOCK) && !defined(_WIN32) + const int64_t cpu_frequency = calculate_cpu_frequency(); + CPU_FREQUENCY.store(cpu_frequency, std::memory_order_release); +#endif +} + +ProfileManager::~ProfileManager() +{ +#ifndef EASY_PROFILER_API_DISABLED + stopListen(); +#endif + + for (auto desc : m_descriptors) { +#if EASY_BLOCK_DESC_FULL_COPY == 0 + if (desc) + desc->~BlockDescriptor(); + free(desc); +#else + delete desc; +#endif + } +} + +#ifndef EASY_MAGIC_STATIC_AVAILABLE +class ProfileManagerInstance { + friend ProfileManager; + ProfileManager instance; +} PROFILE_MANAGER; +#endif + +////////////////////////////////////////////////////////////////////////// + +ProfileManager& ProfileManager::instance() +{ +#ifndef EASY_MAGIC_STATIC_AVAILABLE + return PROFILE_MANAGER.instance; +#else + ///C++11 makes possible to create Singleton without any warry about thread-safeness + ///http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/ + static ProfileManager profileManager; + return profileManager; +#endif +} + +////////////////////////////////////////////////////////////////////////// + +ThreadStorage& ProfileManager::_threadStorage(profiler::thread_id_t _thread_id) +{ + return m_threads[_thread_id]; +} + +ThreadStorage* ProfileManager::_findThreadStorage(profiler::thread_id_t _thread_id) +{ + auto it = m_threads.find(_thread_id); + return it != m_threads.end() ? &it->second : nullptr; +} + +////////////////////////////////////////////////////////////////////////// + +const BaseBlockDescriptor* ProfileManager::addBlockDescriptor(EasyBlockStatus _defaultStatus, + const char* _autogenUniqueId, + const char* _name, + const char* _filename, + int _line, + block_type_t _block_type, + color_t _color, + bool _copyName) +{ + guard_lock_t lock(m_storedSpin); + + descriptors_map_t::key_type key(_autogenUniqueId); + auto it = m_descriptorsMap.find(key); + if (it != m_descriptorsMap.end()) + return m_descriptors[it->second]; + + const auto nameLen = strlen(_name); + m_usedMemorySize += sizeof(profiler::SerializedBlockDescriptor) + nameLen + strlen(_filename) + 2; + +#if EASY_BLOCK_DESC_FULL_COPY == 0 + BlockDescriptor* desc = nullptr; + + if (_copyName) + { + void* data = malloc(sizeof(BlockDescriptor) + nameLen + 1); + char* name = reinterpret_cast(data) + sizeof(BlockDescriptor); + strncpy(name, _name, nameLen); + desc = ::new (data)BlockDescriptor(static_cast(m_descriptors.size()), _defaultStatus, name, _filename, _line, _block_type, _color); + } + else + { + void* data = malloc(sizeof(BlockDescriptor)); + desc = ::new (data)BlockDescriptor(static_cast(m_descriptors.size()), _defaultStatus, _name, _filename, _line, _block_type, _color); + } +#else + auto desc = new BlockDescriptor(static_cast(m_descriptors.size()), _defaultStatus, _name, _filename, _line, _block_type, _color); +#endif + + m_descriptors.emplace_back(desc); + m_descriptorsMap.emplace(key, desc->id()); + + return desc; +} + +////////////////////////////////////////////////////////////////////////// + +void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin) +{ + const auto state = m_profilerStatus.load(std::memory_order_acquire); + if (state != EASY_PROF_ENABLED || (_desc->m_status & profiler::ON) == 0) + return; + + if (THIS_THREAD == nullptr) + registerThread(); + +#if EASY_ENABLE_BLOCK_STATUS != 0 + if (!THIS_THREAD->allowChildren && (_desc->m_status & FORCE_ON_FLAG) == 0) + return; +#endif + + THIS_THREAD->storeValue(getCurrentTime(), _desc->id(), _type, _data, _size, _isArray, _vin); +} + +////////////////////////////////////////////////////////////////////////// + +bool ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName) +{ + const auto state = m_profilerStatus.load(std::memory_order_acquire); + if (state == EASY_PROF_DISABLED || (_desc->m_status & profiler::ON) == 0) + return false; + + if (state == EASY_PROF_DUMP) + { + if (THIS_THREAD == nullptr || THIS_THREAD->halt) + return false; + } + else if (THIS_THREAD == nullptr) + { + registerThread(); + } + +#if EASY_ENABLE_BLOCK_STATUS != 0 + if (!THIS_THREAD->allowChildren && (_desc->m_status & FORCE_ON_FLAG) == 0) + return false; +#endif + + const auto time = getCurrentTime(); + THIS_THREAD->storeBlock(profiler::Block(time, time, _desc->id(), _runtimeName)); + + return true; +} + +bool ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime) +{ + const auto state = m_profilerStatus.load(std::memory_order_acquire); + if (state == EASY_PROF_DISABLED || (_desc->m_status & profiler::ON) == 0) + return false; + + if (state == EASY_PROF_DUMP) + { + if (THIS_THREAD == nullptr || THIS_THREAD->halt) + return false; + } + else if (THIS_THREAD == nullptr) + { + registerThread(); + } + +#if EASY_ENABLE_BLOCK_STATUS != 0 + if (!THIS_THREAD->allowChildren && (_desc->m_status & FORCE_ON_FLAG) == 0) + return false; +#endif + + profiler::Block b(_beginTime, _endTime, _desc->id(), _runtimeName); + THIS_THREAD->storeBlock(b); + b.m_end = b.m_begin; + + return true; +} + +////////////////////////////////////////////////////////////////////////// + +void ProfileManager::storeBlockForce(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t& _timestamp) +{ + if ((_desc->m_status & profiler::ON) == 0) + return; + + if (THIS_THREAD == nullptr) + registerThread(); + +#if EASY_ENABLE_BLOCK_STATUS != 0 + if (!THIS_THREAD->allowChildren && (_desc->m_status & FORCE_ON_FLAG) == 0) + return; +#endif + + _timestamp = getCurrentTime(); + THIS_THREAD->storeBlock(profiler::Block(_timestamp, _timestamp, _desc->id(), _runtimeName)); +} + +void ProfileManager::storeBlockForce2(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t _timestamp) +{ + if ((_desc->m_status & profiler::ON) == 0) + return; + + if (THIS_THREAD == nullptr) + registerThread(); + +#if EASY_ENABLE_BLOCK_STATUS != 0 + if (!THIS_THREAD->allowChildren && (_desc->m_status & FORCE_ON_FLAG) == 0) + return; +#endif + + THIS_THREAD->storeBlock(profiler::Block(_timestamp, _timestamp, _desc->id(), _runtimeName)); +} + +void ProfileManager::storeBlockForce2(ThreadStorage& _registeredThread, const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t _timestamp) +{ + _registeredThread.storeBlock(profiler::Block(_timestamp, _timestamp, _desc->id(), _runtimeName)); +} + +////////////////////////////////////////////////////////////////////////// + +void ProfileManager::beginBlock(Block& _block) +{ + if (THIS_THREAD == nullptr) + registerThread(); + + if (++THIS_THREAD->stackSize > 1) + { + _block.m_status = profiler::OFF; + THIS_THREAD->blocks.openedList.emplace_back(_block); + return; + } + + bool empty = true; + const auto state = m_profilerStatus.load(std::memory_order_acquire); + switch (state) + { + case EASY_PROF_DISABLED: + { + _block.m_status = profiler::OFF; + THIS_THREAD->halt = false; + THIS_THREAD->blocks.openedList.emplace_back(_block); + beginFrame(); + return; + } + + case EASY_PROF_DUMP: + { + const bool halt = THIS_THREAD->halt; + if (halt || THIS_THREAD->blocks.openedList.empty()) + { + _block.m_status = profiler::OFF; + THIS_THREAD->blocks.openedList.emplace_back(_block); + + if (!halt) + { + THIS_THREAD->halt = true; + beginFrame(); + } + + return; + } + + empty = false; + break; + } + + default: + { + empty = THIS_THREAD->blocks.openedList.empty(); + break; + } + } + + THIS_THREAD->stackSize = 0; + THIS_THREAD->halt = false; + + auto blockStatus = _block.m_status; +#if EASY_ENABLE_BLOCK_STATUS != 0 + if (THIS_THREAD->allowChildren) + { +#endif + if (blockStatus & profiler::ON) + _block.start(); +#if EASY_ENABLE_BLOCK_STATUS != 0 + THIS_THREAD->allowChildren = ((blockStatus & profiler::OFF_RECURSIVE) == 0); + } + else if (blockStatus & FORCE_ON_FLAG) + { + _block.start(); + _block.m_status = profiler::FORCE_ON_WITHOUT_CHILDREN; + } + else + { + _block.m_status = profiler::OFF_RECURSIVE; + } +#endif + + if (empty) + { + beginFrame(); + THIS_THREAD->profiledFrameOpened.store(true, std::memory_order_release); + } + + THIS_THREAD->blocks.openedList.emplace_back(_block); +} + +void ProfileManager::beginNonScopedBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName) +{ + if (THIS_THREAD == nullptr) + registerThread(); + + NonscopedBlock& b = THIS_THREAD->nonscopedBlocks.push(_desc, _runtimeName, false); + beginBlock(b); + b.copyname(); +} + +void ProfileManager::beginContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _time, profiler::thread_id_t _target_thread_id, const char* _target_process, bool _lockSpin) +{ + auto ts = _lockSpin ? findThreadStorage(_thread_id) : _findThreadStorage(_thread_id); + if (ts != nullptr) + // Dirty hack: _target_thread_id will be written to the field "block_id_t m_id" + // and will be available calling method id(). + ts->sync.openedList.emplace_back(_time, _target_thread_id, _target_process); +} + +////////////////////////////////////////////////////////////////////////// + +void ProfileManager::endBlock() +{ + if (--THIS_THREAD->stackSize > 0) + { + THIS_THREAD->popSilent(); + return; + } + + THIS_THREAD->stackSize = 0; + if (THIS_THREAD->halt || m_profilerStatus.load(std::memory_order_acquire) == EASY_PROF_DISABLED) + { + THIS_THREAD->popSilent(); + endFrame(); + return; + } + + if (THIS_THREAD->blocks.openedList.empty()) + return; + + Block& top = THIS_THREAD->blocks.openedList.back(); + if (top.m_status & profiler::ON) + { + if (!top.finished()) + top.finish(); + THIS_THREAD->storeBlock(top); + } + else + { + top.m_end = top.m_begin; // this is to restrict endBlock() call inside ~Block() + } + + if (!top.m_isScoped) + THIS_THREAD->nonscopedBlocks.pop(); + + THIS_THREAD->blocks.openedList.pop_back(); + const bool empty = THIS_THREAD->blocks.openedList.empty(); + if (empty) + { + THIS_THREAD->profiledFrameOpened.store(false, std::memory_order_release); + endFrame(); +#if EASY_ENABLE_BLOCK_STATUS != 0 + THIS_THREAD->allowChildren = true; + } + else + { + THIS_THREAD->allowChildren = + ((THIS_THREAD->blocks.openedList.back().get().m_status & profiler::OFF_RECURSIVE) == 0); + } +#else + } +#endif +} + +void ProfileManager::endContextSwitch(profiler::thread_id_t _thread_id, processid_t _process_id, profiler::timestamp_t _endtime, bool _lockSpin) +{ + ThreadStorage* ts = nullptr; + if (_process_id == m_processId) + { + // Implicit thread registration. + // If thread owned by current process then create new ThreadStorage if there is no one +#if EASY_OPTION_IMPLICIT_THREAD_REGISTRATION != 0 + ts = _lockSpin ? &threadStorage(_thread_id) : &_threadStorage(_thread_id); +# if !defined(_WIN32) && !defined(EASY_CXX11_TLS_AVAILABLE) +# if EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS != 0 +# pragma message "Warning: Implicit thread registration together with removing empty unguarded threads may cause application crash because there is no possibility to check thread state (dead or alive) for pthreads and removed ThreadStorage may be reused if thread is still alive." +# else +# pragma message "Warning: Implicit thread registration without removing empty unguarded threads may lead to memory leak because there is no possibility to check thread state (dead or alive) for pthreads." +# endif +# endif +#endif + } + else + { + // If thread owned by another process OR _process_id IS UNKNOWN then do not create ThreadStorage for this + ts = _lockSpin ? findThreadStorage(_thread_id) : _findThreadStorage(_thread_id); + } + + if (ts == nullptr || ts->sync.openedList.empty()) + return; + + CSwitchBlock& lastBlock = ts->sync.openedList.back(); + lastBlock.m_end = _endtime; + + ts->storeCSwitch(lastBlock); + ts->sync.openedList.pop_back(); +} + +////////////////////////////////////////////////////////////////////////// + +void ProfileManager::beginFrame() +{ + THIS_THREAD->beginFrame(); +} + +void ProfileManager::endFrame() +{ + if (!THIS_THREAD->frameOpened) + return; + + const profiler::timestamp_t duration = THIS_THREAD->endFrame(); + + if (THIS_THREAD_FRAME_T_RESET_MAX) THIS_THREAD_FRAME_T_MAX = 0; + THIS_THREAD_FRAME_T_RESET_MAX = false; + + THIS_THREAD_FRAME_T_CUR = duration; + if (duration > THIS_THREAD_FRAME_T_MAX) + THIS_THREAD_FRAME_T_MAX = duration; + + THIS_THREAD_FRAME_T_RESET_AVG = THIS_THREAD_FRAME_T_RESET_AVG || THIS_THREAD_N_FRAMES > 10000; + + if (THIS_THREAD_IS_MAIN) + { + if (m_frameAvgReset.exchange(false, std::memory_order_release) || THIS_THREAD_FRAME_T_RESET_AVG) + { + if (THIS_THREAD_N_FRAMES > 0) + m_frameAvg.store(THIS_THREAD_FRAME_T_ACC / THIS_THREAD_N_FRAMES, std::memory_order_release); + THIS_THREAD_FRAME_T_RESET_AVG = false; + THIS_THREAD_FRAME_T_ACC = duration; + THIS_THREAD_N_FRAMES = 1; + } + else + { + THIS_THREAD_FRAME_T_ACC += duration; + ++THIS_THREAD_N_FRAMES; + m_frameAvg.store(THIS_THREAD_FRAME_T_ACC / THIS_THREAD_N_FRAMES, std::memory_order_release); + } + + const auto maxDuration = m_frameMax.load(std::memory_order_acquire); + if (m_frameMaxReset.exchange(false, std::memory_order_release) || duration > maxDuration) + m_frameMax.store(duration, std::memory_order_release); + + m_frameCur.store(duration, std::memory_order_release); + + return; + } + + const auto reset = (uint32_t)!THIS_THREAD_FRAME_T_RESET_AVG; + THIS_THREAD_FRAME_T_RESET_AVG = false; + THIS_THREAD_N_FRAMES = 1 + reset * THIS_THREAD_N_FRAMES; + THIS_THREAD_FRAME_T_ACC = duration + reset * THIS_THREAD_FRAME_T_ACC; +} + +profiler::timestamp_t ProfileManager::maxFrameDuration() +{ + auto duration = m_frameMax.load(std::memory_order_acquire); + m_frameMaxReset.store(true, std::memory_order_release); + return duration; +} + +profiler::timestamp_t ProfileManager::avgFrameDuration() +{ + auto duration = m_frameAvg.load(std::memory_order_acquire); + m_frameAvgReset.store(true, std::memory_order_release); + return duration; +} + +profiler::timestamp_t ProfileManager::curFrameDuration() const +{ + return m_frameCur.load(std::memory_order_acquire); +} + +////////////////////////////////////////////////////////////////////////// + +void ProfileManager::enableEventTracer() +{ +#ifdef _WIN32 + if (m_isEventTracingEnabled.load(std::memory_order_acquire)) + EasyEventTracer::instance().enable(true); +#endif +} + +void ProfileManager::disableEventTracer() +{ +#ifdef _WIN32 + EasyEventTracer::instance().disable(); +#endif +} + +void ProfileManager::setEnabled(bool isEnable) +{ + guard_lock_t lock(m_dumpSpin); + + auto time = getCurrentTime(); + const auto status = isEnable ? EASY_PROF_ENABLED : EASY_PROF_DISABLED; + const auto prev = m_profilerStatus.exchange(status, std::memory_order_release); + if (prev == status) + return; + + if (isEnable) + { + EASY_LOGMSG("Enabled profiling\n"); + enableEventTracer(); + m_beginTime = time; + } + else + { + EASY_LOGMSG("Disabled profiling\n"); + disableEventTracer(); + m_endTime = time; + } +} + +bool ProfileManager::isEnabled() const +{ + return m_profilerStatus.load(std::memory_order_acquire) == EASY_PROF_ENABLED; +} + +void ProfileManager::setEventTracingEnabled(bool _isEnable) +{ + m_isEventTracingEnabled.store(_isEnable, std::memory_order_release); +} + +bool ProfileManager::isEventTracingEnabled() const +{ + return m_isEventTracingEnabled.load(std::memory_order_acquire); +} + +////////////////////////////////////////////////////////////////////////// + +char ProfileManager::checkThreadExpired(ThreadStorage& _registeredThread) +{ + const char val = _registeredThread.expired.load(std::memory_order_acquire); + if (val != 0) + return val; + + if (_registeredThread.guarded) + return 0; + +#ifdef _WIN32 + // Check thread state for Windows + + DWORD exitCode = 0; + auto hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)_registeredThread.id); + if (hThread == nullptr || GetExitCodeThread(hThread, &exitCode) == FALSE || exitCode != STILL_ACTIVE) + { + // Thread has been expired + _registeredThread.expired.store(1, std::memory_order_release); + if (hThread != nullptr) + CloseHandle(hThread); + return 1; + } + + if (hThread != nullptr) + CloseHandle(hThread); + + return 0; +#else + // Check thread state for Linux and MacOS/iOS + + // This would drop the application if pthread already died + //return pthread_kill(_registeredThread.pthread_id, 0) != 0 ? 1 : 0; + + // There is no function to check external pthread state in Linux! :(( + +#ifndef EASY_CXX11_TLS_AVAILABLE +#pragma message "Warning: Your compiler does not support thread_local C++11 feature. Please use EASY_THREAD_SCOPE as much as possible. Otherwise, there is a possibility of memory leak if there are a lot of rapidly created and destroyed threads." +#endif + + return 0; +#endif +} + +////////////////////////////////////////////////////////////////////////// + +uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream, bool _lockSpin, bool _async) +{ + EASY_LOGMSG("dumpBlocksToStream(_lockSpin = " << _lockSpin << ")...\n"); + + if (_lockSpin) + m_dumpSpin.lock(); + + const auto state = m_profilerStatus.load(std::memory_order_acquire); + +#ifndef _WIN32 + const bool eventTracingEnabled = m_isEventTracingEnabled.load(std::memory_order_acquire); +#endif + + if (state == EASY_PROF_ENABLED) { + m_profilerStatus.store(EASY_PROF_DUMP, std::memory_order_release); + disableEventTracer(); + m_endTime = getCurrentTime(); + } + + + // This is to make sure that no new descriptors or new threads will be + // added until we finish sending data. + //m_spin.lock(); + // This is the only place using both spins, so no dead-lock will occur + + if (_async && m_stopDumping.load(std::memory_order_acquire)) + { + if (_lockSpin) + m_dumpSpin.unlock(); + return 0; + } + + // Wait for some time to be sure that all operations which began before setEnabled(false) will be finished. + // This is much better than inserting spin-lock or atomic variable check into each store operation. + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + + // wait for all threads finish opened frames + EASY_LOG_ONLY(bool logged = false); + for (auto thread_it = m_threads.begin(), end = m_threads.end(); thread_it != end;) + { + if (_async && m_stopDumping.load(std::memory_order_acquire)) + { + if (_lockSpin) + m_dumpSpin.unlock(); + return 0; + } + + if (!thread_it->second.profiledFrameOpened.load(std::memory_order_acquire)) + { + ++thread_it; + EASY_LOG_ONLY(logged = false); + } + else + { + EASY_LOG_ONLY( + if (!logged) + { + logged = true; + if (thread_it->second.named) + EASY_WARNING("Waiting for thread \"" << thread_it->second.name << "\" finish opened frame (which is top EASY_BLOCK for this thread)...\n"); + else + EASY_WARNING("Waiting for thread " << thread_it->first << " finish opened frame (which is top EASY_BLOCK for this thread)...\n"); + } + ); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + + m_profilerStatus.store(EASY_PROF_DISABLED, std::memory_order_release); + + EASY_LOGMSG("All threads have closed frames\n"); + EASY_LOGMSG("Disabled profiling\n"); + + m_spin.lock(); + m_storedSpin.lock(); + // TODO: think about better solution because this one is not 100% safe... + + const profiler::timestamp_t now = getCurrentTime(); + const profiler::timestamp_t endtime = m_endTime == 0 ? now : std::min(now, m_endTime); + +#ifndef _WIN32 + if (eventTracingEnabled) + { + // Read thread context switch events from temporary file + + if (_async && m_stopDumping.load(std::memory_order_acquire)) + { + m_spin.unlock(); + m_storedSpin.unlock(); + if (_lockSpin) + m_dumpSpin.unlock(); + return 0; + } + + EASY_LOGMSG("Writing context switch events...\n"); + + uint64_t timestamp = 0; + profiler::thread_id_t thread_from = 0, thread_to = 0; + + std::ifstream infile(m_csInfoFilename.c_str()); + if(infile.is_open()) + { + EASY_LOG_ONLY(uint32_t num = 0); + std::string next_task_name; + pid_t process_to = 0; + while (infile >> timestamp >> thread_from >> thread_to >> next_task_name >> process_to) + { + if (_async && m_stopDumping.load(std::memory_order_acquire)) + { + m_spin.unlock(); + m_storedSpin.unlock(); + if (_lockSpin) + m_dumpSpin.unlock(); + return 0; + } + + beginContextSwitch(thread_from, timestamp, thread_to, next_task_name.c_str(), false); + endContextSwitch(thread_to, (processid_t)process_to, timestamp, false); + EASY_LOG_ONLY(++num); + } + + EASY_LOGMSG("Done, " << num << " context switch events wrote\n"); + } + EASY_LOG_ONLY( + else { + EASY_ERROR("Can not open context switch log-file \"" << m_csInfoFilename << "\"\n"); + } + ) + } +#endif + + bool mainThreadExpired = false; + + // Calculate used memory total size and total blocks number + uint64_t usedMemorySize = 0; + uint32_t blocks_number = 0; + for (auto thread_it = m_threads.begin(), end = m_threads.end(); thread_it != end;) + { + if (_async && m_stopDumping.load(std::memory_order_acquire)) + { + m_spin.unlock(); + m_storedSpin.unlock(); + if (_lockSpin) + m_dumpSpin.unlock(); + return 0; + } + + auto& thread = thread_it->second; + uint32_t num = static_cast(thread.blocks.closedList.size()) + static_cast(thread.sync.closedList.size()); + const char expired = ProfileManager::checkThreadExpired(thread); + +#ifdef _WIN32 + if (num == 0 && expired != 0) +#elif defined(EASY_CXX11_TLS_AVAILABLE) + // Removing !guarded thread when thread_local feature is supported is safe. + if (num == 0 && (expired != 0 || !thread.guarded)) +#elif EASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS != 0 +# pragma message "Warning: Removing !guarded thread without thread_local support may cause an application crash, but fixes potential memory leak when using pthreads." + // Removing !guarded thread may cause an application crash if a thread would start to write blocks after ThreadStorage remove. + // TODO: Find solution to check thread state for pthread or to nullify THIS_THREAD pointer for removed ThreadStorage + if (num == 0 && (expired != 0 || !t.guarded)) +#else +# pragma message "Warning: Can not check pthread state (dead or alive). This may cause memory leak because ThreadStorage-s would not be removed ever during an application launched." + if (num == 0 && expired != 0) +#endif + { + // Remove thread if it contains no profiled information and has been finished (or is not guarded --deprecated). + profiler::thread_id_t id = thread_it->first; + if (!mainThreadExpired && m_mainThreadId.compare_exchange_weak(id, 0, std::memory_order_release, std::memory_order_acquire)) + mainThreadExpired = true; + m_threads.erase(thread_it++); + continue; + } + + if (expired == 1) + { + EASY_FORCE_EVENT3(thread, endtime, "ThreadExpired", EASY_COLOR_THREAD_END); + ++num; + } + + usedMemorySize += thread.blocks.usedMemorySize + thread.sync.usedMemorySize; + blocks_number += num; + ++thread_it; + } + + // Write profiler signature and version + _outputStream.write(PROFILER_SIGNATURE); + _outputStream.write(EASY_CURRENT_VERSION); + _outputStream.write(m_processId); + + // Write CPU frequency to let GUI calculate real time value from CPU clocks +#if defined(EASY_CHRONO_CLOCK) || defined(_WIN32) + _outputStream.write(CPU_FREQUENCY); +#else + EASY_LOGMSG("Calculating CPU frequency\n"); + const int64_t cpu_frequency = calculate_cpu_frequency(); + _outputStream.write(cpu_frequency * 1000LL); + EASY_LOGMSG("Done calculating CPU frequency\n"); + + CPU_FREQUENCY.store(cpu_frequency, std::memory_order_release); +#endif + + // Write begin and end time + _outputStream.write(m_beginTime); + _outputStream.write(m_endTime); + + // Write blocks number and used memory size + _outputStream.write(blocks_number); + _outputStream.write(usedMemorySize); + _outputStream.write(static_cast(m_descriptors.size())); + _outputStream.write(m_usedMemorySize); + + // Write block descriptors + for (const auto descriptor : m_descriptors) + { + const auto name_size = descriptor->nameSize(); + const auto filename_size = descriptor->filenameSize(); + const auto size = static_cast(sizeof(profiler::SerializedBlockDescriptor) + name_size + filename_size); + + _outputStream.write(size); + _outputStream.write(*descriptor); + _outputStream.write(name_size); + _outputStream.write(descriptor->name(), name_size); + _outputStream.write(descriptor->filename(), filename_size); + } + + // Write blocks and context switch events for each thread + for (auto thread_it = m_threads.begin(), end = m_threads.end(); thread_it != end;) + { + if (_async && m_stopDumping.load(std::memory_order_acquire)) + { + m_spin.unlock(); + m_storedSpin.unlock(); + if (_lockSpin) + m_dumpSpin.unlock(); + return 0; + } + + auto& thread = thread_it->second; + + _outputStream.write(thread_it->first); + + const auto name_size = static_cast(thread.name.size() + 1); + _outputStream.write(name_size); + _outputStream.write(name_size > 1 ? thread.name.c_str() : "", name_size); + + _outputStream.write(thread.sync.closedList.size()); + if (!thread.sync.closedList.empty()) + thread.sync.closedList.serialize(_outputStream); + + _outputStream.write(thread.blocks.closedList.size()); + if (!thread.blocks.closedList.empty()) + thread.blocks.closedList.serialize(_outputStream); + + thread.clearClosed(); + //t.blocks.openedList.clear(); + thread.sync.openedList.clear(); + + if (thread.expired.load(std::memory_order_acquire) != 0) + { + // Remove expired thread after writing all profiled information + profiler::thread_id_t id = thread_it->first; + if (!mainThreadExpired && m_mainThreadId.compare_exchange_weak(id, 0, std::memory_order_release, std::memory_order_acquire)) + mainThreadExpired = true; + m_threads.erase(thread_it++); + } + else + { + ++thread_it; + } + } + + m_storedSpin.unlock(); + m_spin.unlock(); + + if (_lockSpin) + m_dumpSpin.unlock(); + + EASY_LOGMSG("Done dumpBlocksToStream(). Dumped " << blocks_number << " blocks\n"); + + return blocks_number; +} + +uint32_t ProfileManager::dumpBlocksToFile(const char* _filename) +{ + EASY_LOGMSG("dumpBlocksToFile(\"" << _filename << "\")...\n"); + + std::ofstream outputFile(_filename, std::fstream::binary); + if (!outputFile.is_open()) + { + EASY_ERROR("Can not open \"" << _filename << "\" for writing\n"); + return 0; + } + + profiler::OStream outputStream; + + // Replace outputStream buffer to outputFile buffer to avoid redundant copying + typedef ::std::basic_iostream stringstream_parent; + stringstream_parent& s = outputStream.stream(); + auto oldbuf = s.rdbuf(outputFile.rdbuf()); + + // Write data directly to file + const auto blocksNumber = dumpBlocksToStream(outputStream, true, false); + + // Restore old outputStream buffer to avoid possible second memory free on stringstream destructor + s.rdbuf(oldbuf); + + EASY_LOGMSG("Done dumpBlocksToFile()\n"); + + return blocksNumber; +} + +void ProfileManager::registerThread() +{ + THIS_THREAD = &threadStorage(getCurrentThreadId()); + +#ifdef EASY_CXX11_TLS_AVAILABLE + THIS_THREAD->guarded = true; + THIS_THREAD_GUARD.m_id = THIS_THREAD->id; +#endif +} + +const char* ProfileManager::registerThread(const char* name, ThreadGuard& threadGuard) +{ + if (THIS_THREAD == nullptr) + THIS_THREAD = &threadStorage(getCurrentThreadId()); + + THIS_THREAD->guarded = true; + if (!THIS_THREAD->named) + { + THIS_THREAD->named = true; + THIS_THREAD->name = name; + + if (THIS_THREAD->name == "Main") + { + profiler::thread_id_t id = 0; + THIS_THREAD_IS_MAIN = m_mainThreadId.compare_exchange_weak(id, THIS_THREAD->id, std::memory_order_release, std::memory_order_acquire); + } + +#ifdef EASY_CXX11_TLS_AVAILABLE + THIS_THREAD_GUARD.m_id = THIS_THREAD->id; + } + + (void)threadGuard; // this is just to prevent from warning about unused variable +#else + } + + threadGuard.m_id = THIS_THREAD->id; +#endif + + return THIS_THREAD->name.c_str(); +} + +const char* ProfileManager::registerThread(const char* name) +{ + if (THIS_THREAD == nullptr) + THIS_THREAD = &threadStorage(getCurrentThreadId()); + + if (!THIS_THREAD->named) + { + THIS_THREAD->named = true; + THIS_THREAD->name = name; + + if (THIS_THREAD->name == "Main") + { + profiler::thread_id_t id = 0; + THIS_THREAD_IS_MAIN = m_mainThreadId.compare_exchange_weak(id, THIS_THREAD->id, std::memory_order_release, std::memory_order_acquire); + } + +#ifdef EASY_CXX11_TLS_AVAILABLE + THIS_THREAD->guarded = true; + THIS_THREAD_GUARD.m_id = THIS_THREAD->id; +#endif + } + + return THIS_THREAD->name.c_str(); +} + +void ProfileManager::setBlockStatus(block_id_t _id, EasyBlockStatus _status) +{ + if (m_profilerStatus.load(std::memory_order_acquire) != EASY_PROF_DISABLED) + return; // Changing blocks statuses is restricted while profile session is active + + guard_lock_t lock(m_storedSpin); + if (_id < m_descriptors.size()) + { + auto desc = m_descriptors[_id]; + lock.unlock(); + desc->m_status = _status; + } +} + +void ProfileManager::startListen(uint16_t _port) +{ + if (!m_isAlreadyListening.exchange(true, std::memory_order_release)) + { + m_stopListen.store(false, std::memory_order_release); + m_listenThread = std::thread(&ProfileManager::listen, this, _port); + } +} + +void ProfileManager::stopListen() +{ + m_stopListen.store(true, std::memory_order_release); + if (m_listenThread.joinable()) + m_listenThread.join(); + m_isAlreadyListening.store(false, std::memory_order_release); + + EASY_LOGMSG("Listening stopped\n"); +} + +bool ProfileManager::isListening() const +{ + return m_isAlreadyListening.load(std::memory_order_acquire); +} + +////////////////////////////////////////////////////////////////////////// + +template +inline void join(std::future& futureResult) +{ + if (futureResult.valid()) + futureResult.get(); +} + +void ProfileManager::listen(uint16_t _port) +{ + EASY_THREAD_SCOPE("EasyProfiler.Listen"); + + EASY_LOGMSG("Listening started\n"); + + profiler::OStream os; + std::future dumpingResult; + bool dumping = false; + + const auto stopDumping = [this, &dumping, &dumpingResult, &os] + { + dumping = false; + m_stopDumping.store(true, std::memory_order_release); + join(dumpingResult); + os.clear(); + }; + + EasySocket socket; + profiler::net::Message replyMessage(profiler::net::MessageType::Reply_Capturing_Started); + + socket.bind(_port); + int bytes = 0; + while (!m_stopListen.load(std::memory_order_acquire)) + { + if (dumping) + stopDumping(); + + socket.listen(); + socket.accept(); + + bool hasConnect = true; + + // Send reply + { + const bool wasLowPriorityET = +#ifdef _WIN32 + EasyEventTracer::instance().isLowPriority(); +#else + false; +#endif + const profiler::net::EasyProfilerStatus connectionReply( + m_profilerStatus.load(std::memory_order_acquire) == EASY_PROF_ENABLED, + m_isEventTracingEnabled.load(std::memory_order_acquire), wasLowPriorityET); + + bytes = socket.send(&connectionReply, sizeof(profiler::net::EasyProfilerStatus)); + hasConnect = bytes > 0; + } + + while (hasConnect && !m_stopListen.load(std::memory_order_acquire)) + { + if (dumping) + { + if (!dumpingResult.valid()) + { + dumping = false; + socket.setReceiveTimeout(0); + os.clear(); + } + else if (dumpingResult.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) + { + dumping = false; + dumpingResult.get(); + + const auto size = os.stream().tellp(); + static const decltype(size) badSize = -1; + if (size != badSize) + { + const profiler::net::DataMessage dm(static_cast(size), + profiler::net::MessageType::Reply_Blocks); + + const size_t packet_size = sizeof(dm) + dm.size; + std::string sendbuf; + sendbuf.reserve(packet_size + 1); + + if (sendbuf.capacity() >= packet_size) // check if there is enough memory + { + sendbuf.append((const char*) &dm, sizeof(dm)); + sendbuf += os.stream().str(); // TODO: Avoid double-coping data from stringstream! + os.clear(); + + bytes = socket.send(sendbuf.c_str(), packet_size); + hasConnect = bytes > 0; + if (!hasConnect) + break; + } + else + { + EASY_ERROR("Can not send blocks. Not enough memory for allocating " << packet_size + << " bytes"); + os.clear(); + } + } + else + { + EASY_ERROR("Can not send blocks. Bad std::stringstream.tellp() == -1"); + os.clear(); + } + + replyMessage.type = profiler::net::MessageType::Reply_Blocks_End; + bytes = socket.send(&replyMessage, sizeof(replyMessage)); + hasConnect = bytes > 0; + if (!hasConnect) + break; + + socket.setReceiveTimeout(0); + } + } + + char buffer[256] = {}; + bytes = socket.receive(buffer, 255); + + hasConnect = socket.isConnected(); + if (!hasConnect || bytes < static_cast(sizeof(profiler::net::Message))) + continue; + + auto message = (const profiler::net::Message*)buffer; + if (!message->isEasyNetMessage()) + continue; + + switch (message->type) + { + case profiler::net::MessageType::Ping: + { + EASY_LOGMSG("receive MessageType::Ping\n"); + break; + } + + case profiler::net::MessageType::Request_MainThread_FPS: + { + profiler::timestamp_t maxDuration = maxFrameDuration(), avgDuration = avgFrameDuration(); + + maxDuration = TICKS_TO_US(maxDuration); + avgDuration = TICKS_TO_US(avgDuration); + + const profiler::net::TimestampMessage reply(profiler::net::MessageType::Reply_MainThread_FPS, + (uint32_t)maxDuration, (uint32_t)avgDuration); + + bytes = socket.send(&reply, sizeof(profiler::net::TimestampMessage)); + hasConnect = bytes > 0; + + break; + } + + case profiler::net::MessageType::Request_Start_Capture: + { + EASY_LOGMSG("receive MessageType::Request_Start_Capture\n"); + + ::profiler::timestamp_t t = 0; + EASY_FORCE_EVENT(t, "StartCapture", EASY_COLOR_START, profiler::OFF); + + m_dumpSpin.lock(); + const auto prev = m_profilerStatus.exchange(EASY_PROF_ENABLED, std::memory_order_release); + if (prev != EASY_PROF_ENABLED) { + enableEventTracer(); + m_beginTime = t; + } + m_dumpSpin.unlock(); + + replyMessage.type = profiler::net::MessageType::Reply_Capturing_Started; + bytes = socket.send(&replyMessage, sizeof(replyMessage)); + hasConnect = bytes > 0; + + break; + } + + case profiler::net::MessageType::Request_Stop_Capture: + { + EASY_LOGMSG("receive MessageType::Request_Stop_Capture\n"); + + if (dumping) + break; + + m_dumpSpin.lock(); + auto time = getCurrentTime(); + const auto prev = m_profilerStatus.exchange(EASY_PROF_DUMP, std::memory_order_release); + if (prev == EASY_PROF_ENABLED) { + disableEventTracer(); + m_endTime = time; + } + EASY_FORCE_EVENT2(m_endTime, "StopCapture", EASY_COLOR_END, profiler::OFF); + + dumping = true; + socket.setReceiveTimeout(500); // We have to check if dumping ready or not + + m_stopDumping.store(false, std::memory_order_release); + dumpingResult = std::async(std::launch::async, [this, &os] + { + auto result = dumpBlocksToStream(os, false, true); + m_dumpSpin.unlock(); + return result; + }); + + break; + } + + case profiler::net::MessageType::Request_Blocks_Description: + { + EASY_LOGMSG("receive MessageType::Request_Blocks_Description\n"); + + if (dumping) + stopDumping(); + + // Write profiler signature and version + os.write(PROFILER_SIGNATURE); + os.write(EASY_CURRENT_VERSION); + + // Write block descriptors + m_storedSpin.lock(); + os.write(static_cast(m_descriptors.size())); + os.write(m_usedMemorySize); + for (const auto descriptor : m_descriptors) + { + const auto name_size = descriptor->nameSize(); + const auto filename_size = descriptor->filenameSize(); + const auto size = static_cast(sizeof(profiler::SerializedBlockDescriptor) + + name_size + filename_size); + + os.write(size); + os.write(*descriptor); + os.write(name_size); + os.write(descriptor->name(), name_size); + os.write(descriptor->filename(), filename_size); + } + m_storedSpin.unlock(); + // END of Write block descriptors. + + const auto size = os.stream().tellp(); + static const decltype(size) badSize = -1; + if (size != badSize) + { + const profiler::net::DataMessage dm(static_cast(size), + profiler::net::MessageType::Reply_Blocks_Description); + + const size_t packet_size = sizeof(dm) + dm.size; + std::string sendbuf; + sendbuf.reserve(packet_size + 1); + + if (sendbuf.capacity() >= packet_size) // check if there is enough memory + { + sendbuf.append((const char*)&dm, sizeof(dm)); + sendbuf += os.stream().str(); // TODO: Avoid double-coping data from stringstream! + os.clear(); + + bytes = socket.send(sendbuf.c_str(), packet_size); + //hasConnect = bytes > 0; + } + else + { + EASY_ERROR("Can not send block descriptions. Not enough memory for allocating " << packet_size << " bytes"); + } + } + else + { + EASY_ERROR("Can not send block descriptions. Bad std::stringstream.tellp() == -1"); + } + + replyMessage.type = profiler::net::MessageType::Reply_Blocks_Description_End + ; + bytes = socket.send(&replyMessage, sizeof(replyMessage)); + hasConnect = bytes > 0; + + break; + } + + case profiler::net::MessageType::Change_Block_Status: + { + auto data = reinterpret_cast(message); + + EASY_LOGMSG("receive MessageType::ChangeBLock_Status id=" << data->id << " status=" << data->status << std::endl); + + setBlockStatus(data->id, static_cast<::profiler::EasyBlockStatus>(data->status)); + + break; + } + + case profiler::net::MessageType::Change_Event_Tracing_Status: + { + auto data = reinterpret_cast(message); + + EASY_LOGMSG("receive MessageType::Change_Event_Tracing_Status on=" << data->flag << std::endl); + + m_isEventTracingEnabled.store(data->flag, std::memory_order_release); + break; + } + + case profiler::net::MessageType::Change_Event_Tracing_Priority: + { +#if defined(_WIN32) || EASY_OPTION_LOG_ENABLED != 0 + auto data = reinterpret_cast(message); +#endif + + EASY_LOGMSG("receive MessageType::Change_Event_Tracing_Priority low=" << data->flag << std::endl); + +#if defined(_WIN32) + EasyEventTracer::instance().setLowPriority(data->flag); +#endif + break; + } + + default: + break; + } + } + } + + if (dumping) + { + m_stopDumping.store(true, std::memory_order_release); + join(dumpingResult); + } +} + +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/easy_profiler_core/profile_manager.h b/3rdparty/easyprofiler/easy_profiler_core/profile_manager.h new file mode 100644 index 0000000..963f9da --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/profile_manager.h @@ -0,0 +1,211 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_MANAGER_H +#define EASY_PROFILER_MANAGER_H + +#include + +#ifdef _WIN32 +// Do not move this include to other place! +// It should be included before Windows.h which is included in spin_lock.h +# include +#endif // _WIN32 + +#include "spin_lock.h" +#include "outstream.h" +#include "hashed_cstr.h" +#include "thread_storage.h" + +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// + +typedef uint64_t processid_t; + +class BlockDescriptor; + +namespace profiler { class ValueId; } + +class ProfileManager +{ +#ifndef EASY_MAGIC_STATIC_AVAILABLE + friend class ProfileManagerInstance; +#endif + + ProfileManager(); + + typedef profiler::guard_lock guard_lock_t; + typedef std::map map_of_threads_stacks; + typedef std::vector block_descriptors_t; + +#ifdef EASY_PROFILER_HASHED_CSTR_DEFINED + typedef std::unordered_map descriptors_map_t; +#else + typedef std::unordered_map descriptors_map_t; +#endif + + const processid_t m_processId; + + map_of_threads_stacks m_threads; + block_descriptors_t m_descriptors; + descriptors_map_t m_descriptorsMap; + uint64_t m_usedMemorySize; + profiler::timestamp_t m_beginTime; + profiler::timestamp_t m_endTime; + std::atomic m_frameMax; + std::atomic m_frameAvg; + std::atomic m_frameCur; + profiler::spin_lock m_spin; + profiler::spin_lock m_storedSpin; + profiler::spin_lock m_dumpSpin; + std::atomic m_mainThreadId; + std::atomic m_profilerStatus; + std::atomic_bool m_isEventTracingEnabled; + std::atomic_bool m_isAlreadyListening; + std::atomic_bool m_frameMaxReset; + std::atomic_bool m_frameAvgReset; + std::atomic_bool m_stopDumping; + + std::string m_csInfoFilename = "/tmp/cs_profiling_info.log"; + + uint32_t dumpBlocksToStream(profiler::OStream& _outputStream, bool _lockSpin, bool _async); + void setBlockStatus(profiler::block_id_t _id, profiler::EasyBlockStatus _status); + + std::thread m_listenThread; + void listen(uint16_t _port); + + std::atomic_bool m_stopListen; + +public: + + ProfileManager(const ProfileManager&) = delete; + ProfileManager(ProfileManager&&) = delete; + ProfileManager& operator = (const ProfileManager&) = delete; + ProfileManager& operator = (ProfileManager&&) = delete; + + static ProfileManager& instance(); + ~ProfileManager(); + + const profiler::BaseBlockDescriptor* addBlockDescriptor(profiler::EasyBlockStatus _defaultStatus, + const char* _autogenUniqueId, + const char* _name, + const char* _filename, + int _line, + profiler::block_type_t _block_type, + profiler::color_t _color, + bool _copyName = false); + + void storeValue(const profiler::BaseBlockDescriptor* _desc, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin); + bool storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName); + bool storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime); + void beginBlock(profiler::Block& _block); + void beginNonScopedBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName); + void endBlock(); + profiler::timestamp_t maxFrameDuration(); + profiler::timestamp_t avgFrameDuration(); + profiler::timestamp_t curFrameDuration() const; + void setEnabled(bool isEnable); + bool isEnabled() const; + void setEventTracingEnabled(bool _isEnable); + bool isEventTracingEnabled() const; + uint32_t dumpBlocksToFile(const char* filename); + const char* registerThread(const char* name, profiler::ThreadGuard& threadGuard); + const char* registerThread(const char* name); + + void setContextSwitchLogFilename(const char* name) + { + m_csInfoFilename = name; + } + + const char* getContextSwitchLogFilename() const + { + return m_csInfoFilename.c_str(); + } + + void beginContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _time, profiler::thread_id_t _target_thread_id, const char* _target_process, bool _lockSpin = true); + void endContextSwitch(profiler::thread_id_t _thread_id, processid_t _process_id, profiler::timestamp_t _endtime, bool _lockSpin = true); + void startListen(uint16_t _port); + void stopListen(); + bool isListening() const; + +private: + + void registerThread(); + + void beginFrame(); + void endFrame(); + + void enableEventTracer(); + void disableEventTracer(); + + static char checkThreadExpired(ThreadStorage& _registeredThread); + + void storeBlockForce(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t& _timestamp); + void storeBlockForce2(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t _timestamp); + void storeBlockForce2(ThreadStorage& _registeredThread, const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t _timestamp); + + ThreadStorage& _threadStorage(profiler::thread_id_t _thread_id); + ThreadStorage* _findThreadStorage(profiler::thread_id_t _thread_id); + + inline ThreadStorage& threadStorage(profiler::thread_id_t _thread_id) + { + guard_lock_t lock(m_spin); + return _threadStorage(_thread_id); + } + + inline ThreadStorage* findThreadStorage(profiler::thread_id_t _thread_id) + { + guard_lock_t lock(m_spin); + return _findThreadStorage(_thread_id); + } + +}; // END of class ProfileManager. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_MANAGER_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/reader.cpp b/3rdparty/easyprofiler/easy_profiler_core/reader.cpp new file mode 100644 index 0000000..4676374 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/reader.cpp @@ -0,0 +1,1030 @@ +/************************************************************************ +* file name : reader.cpp +* ----------------- : +* creation time : 2016/06/19 +* authors : Sergey Yagovtsev, Victor Zarubkin +* emails : yse.sey@gmail.com, v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of fillTreesFromFile function +* : which reads profiler file and fill profiler blocks tree. +* ----------------- : +* change log : * 2016/06/19 Sergey Yagovtsev: First fillTreesFromFile implementation. +* : +* : * 2016/06/25 Victor Zarubkin: Removed unnecessary memory allocation and copy +* : when creating and inserting blocks into the tree. +* : +* : * 2016/06/26 Victor Zarubkin: Added statistics gathering (min, max, average duration, +* : number of block calls). +* : * 2016/06/26 Victor Zarubkin, Sergey Yagovtsev: Added statistics gathering for root +* : blocks in the tree. +* : +* : * 2016/06/29 Victor Zarubkin: Added calculaton of total children number for blocks. +* : +* : * 2016/06/30 Victor Zarubkin: Added this header. +* : Added tree depth calculation. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include + +#include "hashed_cstr.h" + +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// + +typedef uint64_t processid_t; + +extern const uint32_t PROFILER_SIGNATURE; +extern const uint32_t EASY_CURRENT_VERSION; + +# define EASY_VERSION_INT(v_major, v_minor, v_patch) ((static_cast(v_major) << 24) | (static_cast(v_minor) << 16) | static_cast(v_patch)) +const uint32_t MIN_COMPATIBLE_VERSION = EASY_VERSION_INT(0, 1, 0); ///< minimal compatible version (.prof file format was not changed seriously since this version) +const uint32_t EASY_V_100 = EASY_VERSION_INT(1, 0, 0); ///< in v1.0.0 some additional data were added into .prof file +const uint32_t EASY_V_130 = EASY_VERSION_INT(1, 3, 0); ///< in v1.3.0 changed sizeof(thread_id_t) uint32_t -> uint64_t +# undef EASY_VERSION_INT + +const uint64_t TIME_FACTOR = 1000000000ULL; + +// TODO: use 128 bit integer operations for better accuracy +#define EASY_USE_FLOATING_POINT_CONVERSION + +#ifdef EASY_USE_FLOATING_POINT_CONVERSION + +// Suppress warnings about double to uint64 conversion +# ifdef _MSC_VER +# pragma warning(disable:4244) +# elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +# elif defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wconversion" +# pragma clang diagnostic ignored "-Wsign-conversion" +# endif + +# define EASY_CONVERT_TO_NANO(t, freq, factor) t *= factor + +#else + +# define EASY_CONVERT_TO_NANO(t, freq, factor) t *= TIME_FACTOR; t /= freq + +#endif + +////////////////////////////////////////////////////////////////////////// + +inline bool isCompatibleVersion(uint32_t _version) +{ + return _version >= MIN_COMPATIBLE_VERSION; +} + +inline void write(::std::stringstream& _stream, const char* _value, size_t _size) +{ + _stream.write(_value, _size); +} + +template +inline void write(::std::stringstream& _stream, const T& _value) +{ + _stream.write((const char*)&_value, sizeof(T)); +} + +////////////////////////////////////////////////////////////////////////// + +namespace profiler { + + void SerializedData::set(char* _data, uint64_t _size) + { + delete [] m_data; + m_data = _data; + m_size = _size; + } + + void SerializedData::set(uint64_t _size) + { + if (_size != 0) + set(new char[_size], _size); + else + set(nullptr, 0); + } + + void SerializedData::extend(uint64_t _size) + { + auto olddata = m_data; + auto oldsize = m_size; + + m_size = oldsize + _size; + m_data = new char[m_size]; + + if (olddata != nullptr) { + memcpy(m_data, olddata, oldsize); + delete [] olddata; + } + } + + extern "C" PROFILER_API void release_stats(BlockStatistics*& _stats) + { + if (_stats == nullptr) + return; + + if (--_stats->calls_number == 0) + delete _stats; + + _stats = nullptr; + } + +} + +////////////////////////////////////////////////////////////////////////// + +#ifdef EASY_PROFILER_HASHED_CSTR_DEFINED + +using StatsMap = ::std::unordered_map<::profiler::block_id_t, ::profiler::BlockStatistics*, ::estd::hash<::profiler::block_id_t> >; + +/** \note It is absolutely safe to use hashed_cstr (which simply stores pointer) because std::unordered_map, +which uses it as a key, exists only inside fillTreesFromFile function. */ +using IdMap = ::std::unordered_map<::profiler::hashed_cstr, ::profiler::block_id_t>; + +using CsStatsMap = ::std::unordered_map<::profiler::hashed_cstr, ::profiler::BlockStatistics*>; + +#else + +// TODO: Create optimized version of profiler::hashed_cstr for Linux too. +using StatsMap = ::std::unordered_map<::profiler::block_id_t, ::profiler::BlockStatistics*, ::estd::hash<::profiler::block_id_t> >; +using IdMap = ::std::unordered_map<::profiler::hashed_stdstring, ::profiler::block_id_t>; +using CsStatsMap = ::std::unordered_map<::profiler::hashed_stdstring, ::profiler::BlockStatistics*>; + +#endif + +////////////////////////////////////////////////////////////////////////// + +/** \brief Updates statistics for a profiler block. + +\param _stats_map Storage of statistics for blocks. +\param _current Pointer to the current block. +\param _stats Reference to the variable where pointer to the block statistics must be written. + +\note All blocks with similar name have the same pointer to statistics information. + +\note As all profiler block keeps a pointer to it's statistics, all similar blocks +automatically receive statistics update. + +*/ +::profiler::BlockStatistics* update_statistics(StatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, const ::profiler::blocks_t& _blocks, bool _calculate_children = true) +{ + auto duration = _current.node->duration(); + //StatsMap::key_type key(_current.node->name()); + //auto it = _stats_map.find(key); + auto it = _stats_map.find(_current.node->id()); + if (it != _stats_map.end()) + { + // Update already existing statistics + + auto stats = it->second; // write pointer to statistics into output (this is BlocksTree:: per_thread_stats or per_parent_stats or per_frame_stats) + + ++stats->calls_number; // update calls number of this block + stats->total_duration += duration; // update summary duration of all block calls + + if (_calculate_children) + { + for (auto i : _current.children) + stats->total_children_duration += _blocks[i].node->duration(); + } + + if (duration > _blocks[stats->max_duration_block].node->duration()) + { + // update max duration + stats->max_duration_block = _current_index; + //stats->max_duration = duration; + } + + if (duration < _blocks[stats->min_duration_block].node->duration()) + { + // update min duraton + stats->min_duration_block = _current_index; + //stats->min_duration = duration; + } + + // average duration is calculated inside average_duration() method by dividing total_duration to the calls_number + + return stats; + } + + // This is first time the block appear in the file. + // Create new statistics. + auto stats = new ::profiler::BlockStatistics(duration, _current_index, _parent_index); + //_stats_map.emplace(key, stats); + _stats_map.emplace(_current.node->id(), stats); + + if (_calculate_children) + { + for (auto i : _current.children) + stats->total_children_duration += _blocks[i].node->duration(); + } + + return stats; +} + +::profiler::BlockStatistics* update_statistics(CsStatsMap& _stats_map, const ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, const ::profiler::blocks_t& _blocks, bool _calculate_children = true) +{ + auto duration = _current.node->duration(); + CsStatsMap::key_type key(_current.node->name()); + auto it = _stats_map.find(key); + if (it != _stats_map.end()) + { + // Update already existing statistics + + auto stats = it->second; // write pointer to statistics into output (this is BlocksTree:: per_thread_stats or per_parent_stats or per_frame_stats) + + ++stats->calls_number; // update calls number of this block + stats->total_duration += duration; // update summary duration of all block calls + + if (_calculate_children) + { + for (auto i : _current.children) + stats->total_children_duration += _blocks[i].node->duration(); + } + + if (duration > _blocks[stats->max_duration_block].node->duration()) + { + // update max duration + stats->max_duration_block = _current_index; + //stats->max_duration = duration; + } + + if (duration < _blocks[stats->min_duration_block].node->duration()) + { + // update min duraton + stats->min_duration_block = _current_index; + //stats->min_duration = duration; + } + + // average duration is calculated inside average_duration() method by dividing total_duration to the calls_number + + return stats; + } + + // This is first time the block appear in the file. + // Create new statistics. + auto stats = new ::profiler::BlockStatistics(duration, _current_index, _parent_index); + _stats_map.emplace(key, stats); + + if (_calculate_children) + { + for (auto i : _current.children) + stats->total_children_duration += _blocks[i].node->duration(); + } + + return stats; +} + +////////////////////////////////////////////////////////////////////////// + +void update_statistics_recursive(StatsMap& _stats_map, ::profiler::BlocksTree& _current, ::profiler::block_index_t _current_index, ::profiler::block_index_t _parent_index, ::profiler::blocks_t& _blocks) +{ + _current.per_frame_stats = update_statistics(_stats_map, _current, _current_index, _parent_index, _blocks, false); + for (auto i : _current.children) + { + _current.per_frame_stats->total_children_duration += _blocks[i].node->duration(); + update_statistics_recursive(_stats_map, _blocks[i], i, _parent_index, _blocks); + } +} + +////////////////////////////////////////////////////////////////////////// + +/*void validate_pointers(::std::atomic& _progress, const char* _oldbase, ::profiler::SerializedData& _serialized_blocks, ::profiler::blocks_t& _blocks, size_t _size) +{ + if (_oldbase == nullptr) + { + _progress.store(25, ::std::memory_order_release); + return; + } + + for (size_t i = 0; i < _size; ++i) + { + auto& tree = _blocks[i]; + auto dist = ::std::distance(_oldbase, reinterpret_cast(tree.node)); + tree.node = reinterpret_cast<::profiler::SerializedBlock*>(_serialized_blocks.data() + dist); + _progress.store(20 + static_cast(5 * i / _size), ::std::memory_order_release); + } +} + +void validate_pointers(::std::atomic& _progress, const char* _oldbase, ::profiler::SerializedData& _serialized_descriptors, ::profiler::descriptors_list_t& _descriptors, size_t _size) +{ + if (_oldbase == nullptr) + { + _progress.store(5, ::std::memory_order_release); + return; + } + + for (size_t i = 0; i < _size; ++i) + { + auto dist = ::std::distance(_oldbase, reinterpret_cast(_descriptors[i])); + _descriptors[i] = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(_serialized_descriptors.data() + dist); + _progress.store(static_cast(5 * i / _size)); + } +}*/ + +////////////////////////////////////////////////////////////////////////// + +extern "C" { + + PROFILER_API ::profiler::block_index_t fillTreesFromFile(::std::atomic& progress, const char* filename, + ::profiler::SerializedData& serialized_blocks, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::profiler::blocks_t& blocks, + ::profiler::thread_blocks_tree_t& threaded_trees, + uint32_t& total_descriptors_number, + uint32_t& version, + bool gather_statistics, + ::std::stringstream& _log) + { + auto oldprogress = progress.exchange(0, ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return 0; + } + + ::std::ifstream inFile(filename, ::std::fstream::binary); + if (!inFile.is_open()) + { + _log << "Can not open file " << filename; + return 0; + } + + ::std::stringstream str; + + // Replace str buffer to inFile buffer to avoid redundant copying + typedef ::std::basic_iostream<::std::stringstream::char_type, ::std::stringstream::traits_type> stringstream_parent; + stringstream_parent& s = str; + auto oldbuf = s.rdbuf(inFile.rdbuf()); + + // Read data from file + auto result = fillTreesFromStream(progress, str, serialized_blocks, serialized_descriptors, descriptors, blocks, + threaded_trees, total_descriptors_number, version, gather_statistics, _log); + + // Restore old str buffer to avoid possible second memory free on stringstream destructor + s.rdbuf(oldbuf); + + return result; + } + + ////////////////////////////////////////////////////////////////////////// + + PROFILER_API ::profiler::block_index_t fillTreesFromStream(::std::atomic& progress, ::std::stringstream& inFile, + ::profiler::SerializedData& serialized_blocks, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::profiler::blocks_t& blocks, + ::profiler::thread_blocks_tree_t& threaded_trees, + uint32_t& total_descriptors_number, + uint32_t& version, + bool gather_statistics, + ::std::stringstream& _log) + { + EASY_FUNCTION(::profiler::colors::Cyan); + + auto oldprogress = progress.exchange(0, ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return 0; + } + + uint32_t signature = 0; + inFile.read((char*)&signature, sizeof(uint32_t)); + if (signature != PROFILER_SIGNATURE) + { + _log << "Wrong signature " << signature << "\nThis is not EasyProfiler file/stream."; + return 0; + } + + version = 0; + inFile.read((char*)&version, sizeof(uint32_t)); + if (!isCompatibleVersion(version)) + { + _log << "Incompatible version: v" << (version >> 24) << "." << ((version & 0x00ff0000) >> 16) << "." << (version & 0x0000ffff); + return 0; + } + + processid_t pid = 0; + if (version > EASY_V_100) + { + if (version < EASY_V_130) + { + uint32_t old_pid = 0; + inFile.read((char*)&old_pid, sizeof(uint32_t)); + pid = old_pid; + } + else + { + inFile.read((char*)&pid, sizeof(processid_t)); + } + } + + int64_t file_cpu_frequency = 0LL; + inFile.read((char*)&file_cpu_frequency, sizeof(int64_t)); + uint64_t cpu_frequency = file_cpu_frequency; + const double conversion_factor = static_cast(TIME_FACTOR) / static_cast(cpu_frequency); + + ::profiler::timestamp_t begin_time = 0ULL; + ::profiler::timestamp_t end_time = 0ULL; + inFile.read((char*)&begin_time, sizeof(::profiler::timestamp_t)); + inFile.read((char*)&end_time, sizeof(::profiler::timestamp_t)); + if (cpu_frequency != 0) + { + EASY_CONVERT_TO_NANO(begin_time, cpu_frequency, conversion_factor); + EASY_CONVERT_TO_NANO(end_time, cpu_frequency, conversion_factor); + } + + uint32_t total_blocks_number = 0; + inFile.read((char*)&total_blocks_number, sizeof(uint32_t)); + if (total_blocks_number == 0) + { + _log << "Profiled blocks number == 0"; + return 0; + } + + uint64_t memory_size = 0; + inFile.read((char*)&memory_size, sizeof(decltype(memory_size))); + if (memory_size == 0) + { + _log << "Wrong memory size == 0 for " << total_blocks_number << " blocks"; + return 0; + } + + total_descriptors_number = 0; + inFile.read((char*)&total_descriptors_number, sizeof(uint32_t)); + if (total_descriptors_number == 0) + { + _log << "Blocks description number == 0"; + return 0; + } + + uint64_t descriptors_memory_size = 0; + inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size))); + if (descriptors_memory_size == 0) + { + _log << "Wrong memory size == 0 for " << total_descriptors_number << " blocks descriptions"; + return 0; + } + + descriptors.reserve(total_descriptors_number); + //const char* olddata = append_regime ? serialized_descriptors.data() : nullptr; + serialized_descriptors.set(descriptors_memory_size); + //validate_pointers(progress, olddata, serialized_descriptors, descriptors, descriptors.size()); + + uint64_t i = 0; + while (!inFile.eof() && descriptors.size() < total_descriptors_number) + { + uint16_t sz = 0; + inFile.read((char*)&sz, sizeof(sz)); + if (sz == 0) + { + descriptors.push_back(nullptr); + continue; + } + + //if (i + sz > descriptors_memory_size) { + // printf("FILE CORRUPTED\n"); + // return 0; + //} + + char* data = serialized_descriptors[i]; + inFile.read(data, sz); + auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data); + descriptors.push_back(descriptor); + + i += sz; + oldprogress = progress.exchange(static_cast(15 * i / descriptors_memory_size), ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return 0; // Loading interrupted + } + } + + using PerThreadStats = ::std::unordered_map<::profiler::thread_id_t, StatsMap, ::estd::hash<::profiler::thread_id_t> >; + PerThreadStats parent_statistics, frame_statistics; + IdMap identification_table; + + blocks.reserve(total_blocks_number); + //olddata = append_regime ? serialized_blocks.data() : nullptr; + serialized_blocks.set(memory_size); + //validate_pointers(progress, olddata, serialized_blocks, blocks, blocks.size()); + + i = 0; + uint32_t read_number = 0; + ::profiler::block_index_t blocks_counter = 0; + ::std::vector name; + + const size_t thread_id_t_size = version < EASY_V_130 ? sizeof(uint32_t) : sizeof(::profiler::thread_id_t); + + while (!inFile.eof()) + { + EASY_BLOCK("Read thread data", ::profiler::colors::DarkGreen); + + ::profiler::thread_id_t thread_id = 0; + inFile.read((char*)&thread_id, thread_id_t_size); + if (inFile.eof()) + break; + + auto& root = threaded_trees[thread_id]; + + uint16_t name_size = 0; + inFile.read((char*)&name_size, sizeof(uint16_t)); + if (name_size != 0) + { + name.resize(name_size); + inFile.read(name.data(), name_size); + root.thread_name = name.data(); + } + + CsStatsMap per_thread_statistics_cs; + + uint32_t blocks_number_in_thread = 0; + inFile.read((char*)&blocks_number_in_thread, sizeof(decltype(blocks_number_in_thread))); + auto threshold = read_number + blocks_number_in_thread; + while (!inFile.eof() && read_number < threshold) + { + EASY_BLOCK("Read context switch", ::profiler::colors::Green); + + ++read_number; + + uint16_t sz = 0; + inFile.read((char*)&sz, sizeof(sz)); + if (sz == 0) + { + _log << "Bad CSwitch block size == 0"; + return 0; + } + + char* data = serialized_blocks[i]; + inFile.read(data, sz); + i += sz; + auto baseData = reinterpret_cast<::profiler::SerializedCSwitch*>(data); + auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(data); + auto t_end = t_begin + 1; + + if (cpu_frequency != 0) + { + EASY_CONVERT_TO_NANO(*t_begin, cpu_frequency, conversion_factor); + EASY_CONVERT_TO_NANO(*t_end, cpu_frequency, conversion_factor); + } + + if (*t_end > begin_time) + { + if (*t_begin < begin_time) + *t_begin = begin_time; + + blocks.emplace_back(); + ::profiler::BlocksTree& tree = blocks.back(); + tree.cs = baseData; + const auto block_index = blocks_counter++; + + root.wait_time += baseData->duration(); + root.sync.emplace_back(block_index); + + if (gather_statistics) + { + EASY_BLOCK("Gather per thread statistics", ::profiler::colors::Coral); + tree.per_thread_stats = update_statistics(per_thread_statistics_cs, tree, block_index, ~0U, blocks);//, thread_id, blocks); + } + } + + oldprogress = progress.exchange(20 + static_cast(70 * i / memory_size), ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return 0; // Loading interrupted + } + } + + if (inFile.eof()) + break; + + StatsMap per_thread_statistics; + + blocks_number_in_thread = 0; + inFile.read((char*)&blocks_number_in_thread, sizeof(decltype(blocks_number_in_thread))); + threshold = read_number + blocks_number_in_thread; + while (!inFile.eof() && read_number < threshold) + { + EASY_BLOCK("Read block", ::profiler::colors::Green); + + ++read_number; + + uint16_t sz = 0; + inFile.read((char*)&sz, sizeof(sz)); + if (sz == 0) + { + _log << "Bad block size == 0"; + return 0; + } + + char* data = serialized_blocks[i]; + inFile.read(data, sz); + i += sz; + auto baseData = reinterpret_cast<::profiler::SerializedBlock*>(data); + if (baseData->id() >= total_descriptors_number) + { + _log << "Bad block id == " << baseData->id(); + return 0; + } + + auto desc = descriptors[baseData->id()]; + if (desc == nullptr) + { + _log << "Bad block id == " << baseData->id() << ". Description is null."; + return 0; + } + + auto t_begin = reinterpret_cast<::profiler::timestamp_t*>(data); + auto t_end = t_begin + 1; + + if (cpu_frequency != 0) + { + EASY_CONVERT_TO_NANO(*t_begin, cpu_frequency, conversion_factor); + EASY_CONVERT_TO_NANO(*t_end, cpu_frequency, conversion_factor); + } + + if (*t_end >= begin_time) + { + if (*t_begin < begin_time) + *t_begin = begin_time; + + blocks.emplace_back(); + ::profiler::BlocksTree& tree = blocks.back(); + tree.node = baseData; + const auto block_index = blocks_counter++; + + if (*tree.node->name() != 0) + { + // If block has runtime name then generate new id for such block. + // Blocks with the same name will have same id. + + IdMap::key_type key(tree.node->name()); + auto it = identification_table.find(key); + if (it != identification_table.end()) + { + // There is already block with such name, use it's id + baseData->setId(it->second); + } + else + { + // There were no blocks with such name, generate new id and save it in the table for further usage. + auto id = static_cast<::profiler::block_id_t>(descriptors.size()); + identification_table.emplace(key, id); + if (descriptors.capacity() == descriptors.size()) + descriptors.reserve((descriptors.size() * 3) >> 1); + descriptors.push_back(descriptors[baseData->id()]); + baseData->setId(id); + } + } + + if (!root.children.empty()) + { + auto& back = blocks[root.children.back()]; + auto t1 = back.node->end(); + auto mt0 = tree.node->begin(); + if (mt0 < t1)//parent - starts earlier than last ends + { + //auto lower = ::std::lower_bound(root.children.begin(), root.children.end(), tree); + /**/ + EASY_BLOCK("Find children", ::profiler::colors::Blue); + auto rlower1 = ++root.children.rbegin(); + for (; rlower1 != root.children.rend() && !(mt0 > blocks[*rlower1].node->begin()); ++rlower1); + auto lower = rlower1.base(); + ::std::move(lower, root.children.end(), ::std::back_inserter(tree.children)); + + root.children.erase(lower, root.children.end()); + EASY_END_BLOCK; + + if (gather_statistics) + { + EASY_BLOCK("Gather statistic within parent", ::profiler::colors::Magenta); + auto& per_parent_statistics = parent_statistics[thread_id]; + per_parent_statistics.clear(); + + //per_parent_statistics.reserve(tree.children.size()); // this gives slow-down on Windows + //per_parent_statistics.reserve(tree.children.size() * 2); // this gives no speed-up on Windows + // TODO: check this behavior on Linux + + for (auto i : tree.children) + { + auto& child = blocks[i]; + child.per_parent_stats = update_statistics(per_parent_statistics, child, i, block_index, blocks); + if (tree.depth < child.depth) + tree.depth = child.depth; + } + } + else + { + for (auto i : tree.children) + { + const auto& child = blocks[i]; + if (tree.depth < child.depth) + tree.depth = child.depth; + } + } + + if (tree.depth == 254) + { + // 254 because we need 1 additional level for root (thread). + // In other words: real stack depth = 1 root block + 254 children + + if (*tree.node->name() != 0) + _log << "Stack depth exceeded value of 254\nfor block \"" << desc->name() << "\""; + else + _log << "Stack depth exceeded value of 254\nfor block \"" << desc->name() << "\"\nfrom file \"" << desc->file() << "\":" << desc->line(); + + return 0; + } + + ++tree.depth; + } + } + + ++root.blocks_number; + root.children.emplace_back(block_index);// ::std::move(tree)); + if (desc->type() != ::profiler::BlockType::Block) + root.events.emplace_back(block_index); + + + if (gather_statistics) + { + EASY_BLOCK("Gather per thread statistics", ::profiler::colors::Coral); + tree.per_thread_stats = update_statistics(per_thread_statistics, tree, block_index, ~0U, blocks);//, thread_id, blocks); + } + } + + oldprogress = progress.exchange(20 + static_cast(70 * i / memory_size), ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return 0; // Loading interrupted + } + } + } + + oldprogress = progress.exchange(90, ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return 0; // Loading interrupted + } + + EASY_BLOCK("Gather statistics for roots", ::profiler::colors::Purple); + if (gather_statistics) + { + ::std::vector<::std::thread> statistics_threads; + statistics_threads.reserve(threaded_trees.size()); + + for (auto& it : threaded_trees) + { + auto& root = it.second; + root.thread_id = it.first; + //root.tree.shrink_to_fit(); + + auto& per_frame_statistics = frame_statistics[root.thread_id]; + auto& per_parent_statistics = parent_statistics[it.first]; + per_parent_statistics.clear(); + + statistics_threads.emplace_back(::std::thread([&per_parent_statistics, &per_frame_statistics, &blocks, &descriptors](::profiler::BlocksTreeRoot& root) + { + //::std::sort(root.sync.begin(), root.sync.end(), [&blocks](::profiler::block_index_t left, ::profiler::block_index_t right) + //{ + // return blocks[left].node->begin() < blocks[right].node->begin(); + //}); + + ::profiler::block_index_t cs_index = 0; + for (auto i : root.children) + { + auto& frame = blocks[i]; + + if (descriptors[frame.node->id()]->type() == ::profiler::BlockType::Block) + ++root.frames_number; + + frame.per_parent_stats = update_statistics(per_parent_statistics, frame, i, ~0U, blocks);//, root.thread_id, blocks); + + per_frame_statistics.clear(); + update_statistics_recursive(per_frame_statistics, frame, i, i, blocks); + + if (cs_index < root.sync.size()) + { + CsStatsMap frame_stats_cs; + do { + + auto j = root.sync[cs_index]; + auto& cs = blocks[j]; + if (cs.node->end() < frame.node->begin()) + continue; + if (cs.node->begin() > frame.node->end()) + break; + cs.per_frame_stats = update_statistics(frame_stats_cs, cs, cs_index, i, blocks); + + } while (++cs_index < root.sync.size()); + } + + if (root.depth < frame.depth) + root.depth = frame.depth; + + root.profiled_time += frame.node->duration(); + } + + ++root.depth; + }, ::std::ref(root))); + } + + int j = 0, n = static_cast(statistics_threads.size()); + for (auto& t : statistics_threads) + { + t.join(); + progress.store(90 + (10 * ++j) / n, ::std::memory_order_release); + } + } + else + { + int j = 0, n = static_cast(threaded_trees.size()); + for (auto& it : threaded_trees) + { + auto& root = it.second; + root.thread_id = it.first; + + //::std::sort(root.sync.begin(), root.sync.end(), [&blocks](::profiler::block_index_t left, ::profiler::block_index_t right) + //{ + // return blocks[left].node->begin() < blocks[right].node->begin(); + //}); + + //root.tree.shrink_to_fit(); + for (auto i : root.children) + { + auto& frame = blocks[i]; + + if (descriptors[frame.node->id()]->type() == ::profiler::BlockType::Block) + ++root.frames_number; + + if (root.depth < frame.depth) + root.depth = frame.depth; + + root.profiled_time += frame.node->duration(); + } + + ++root.depth; + + progress.store(90 + (10 * ++j) / n, ::std::memory_order_release); + } + } + // No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors + + progress.store(100, ::std::memory_order_release); + return blocks_counter; + } + + ////////////////////////////////////////////////////////////////////////// + + PROFILER_API bool readDescriptionsFromStream(::std::atomic& progress, ::std::stringstream& inFile, + ::profiler::SerializedData& serialized_descriptors, + ::profiler::descriptors_list_t& descriptors, + ::std::stringstream& _log) + { + EASY_FUNCTION(::profiler::colors::Cyan); + + progress.store(0); + + uint32_t signature = 0; + inFile.read((char*)&signature, sizeof(uint32_t)); + if (signature != PROFILER_SIGNATURE) + { + _log << "Wrong file signature.\nThis is not EasyProfiler file/stream."; + return false; + } + + uint32_t version = 0; + inFile.read((char*)&version, sizeof(uint32_t)); + if (!isCompatibleVersion(version)) + { + _log << "Incompatible version: v" << (version >> 24) << "." << ((version & 0x00ff0000) >> 16) << "." << (version & 0x0000ffff); + return false; + } + + uint32_t total_descriptors_number = 0; + inFile.read((char*)&total_descriptors_number, sizeof(decltype(total_descriptors_number))); + if (total_descriptors_number == 0) + { + _log << "Blocks description number == 0"; + return false; + } + + uint64_t descriptors_memory_size = 0; + inFile.read((char*)&descriptors_memory_size, sizeof(decltype(descriptors_memory_size))); + if (descriptors_memory_size == 0) + { + _log << "Wrong memory size == 0 for " << total_descriptors_number << " blocks descriptions"; + return false; + } + + descriptors.reserve(total_descriptors_number); + //const char* olddata = append_regime ? serialized_descriptors.data() : nullptr; + serialized_descriptors.set(descriptors_memory_size); + //validate_pointers(progress, olddata, serialized_descriptors, descriptors, descriptors.size()); + + uint64_t i = 0; + while (!inFile.eof() && descriptors.size() < total_descriptors_number) + { + uint16_t sz = 0; + inFile.read((char*)&sz, sizeof(sz)); + if (sz == 0) + { + descriptors.push_back(nullptr); + continue; + } + + //if (i + sz > descriptors_memory_size) { + // printf("FILE CORRUPTED\n"); + // return 0; + //} + + char* data = serialized_descriptors[i]; + inFile.read(data, sz); + auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data); + descriptors.push_back(descriptor); + + i += sz; + auto oldprogress = progress.exchange(static_cast(100 * i / descriptors_memory_size), ::std::memory_order_release); + if (oldprogress < 0) + { + _log << "Reading was interrupted"; + return false; // Loading interrupted + } + } + + return !descriptors.empty(); + } + + ////////////////////////////////////////////////////////////////////////// + +} + +#undef EASY_CONVERT_TO_NANO + +#ifdef EASY_USE_FLOATING_POINT_CONVERSION +# ifdef _MSC_VER +# pragma warning(default:4244) +# elif defined(__GNUC__) +# pragma GCC diagnostic pop +# elif defined(__clang__) +# pragma clang diagnostic pop +# endif +# undef EASY_USE_FLOATING_POINT_CONVERSION +#endif diff --git a/3rdparty/easyprofiler/easy_profiler_core/resources.rc b/3rdparty/easyprofiler/easy_profiler_core/resources.rc new file mode 100644 index 0000000..e68eb4d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/resources.rc @@ -0,0 +1,30 @@ +1 VERSIONINFO + +# define EASY_STRINGIFY(a) #a +# define EASY_STRINGIFICATION(a) EASY_STRINGIFY(a) + +#define EASY_PROFILER_PRODUCT_VERSION "v" EASY_STRINGIFICATION(EASY_PROFILER_VERSION_MAJOR) "." \ + EASY_STRINGIFICATION(EASY_PROFILER_VERSION_MINOR) "." \ + EASY_STRINGIFICATION(EASY_PROFILER_VERSION_PATCH) + +FILEVERSION EASY_PROFILER_VERSION_MAJOR, EASY_PROFILER_VERSION_MINOR, EASY_PROFILER_VERSION_PATCH +PRODUCTVERSION EASY_PROFILER_VERSION_MAJOR, EASY_PROFILER_VERSION_MINOR, EASY_PROFILER_VERSION_PATCH +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "CompanyName", "EasySolutions" + VALUE "FileDescription", "Lightweight profiler library for c++" + VALUE "LegalCopyright", "Copyright (C) 2016-2017 Victor Zarubkin, Sergey Yagovtsev" + VALUE "LegalTrademarks1", "All Rights Reserved" + VALUE "LegalTrademarks2", "All Rights Reserved" + VALUE "ProductName", "easy_profiler lib" + VALUE "ProductVersion", EASY_PROFILER_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END diff --git a/3rdparty/easyprofiler/easy_profiler_core/spin_lock.h b/3rdparty/easyprofiler/easy_profiler_core/spin_lock.h new file mode 100644 index 0000000..705540d --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/spin_lock.h @@ -0,0 +1,126 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_SPIN_LOCK_H +#define EASY_PROFILER_SPIN_LOCK_H + +#define EASY_USE_CRITICAL_SECTION // Use CRITICAL_SECTION instead of std::atomic_flag + +#if defined(_WIN32) && defined(EASY_USE_CRITICAL_SECTION) +#include +#else +#include +#endif + +namespace profiler { + +#if defined(_WIN32) && defined(EASY_USE_CRITICAL_SECTION) + // std::atomic_flag on Windows works slower than critical section, so we will use it instead of std::atomic_flag... + // By the way, Windows critical sections are slower than std::atomic_flag on Unix. + class spin_lock { CRITICAL_SECTION m_lock; public: + + void lock() { + EnterCriticalSection(&m_lock); + } + + void unlock() { + LeaveCriticalSection(&m_lock); + } + + spin_lock() { + InitializeCriticalSection(&m_lock); + } + + ~spin_lock() { + DeleteCriticalSection(&m_lock); + } + }; +#else + // std::atomic_flag on Unix works fine and very fast (almost instant!) + class spin_lock { ::std::atomic_flag m_lock; public: + + void lock() { + while (m_lock.test_and_set(::std::memory_order_acquire)); + } + + void unlock() { + m_lock.clear(::std::memory_order_release); + } + + spin_lock() { + m_lock.clear(); + } + }; +#endif + + template + class guard_lock + { + T& m_lock; + bool m_isLocked = false; + + public: + + explicit guard_lock(T& m) : m_lock(m) { + m_lock.lock(); + m_isLocked = true; + } + + ~guard_lock() { + unlock(); + } + + inline void unlock() { + if (m_isLocked) { + m_lock.unlock(); + m_isLocked = false; + } + } + }; + +} // END of namespace profiler. + +#ifdef EASY_USE_CRITICAL_SECTION +# undef EASY_USE_CRITICAL_SECTION +#endif + +#endif // EASY_PROFILER_SPIN_LOCK_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/stack_buffer.h b/3rdparty/easyprofiler/easy_profiler_core/stack_buffer.h new file mode 100644 index 0000000..a59ad06 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/stack_buffer.h @@ -0,0 +1,140 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_STACK_BUFFER_H +#define EASY_PROFILER_STACK_BUFFER_H + +#include "nonscoped_block.h" +#include +#include +#include + +#ifdef max +#undef max +#endif + +template +inline void destroy_elem(T*) +{ + +} + +inline void destroy_elem(NonscopedBlock* _elem) +{ + _elem->destroy(); +} + +template +class StackBuffer +{ + struct chunk { int8_t data[sizeof(T)]; }; + + std::list m_overflow; ///< List of additional stack elements if current capacity of buffer is not enough + T* m_buffer; ///< Contiguous buffer used for stack + uint32_t m_size; ///< Current size of stack + uint32_t m_capacity; ///< Current capacity of m_buffer + uint32_t m_maxcapacity; ///< Maximum used capacity including m_buffer and m_overflow + +public: + + StackBuffer() = delete; + StackBuffer(const StackBuffer&) = delete; + StackBuffer(StackBuffer&&) = delete; + + explicit StackBuffer(uint32_t N) + : m_buffer(static_cast(malloc(N * sizeof(T)))) + , m_size(0) + , m_capacity(N) + , m_maxcapacity(N) + { + } + + ~StackBuffer() + { + for (uint32_t i = 0; i < m_size; ++i) + destroy_elem(m_buffer + i); + + free(m_buffer); + + for (auto& elem : m_overflow) + destroy_elem(reinterpret_cast(elem.data + 0)); + } + + template + T& push(TArgs ... _args) + { + if (m_size < m_capacity) + return *(::new (m_buffer + m_size++) T(_args...)); + + m_overflow.emplace_back(); + const uint32_t cap = m_capacity + static_cast(m_overflow.size()); + if (m_maxcapacity < cap) + m_maxcapacity = cap; + + return *(::new (m_overflow.back().data + 0) T(_args...)); + } + + void pop() + { + if (m_overflow.empty()) + { + // m_size should not be equal to 0 here because ProfileManager behavior does not allow such situation + destroy_elem(m_buffer + --m_size); + + if (m_size == 0 && m_maxcapacity > m_capacity) + { + // When stack gone empty we can resize buffer to use enough space in the future + free(m_buffer); + m_maxcapacity = m_capacity = std::max(m_maxcapacity, m_capacity << 1); + m_buffer = static_cast(malloc(m_capacity * sizeof(T))); + } + + return; + } + + destroy_elem(reinterpret_cast(m_overflow.back().data + 0)); + m_overflow.pop_back(); + } + +}; // END of class StackBuffer. + +#endif // EASY_PROFILER_STACK_BUFFER_H diff --git a/3rdparty/easyprofiler/easy_profiler_core/thread_storage.cpp b/3rdparty/easyprofiler/easy_profiler_core/thread_storage.cpp new file mode 100644 index 0000000..beb6839 --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/thread_storage.cpp @@ -0,0 +1,157 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#include "thread_storage.h" +#include "current_thread.h" +#include "current_time.h" + +ThreadStorage::ThreadStorage() + : nonscopedBlocks(16) + , frameStartTime(0) + , id(getCurrentThreadId()) + , stackSize(0) + , allowChildren(true) + , named(false) + , guarded(false) + , frameOpened(false) + , halt(false) +{ + expired = ATOMIC_VAR_INIT(0); + profiledFrameOpened = ATOMIC_VAR_INIT(false); +} + +void ThreadStorage::storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin) +{ + const uint16_t serializedDataSize = static_cast(sizeof(profiler::ArbitraryValue) + _size); + void* data = blocks.closedList.allocate(serializedDataSize); + + ::new (data) profiler::ArbitraryValue(_timestamp, _vin.m_id, _id, static_cast(_size), _type, _isArray); + + char* cdata = reinterpret_cast(data); + memcpy(cdata + sizeof(profiler::ArbitraryValue), _data, _size); + + blocks.usedMemorySize += serializedDataSize; +} + +void ThreadStorage::storeBlock(const profiler::Block& block) +{ +#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 + EASY_LOCAL_STATIC_PTR(const BaseBlockDescriptor*, desc, \ + MANAGER.addBlockDescriptor(EASY_OPTION_STORAGE_EXPAND_BLOCKS_ON ? profiler::ON : profiler::OFF, EASY_UNIQUE_LINE_ID, "EasyProfiler.ExpandStorage", \ + __FILE__, __LINE__, profiler::BlockType::Block, EASY_COLOR_INTERNAL_EVENT)); + + EASY_THREAD_LOCAL static profiler::timestamp_t beginTime = 0ULL; + EASY_THREAD_LOCAL static profiler::timestamp_t endTime = 0ULL; +#endif + + uint16_t nameLength = static_cast(strlen(block.name())); + uint16_t serializedDataSize = static_cast(sizeof(profiler::BaseBlockData) + nameLength + 1); + +#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 + const bool expanded = (desc->m_status & profiler::ON) && blocks.closedList.need_expand(serializedDataSize); + if (expanded) beginTime = getCurrentTime(); +#endif + + void* data = blocks.closedList.allocate(serializedDataSize); + +#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 + if (expanded) endTime = getCurrentTime(); +#endif + + ::new (data) profiler::SerializedBlock(block, nameLength); + blocks.usedMemorySize += serializedDataSize; + +#if EASY_OPTION_MEASURE_STORAGE_EXPAND != 0 + if (expanded) + { + profiler::Block b(beginTime, desc->id(), ""); + b.finish(endTime); + + serializedDataSize = static_cast(sizeof(profiler::BaseBlockData) + 1); + data = blocks.closedList.allocate(serializedDataSize); + ::new (data) profiler::SerializedBlock(b, 0); + blocks.usedMemorySize += serializedDataSize; + } +#endif +} + +void ThreadStorage::storeCSwitch(const CSwitchBlock& block) +{ + uint16_t nameLength = static_cast(strlen(block.name())); + uint16_t serializedDataSize = static_cast(sizeof(profiler::CSwitchEvent) + nameLength + 1); + void* data = sync.closedList.allocate(serializedDataSize); + ::new (data) profiler::SerializedCSwitch(block, nameLength); + sync.usedMemorySize += serializedDataSize; +} + +void ThreadStorage::clearClosed() +{ + blocks.clearClosed(); + sync.clearClosed(); +} + +void ThreadStorage::popSilent() +{ + if (!blocks.openedList.empty()) + { + profiler::Block& top = blocks.openedList.back(); + top.m_end = top.m_begin; + if (!top.m_isScoped) + nonscopedBlocks.pop(); + blocks.openedList.pop_back(); + } +} + +void ThreadStorage::beginFrame() +{ + if (!frameOpened) + { + frameStartTime = getCurrentTime(); + frameOpened = true; + } +} + +profiler::timestamp_t ThreadStorage::endFrame() +{ + frameOpened = false; + return getCurrentTime() - frameStartTime; +} diff --git a/3rdparty/easyprofiler/easy_profiler_core/thread_storage.h b/3rdparty/easyprofiler/easy_profiler_core/thread_storage.h new file mode 100644 index 0000000..bdfc08f --- /dev/null +++ b/3rdparty/easyprofiler/easy_profiler_core/thread_storage.h @@ -0,0 +1,134 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_PROFILER_THREAD_STORAGE_H +#define EASY_PROFILER_THREAD_STORAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include "stack_buffer.h" +#include "chunk_allocator.h" + +////////////////////////////////////////////////////////////////////////// + +template +struct BlocksList +{ + BlocksList() = default; + + std::vector openedList; + chunk_allocator closedList; + uint64_t usedMemorySize = 0; + + void clearClosed() { + //closedList.clear(); + usedMemorySize = 0; + } + +private: + + BlocksList(const BlocksList&) = delete; + BlocksList(BlocksList&&) = delete; + +}; // END of struct BlocksList. + +////////////////////////////////////////////////////////////////////////// + +class CSwitchBlock : public profiler::CSwitchEvent +{ + const char* m_name; + +public: + + CSwitchBlock(profiler::timestamp_t _begin_time, profiler::thread_id_t _tid, const char* _runtimeName) EASY_NOEXCEPT; + inline const char* name() const EASY_NOEXCEPT { return m_name; } +}; + +////////////////////////////////////////////////////////////////////////// + +const uint16_t SIZEOF_BLOCK = sizeof(profiler::BaseBlockData) + 1 + sizeof(uint16_t); // SerializedBlock stores BaseBlockData + at least 1 character for name ('\0') + 2 bytes for size of serialized data +const uint16_t SIZEOF_CSWITCH = sizeof(profiler::CSwitchEvent) + 1 + sizeof(uint16_t); // SerializedCSwitch also stores additional 4 bytes to be able to save 64-bit thread_id + +struct ThreadStorage EASY_FINAL +{ + StackBuffer nonscopedBlocks; + BlocksList, SIZEOF_BLOCK * (uint16_t)128U> blocks; + BlocksList sync; + + std::string name; ///< Thread name + profiler::timestamp_t frameStartTime; ///< Current frame start time. Used to calculate FPS. + const profiler::thread_id_t id; ///< Thread ID + std::atomic expired; ///< Is thread expired + std::atomic_bool profiledFrameOpened; ///< Is new profiled frame opened (this is true when profiling is enabled and there is an opened frame) \sa frameOpened + int32_t stackSize; ///< Current thread stack depth. Used when switching profiler state to begin collecting blocks only when new frame would be opened. + bool allowChildren; ///< False if one of previously opened blocks has OFF_RECURSIVE or ON_WITHOUT_CHILDREN status + bool named; ///< True if thread name was set + bool guarded; ///< True if thread has been registered using ThreadGuard + bool frameOpened; ///< Is new frame opened (this does not depend on profiling status) \sa profiledFrameOpened + bool halt; ///< This is set to true when new frame started while dumping blocks. Used to restrict collecting blocks during dumping process. + + void storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin); + void storeBlock(const profiler::Block& _block); + void storeCSwitch(const CSwitchBlock& _block); + void clearClosed(); + void popSilent(); + + void beginFrame(); + profiler::timestamp_t endFrame(); + + ThreadStorage(); + +private: + + ThreadStorage(const ThreadStorage&) = delete; + ThreadStorage(ThreadStorage&&) = delete; + +}; // END of struct ThreadStorage. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_THREAD_STORAGE_H diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/CMakeDirectoryInformation.cmake b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..9ecfcf5 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/alex/Work/C++Projects/easyprofiler") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/alex/Work/C++Projects/easyprofiler") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/DependInfo.cmake b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/DependInfo.cmake new file mode 100644 index 0000000..6d9b6e3 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/DependInfo.cmake @@ -0,0 +1,59 @@ +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +set(CMAKE_DEPENDS_CHECK_CXX + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/qrc_resources.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_graphics_view.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_tree_widget.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_functions.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/descriptors_tree_widget.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_chronometer_item.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_item.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_qtimer.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals_qobjects.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/main.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/main_window.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/profiler_gui_automoc.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_item.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_loader.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o" + "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp" "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o" + ) +set(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +set(CMAKE_TARGET_DEFINITIONS_CXX + "BUILD_WITH_EASY_PROFILER=1" + "EASY_DEFAULT_PORT=28077" + "EASY_PROFILER_VERSION_MAJOR=1" + "EASY_PROFILER_VERSION_MINOR=3" + "EASY_PROFILER_VERSION_PATCH=0" + "QT_CORE_LIB" + "QT_GUI_LIB" + "QT_NO_DEBUG" + "QT_WIDGETS_LIB" + ) + +# The include file search paths: +set(CMAKE_CXX_TARGET_INCLUDE_PATH + "profiler_gui" + "/home/alex/Work/Qt/5.8/gcc_64/include" + "/home/alex/Work/Qt/5.8/gcc_64/include/QtWidgets" + "/home/alex/Work/Qt/5.8/gcc_64/include/QtGui" + "/home/alex/Work/Qt/5.8/gcc_64/include/QtCore" + "/home/alex/Work/Qt/5.8/gcc_64/./mkspecs/linux-g++" + "easy_profiler_core/include" + ) + +# Targets to which this target links. +set(CMAKE_TARGET_LINKED_INFO_FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake" + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/build.make b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/build.make new file mode 100644 index 0000000..8554a13 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/build.make @@ -0,0 +1,603 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/alex/Work/C++Projects/easyprofiler + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/alex/Work/C++Projects/easyprofiler + +# Include any dependencies generated for this target. +include profiler_gui/CMakeFiles/profiler_gui.dir/depend.make + +# Include the progress variables for this target. +include profiler_gui/CMakeFiles/profiler_gui.dir/progress.make + +# Include the compile flags for this target's objects. +include profiler_gui/CMakeFiles/profiler_gui.dir/flags.make + +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o: profiler_gui/main.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/main.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/main.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/main.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/main.cpp > CMakeFiles/profiler_gui.dir/main.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/main.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/main.cpp -o CMakeFiles/profiler_gui.dir/main.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o: profiler_gui/arbitrary_value_inspector.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp > CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp -o CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o: profiler_gui/blocks_graphics_view.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_graphics_view.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_graphics_view.cpp > CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_graphics_view.cpp -o CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o: profiler_gui/blocks_tree_widget.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_tree_widget.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_tree_widget.cpp > CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_tree_widget.cpp -o CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o: profiler_gui/common_functions.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_5) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/common_functions.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_functions.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/common_functions.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_functions.cpp > CMakeFiles/profiler_gui.dir/common_functions.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/common_functions.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_functions.cpp -o CMakeFiles/profiler_gui.dir/common_functions.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o: profiler_gui/descriptors_tree_widget.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_6) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/descriptors_tree_widget.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/descriptors_tree_widget.cpp > CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/descriptors_tree_widget.cpp -o CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o: profiler_gui/easy_chronometer_item.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_7) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_chronometer_item.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_chronometer_item.cpp > CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_chronometer_item.cpp -o CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o: profiler_gui/easy_frame_rate_viewer.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_8) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp > CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp -o CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o: profiler_gui/easy_graphics_item.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_9) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_item.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_item.cpp > CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_item.cpp -o CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o: profiler_gui/easy_graphics_scrollbar.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_10) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp > CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp -o CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o: profiler_gui/easy_qtimer.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_11) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_qtimer.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_qtimer.cpp > CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_qtimer.cpp -o CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o: profiler_gui/globals.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_12) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/globals.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/globals.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals.cpp > CMakeFiles/profiler_gui.dir/globals.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/globals.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals.cpp -o CMakeFiles/profiler_gui.dir/globals.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o: profiler_gui/globals_qobjects.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_13) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals_qobjects.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals_qobjects.cpp > CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals_qobjects.cpp -o CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o: profiler_gui/main_window.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_14) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/main_window.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/main_window.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/main_window.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/main_window.cpp > CMakeFiles/profiler_gui.dir/main_window.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/main_window.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/main_window.cpp -o CMakeFiles/profiler_gui.dir/main_window.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o: profiler_gui/tree_widget_item.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_15) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_item.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_item.cpp > CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_item.cpp -o CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o: profiler_gui/tree_widget_loader.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_16) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_loader.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_loader.cpp > CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_loader.cpp -o CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o: profiler_gui/treeview_first_column_delegate.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_17) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp > CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp -o CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o: profiler_gui/profiler_gui_automoc.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_18) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/profiler_gui_automoc.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/profiler_gui_automoc.cpp > CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/profiler_gui_automoc.cpp -o CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o + + +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/flags.make +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o: profiler_gui/CMakeFiles/profiler_gui.dir/qrc_resources.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_19) "Building CXX object profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/qrc_resources.cpp + +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/qrc_resources.cpp > CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.i + +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/qrc_resources.cpp -o CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.s + +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.requires: + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.requires + +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.provides: profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.requires + $(MAKE) -f profiler_gui/CMakeFiles/profiler_gui.dir/build.make profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.provides.build +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.provides + +profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.provides.build: profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o + + +# Object files for target profiler_gui +profiler_gui_OBJECTS = \ +"CMakeFiles/profiler_gui.dir/main.cpp.o" \ +"CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o" \ +"CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o" \ +"CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o" \ +"CMakeFiles/profiler_gui.dir/common_functions.cpp.o" \ +"CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o" \ +"CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o" \ +"CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o" \ +"CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o" \ +"CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o" \ +"CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o" \ +"CMakeFiles/profiler_gui.dir/globals.cpp.o" \ +"CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o" \ +"CMakeFiles/profiler_gui.dir/main_window.cpp.o" \ +"CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o" \ +"CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o" \ +"CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o" \ +"CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o" \ +"CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o" + +# External object files for target profiler_gui +profiler_gui_EXTERNAL_OBJECTS = + +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/build.make +bin/profiler_gui: /home/alex/Work/Qt/5.8/gcc_64/lib/libQt5Widgets.so.5.8.0 +bin/profiler_gui: bin/libeasy_profiler.so +bin/profiler_gui: /home/alex/Work/Qt/5.8/gcc_64/lib/libQt5Gui.so.5.8.0 +bin/profiler_gui: /home/alex/Work/Qt/5.8/gcc_64/lib/libQt5Core.so.5.8.0 +bin/profiler_gui: profiler_gui/CMakeFiles/profiler_gui.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_20) "Linking CXX executable ../bin/profiler_gui" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profiler_gui.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +profiler_gui/CMakeFiles/profiler_gui.dir/build: bin/profiler_gui + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/build + +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/main.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/common_functions.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/globals.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/main_window.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o.requires +profiler_gui/CMakeFiles/profiler_gui.dir/requires: profiler_gui/CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o.requires + +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/requires + +profiler_gui/CMakeFiles/profiler_gui.dir/clean: + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && $(CMAKE_COMMAND) -P CMakeFiles/profiler_gui.dir/cmake_clean.cmake +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/clean + +profiler_gui/CMakeFiles/profiler_gui.dir/depend: + cd /home/alex/Work/C++Projects/easyprofiler && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/profiler_gui /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/profiler_gui /home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : profiler_gui/CMakeFiles/profiler_gui.dir/depend + diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/cmake_clean.cmake b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/cmake_clean.cmake new file mode 100644 index 0000000..bdaff9d --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/cmake_clean.cmake @@ -0,0 +1,30 @@ +file(REMOVE_RECURSE + "profiler_gui_automoc.cpp" + "CMakeFiles/profiler_gui.dir/qrc_resources.cpp" + "CMakeFiles/profiler_gui.dir/main.cpp.o" + "CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o" + "CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o" + "CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o" + "CMakeFiles/profiler_gui.dir/common_functions.cpp.o" + "CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o" + "CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o" + "CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o" + "CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o" + "CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o" + "CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o" + "CMakeFiles/profiler_gui.dir/globals.cpp.o" + "CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o" + "CMakeFiles/profiler_gui.dir/main_window.cpp.o" + "CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o" + "CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o" + "CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o" + "CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o" + "CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o" + "../bin/profiler_gui.pdb" + "../bin/profiler_gui" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profiler_gui.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/depend.make b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/depend.make new file mode 100644 index 0000000..cc4c540 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profiler_gui. +# This may be replaced when dependencies are built. diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/flags.make b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/flags.make new file mode 100644 index 0000000..f9e76bf --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -O3 -DNDEBUG -fPIC -DEASY_CHRONO_STEADY_CLOCK=0 -DEASY_CHRONO_HIGHRES_CLOCK=0 -DEASY_OPTION_START_LISTEN_ON_STARTUP=0 -DEASY_OPTION_MEASURE_STORAGE_EXPAND=0 -DEASY_OPTION_STORAGE_EXPAND_BLOCKS_ON=0 -DEASY_OPTION_IMPLICIT_THREAD_REGISTRATION=1 -DEASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS=0 -DEASY_OPTION_LOG_ENABLED=0 -DEASY_OPTION_PRETTY_PRINT_FUNCTIONS=0 -DEASY_OPTION_BUILTIN_COLORS=1 -std=gnu++11 -std=gnu++11 + +CXX_DEFINES = -DBUILD_WITH_EASY_PROFILER=1 -DEASY_DEFAULT_PORT=28077 -DEASY_PROFILER_VERSION_MAJOR=1 -DEASY_PROFILER_VERSION_MINOR=3 -DEASY_PROFILER_VERSION_PATCH=0 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_DEBUG -DQT_WIDGETS_LIB + +CXX_INCLUDES = -I/home/alex/Work/C++Projects/easyprofiler/profiler_gui -isystem /home/alex/Work/Qt/5.8/gcc_64/include -isystem /home/alex/Work/Qt/5.8/gcc_64/include/QtWidgets -isystem /home/alex/Work/Qt/5.8/gcc_64/include/QtGui -isystem /home/alex/Work/Qt/5.8/gcc_64/include/QtCore -isystem /home/alex/Work/Qt/5.8/gcc_64/./mkspecs/linux-g++ -I/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include + diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/link.txt b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/link.txt new file mode 100644 index 0000000..cd1eaaf --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/profiler_gui.dir/main.cpp.o CMakeFiles/profiler_gui.dir/arbitrary_value_inspector.cpp.o CMakeFiles/profiler_gui.dir/blocks_graphics_view.cpp.o CMakeFiles/profiler_gui.dir/blocks_tree_widget.cpp.o CMakeFiles/profiler_gui.dir/common_functions.cpp.o CMakeFiles/profiler_gui.dir/descriptors_tree_widget.cpp.o CMakeFiles/profiler_gui.dir/easy_chronometer_item.cpp.o CMakeFiles/profiler_gui.dir/easy_frame_rate_viewer.cpp.o CMakeFiles/profiler_gui.dir/easy_graphics_item.cpp.o CMakeFiles/profiler_gui.dir/easy_graphics_scrollbar.cpp.o CMakeFiles/profiler_gui.dir/easy_qtimer.cpp.o CMakeFiles/profiler_gui.dir/globals.cpp.o CMakeFiles/profiler_gui.dir/globals_qobjects.cpp.o CMakeFiles/profiler_gui.dir/main_window.cpp.o CMakeFiles/profiler_gui.dir/tree_widget_item.cpp.o CMakeFiles/profiler_gui.dir/tree_widget_loader.cpp.o CMakeFiles/profiler_gui.dir/treeview_first_column_delegate.cpp.o CMakeFiles/profiler_gui.dir/profiler_gui_automoc.cpp.o CMakeFiles/profiler_gui.dir/CMakeFiles/profiler_gui.dir/qrc_resources.cpp.o -o ../bin/profiler_gui -rdynamic /home/alex/Work/Qt/5.8/gcc_64/lib/libQt5Widgets.so.5.8.0 ../bin/libeasy_profiler.so /home/alex/Work/Qt/5.8/gcc_64/lib/libQt5Gui.so.5.8.0 /home/alex/Work/Qt/5.8/gcc_64/lib/libQt5Core.so.5.8.0 -lpthread -Wl,-rpath,/home/alex/Work/Qt/5.8/gcc_64/lib:/home/alex/Work/C++Projects/easyprofiler/bin: diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/progress.make b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/progress.make new file mode 100644 index 0000000..c417330 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui.dir/progress.make @@ -0,0 +1,21 @@ +CMAKE_PROGRESS_1 = 9 +CMAKE_PROGRESS_2 = 10 +CMAKE_PROGRESS_3 = 11 +CMAKE_PROGRESS_4 = 12 +CMAKE_PROGRESS_5 = 13 +CMAKE_PROGRESS_6 = 14 +CMAKE_PROGRESS_7 = 15 +CMAKE_PROGRESS_8 = 16 +CMAKE_PROGRESS_9 = 17 +CMAKE_PROGRESS_10 = 18 +CMAKE_PROGRESS_11 = 19 +CMAKE_PROGRESS_12 = 20 +CMAKE_PROGRESS_13 = 21 +CMAKE_PROGRESS_14 = 22 +CMAKE_PROGRESS_15 = 23 +CMAKE_PROGRESS_16 = 24 +CMAKE_PROGRESS_17 = 25 +CMAKE_PROGRESS_18 = 26 +CMAKE_PROGRESS_19 = 27 +CMAKE_PROGRESS_20 = 28 + diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/AutogenInfo.cmake b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/AutogenInfo.cmake new file mode 100644 index 0000000..3f8c232 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/AutogenInfo.cmake @@ -0,0 +1,29 @@ +set(AM_SOURCES "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/main.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_graphics_view.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_tree_widget.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_functions.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/descriptors_tree_widget.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_chronometer_item.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_item.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_qtimer.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals_qobjects.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/main_window.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_item.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_loader.cpp;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp" ) +set(AM_RCC_SOURCES "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/resources.qrc" ) +set(AM_RCC_INPUTS "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/logo.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/arrow-up-hover.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/radio-indicator.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/settings.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/reload.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/open-folder2.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/arrow-up-disabled.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/statistics.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/lan_on.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/wifi.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/check-disabled.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/close-white.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/maximize-white-pressed.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/save.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/play.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/close-white-hover.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/collapse.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/reload-folder2.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/list.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/search-prev.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/off.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/arrow-down-disabled.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/radio-indicator-disabled.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/search-next.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/arrow-up.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/maximize-white.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/check.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/lan.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/maximize-white-hover.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/lan.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/minimize-white.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/stop.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/minimize-white-pressed.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/delete.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/arrow-down.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/wifi_on.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/lan_on.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/expand.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/close-white-pressed.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/arrow-down-hover.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/minimize-white-hover.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/images/default/statistics2.svg@list_sep@/home/alex/Work/C++Projects/easyprofiler/profiler_gui/themes/default.css") +set(AM_SKIP_MOC "" ) +set(AM_SKIP_UIC ) +set(AM_HEADERS "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/arbitrary_value_inspector.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_graphics_view.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/blocks_tree_widget.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_functions.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/common_types.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/descriptors_tree_widget.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_chronometer_item.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_frame_rate_viewer.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_item.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_graphics_scrollbar.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/easy_qtimer.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/globals.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/main_window.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_item.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/tree_widget_loader.h;/home/alex/Work/C++Projects/easyprofiler/profiler_gui/treeview_first_column_delegate.h" ) +set(AM_MOC_COMPILE_DEFINITIONS "BUILD_WITH_EASY_PROFILER=1;EASY_DEFAULT_PORT=28077;EASY_PROFILER_VERSION_MAJOR=1;EASY_PROFILER_VERSION_MINOR=3;EASY_PROFILER_VERSION_PATCH=0;QT_CORE_LIB;QT_GUI_LIB;QT_NO_DEBUG;QT_WIDGETS_LIB") +set(AM_MOC_INCLUDES "/home/alex/Work/C++Projects/easyprofiler/profiler_gui;/home/alex/Work/Qt/5.8/gcc_64/include;/home/alex/Work/Qt/5.8/gcc_64/include/QtWidgets;/home/alex/Work/Qt/5.8/gcc_64/include/QtGui;/home/alex/Work/Qt/5.8/gcc_64/include/QtCore;/home/alex/Work/Qt/5.8/gcc_64/./mkspecs/linux-g++;/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include;/usr/include") +set(AM_MOC_OPTIONS "") +set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "") +set(AM_CMAKE_BINARY_DIR "/home/alex/Work/C++Projects/easyprofiler/") +set(AM_CMAKE_SOURCE_DIR "/home/alex/Work/C++Projects/easyprofiler/") +set(AM_QT_MOC_EXECUTABLE "/home/alex/Work/Qt/5.8/gcc_64/bin/moc") +set(AM_QT_UIC_EXECUTABLE "") +set(AM_QT_RCC_EXECUTABLE "/home/alex/Work/Qt/5.8/gcc_64/bin/rcc") +if(DEFINED ENV{DEB_BUILD_MULTIARCH} AND DEFINED ENV{DEB_HOST_MULTIARCH} AND "/home/alex/Work/Qt/5.8/gcc_64/bin/moc" MATCHES "/usr/lib/$ENV{DEB_HOST_MULTIARCH}/qt5/bin/moc") + set(AM_QT_MOC_EXECUTABLE "/usr/lib/$ENV{DEB_BUILD_MULTIARCH}/qt5/bin/moc") +endif() +set(AM_CMAKE_CURRENT_SOURCE_DIR "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/") +set(AM_CMAKE_CURRENT_BINARY_DIR "/home/alex/Work/C++Projects/easyprofiler/profiler_gui/") +set(AM_QT_VERSION_MAJOR "5") +set(AM_TARGET_NAME "profiler_gui_automoc") +set(AM_ORIGIN_TARGET_NAME "profiler_gui") +set(AM_RELAXED_MODE "FALSE") +set(AM_UIC_TARGET_OPTIONS ) +set(AM_UIC_OPTIONS_FILES ) +set(AM_UIC_OPTIONS_OPTIONS ) +set(AM_RCC_OPTIONS_FILES "") +set(AM_RCC_OPTIONS_OPTIONS "") diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/DependInfo.cmake b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/DependInfo.cmake new file mode 100644 index 0000000..19fab21 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/DependInfo.cmake @@ -0,0 +1,11 @@ +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) +# The set of files for implicit dependencies of each language: + +# Targets to which this target links. +set(CMAKE_TARGET_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/build.make b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/build.make new file mode 100644 index 0000000..8b445e6 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/build.make @@ -0,0 +1,77 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/alex/Work/C++Projects/easyprofiler + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/alex/Work/C++Projects/easyprofiler + +# Utility rule file for profiler_gui_automoc. + +# Include the progress variables for this target. +include profiler_gui/CMakeFiles/profiler_gui_automoc.dir/progress.make + +profiler_gui/CMakeFiles/profiler_gui_automoc: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Automatic moc and rcc for target profiler_gui" + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && /usr/bin/cmake -E cmake_autogen /home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/ Release + +profiler_gui_automoc: profiler_gui/CMakeFiles/profiler_gui_automoc +profiler_gui_automoc: profiler_gui/CMakeFiles/profiler_gui_automoc.dir/build.make + +.PHONY : profiler_gui_automoc + +# Rule to build all files generated by this target. +profiler_gui/CMakeFiles/profiler_gui_automoc.dir/build: profiler_gui_automoc + +.PHONY : profiler_gui/CMakeFiles/profiler_gui_automoc.dir/build + +profiler_gui/CMakeFiles/profiler_gui_automoc.dir/clean: + cd /home/alex/Work/C++Projects/easyprofiler/profiler_gui && $(CMAKE_COMMAND) -P CMakeFiles/profiler_gui_automoc.dir/cmake_clean.cmake +.PHONY : profiler_gui/CMakeFiles/profiler_gui_automoc.dir/clean + +profiler_gui/CMakeFiles/profiler_gui_automoc.dir/depend: + cd /home/alex/Work/C++Projects/easyprofiler && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/profiler_gui /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/profiler_gui /home/alex/Work/C++Projects/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : profiler_gui/CMakeFiles/profiler_gui_automoc.dir/depend + diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/cmake_clean.cmake b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/cmake_clean.cmake new file mode 100644 index 0000000..186b8e5 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +file(REMOVE_RECURSE + "profiler_gui_automoc.cpp" + "CMakeFiles/profiler_gui.dir/qrc_resources.cpp" + "CMakeFiles/profiler_gui_automoc" +) + +# Per-language clean rules from dependency scanning. +foreach(lang ) + include(CMakeFiles/profiler_gui_automoc.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/progress.make b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/progress.make new file mode 100644 index 0000000..c7c4328 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/profiler_gui_automoc.dir/progress.make @@ -0,0 +1,2 @@ +CMAKE_PROGRESS_1 = 29 + diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeFiles/progress.marks b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/progress.marks new file mode 100644 index 0000000..f04c001 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeFiles/progress.marks @@ -0,0 +1 @@ +29 diff --git a/3rdparty/easyprofiler/profiler_gui/CMakeLists.txt b/3rdparty/easyprofiler/profiler_gui/CMakeLists.txt new file mode 100644 index 0000000..e78c964 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/CMakeLists.txt @@ -0,0 +1,70 @@ +#set(CMAKE_PREFIX_PATH f:/qt/5.5/5.6/msvc2013_64/lib/cmake) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +find_package(Qt5Widgets) + +if (Qt5Widgets_FOUND) + if (NOT("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") AND WIN32) + set(APPLICATION_PLATFORM WIN32) + endif () + add_executable(profiler_gui ${APPLICATION_PLATFORM} + main.cpp + arbitrary_value_inspector.h + arbitrary_value_inspector.cpp + blocks_graphics_view.h + blocks_graphics_view.cpp + blocks_tree_widget.h + blocks_tree_widget.cpp + common_functions.h + common_functions.cpp + common_types.h + descriptors_tree_widget.h + descriptors_tree_widget.cpp + easy_chronometer_item.h + easy_chronometer_item.cpp + easy_frame_rate_viewer.h + easy_frame_rate_viewer.cpp + easy_graphics_item.h + easy_graphics_item.cpp + easy_graphics_scrollbar.h + easy_graphics_scrollbar.cpp + easy_qtimer.h + easy_qtimer.cpp + globals.h + globals.cpp + globals_qobjects.cpp + main_window.h + main_window.cpp + tree_widget_item.h + tree_widget_item.cpp + tree_widget_loader.h + tree_widget_loader.cpp + treeview_first_column_delegate.h + treeview_first_column_delegate.cpp + resources.qrc + resources.rc + ) + target_link_libraries(profiler_gui Qt5::Widgets easy_profiler) + if (WIN32) + target_compile_definitions(profiler_gui PRIVATE -D_WIN32_WINNT=0x0600) + endif () + if (MINGW) + target_compile_definitions(profiler_gui PRIVATE -DSTRSAFE_NO_DEPRECATE) + endif () + + install( + TARGETS + profiler_gui + RUNTIME + DESTINATION + bin + ) + + set_property(TARGET profiler_gui PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) +else () + message(STATUS "INFO\n\n\tQt5 not found! Generating EasyProfiler projects without GUI.\n") +endif () + diff --git a/3rdparty/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp b/3rdparty/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp new file mode 100644 index 0000000..2655827 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/arbitrary_value_inspector.cpp @@ -0,0 +1,1060 @@ +/************************************************************************ +* file name : arbitrary_value_inspector.cpp +* ----------------- : +* creation time : 2017/11/30 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of . +* ----------------- : +* change log : * 2017/11/30 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "arbitrary_value_inspector.h" +#include "treeview_first_column_delegate.h" +#include "globals.h" + +////////////////////////////////////////////////////////////////////////// + +void getChartPoints(const ArbitraryValuesCollection& _collection, Points& _points, qreal& _minValue, qreal& _maxValue) +{ + _minValue = 1e300; + _maxValue = -1e300; + + const auto size = _collection.size(); + _points.clear(); + _points.reserve(size); + + if (size == 0) + return; + + const auto& valuesByThread = _collection.valuesMap(); + + if (valuesByThread.size() == 1) + { + const auto& values = valuesByThread.begin()->second; + for (auto value : values) + { + const qreal x = sceneX(value->begin()); + const qreal y = profiler_gui::value2real(*value); + _points.emplace_back(x, y); + + if (y > _maxValue) + _maxValue = y; + if (y < _minValue) + _minValue = y; + } + } + else + { + std::list threadIds; + for (const auto& it : valuesByThread) + threadIds.push_back(it.first); + + size_t i = 0; + while (!threadIds.empty()) + { + for (auto it = threadIds.begin(); it != threadIds.end();) + { + const auto& values = valuesByThread.at(*it); + if (i >= values.size()) + { + it = threadIds.erase(it); + continue; + } + + const qreal x = sceneX(values[i]->begin()); + const qreal y = profiler_gui::value2real(*values[i]); + _points.emplace_back(x, y); + + if (y > _maxValue) + _maxValue = y; + if (y < _minValue) + _minValue = y; + + ++it; + } + } + + std::sort(_points.begin(), _points.end(), [](const QPointF& lhs, const QPointF& rhs) -> bool { + return lhs.x() < rhs.x(); + }); + } +} + +////////////////////////////////////////////////////////////////////////// + +ArbitraryValuesCollection::ArbitraryValuesCollection() + : m_beginTime(0) + , m_minValue(1e300) + , m_maxValue(-1e300) + , m_jobType(0) +{ + m_status = ATOMIC_VAR_INIT(Idle); + m_bInterrupt = ATOMIC_VAR_INIT(false); +} + +ArbitraryValuesCollection::~ArbitraryValuesCollection() +{ + interrupt(); +} + +const ArbitraryValuesMap& ArbitraryValuesCollection::valuesMap() const +{ + return m_values; +} + +const Points& ArbitraryValuesCollection::points() const +{ + return m_points; +} + +ArbitraryValuesCollection::JobStatus ArbitraryValuesCollection::status() const +{ + return static_cast(m_status.load(std::memory_order_acquire)); +} + +size_t ArbitraryValuesCollection::size() const +{ + size_t totalSize = 0; + for (const auto& it : m_values) + totalSize += it.second.size(); + return totalSize; +} + +qreal ArbitraryValuesCollection::minValue() const +{ + return m_minValue; +} + +qreal ArbitraryValuesCollection::maxValue() const +{ + return m_maxValue; +} + +void ArbitraryValuesCollection::collectValues(profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName) +{ + interrupt(); + + setStatus(InProgress); + m_points.clear(); + m_jobType = ValuesJob; + + if (_valueId == 0) + m_collectorThread = std::thread(&This::collectByName, this, _threadId, _valueName); + else + m_collectorThread = std::thread(&This::collectById, this, _threadId, _valueId); +} + +void ArbitraryValuesCollection::collectValues(profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName, profiler::timestamp_t _beginTime) +{ + interrupt(); + + setStatus(InProgress); + m_points.clear(); + m_beginTime = _beginTime; + m_minValue = 1e300; + m_maxValue = -1e300; + m_jobType = ValuesJob | PointsJob; + + if (_valueId == 0) + m_collectorThread = std::thread(&This::collectByName, this, _threadId, _valueName); + else + m_collectorThread = std::thread(&This::collectById, this, _threadId, _valueId); +} + +bool ArbitraryValuesCollection::calculatePoints(profiler::timestamp_t _beginTime) +{ + if (status() != Ready || m_values.empty()) + return false; + + if (m_collectorThread.joinable()) + m_collectorThread.join(); + + setStatus(InProgress); + m_points.clear(); + m_beginTime = _beginTime; + m_minValue = 1e300; + m_maxValue = -1e300; + m_jobType = PointsJob; + + m_collectorThread = std::thread([this] + { + getChartPoints(*this, m_points, m_minValue, m_maxValue); + setStatus(Ready); + }); + + return true; +} + +void ArbitraryValuesCollection::interrupt() +{ + if (!m_collectorThread.joinable()) + return; + + m_bInterrupt.store(true, std::memory_order_release); + m_collectorThread.join(); + m_bInterrupt.store(false, std::memory_order_release); + + setStatus(Idle); + m_jobType = None; + m_values.clear(); +} + +void ArbitraryValuesCollection::setStatus(JobStatus _status) +{ + m_status.store(static_cast(_status), std::memory_order_release); +} + +void ArbitraryValuesCollection::collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId) +{ + if (_threadId == 0) + { + const auto threadsCount = EASY_GLOBALS.profiler_blocks.size(); + const bool calculatePointsInner = (m_jobType & PointsJob) != 0 && threadsCount == 1; + + for (const auto& it : EASY_GLOBALS.profiler_blocks) + { + if (!collectByIdForThread(it.second, _valueId, calculatePointsInner)) + return; + } + + if ((m_jobType & PointsJob) != 0 && threadsCount > 1) + getChartPoints(*this, m_points, m_minValue, m_maxValue); + } + else + { + const auto t = EASY_GLOBALS.profiler_blocks.find(_threadId); + if (t != EASY_GLOBALS.profiler_blocks.end() && !collectByIdForThread(t->second, _valueId, (m_jobType & PointsJob) != 0)) + return; + } + + setStatus(Ready); +} + +bool ArbitraryValuesCollection::collectByIdForThread(const profiler::BlocksTreeRoot& _threadRoot, + profiler::vin_t _valueId, bool _calculatePoints) +{ + auto& valuesList = m_values[_threadRoot.thread_id]; + + for (auto i : _threadRoot.events) + { + if (m_bInterrupt.load(std::memory_order_acquire)) + return false; + + const auto& block = easyBlock(i).tree; + const auto& desc = easyDescriptor(block.node->id()); + if (desc.type() != profiler::BlockType::Value) + continue; + + const auto value = block.value; + if (value->value_id() != _valueId) + continue; + + valuesList.push_back(value); + + if (_calculatePoints) + { + const auto p = point(*block.value); + + if (p.y() > m_maxValue) + m_maxValue = p.y(); + if (p.y() < m_minValue) + m_minValue = p.y(); + + m_points.push_back(p); + } + } + + return true; +} + +void ArbitraryValuesCollection::collectByName(profiler::thread_id_t _threadId, const std::string _valueName) +{ + if (_threadId == 0) + { + const auto threadsCount = EASY_GLOBALS.profiler_blocks.size(); + const bool calculatePointsInner = (m_jobType & PointsJob) != 0 && threadsCount == 1; + + for (const auto& it : EASY_GLOBALS.profiler_blocks) + { + if (!collectByNameForThread(it.second, _valueName, calculatePointsInner)) + return; + } + + if ((m_jobType & PointsJob) != 0 && threadsCount > 1) + getChartPoints(*this, m_points, m_minValue, m_maxValue); + } + else + { + const auto t = EASY_GLOBALS.profiler_blocks.find(_threadId); + if (t != EASY_GLOBALS.profiler_blocks.end() && !collectByNameForThread(t->second, _valueName, (m_jobType & PointsJob) != 0)) + return; + } + + setStatus(Ready); +} + +bool ArbitraryValuesCollection::collectByNameForThread(const profiler::BlocksTreeRoot& _threadRoot, + const std::string& _valueName, bool _calculatePoints) +{ + auto& valuesList = m_values[_threadRoot.thread_id]; + + for (auto i : _threadRoot.events) + { + if (m_bInterrupt.load(std::memory_order_acquire)) + return false; + + const auto& block = easyBlock(i).tree; + const auto& desc = easyDescriptor(block.node->id()); + if (desc.type() != profiler::BlockType::Value || _valueName != desc.name()) + continue; + + valuesList.push_back(block.value); + + if (_calculatePoints) + { + const auto p = point(*block.value); + + if (p.y() > m_maxValue) + m_maxValue = p.y(); + if (p.y() < m_minValue) + m_minValue = p.y(); + + m_points.push_back(p); + } + } + + return true; +} + +QPointF ArbitraryValuesCollection::point(const profiler::ArbitraryValue& _value) const +{ + const qreal x = PROF_MICROSECONDS(qreal(_value.begin() - m_beginTime)); + const qreal y = profiler_gui::value2real(_value); + return {x, y}; +} + +////////////////////////////////////////////////////////////////////////// + +EasyArbitraryValuesChartItem::EasyArbitraryValuesChartItem() + : Parent(nullptr) +{ +} + +EasyArbitraryValuesChartItem::~EasyArbitraryValuesChartItem() +{ + +} + +void EasyArbitraryValuesChartItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + if (m_collections.empty()) + return; + + const auto& chart = *reinterpret_cast(scene()->parent()); + const auto scale = chart.xscale(); + + qreal minValue = 1e300, maxValue = -1e300; + for (const auto& c : m_collections) + { + const auto& collection = *c.ptr; + if (minValue > collection.minValue()) + minValue = collection.minValue(); + if (maxValue < collection.maxValue()) + maxValue = collection.maxValue(); + } + + const qreal height = std::max(maxValue - minValue, 1.); + + auto r = scene()->sceneRect(); + + + _painter->save(); + + for (const auto& c : m_collections) + { + const auto& points = c.ptr->points(); + if (points.empty()) + continue; + + if (c.selected) + { + auto pen = _painter->pen(); + pen.setColor(QColor::fromRgba(c.color)); + pen.setWidth(3); + _painter->setPen(pen); + } + else + { + _painter->setPen(QColor::fromRgba(c.color)); + } + + if (points.size() == 1) + _painter->drawPoint(points.front()); + else + { + auto gety = [&r, &minValue, &maxValue, &height] (qreal y) + { + y = maxValue - y; + y /= height; + y *= r.height() - 10; + y += r.top() + 5; + return y; + }; + + if (c.chartType == ChartType::Points) + { + for (const auto& p : points) + _painter->drawPoint(QPointF {p.x() * scale, gety(p.y())}); + } + else + { + QPointF p1 = points.front(); + for (int i = 1; i < points.size(); ++i) + { + const auto& p2 = points[i]; + _painter->drawLine(QPointF {p1.x() * scale, gety(p1.y())}, QPointF {p2.x() * scale, gety(p2.y())}); + p1 = p2; + } + } + //_painter->drawPolyline(points.data(), static_cast(points.size())); + } + } + + _painter->restore(); +} + +QRectF EasyArbitraryValuesChartItem::boundingRect() const +{ + return m_boundingRect; +} + +void EasyArbitraryValuesChartItem::setBoundingRect(const QRectF& _rect) +{ + m_boundingRect = _rect; +} + +void EasyArbitraryValuesChartItem::setBoundingRect(qreal _left, qreal _top, qreal _width, qreal _height) +{ + m_boundingRect.setRect(_left, _top, _width, _height); +} + +void EasyArbitraryValuesChartItem::update(Collections _collections) +{ + m_collections = std::move(_collections); +} + +void EasyArbitraryValuesChartItem::update(const ArbitraryValuesCollection* _selected) +{ + for (auto& collection : m_collections) + collection.selected = collection.ptr == _selected; +} + +////////////////////////////////////////////////////////////////////////// + +EasyGraphicsChart::EasyGraphicsChart(QWidget* _parent) + : Parent(_parent) + , m_chartItem(new EasyArbitraryValuesChartItem()) + , m_left(0) + , m_right(100) + , m_offset(0) + , m_xscale(1) + , m_visibleRegionWidth(100) + , m_bBindMode(false) +{ + setCacheMode(QGraphicsView::CacheNone); + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + setOptimizationFlag(QGraphicsView::DontSavePainterState, true); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setContentsMargins(0, 0, 0, 0); + + setScene(new QGraphicsScene(this)); + scene()->setSceneRect(0, -250, 500, 500); + scene()->addItem(m_chartItem); + + connect(&EASY_GLOBALS.events, &profiler_gui::EasyGlobalSignals::sceneSizeChanged, + this, &This::onSceneSizeChanged, Qt::QueuedConnection); + + onSceneSizeChanged(); +} + +EasyGraphicsChart::~EasyGraphicsChart() +{ + +} + +void EasyGraphicsChart::onSceneSizeChanged() +{ + setRange(EASY_GLOBALS.scene_left, EASY_GLOBALS.scene_right); +} + +void EasyGraphicsChart::resizeEvent(QResizeEvent* _event) +{ + auto size = _event->size(); + onWindowSizeChanged(size.width(), size.height()); + scene()->update(); +} + +void EasyGraphicsChart::clear() +{ + m_chartItem->update(Collections {}); +} + +bool EasyGraphicsChart::bindMode() const +{ + return m_bBindMode; +} + +qreal EasyGraphicsChart::xscale() const +{ + return m_xscale; +} + +qreal EasyGraphicsChart::left() const +{ + return m_left; +} + +qreal EasyGraphicsChart::right() const +{ + return m_right; +} + +qreal EasyGraphicsChart::range() const +{ + return m_right - m_left; +} + +qreal EasyGraphicsChart::offset() const +{ + return m_bBindMode ? m_offset : 0; +} + +qreal EasyGraphicsChart::region() const +{ + return m_bBindMode ? m_visibleRegionWidth : range(); +} + +void EasyGraphicsChart::setOffset(qreal _offset) +{ + m_offset = std::min(std::max(m_left, m_offset), m_right - m_visibleRegionWidth); +} + +void EasyGraphicsChart::setRange(qreal _left, qreal _right) +{ + const auto oldRange = range(); + const auto oldOffsetPart = oldRange < 1e-3 ? 0.0 : m_offset / oldRange; + + m_left = _left; + m_right = _right; + + if (m_left > m_right) + std::swap(m_left, m_right); + + const auto sceneRange = range(); + //scene()->setSceneRect(m_left, -(height() >> 1), sceneRange, height()); + //m_chartItem->setBoundingRect(scene()->sceneRect()); + + m_offset = m_left + oldOffsetPart * sceneRange; + m_visibleRegionWidth = std::min(m_visibleRegionWidth, sceneRange); + + //const auto oldXScale = m_xscale; + m_xscale = sceneRange < 1e-3 ? 1.0 : width() / sceneRange; + //scale(m_xscale / oldXScale, 1); + + scene()->update(); +} + +void EasyGraphicsChart::setRegion(qreal _visibleRegionWidth) +{ + m_visibleRegionWidth = std::min(_visibleRegionWidth, range()); + setOffset(m_offset); +} + +void EasyGraphicsChart::onWindowSizeChanged(qreal _width, qreal _height) +{ + //const auto oldXScale = m_xscale; + const auto sceneRange = range(); + + m_xscale = sceneRange < 1e-3 ? 1.0 : _width / sceneRange; + + scene()->setSceneRect(0, -_height * 0.5, _width, _height); + //scene()->setSceneRect(m_left, -_height * 0.5, sceneRange, _height); + m_chartItem->setBoundingRect(scene()->sceneRect()); + //scale(m_xscale / oldXScale, 1); +} + +void EasyGraphicsChart::update(Collections _collections) +{ + m_chartItem->update(std::move(_collections)); + scene()->update(); +} + +void EasyGraphicsChart::update(const ArbitraryValuesCollection* _selected) +{ + m_chartItem->update(_selected); + scene()->update(); +} + +////////////////////////////////////////////////////////////////////////// + +enum class ArbitraryColumns : uint8_t +{ + Name = 0, + Type, + Value, + Vin, + + Count +}; + +EASY_CONSTEXPR auto CheckColumn = int_cast(ArbitraryColumns::Name); +EASY_CONSTEXPR auto StdItemType = QTreeWidgetItem::UserType; +EASY_CONSTEXPR auto ValueItemType = QTreeWidgetItem::UserType + 1; + +struct UsedValueTypes { + EasyArbitraryTreeWidgetItem* items[int_cast(profiler::DataType::TypesCount)]; + UsedValueTypes(int = 0) { memset(items, 0, sizeof(items)); } +}; + +////////////////////////////////////////////////////////////////////////// + +EasyArbitraryTreeWidgetItem::EasyArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, profiler::color_t _color, profiler::vin_t _vin) + : Parent(_parent, ValueItemType) + , m_vin(_vin) + , m_color(_color) + , m_widthHint(0) +{ + setFlags(flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable); + setCheckState(CheckColumn, Qt::Unchecked); +} + +EasyArbitraryTreeWidgetItem::~EasyArbitraryTreeWidgetItem() +{ + +} + +QVariant EasyArbitraryTreeWidgetItem::data(int _column, int _role) const +{ + if (_column == CheckColumn && _role == Qt::SizeHintRole) + return QSize(m_widthHint, 26); + return Parent::data(_column, _role); +} + +void EasyArbitraryTreeWidgetItem::setWidthHint(int _width) +{ + m_widthHint = _width; +} + +const ArbitraryValuesCollection* EasyArbitraryTreeWidgetItem::collection() const +{ + return m_collection.get(); +} + +void EasyArbitraryTreeWidgetItem::collectValues(profiler::thread_id_t _threadId) +{ + if (!m_collection) + m_collection = CollectionPtr(new ArbitraryValuesCollection); + else + m_collection->interrupt(); + + m_collection->collectValues(_threadId, m_vin, text(int_cast(ArbitraryColumns::Name)).toStdString().c_str(), EASY_GLOBALS.begin_time); +} + +void EasyArbitraryTreeWidgetItem::interrupt() +{ + if (!m_collection) + return; + + m_collection->interrupt(); + m_collection.release(); +} + +profiler::color_t EasyArbitraryTreeWidgetItem::color() const +{ + return m_color; +} + +////////////////////////////////////////////////////////////////////////// + +EasyArbitraryValuesWidget::EasyArbitraryValuesWidget(QWidget* _parent) + : Parent(_parent) + , m_treeWidget(new QTreeWidget(this)) + , m_chart(new EasyGraphicsChart(this)) +{ + auto layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_treeWidget); + layout->addWidget(m_chart); + layout->setStretch(0, 1); + layout->setStretch(1, 1); + + m_treeWidget->setAutoFillBackground(false); + m_treeWidget->setAlternatingRowColors(true); + m_treeWidget->setItemsExpandable(true); + m_treeWidget->setAnimated(true); + //m_treeWidget->setSortingEnabled(false); + m_treeWidget->setColumnCount(int_cast(ArbitraryColumns::Count)); + m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_treeWidget->setItemDelegateForColumn(0, new EasyTreeViewFirstColumnItemDelegate(this)); + + auto headerItem = new QTreeWidgetItem(); + headerItem->setText(int_cast(ArbitraryColumns::Type), "Type"); + headerItem->setText(int_cast(ArbitraryColumns::Name), "Name"); + headerItem->setText(int_cast(ArbitraryColumns::Value), "Value"); + headerItem->setText(int_cast(ArbitraryColumns::Vin), "ID"); + m_treeWidget->setHeaderItem(headerItem); + +// auto mainLayout = new QVBoxLayout(this); +// mainLayout->setContentsMargins(1, 1, 1, 1); +// mainLayout->addWidget(m_treeWidget); + + connect(&m_timer, &QTimer::timeout, this, &This::rebuild); + connect(&m_collectionsTimer, &QTimer::timeout, this, &This::onCollectionsTimeout); + + connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &This::onItemDoubleClicked); + connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged); + connect(m_treeWidget, &QTreeWidget::currentItemChanged, this, &This::onCurrentItemChanged); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChanged); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChanged); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged); +} + +EasyArbitraryValuesWidget::~EasyArbitraryValuesWidget() +{ + +} + +void EasyArbitraryValuesWidget::clear() +{ + if (m_collectionsTimer.isActive()) + m_collectionsTimer.stop(); + if (m_timer.isActive()) + m_timer.stop(); + m_checkedItems.clear(); + m_treeWidget->clear(); +} + +void EasyArbitraryValuesWidget::onSelectedThreadChanged(::profiler::thread_id_t) +{ + if (!m_timer.isActive()) + m_timer.start(100); +} + +void EasyArbitraryValuesWidget::onSelectedBlockChanged(uint32_t) +{ + if (!m_timer.isActive()) + m_timer.start(100); +} + +void EasyArbitraryValuesWidget::onSelectedBlockIdChanged(::profiler::block_id_t) +{ + if (!m_timer.isActive()) + m_timer.start(100); +} + +void EasyArbitraryValuesWidget::onItemDoubleClicked(QTreeWidgetItem* _item, int) +{ + if (_item == nullptr || _item->type() != ValueItemType) + return; + + _item->setCheckState(CheckColumn, _item->checkState(CheckColumn) == Qt::Checked ? Qt::Unchecked : Qt::Checked); +} + +void EasyArbitraryValuesWidget::onItemChanged(QTreeWidgetItem* _item, int _column) +{ + if (_item == nullptr || _item->type() != ValueItemType || _column != CheckColumn) + return; + + auto item = static_cast(_item); + + if (item->checkState(CheckColumn) == Qt::Checked) + { + m_checkedItems.push_back(item); + item->collectValues(EASY_GLOBALS.selected_thread); + if (!m_collectionsTimer.isActive()) + m_collectionsTimer.start(100); + } + else + { + m_checkedItems.removeOne(item); + item->interrupt(); + onCollectionsTimeout(); + } +} + +void EasyArbitraryValuesWidget::onCurrentItemChanged(QTreeWidgetItem* _current, QTreeWidgetItem*) +{ + if (_current == nullptr || _current->type() != ValueItemType) + { + m_chart->update(nullptr); + return; + } + + auto item = static_cast(_current); + m_chart->update(item->collection()); +} + +void EasyArbitraryValuesWidget::rebuild() +{ + clear(); + + buildTree(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block, EASY_GLOBALS.selected_block_id); + + m_treeWidget->expandAll(); + for (int i = 0, columns = m_treeWidget->columnCount(); i < columns; ++i) + m_treeWidget->resizeColumnToContents(i); +} + +void EasyArbitraryValuesWidget::onCollectionsTimeout() +{ + if (m_checkedItems.isEmpty()) + { + if (m_collectionsTimer.isActive()) + m_collectionsTimer.stop(); + m_chart->update(Collections {}); + return; + } + + Collections collections; + collections.reserve(m_checkedItems.size()); + for (auto item : m_checkedItems) + { + if (item->collection()->status() != ArbitraryValuesCollection::InProgress) + { + collections.push_back(EasyCollectionPaintData {item->collection(), item->color(), + ChartType::Line, item == m_treeWidget->currentItem()}); + } + } + + if (collections.size() == m_checkedItems.size()) + { + if (m_collectionsTimer.isActive()) + m_collectionsTimer.stop(); + m_chart->update(std::move(collections)); + } +} + +void EasyArbitraryValuesWidget::buildTree(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId) +{ + m_treeWidget->clear(); + m_treeWidget->setColumnHidden(int_cast(ArbitraryColumns::Value), profiler_gui::is_max(_blockIndex)); + + if (_threadId != 0) + { + auto it = EASY_GLOBALS.profiler_blocks.find(_threadId); + if (it != EASY_GLOBALS.profiler_blocks.end()) + { + auto threadItem = buildTreeForThread(it->second, _blockIndex, _blockId); + m_treeWidget->addTopLevelItem(threadItem); + } + } + else + { + for (const auto& it : EASY_GLOBALS.profiler_blocks) + { + auto threadItem = buildTreeForThread(it.second, _blockIndex, _blockId); + m_treeWidget->addTopLevelItem(threadItem); + } + } +} + +QTreeWidgetItem* EasyArbitraryValuesWidget::buildTreeForThread(const profiler::BlocksTreeRoot& _threadRoot, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId) +{ + auto fm = m_treeWidget->fontMetrics(); + + auto rootItem = new QTreeWidgetItem(StdItemType); + rootItem->setText(int_cast(ArbitraryColumns::Type), QStringLiteral("Thread")); + rootItem->setText(int_cast(ArbitraryColumns::Name), + profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _threadRoot, EASY_GLOBALS.hex_thread_id)); + + const bool hasConcreteBlock = !profiler_gui::is_max(_blockIndex); + if (hasConcreteBlock) + { + const auto& block = easyBlocksTree(_blockIndex); + const auto& desc = easyDescriptor(block.node->id()); + if (desc.type() == profiler::BlockType::Value) + { + auto valueItem = new EasyArbitraryTreeWidgetItem(rootItem, desc.color(), block.value->value_id()); + valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*block.value)); + valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name()); + valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(block.value->value_id(), 0, 16)); + valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*block.value)); + + const auto sizeHintWidth = valueItem->sizeHint(CheckColumn).width(); + valueItem->setWidthHint(std::max(sizeHintWidth, fm.width(valueItem->text(CheckColumn))) + 32); + + return rootItem; + } + + _blockId = block.node->id(); + } + + const bool noId = profiler_gui::is_max(_blockId); + QTreeWidgetItem* blockItem = nullptr; + if (!noId) + { + blockItem = new QTreeWidgetItem(rootItem, StdItemType); + blockItem->setText(int_cast(ArbitraryColumns::Type), QStringLiteral("Block")); + if (hasConcreteBlock) + blockItem->setText(int_cast(ArbitraryColumns::Name), easyBlockName(_blockIndex)); + else + blockItem->setText(int_cast(ArbitraryColumns::Name), easyDescriptor(_blockId).name()); + } + + std::unordered_map > blocks; + std::unordered_map > vins; + std::unordered_map names; + + std::vector stack; + for (auto childIndex : _threadRoot.children) + { + stack.push_back(childIndex); + while (!stack.empty()) + { + const auto i = stack.back(); + stack.pop_back(); + + const auto& block = easyBlocksTree(i); + if (noId || block.node->id() == _blockId || easyDescriptor(block.node->id()).id() == _blockId) + { + for (auto c : block.children) + { + if (noId) + stack.push_back(c); + + const auto& child = easyBlocksTree(c); + const auto& desc = easyDescriptor(child.node->id()); + if (desc.type() != profiler::BlockType::Value) + continue; + + if (blockItem == nullptr) + { + const auto id = block.node->id(); + auto it = blocks.find(id); + if (it != blocks.end()) + { + blockItem = it->second; + } + else + { + blockItem = new QTreeWidgetItem(rootItem, StdItemType); + blockItem->setText(int_cast(ArbitraryColumns::Type), QStringLiteral("Block")); + blockItem->setText(int_cast(ArbitraryColumns::Name), easyBlockName(block)); + blocks.emplace(id, blockItem); + } + } + + const auto typeIndex = int_cast(child.value->type()); + auto vin = child.value->value_id(); + + EasyArbitraryTreeWidgetItem** usedItems = nullptr; + EasyArbitraryTreeWidgetItem* valueItem = nullptr; + if (vin == 0) + { + auto result = names.emplace(desc.name(), 0); + usedItems = result.first->second.items; + if (!result.second && (valueItem = *(usedItems + typeIndex))) + { + if (i == _blockIndex) + valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value)); + continue; // already in set + } + } + else + { + auto result = vins.emplace(vin, 0); + usedItems = result.first->second.items; + if (!result.second && (valueItem = *(usedItems + typeIndex))) + { + if (i == _blockIndex) + valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value)); + continue; // already in set + } + } + + valueItem = new EasyArbitraryTreeWidgetItem(blockItem, desc.color(), vin); + valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*child.value)); + valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name()); + valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(vin, 0, 16)); + + if (i == _blockIndex) + valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*child.value)); + + const auto sizeHintWidth = valueItem->sizeHint(CheckColumn).width(); + valueItem->setWidthHint(std::max(sizeHintWidth, fm.width(valueItem->text(CheckColumn))) + 32); + + *(usedItems + typeIndex) = valueItem; + } + + if (noId) + blockItem = nullptr; + } + else + { + for (auto c : block.children) + stack.push_back(c); + } + } + } + + return rootItem; +} + diff --git a/3rdparty/easyprofiler/profiler_gui/arbitrary_value_inspector.h b/3rdparty/easyprofiler/profiler_gui/arbitrary_value_inspector.h new file mode 100644 index 0000000..01779d4 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/arbitrary_value_inspector.h @@ -0,0 +1,299 @@ +/************************************************************************ +* file name : arbitrary_value_inspector.h +* ----------------- : +* creation time : 2017/11/30 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of . +* ----------------- : +* change log : * 2017/11/30 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER_GUI_ARBITRARY_VALUE_INSPECTOR_H +#define EASY_PROFILER_GUI_ARBITRARY_VALUE_INSPECTOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// + +using Points = std::vector; +using ArbitraryValues = std::vector; +using ArbitraryValuesMap = std::unordered_map >; + +class ArbitraryValuesCollection EASY_FINAL +{ +public: + + enum JobStatus : uint8_t { Idle = 0, Ready, InProgress }; + enum JobType : uint8_t { None = 0, ValuesJob = 1 << 0, PointsJob = 1 << 1 }; + +private: + + using This = ArbitraryValuesCollection; + + ArbitraryValuesMap m_values; + Points m_points; + std::thread m_collectorThread; + profiler::timestamp_t m_beginTime; + qreal m_minValue; + qreal m_maxValue; + std::atomic m_status; + std::atomic_bool m_bInterrupt; + uint8_t m_jobType; + +public: + + explicit ArbitraryValuesCollection(); + ~ArbitraryValuesCollection(); + + const ArbitraryValuesMap& valuesMap() const; + const Points& points() const; + JobStatus status() const; + size_t size() const; + + qreal minValue() const; + qreal maxValue() const; + + void collectValues(profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName); + void collectValues(profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName, profiler::timestamp_t _beginTime); + bool calculatePoints(profiler::timestamp_t _beginTime); + void interrupt(); + +private: + + void setStatus(JobStatus _status); + void collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId); + void collectByName(profiler::thread_id_t _threadId, const std::string _valueName); + bool collectByIdForThread(const profiler::BlocksTreeRoot& _threadRoot, profiler::vin_t _valueId, bool _calculatePoints); + bool collectByNameForThread(const profiler::BlocksTreeRoot& _threadRoot, const std::string& _valueName, bool _calculatePoints); + + QPointF point(const profiler::ArbitraryValue& _value) const; + +}; // end of class ArbitraryValuesCollection. + +enum class ChartType : uint8_t +{ + Line = 0, + Points +}; + +struct EasyCollectionPaintData EASY_FINAL +{ + const ArbitraryValuesCollection* ptr; + QRgb color; + ChartType chartType; + bool selected; +}; + +using Collections = std::vector; + +////////////////////////////////////////////////////////////////////////// + +class EasyArbitraryValuesChartItem : public QGraphicsItem +{ + using Parent = QGraphicsItem; + using This = EasyArbitraryValuesChartItem; + + Collections m_collections; + QRectF m_boundingRect; + +public: + + explicit EasyArbitraryValuesChartItem(); + ~EasyArbitraryValuesChartItem() override; + + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; + + QRectF boundingRect() const override; + void setBoundingRect(const QRectF& _rect); + void setBoundingRect(qreal _left, qreal _top, qreal _width, qreal _height); + + void update(Collections _collections); + void update(const ArbitraryValuesCollection* _selected); + +}; // end of class EasyArbitraryValuesChartItem. + +class EasyGraphicsChart : public QGraphicsView +{ + Q_OBJECT + +private: + + using Parent = QGraphicsView; + using This = EasyGraphicsChart; + + EasyArbitraryValuesChartItem* m_chartItem; + qreal m_left; + qreal m_right; + qreal m_offset; + qreal m_xscale; + qreal m_visibleRegionWidth; + bool m_bBindMode; + +public: + + explicit EasyGraphicsChart(QWidget* _parent = nullptr); + ~EasyGraphicsChart() override; + + void resizeEvent(QResizeEvent* _event) override; + + void clear(); + + bool bindMode() const; + qreal xscale() const; + + qreal left() const; + qreal right() const; + qreal range() const; + qreal offset() const; + qreal region() const; + + void setOffset(qreal _offset); + void setRange(qreal _left, qreal _right); + void setRegion(qreal _visibleRegionWidth); + + void update(Collections _collections); + void update(const ArbitraryValuesCollection* _selected); + +private slots: + + void onSceneSizeChanged(); + void onWindowSizeChanged(qreal _width, qreal _height); + +}; // end of class EasyGraphicsChart. + +////////////////////////////////////////////////////////////////////////// + +class EasyArbitraryTreeWidgetItem : public QTreeWidgetItem +{ + using Parent = QTreeWidgetItem; + using This = EasyArbitraryTreeWidgetItem; + using CollectionPtr = std::unique_ptr; + + CollectionPtr m_collection; + profiler::vin_t m_vin; + profiler::color_t m_color; + int m_widthHint; + +public: + + explicit EasyArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, profiler::color_t _color, profiler::vin_t _vin = 0); + ~EasyArbitraryTreeWidgetItem() override; + + QVariant data(int _column, int _role) const override; + + void setWidthHint(int _width); + + const ArbitraryValuesCollection* collection() const; + void collectValues(profiler::thread_id_t _threadId); + void interrupt(); + + profiler::color_t color() const; + +}; // end of class EasyArbitraryTreeWidgetItem. + +////////////////////////////////////////////////////////////////////////// + +class EasyArbitraryValuesWidget : public QWidget +{ + Q_OBJECT + + using Parent = QWidget; + using This = EasyArbitraryValuesWidget; + + QTimer m_timer; + QTimer m_collectionsTimer; + QList m_checkedItems; + QTreeWidget* m_treeWidget; + EasyGraphicsChart* m_chart; + +public: + + explicit EasyArbitraryValuesWidget(QWidget* _parent = nullptr); + ~EasyArbitraryValuesWidget() override; + + void clear(); + +public slots: + + void rebuild(); + +private slots: + + void onSelectedThreadChanged(profiler::thread_id_t _id); + void onSelectedBlockChanged(uint32_t _block_index); + void onSelectedBlockIdChanged(profiler::block_id_t _id); + void onItemDoubleClicked(QTreeWidgetItem* _item, int _column); + void onItemChanged(QTreeWidgetItem* _item, int _column); + void onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*); + void onCollectionsTimeout(); + +private: + + void buildTree(profiler::thread_id_t _threadId, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId); + QTreeWidgetItem* buildTreeForThread(const profiler::BlocksTreeRoot& _threadRoot, profiler::block_index_t _blockIndex, profiler::block_id_t _blockId); + +}; // end of class EasyArbitraryValuesWidget. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_GUI_ARBITRARY_VALUE_INSPECTOR_H diff --git a/3rdparty/easyprofiler/profiler_gui/blocks_graphics_view.cpp b/3rdparty/easyprofiler/profiler_gui/blocks_graphics_view.cpp new file mode 100644 index 0000000..1639bac --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/blocks_graphics_view.cpp @@ -0,0 +1,2509 @@ +/************************************************************************ +* file name : blocks_graphics_view.cpp +* ----------------- : +* creation time : 2016/06/26 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of GraphicsScene and GraphicsView and +* : it's auxiliary classes for displyaing easy_profiler blocks tree. +* ----------------- : +* change log : * 2016/06/26 Victor Zarubkin: Moved sources from graphics_view.h +* : and renamed classes from My* to Prof*. +* : +* : * 2016/06/27 Victor Zarubkin: Added text shifting relatively to it's parent item. +* : Disabled border lines painting because of vertical lines painting bug. +* : Changed height of blocks. Variable thread-block height. +* : +* : * 2016/06/29 Victor Zarubkin: Highly optimized painting performance and memory consumption. +* : +* : * 2016/06/30 Victor Zarubkin: Replaced doubles with floats (in ProfBlockItem) for less memory consumption. +* : +* : * 2016/09/15 Victor Zarubkin: Moved sources of EasyGraphicsItem and EasyChronometerItem to separate files. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "blocks_graphics_view.h" +#include "easy_graphics_item.h" +#include "easy_chronometer_item.h" +#include "easy_graphics_scrollbar.h" +#include "globals.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +const qreal MIN_SCALE = pow(::profiler_gui::SCALING_COEFFICIENT_INV, 70); // Up to 1000 sec scale +const qreal MAX_SCALE = pow(::profiler_gui::SCALING_COEFFICIENT, 45); // ~23000 --- Up to 10 ns scale +const qreal BASE_SCALE = pow(::profiler_gui::SCALING_COEFFICIENT_INV, 25); // ~0.003 + +EASY_CONSTEXPR uint16_t TIMELINE_ROW_SIZE = 24; + +EASY_CONSTEXPR QRgb BACKGROUND_1 = 0xffe4e4ec; +EASY_CONSTEXPR QRgb BACKGROUND_2 = ::profiler::colors::White; +EASY_CONSTEXPR QRgb TIMELINE_BACKGROUND = 0x20000000 | (::profiler::colors::Grey800 & 0x00ffffff);// 0x20303030; +EASY_CONSTEXPR QRgb TIMELINE_BORDER = 0xffa8a0a0; + +EASY_CONSTEXPR int IDLE_TIMER_INTERVAL = 200; // 5Hz +EASY_CONSTEXPR uint64_t IDLE_TIME = 400; + +EASY_CONSTEXPR int FLICKER_INTERVAL = 10; // 100Hz +EASY_CONSTEXPR qreal FLICKER_FACTOR = 16.0 / FLICKER_INTERVAL; + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +using estd::clamp; + +////////////////////////////////////////////////////////////////////////// + +EasyBoldLabel::EasyBoldLabel(const QString& _text, QWidget* _parent) : QLabel(_text, _parent) +{ + auto f = font(); + f.setBold(true); + setFont(f); +} + +EasyBoldLabel::~EasyBoldLabel() +{ + +} + +////////////////////////////////////////////////////////////////////////// + +void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + auto const sceneView = static_cast(scene()->parent()); + const auto visibleSceneRect = sceneView->visibleSceneRect(); + const auto currentScale = sceneView->scale(); + const auto offset = sceneView->offset(); + const auto left = offset * currentScale; + const auto h = visibleSceneRect.height(); + const auto visibleBottom = h - 1; + const auto borderColor = QColor::fromRgb(TIMELINE_BORDER); + const auto textShiftY = h + TIMELINE_ROW_SIZE - 5; + + QRectF rect; + + _painter->save(); + _painter->setTransform(QTransform::fromTranslate(-x(), -y())); + + const auto& items = sceneView->getItems(); + if (!items.empty()) + { + static const uint16_t OVERLAP = ::profiler_gui::THREADS_ROW_SPACING >> 1; + static const QBrush brushes[2] = {QColor::fromRgb(BACKGROUND_1), QColor::fromRgb(BACKGROUND_2)}; + int i = -1; + + // Draw background + _painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + for (auto item : items) + { + ++i; + + auto br = item->boundingRect(); + auto top = item->y() + br.top() - visibleSceneRect.top(); + auto bottom = top + br.height(); + + if (top > h || bottom < 0) + continue; + + if (item->threadId() == EASY_GLOBALS.selected_thread) + _painter->setBrush(QBrush(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_BACKGROUND))); + else + _painter->setBrush(brushes[i & 1]); + + rect.setRect(0, top - OVERLAP, visibleSceneRect.width(), br.height() + ::profiler_gui::THREADS_ROW_SPACING); + const auto dh = rect.bottom() - visibleBottom; + if (dh > 0) + rect.setHeight(rect.height() - dh); + + if (rect.top() < 0) + rect.setTop(0); + + _painter->drawRect(rect); + } + } + + // Draw timeline scale marks ---------------- + _painter->setBrush(QColor::fromRgba(TIMELINE_BACKGROUND)); + + const auto sceneStep = sceneView->timelineStep(); + const auto factor = ::profiler_gui::timeFactor(sceneStep); + const auto step = sceneStep * currentScale; + auto first = static_cast(offset / sceneStep); + const int odd = first & 1; + const auto nsteps = (1 + odd) * 2 + static_cast(visibleSceneRect.width() / step); + first -= odd; + + QPen pen(borderColor); + pen.setWidth(2); + _painter->setPen(pen); + _painter->drawLine(QPointF(0, h), QPointF(visibleSceneRect.width(), h)); + _painter->setPen(borderColor); + + QLineF marks[20]; + qreal first_x = first * sceneStep; + const auto textWidth = QFontMetricsF(_painter->font(), sceneView).width(QString::number(static_cast(0.5 + first_x * factor))) * ::profiler_gui::FONT_METRICS_FACTOR + 10; + const int n = 1 + static_cast(textWidth / step); + int next = first % n; + if (next) + next = n - next; + + first_x *= currentScale; + for (int i = 0; i < nsteps; ++i, --next) + { + auto current = first_x - left + step * i; + + if ((i & 1) == 0) + { + rect.setRect(current, 0, step, h); + _painter->drawRect(rect); + + for (int j = 0; j < 20; ++j) + { + auto xmark = current + j * step * 0.1; + marks[j].setLine(xmark, h, xmark, h + ((j % 5) ? 4 : 8)); + } + + _painter->drawLines(marks, 20); + } + + if (next <= 0) + { + next = n; + _painter->setPen(::profiler_gui::TEXT_COLOR); + _painter->drawText(QPointF(current + 1, textShiftY), + QString::number(static_cast(0.5 + (current + left) * factor / currentScale))); + _painter->setPen(borderColor); + } + + // TEST + // this is for testing (order of lines will be painted): + //_painter->setPen(Qt::black); + //_painter->drawText(QPointF(current + step * 0.4, h - 20), QString::number(i)); + //_painter->setPen(Qt::gray); + // TEST + } + // END Draw timeline scale marks ~~~~~~~~~~~~ + + _painter->restore(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTimelineIndicatorItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + const auto sceneView = static_cast(scene()->parent()); + const auto visibleSceneRect = sceneView->visibleSceneRect(); + const auto step = sceneView->timelineStep() * sceneView->scale(); + const QString text = ::profiler_gui::autoTimeStringInt(units2microseconds(sceneView->timelineStep())); // Displayed text + + // Draw scale indicator + _painter->save(); + _painter->setTransform(QTransform::fromTranslate(-x(), -y())); + //_painter->setCompositionMode(QPainter::CompositionMode_Difference); + _painter->setBrush(Qt::NoBrush); + + QPen pen(Qt::black); + pen.setWidth(3); + _painter->setPen(pen); + + _painter->drawLine(QLineF(visibleSceneRect.width() - 9 - step, visibleSceneRect.height() - 10, visibleSceneRect.width() - 11, visibleSceneRect.height() - 10)); + + _painter->setPen(Qt::black); + _painter->drawLine(QLineF(visibleSceneRect.width() - 10 - step, visibleSceneRect.height() - 6, visibleSceneRect.width() - 10 - step, visibleSceneRect.height() - 14)); + _painter->drawLine(QLineF(visibleSceneRect.width() - 10, visibleSceneRect.height() - 6, visibleSceneRect.width() - 10, visibleSceneRect.height() - 14)); + + _painter->setPen(Qt::black); + _painter->setFont(EASY_GLOBALS.bg_font); + _painter->drawText(QRectF(visibleSceneRect.width() - 10 - step, visibleSceneRect.height() - 63, step, 50), Qt::AlignRight | Qt::AlignBottom | Qt::TextDontClip, text); + + _painter->restore(); +} + +////////////////////////////////////////////////////////////////////////// + +EasyGraphicsView::EasyGraphicsView(QWidget* _parent) + : Parent(_parent) + , m_beginTime(::std::numeric_limits::max()) + , m_sceneWidth(0) + , m_scale(1) + , m_offset(0) + , m_timelineStep(0) + , m_idleTime(0) + , m_mouseButtons(Qt::NoButton) + , m_pScrollbar(nullptr) + , m_chronometerItem(nullptr) + , m_chronometerItemAux(nullptr) + , m_popupWidget(nullptr) + , m_flickerSpeedX(0) + , m_flickerSpeedY(0) + , m_flickerCounterX(0) + , m_flickerCounterY(0) + , m_bDoubleClick(false) + , m_bUpdatingRect(false) + , m_bEmpty(true) +{ + initMode(); + setScene(new QGraphicsScene(this)); + updateVisibleSceneRect(); +} + +EasyGraphicsView::~EasyGraphicsView() +{ +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::removePopup(bool _removeFromScene) +{ + if (m_popupWidget != nullptr) + { + auto widget = m_popupWidget->widget(); + widget->setParent(nullptr); + m_popupWidget->setWidget(nullptr); + delete widget; + + if (_removeFromScene) + scene()->removeItem(m_popupWidget); + + m_popupWidget = nullptr; + } +} + +////////////////////////////////////////////////////////////////////////// + +qreal EasyGraphicsView::sceneWidth() const +{ + return m_sceneWidth; +} + +qreal EasyGraphicsView::chronoTime() const +{ + return m_chronometerItem->width(); +} + +qreal EasyGraphicsView::chronoTimeAux() const +{ + return m_chronometerItemAux->width(); +} + +////////////////////////////////////////////////////////////////////////// + +EasyChronometerItem* EasyGraphicsView::createChronometer(bool _main) +{ + auto chronoItem = new EasyChronometerItem(_main); + chronoItem->setColor(_main ? ::profiler_gui::CHRONOMETER_COLOR : ::profiler_gui::CHRONOMETER_COLOR2); + chronoItem->setBoundingRect(sceneRect()); + chronoItem->hide(); + scene()->addItem(chronoItem); + + return chronoItem; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::clear() +{ + const QSignalBlocker blocker(this), sceneBlocker(scene()); // block all scene signals (otherwise clear() would be extremely slow!) + + // Stop flicking + m_flickerTimer.stop(); + m_flickerSpeedX = 0; + m_flickerSpeedY = 0; + m_flickerCounterX = 0; + m_flickerCounterY = 0; + + // Clear all items + removePopup(); + scene()->clear(); + m_items.clear(); + m_selectedBlocks.clear(); + + m_beginTime = ::std::numeric_limits::max(); // reset begin time + m_scale = 1; // scale back to initial 100% scale + m_timelineStep = 1; + m_offset = 0; // scroll back to the beginning of the scene + + m_idleTimer.stop(); + m_idleTime = 0; + + // Reset necessary flags + m_bEmpty = true; + + m_sceneWidth = 10; + setSceneRect(0, 0, 10, 10); + + // notify ProfTreeWidget that selection was reset + emit intervalChanged(m_selectedBlocks, m_beginTime, 0, 0, false); +} + +void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTree) +{ + // clear scene + clear(); + + if (_blocksTree.empty()) + { + return; + } + + auto bgItem = new EasyBackgroundItem(); + scene()->addItem(bgItem); + + // set new blocks tree + // calculate scene size and fill it with items + + // Calculating start and end time + ::profiler::timestamp_t finish = 0, busyTime = 0; + ::profiler::thread_id_t longestTree = 0, mainTree = 0; + for (const auto& threadTree : _blocksTree) + { + const auto& t = threadTree.second; + + auto timestart = m_beginTime; + auto timefinish = finish; + + if (!t.children.empty()) + timestart = easyBlocksTree(t.children.front()).node->begin(); + if (!t.sync.empty()) + timestart = ::std::min(timestart, easyBlocksTree(t.sync.front()).node->begin()); + + if (!t.children.empty()) + timefinish = easyBlocksTree(t.children.back()).node->end(); + if (!t.sync.empty()) + timefinish = ::std::max(timefinish, easyBlocksTree(t.sync.back()).node->end()); + + if (m_beginTime > timestart) + m_beginTime = timestart; + + if (finish < timefinish) + finish = timefinish; + + if (t.profiled_time > busyTime) { + busyTime = t.profiled_time; + longestTree = threadTree.first; + } + + if (mainTree == 0 && strcmp(t.name(), "Main") == 0) + mainTree = threadTree.first; + } + + const decltype(m_beginTime) additional_offset = (finish - m_beginTime) / 20; // Additional 5% before first block and after last block + finish += additional_offset; + m_beginTime -= ::std::min(m_beginTime, additional_offset); + EASY_GLOBALS.begin_time = m_beginTime; + + // Sort threads by name + ::std::vector<::std::reference_wrapper > sorted_roots; + sorted_roots.reserve(_blocksTree.size()); + for (const auto& threadTree : _blocksTree) + sorted_roots.push_back(threadTree.second); + ::std::sort(sorted_roots.begin(), sorted_roots.end(), [](const ::profiler::BlocksTreeRoot& _a, const ::profiler::BlocksTreeRoot& _b) { + return _a.thread_name < _b.thread_name; + }); + + // Filling scene with items + m_items.reserve(_blocksTree.size()); + qreal y = TIMELINE_ROW_SIZE; + const EasyGraphicsItem *longestItem = nullptr, *mainThreadItem = nullptr; + for (const ::profiler::BlocksTreeRoot& t : sorted_roots) + { + if (m_items.size() == 0xff) + { + qWarning() << "Warning: Maximum threads number (255 threads) exceeded! See EasyGraphicsView::setTree() : " << __LINE__ << " in file " << __FILE__; + break; + } + + // fill scene with new items + qreal h = 0, x = 0; + + if (!t.children.empty()) + x = time2position(easyBlocksTree(t.children.front()).node->begin()); + else if (!t.sync.empty()) + x = time2position(easyBlocksTree(t.sync.front()).node->begin()); + + auto item = new EasyGraphicsItem(static_cast(m_items.size()), t); + if (t.depth) + item->setLevels(t.depth); + item->setPos(0, y); + + qreal children_duration = 0; + + if (!t.children.empty()) + { + uint32_t dummy = 0; + children_duration = setTree(item, t.children, h, dummy, y, 0); + } + else + { + if (!t.sync.empty()) + children_duration = time2position(easyBlocksTree(t.sync.back()).node->end()) - x; + h = ::profiler_gui::GRAPHICS_ROW_SIZE; + } + + item->setBoundingRect(0, 0, children_duration + x, h); + m_items.push_back(item); + scene()->addItem(item); + + y += h + ::profiler_gui::THREADS_ROW_SPACING; + + if (longestTree == t.thread_id) + longestItem = item; + + if (mainTree == t.thread_id) + mainThreadItem = item; + } + + // Calculating scene rect + m_sceneWidth = time2position(finish); + setSceneRect(0, 0, m_sceneWidth, y + TIMELINE_ROW_SIZE); + + EASY_GLOBALS.scene_left = 0; + EASY_GLOBALS.scene_right = m_sceneWidth; + emit EASY_GLOBALS.events.sceneSizeChanged(); + + // Center view on the beginning of the scene + updateVisibleSceneRect(); + setScrollbar(m_pScrollbar); + + // Create new chronometer item (previous item was destroyed by scene on scene()->clear()). + // It will be shown on mouse right button click. + m_chronometerItemAux = createChronometer(false); + m_chronometerItem = createChronometer(true); + + bgItem->setBoundingRect(0, 0, m_sceneWidth, y); + auto indicator = new EasyTimelineIndicatorItem(); + indicator->setBoundingRect(0, 0, m_sceneWidth, y); + scene()->addItem(indicator); + + // Setting flags + m_bEmpty = false; + + scaleTo(BASE_SCALE); + + + emit treeChanged(); + + if (mainThreadItem != nullptr) + { + longestItem = mainThreadItem; + } + + if (longestItem != nullptr) + { + EASY_GLOBALS.selected_thread = longestItem->threadId(); + emit EASY_GLOBALS.events.selectedThreadChanged(longestItem->threadId()); + + scrollTo(longestItem); + m_pScrollbar->setHistogramSource(longestItem->threadId(), longestItem->items(0)); + if (!longestItem->items(0).empty()) + m_pScrollbar->setValue(longestItem->items(0).front().left() - m_pScrollbar->sliderWidth() * 0.25); + } + + m_idleTimer.start(IDLE_TIMER_INTERVAL); +} + +const EasyGraphicsView::Items &EasyGraphicsView::getItems() const +{ + return m_items; +} + +qreal EasyGraphicsView::setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, uint32_t& _maxDepthChild, qreal _y, short _level) +{ + if (_children.empty()) + { + return 0; + } + + const auto level = static_cast(_level); + const auto n = static_cast(_children.size()); + _item->reserve(level, n); + + _maxDepthChild = 0; + uint8_t maxDepth = 0; + const short next_level = _level + 1; + bool warned = false; + qreal total_duration = 0, prev_end = 0, maxh = 0; + qreal start_time = -1; + uint32_t j = 0; + for (auto child_index : _children) + { + auto& gui_block = easyBlock(child_index); + const auto& child = gui_block.tree; + if (child.depth > maxDepth) + { + maxDepth = child.depth; + _maxDepthChild = j; + } + + auto xbegin = time2position(child.node->begin()); + if (start_time < 0) + { + start_time = xbegin; + } + + auto duration = time2position(child.node->end()) - xbegin; + + //const auto dt = xbegin - prev_end; + //if (dt < 0) + //{ + // duration += dt; + // xbegin -= dt; + //} + + //static const qreal MIN_DURATION = 0.25; + //if (duration < MIN_DURATION) + // duration = MIN_DURATION; + + const auto i = _item->addItem(level); + auto& b = _item->getItem(level, i); + + gui_block.graphics_item = _item->index(); + gui_block.graphics_item_level = level; + gui_block.graphics_item_index = i; + + if (next_level < 256 && next_level < _item->levels() && !child.children.empty()) + { + b.children_begin = static_cast(_item->items(static_cast(next_level)).size()); + } + else + { + ::profiler_gui::set_max(b.children_begin); + } + + qreal h = 0; + qreal children_duration = 0; + uint32_t maxDepthChild = 0; + + if (next_level < 256) + { + children_duration = setTree(_item, child.children, h, maxDepthChild, _y + ::profiler_gui::GRAPHICS_ROW_SIZE_FULL, next_level); + } + else if (!child.children.empty() && !warned) + { + warned = true; + qWarning() << "Warning: Maximum blocks depth (255) exceeded! See EasyGraphicsView::setTree() : " << __LINE__ << " in file " << __FILE__; + } + + if (duration < children_duration) + { + duration = children_duration; + } + + if (h > maxh) + { + maxh = h; + } + + b.block = child_index;// &child; + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + b.neighbours = n; + b.state = j > 0 || level == 0 ? 0 : -1; +#else + b.max_depth_child = maxDepthChild; +#endif + + b.setPos(xbegin, duration); + //b.totalHeight = ::profiler_gui::GRAPHICS_ROW_SIZE + h; + + prev_end = xbegin + duration; + total_duration = prev_end - start_time; + + ++j; + } + + _height += ::profiler_gui::GRAPHICS_ROW_SIZE_FULL + maxh; + + return total_duration; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::setScrollbar(EasyGraphicsScrollbar* _scrollbar) +{ + auto const prevScrollbar = m_pScrollbar; + const bool makeConnect = prevScrollbar == nullptr || prevScrollbar != _scrollbar; + + if (prevScrollbar != nullptr && prevScrollbar != _scrollbar) + { + disconnect(prevScrollbar, &EasyGraphicsScrollbar::valueChanged, this, &This::onGraphicsScrollbarValueChange); + disconnect(prevScrollbar, &EasyGraphicsScrollbar::wheeled, this, &This::onGraphicsScrollbarWheel); + } + + m_pScrollbar = _scrollbar; + m_pScrollbar->clear(); + m_pScrollbar->setRange(0, m_sceneWidth); + + auto vbar = verticalScrollBar(); + const int vbar_width = (vbar != nullptr && vbar->isVisible() ? vbar->width() + 2 : 0); + m_pScrollbar->setSliderWidth(m_visibleSceneRect.width() + vbar_width); + + if (makeConnect) + { + connect(m_pScrollbar, &EasyGraphicsScrollbar::valueChanged, this, &This::onGraphicsScrollbarValueChange); + connect(m_pScrollbar, &EasyGraphicsScrollbar::wheeled, this, &This::onGraphicsScrollbarWheel); + } + + EASY_GLOBALS.selected_thread = 0; + emit EASY_GLOBALS.events.selectedThreadChanged(0); +} + +////////////////////////////////////////////////////////////////////////// + +int EasyGraphicsView::updateVisibleSceneRect() +{ + m_visibleSceneRect = mapToScene(rect()).boundingRect(); + + auto vbar = verticalScrollBar(); + int vbar_width = 0; + if (vbar != nullptr && vbar->isVisible()) + vbar_width = vbar->width() + 2; + + m_visibleSceneRect.setWidth(m_visibleSceneRect.width() - vbar_width); + m_visibleSceneRect.setHeight(m_visibleSceneRect.height() - TIMELINE_ROW_SIZE); + + return vbar_width; +} + +void EasyGraphicsView::updateTimelineStep(qreal _windowWidth) +{ + const auto time = units2microseconds(_windowWidth); + if (time < 100) + m_timelineStep = 1e-2; + else if (time < 10e3) + m_timelineStep = 1; + else if (time < 10e6) + m_timelineStep = 1e3; + else + m_timelineStep = 1e6; + + const auto optimal_steps = static_cast(40 * m_visibleSceneRect.width() / 1500); + auto steps = time / m_timelineStep; + while (steps > optimal_steps) { + m_timelineStep *= 10; + steps *= 0.1; + } + + m_timelineStep = microseconds2units(m_timelineStep); +} + +void EasyGraphicsView::repaintScene() +{ + scene()->update(m_visibleSceneRect); + emit sceneUpdated(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::scaleTo(qreal _scale) +{ + if (m_bEmpty) + { + return; + } + + // have to limit scale because of Qt's QPainter feature: it doesn't draw text + // with very big coordinates (but it draw rectangles with the same coordinates good). + m_scale = clamp(MIN_SCALE, _scale, MAX_SCALE); + const int vbar_width = updateVisibleSceneRect(); + + // Update slider width for scrollbar + const auto windowWidth = (m_visibleSceneRect.width() + vbar_width) / m_scale; + m_pScrollbar->setSliderWidth(windowWidth); + + updateTimelineStep(windowWidth); + repaintScene(); +} + +void EasyGraphicsView::wheelEvent(QWheelEvent* _event) +{ + m_idleTime = 0; + + if (!m_bEmpty) + onWheel(mapToScene(_event->pos()).x(), _event->delta()); + _event->accept(); +} + +void EasyGraphicsView::onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta) +{ + m_idleTime = 0; + + for (auto item : m_items) + { + if (item->threadId() == EASY_GLOBALS.selected_thread) + { + scrollTo(item); + break; + } + } + + onWheel(_mouseX, _wheelDelta); +} + +void EasyGraphicsView::scrollTo(const EasyGraphicsItem* _item) +{ + m_bUpdatingRect = true; + auto vbar = verticalScrollBar(); + vbar->setValue(_item->y() + (_item->boundingRect().height() - vbar->pageStep()) * 0.5); + m_bUpdatingRect = false; +} + +void EasyGraphicsView::onWheel(qreal _mouseX, int _wheelDelta) +{ + const decltype(m_scale) scaleCoeff = _wheelDelta > 0 ? ::profiler_gui::SCALING_COEFFICIENT : ::profiler_gui::SCALING_COEFFICIENT_INV; + + // Remember current mouse position + _mouseX = clamp(0., _mouseX, m_sceneWidth); + const auto mousePosition = m_offset + _mouseX / m_scale; + + // have to limit scale because of Qt's QPainter feature: it doesn't draw text + // with very big coordinates (but it draw rectangles with the same coordinates good). + m_scale = clamp(MIN_SCALE, m_scale * scaleCoeff, MAX_SCALE); + + //updateVisibleSceneRect(); // Update scene rect + + // Update slider width for scrollbar + auto vbar = verticalScrollBar(); + const int vbar_width = (vbar != nullptr && vbar->isVisible() ? vbar->width() + 2 : 0); + const auto windowWidth = (m_visibleSceneRect.width() + vbar_width) / m_scale; + m_pScrollbar->setSliderWidth(windowWidth); + + // Calculate new offset to simulate QGraphicsView::AnchorUnderMouse scaling behavior + m_offset = clamp(0., mousePosition - _mouseX / m_scale, m_sceneWidth - windowWidth); + + // Update slider position + m_bUpdatingRect = true; // To be sure that updateVisibleSceneRect will not be called by scrollbar change + m_pScrollbar->setValue(m_offset); + m_bUpdatingRect = false; + + updateVisibleSceneRect(); // Update scene rect + updateTimelineStep(windowWidth); + repaintScene(); // repaint scene +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::mousePressEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + if (m_bEmpty) + { + _event->accept(); + return; + } + + m_mouseButtons = _event->buttons(); + m_mousePressPos = _event->pos(); + + if (m_mouseButtons & Qt::LeftButton) + { + if (m_chronometerItemAux->isVisible() && (m_chronometerItemAux->hoverLeft() || m_chronometerItemAux->hoverRight())) + { + m_chronometerItemAux->setReverse(m_chronometerItemAux->hoverLeft()); + m_bDoubleClick = true; + } + else if (m_chronometerItem->isVisible() && (m_chronometerItem->hoverLeft() || m_chronometerItem->hoverRight())) + { + m_chronometerItem->setReverse(m_chronometerItem->hoverLeft()); + m_mouseButtons = Qt::RightButton; + return; + } + } + + if (m_mouseButtons & Qt::RightButton) + { + if (m_chronometerItem->isVisible() && (m_chronometerItem->hoverLeft() || m_chronometerItem->hoverRight())) + { + m_chronometerItem->setReverse(m_chronometerItem->hoverLeft()); + } + else + { + const auto mouseX = m_offset + mapToScene(m_mousePressPos).x() / m_scale; + m_chronometerItem->setLeftRight(mouseX, mouseX); + m_chronometerItem->hide(); + m_pScrollbar->hideChrono(); + } + } + + _event->accept(); +} + +void EasyGraphicsView::mouseDoubleClickEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + if (m_bEmpty) + { + _event->accept(); + return; + } + + m_mouseButtons = _event->buttons(); + m_mousePressPos = _event->pos(); + m_bDoubleClick = true; + + if (m_mouseButtons & Qt::LeftButton) + { + const auto mouseX = m_offset + mapToScene(m_mousePressPos).x() / m_scale; + m_chronometerItemAux->setLeftRight(mouseX, mouseX); + m_chronometerItemAux->hide(); + emit sceneUpdated(); + } + + _event->accept(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + if (m_bEmpty) + { + _event->accept(); + return; + } + + bool chronoHidden = false; + bool changedSelection = false, changedSelectedItem = false; + if (m_mouseButtons & Qt::RightButton) + { + if (m_chronometerItem->isVisible() && m_chronometerItem->width() < 1e-6) + { + m_chronometerItem->hide(); + m_pScrollbar->hideChrono(); + } + + if (!m_selectedBlocks.empty()) + { + changedSelection = true; + m_selectedBlocks.clear(); + } + + if (m_chronometerItem->isVisible()) + { + //printf("INTERVAL: {%lf, %lf} ms\n", m_chronometerItem->left(), m_chronometerItem->right()); + + for (auto item : m_items) + { + if (!EASY_GLOBALS.only_current_thread_hierarchy || item->threadId() == EASY_GLOBALS.selected_thread) + item->getBlocks(m_chronometerItem->left(), m_chronometerItem->right(), m_selectedBlocks); + } + + if (!m_selectedBlocks.empty()) + { + changedSelection = true; + } + } + } + + const ::profiler_gui::EasyBlock* selectedBlock = nullptr; + ::profiler::thread_id_t selectedBlockThread = 0; + const auto previouslySelectedBlock = EASY_GLOBALS.selected_block; + if (m_mouseButtons & Qt::LeftButton) + { + bool clicked = false; + + if (m_chronometerItemAux->isVisible() && m_chronometerItemAux->width() < 1e-6) + { + chronoHidden = true; + m_chronometerItemAux->hide(); + } + else if (m_chronometerItem->isVisible() && m_chronometerItem->hoverIndicator()) + { + // Jump to selected zone + clicked = true; + m_flickerSpeedX = m_flickerSpeedY = 0; + m_pScrollbar->setValue(m_chronometerItem->left() + m_chronometerItem->width() * 0.5 - m_pScrollbar->sliderHalfWidth()); + } + + if (!clicked && m_mouseMovePath.manhattanLength() < 5) + { + // Handle Click + + //clicked = true; + auto mouseClickPos = mapToScene(m_mousePressPos); + if (mouseClickPos.x() >= 0) + { + mouseClickPos.setX(m_offset + mouseClickPos.x() / m_scale); + + // Try to select one of item blocks + for (auto item : m_items) + { + ::profiler::block_index_t i = ~0U; + auto block = item->intersect(mouseClickPos, i); + if (block) + { + changedSelectedItem = true; + selectedBlock = block; + selectedBlockThread = item->threadId(); + EASY_GLOBALS.selected_block = i; + EASY_GLOBALS.selected_block_id = easyBlock(i).tree.node->id(); + break; + } + } + + if (!changedSelectedItem && !::profiler_gui::is_max(EASY_GLOBALS.selected_block)) + { + changedSelectedItem = true; + ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + } + } + } + } + + m_bDoubleClick = false; + m_mouseButtons = _event->buttons(); + m_mouseMovePath = QPoint(); + _event->accept(); + + if (changedSelection) + { + emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_chronometerItem->left()), position2time(m_chronometerItem->right()), m_chronometerItem->reverse()); + } + + if (changedSelectedItem) + { + m_bUpdatingRect = true; + if (selectedBlock != nullptr && previouslySelectedBlock == EASY_GLOBALS.selected_block && !selectedBlock->tree.children.empty()) + { + EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded = !EASY_GLOBALS.gui_blocks[previouslySelectedBlock].expanded; + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } + emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block); + + if (EASY_GLOBALS.selecting_block_changes_thread && selectedBlock != nullptr && EASY_GLOBALS.selected_thread != selectedBlockThread) + { + EASY_GLOBALS.selected_thread = selectedBlockThread; + + m_pScrollbar->lock(); + emit EASY_GLOBALS.events.selectedThreadChanged(EASY_GLOBALS.selected_thread); + m_pScrollbar->unlock(); + } + m_bUpdatingRect = false; + + if (selectedBlock != nullptr && selectedBlockThread == EASY_GLOBALS.selected_thread) + m_pScrollbar->setHistogramSource(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block_id); + else + { + for (auto item : m_items) + { + if (item->threadId() == EASY_GLOBALS.selected_thread) + { + m_pScrollbar->setHistogramSource(EASY_GLOBALS.selected_thread, item->items(0)); + break; + } + } + } + + repaintScene(); + } + else if (chronoHidden) + { + emit sceneUpdated(); + } +} + +////////////////////////////////////////////////////////////////////////// + +bool EasyGraphicsView::moveChrono(EasyChronometerItem* _chronometerItem, qreal _mouseX) +{ + if (_chronometerItem->reverse()) + { + if (_mouseX > _chronometerItem->right()) + { + _chronometerItem->setReverse(false); + _chronometerItem->setLeftRight(_chronometerItem->right(), _mouseX); + + if (_chronometerItem->hoverLeft()) + { + _chronometerItem->setHoverLeft(false); + _chronometerItem->setHoverRight(true); + } + } + else + { + _chronometerItem->setLeftRight(_mouseX, _chronometerItem->right()); + } + } + else + { + if (_mouseX < _chronometerItem->left()) + { + _chronometerItem->setReverse(true); + _chronometerItem->setLeftRight(_mouseX, _chronometerItem->left()); + + if (_chronometerItem->hoverRight()) + { + _chronometerItem->setHoverLeft(true); + _chronometerItem->setHoverRight(false); + } + } + else + { + _chronometerItem->setLeftRight(_chronometerItem->left(), _mouseX); + } + } + + if (!_chronometerItem->isVisible() && _chronometerItem->width() > 1e-6) + { + _chronometerItem->show(); + return true; + } + + return false; +} + +void EasyGraphicsView::mouseMoveEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + if (m_bEmpty || (m_mouseButtons == 0 && !m_chronometerItem->isVisible() && !m_chronometerItemAux->isVisible())) + { + _event->accept(); + return; + } + + bool needUpdate = false; + const auto pos = _event->pos(); + const auto delta = pos - m_mousePressPos; + m_mousePressPos = pos; + + if (m_mouseButtons != 0) + { + m_mouseMovePath.setX(m_mouseMovePath.x() + qAbs(delta.x())); + m_mouseMovePath.setY(m_mouseMovePath.y() + qAbs(delta.y())); + } + + auto mouseScenePos = mapToScene(m_mousePressPos); + mouseScenePos.setX(m_offset + mouseScenePos.x() / m_scale); + const auto x = clamp(0., mouseScenePos.x(), m_sceneWidth); + + if (m_mouseButtons & Qt::RightButton) + { + bool showItem = moveChrono(m_chronometerItem, x); + m_pScrollbar->setChronoPos(m_chronometerItem->left(), m_chronometerItem->right()); + + if (showItem) + { + m_pScrollbar->showChrono(); + } + + needUpdate = true; + } + + if (m_mouseButtons & Qt::LeftButton) + { + if (m_bDoubleClick) + { + moveChrono(m_chronometerItemAux, x); + } + else + { + auto vbar = verticalScrollBar(); + + m_bUpdatingRect = true; // Block scrollbars from updating scene rect to make it possible to do it only once + vbar->setValue(vbar->value() - delta.y()); + m_pScrollbar->setValue(m_pScrollbar->value() - delta.x() / m_scale); + m_bUpdatingRect = false; + // Seems like an ugly stub, but QSignalBlocker is also a bad decision + // because if scrollbar does not emit valueChanged signal then viewport does not move + + updateVisibleSceneRect(); // Update scene visible rect only once + + // Update flicker speed + m_flickerSpeedX += delta.x() >> 1; + m_flickerSpeedY += delta.y(); + if (!m_flickerTimer.isActive()) + { + // If flicker timer is not started, then start it + m_flickerTimer.start(FLICKER_INTERVAL); + } + } + + needUpdate = true; + } + + if (m_mouseButtons == 0) + { + if (m_chronometerItem->isVisible()) + { + auto prevValue = m_chronometerItem->hoverIndicator(); + m_chronometerItem->setHoverIndicator(m_chronometerItem->indicatorContains(mouseScenePos)); + needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverIndicator()); + + prevValue = m_chronometerItem->hoverLeft(); + m_chronometerItem->setHoverLeft(m_chronometerItem->hoverLeft(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverLeft()); + + if (!m_chronometerItem->hoverLeft()) + { + prevValue = m_chronometerItem->hoverRight(); + m_chronometerItem->setHoverRight(m_chronometerItem->hoverRight(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverRight()); + } + } + + if (m_chronometerItemAux->isVisible()) + { + auto prevValue = m_chronometerItemAux->hoverLeft(); + m_chronometerItemAux->setHoverLeft(m_chronometerItemAux->hoverLeft(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItemAux->hoverLeft()); + + if (!m_chronometerItemAux->hoverLeft()) + { + prevValue = m_chronometerItemAux->hoverRight(); + m_chronometerItemAux->setHoverRight(m_chronometerItemAux->hoverRight(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItemAux->hoverRight()); + } + } + } + + if (needUpdate) + { + repaintScene(); // repaint scene + } + + _event->accept(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::keyPressEvent(QKeyEvent* _event) +{ + static const int KeyStep = 100; + + const int key = _event->key(); + m_idleTime = 0; + + switch (key) + { + case Qt::Key_Right: + case Qt::Key_6: + { + m_pScrollbar->setValue(m_pScrollbar->value() + KeyStep / m_scale); + break; + } + + case Qt::Key_Left: + case Qt::Key_4: + { + m_pScrollbar->setValue(m_pScrollbar->value() - KeyStep / m_scale); + break; + } + + case Qt::Key_Up: + case Qt::Key_8: + { + auto vbar = verticalScrollBar(); + vbar->setValue(vbar->value() - KeyStep); + break; + } + + case Qt::Key_Down: + case Qt::Key_2: + { + auto vbar = verticalScrollBar(); + vbar->setValue(vbar->value() + KeyStep); + break; + } + + case Qt::Key_Plus: + case Qt::Key_Equal: + { + onWheel(mapToScene(mapFromGlobal(QCursor::pos())).x(), KeyStep); + break; + } + + case Qt::Key_Minus: + { + onWheel(mapToScene(mapFromGlobal(QCursor::pos())).x(), -KeyStep); + break; + } + } + + //m_keys.insert(key); + _event->accept(); +} + +void EasyGraphicsView::keyReleaseEvent(QKeyEvent* _event) +{ + //const int key = _event->key(); + m_idleTime = 0; + + //m_keys.erase(key); + _event->accept(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::resizeEvent(QResizeEvent* _event) +{ + Parent::resizeEvent(_event); + + const QRectF previousRect = m_visibleSceneRect; + const int vbar_width = updateVisibleSceneRect(); // Update scene visible rect only once + + // Update slider width for scrollbar + const auto windowWidth = (m_visibleSceneRect.width() + vbar_width) / m_scale; + m_pScrollbar->setSliderWidth(windowWidth); + + // Calculate new offset to save old screen center + const auto deltaWidth = m_visibleSceneRect.width() - previousRect.width(); + m_offset = clamp(0., m_offset - deltaWidth * 0.5 / m_scale, m_sceneWidth - windowWidth); + + // Update slider position + m_bUpdatingRect = true; // To be sure that updateVisibleSceneRect will not be called by scrollbar change + m_pScrollbar->setValue(m_offset); + m_bUpdatingRect = false; + + repaintScene(); // repaint scene +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::initMode() +{ + // TODO: find mode with least number of bugs :) + // There are always some display bugs... + + setCacheMode(QGraphicsView::CacheNone); + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + setOptimizationFlag(QGraphicsView::DontSavePainterState, true); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &This::onScrollbarValueChange); + connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout); + connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout); + + auto globalSignals = &EASY_GLOBALS.events; + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::itemsExpandStateChanged, this, &This::onRefreshRequired); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::refreshRequired, this, &This::onRefreshRequired); + + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::selectedBlockIdChanged, [this](::profiler::block_id_t) + { + if (::profiler_gui::is_max(EASY_GLOBALS.selected_block_id)) + { + if (EASY_GLOBALS.selected_thread != 0) + { + for (auto item : m_items) + { + if (item->threadId() == EASY_GLOBALS.selected_thread) + { + m_pScrollbar->setHistogramSource(EASY_GLOBALS.selected_thread, item->items(0)); + break; + } + } + } + else + { + m_pScrollbar->setHistogramSource(0, nullptr); + } + } + else + m_pScrollbar->setHistogramSource(EASY_GLOBALS.selected_thread, EASY_GLOBALS.selected_block_id); + onRefreshRequired(); + }); + + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, this, &This::onThreadViewChanged); + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::hexThreadIdChanged, this, &This::onThreadViewChanged); + + connect(globalSignals, &::profiler_gui::EasyGlobalSignals::blocksTreeModeChanged, [this]() + { + if (!m_selectedBlocks.empty()) + emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_chronometerItem->left()), position2time(m_chronometerItem->right()), m_chronometerItem->reverse()); + }); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onThreadViewChanged() +{ + if (m_bEmpty) + return; + + for (auto item : m_items) + item->validateName(); + + emit treeChanged(); + + updateVisibleSceneRect(); + onHierarchyFlagChange(EASY_GLOBALS.only_current_thread_hierarchy); + + repaintScene(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onScrollbarValueChange(int) +{ + if (!m_bUpdatingRect && !m_bEmpty) + updateVisibleSceneRect(); +} + +void EasyGraphicsView::onGraphicsScrollbarValueChange(qreal _value) +{ + if (!m_bEmpty) + { + m_offset = _value; + if (!m_bUpdatingRect) + { + updateVisibleSceneRect(); + repaintScene(); + } + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onFlickerTimeout() +{ + ++m_flickerCounterX; + ++m_flickerCounterY; + + if (m_mouseButtons & Qt::LeftButton) + { + // Fast slow-down and stop if mouse button is pressed, no flicking. + m_flickerSpeedX >>= 1; + m_flickerSpeedY >>= 1; + if (m_flickerSpeedX == -1) m_flickerSpeedX = 0; + if (m_flickerSpeedY == -1) m_flickerSpeedY = 0; + } + else + { + // Flick when mouse button is not pressed + + using estd::sign; + using estd::absmin; + + auto vbar = verticalScrollBar(); + + m_bUpdatingRect = true; // Block scrollbars from updating scene rect to make it possible to do it only once + m_pScrollbar->setValue(m_pScrollbar->value() - m_flickerSpeedX / m_scale); + vbar->setValue(vbar->value() - m_flickerSpeedY); + m_bUpdatingRect = false; + // Seems like an ugly stub, but QSignalBlocker is also a bad decision + // because if scrollbar does not emit valueChanged signal then viewport does not move + + updateVisibleSceneRect(); // Update scene visible rect only once + repaintScene(); // repaint scene + + const int dx = static_cast(sign(m_flickerSpeedX) * m_flickerCounterX / FLICKER_FACTOR); + const int dy = static_cast(sign(m_flickerSpeedY) * m_flickerCounterY / FLICKER_FACTOR); + + if (abs(dx) > 0) + { + m_flickerSpeedX -= absmin(dx, m_flickerSpeedX); + m_flickerCounterX = 0; + } + + if (abs(dy) > 0) + { + m_flickerSpeedY -= absmin(dy, m_flickerSpeedY); + m_flickerCounterY = 0; + } + } + + if (m_flickerSpeedX == 0 && m_flickerSpeedY == 0) + { + // Flicker stopped, no timer needed. + m_flickerTimer.stop(); + m_flickerSpeedX = 0; + m_flickerSpeedY = 0; + m_flickerCounterX = 0; + m_flickerCounterY = 0; + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onIdleTimeout() +{ + m_idleTime += IDLE_TIMER_INTERVAL; + + if (m_idleTime < IDLE_TIME) + { + removePopup(true); + return; + } + + if (m_popupWidget != nullptr) + return; + + auto scenePos = mapToScene(mapFromGlobal(QCursor::pos())); + + if (scenePos.x() < m_visibleSceneRect.left() || scenePos.x() > m_visibleSceneRect.right()) + return; + + if (scenePos.y() < m_visibleSceneRect.top() || scenePos.y() > m_visibleSceneRect.bottom()) + return; + + decltype(scenePos) pos(m_offset + scenePos.x() / m_scale, scenePos.y()); + + // Try to select one of context switches or items + for (auto item : m_items) + { + auto cse = item->intersectEvent(pos); + if (cse != nullptr) + { + const auto& itemBlock = cse->tree; + + auto widget = new QWidget(nullptr, Qt::FramelessWindowHint); + if (widget == nullptr) + return; + + widget->setAttribute(Qt::WA_ShowWithoutActivating, true); + widget->setFocusPolicy(Qt::NoFocus); + + auto lay = new QGridLayout(widget); + if (lay == nullptr) + return; + + int row = 0; + lay->addWidget(new EasyBoldLabel("Context switch event", widget), row, 0, 1, 3, Qt::AlignHCenter); + ++row; + + lay->addWidget(new QLabel("Thread:", widget), row, 0, Qt::AlignRight); + + const char* process_name = ""; + ::profiler::thread_id_t tid = 0; + if (EASY_GLOBALS.version < ::profiler_gui::V130) + { + tid = cse->tree.node->id(); + process_name = cse->tree.node->name(); + } + else + { + tid = cse->tree.cs->tid(); + process_name = cse->tree.cs->name(); + } + + auto it = EASY_GLOBALS.profiler_blocks.find(tid); + + if (it != EASY_GLOBALS.profiler_blocks.end()) + { + if (EASY_GLOBALS.hex_thread_id) + lay->addWidget(new QLabel(QString("0x%1 %2").arg(tid, 0, 16).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft); + else + lay->addWidget(new QLabel(QString("%1 %2").arg(tid).arg(it->second.name()), widget), row, 1, 1, 2, Qt::AlignLeft); + } + else if (EASY_GLOBALS.hex_thread_id) + lay->addWidget(new QLabel(QString("0x%1").arg(tid, 0, 16), widget), row, 1, 1, 2, Qt::AlignLeft); + else + lay->addWidget(new QLabel(QString::number(tid), widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("Process:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(process_name, widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + const auto duration = itemBlock.node->duration(); + lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, duration, 3), widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + if (itemBlock.per_thread_stats) + { + lay->addWidget(new QLabel("Sum:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.per_thread_stats->total_duration, 3), widget), row, 1, 1, 2, Qt::AlignLeft); + ++row; + + lay->addWidget(new EasyBoldLabel("-------- Statistics --------", widget), row, 0, 1, 3, Qt::AlignHCenter); + lay->addWidget(new QLabel("per ", widget), row + 1, 0, Qt::AlignRight); + lay->addWidget(new QLabel("This %:", widget), row + 2, 0, Qt::AlignRight); + lay->addWidget(new QLabel("Sum %:", widget), row + 3, 0, Qt::AlignRight); + lay->addWidget(new QLabel("N Calls:", widget), row + 4, 0, Qt::AlignRight); + + lay->addWidget(new QLabel("Thread", widget), row + 1, 1, Qt::AlignHCenter); + + auto percent = ::profiler_gui::percentReal(duration, item->root()->profiled_time); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(::profiler_gui::percent(itemBlock.per_thread_stats->total_duration, item->root()->profiled_time)), widget), row + 3, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row + 4, 1, Qt::AlignHCenter); + + if (itemBlock.per_frame_stats && !::profiler_gui::is_max(itemBlock.per_frame_stats->parent_block)) + { + int col = 2; + auto frame_duration = easyBlocksTree(itemBlock.per_frame_stats->parent_block).node->duration(); + + lay->addWidget(new QLabel("Frame", widget), row + 1, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(itemBlock.per_frame_stats->total_duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 3, col, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_frame_stats->calls_number), widget), row + 4, col, Qt::AlignHCenter); + } + } + + m_popupWidget = new QGraphicsProxyWidget(); + m_popupWidget->setWidget(widget); + + break; + } + + ::profiler::block_index_t i = ~0U; + auto block = item->intersect(pos, i); + if (block != nullptr) + { + const auto& itemBlock = block->tree; + const auto& itemDesc = easyDescriptor(itemBlock.node->id()); + + auto widget = new QWidget(nullptr, Qt::FramelessWindowHint); + if (widget == nullptr) + return; + + widget->setObjectName(QStringLiteral("DiagramPopup")); + widget->setAttribute(Qt::WA_ShowWithoutActivating, true); + widget->setFocusPolicy(Qt::NoFocus); + + auto lay = new QGridLayout(widget); + if (lay == nullptr) + return; + + lay->setSpacing(2); + + int row = 0; + switch (itemDesc.type()) + { + case ::profiler::BlockType::Block: + { + const auto name = *itemBlock.node->name() != 0 ? itemBlock.node->name() : itemDesc.name(); + + //lay->addWidget(new QLabel("Name:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new EasyBoldLabel(::profiler_gui::toUnicode(name), widget), row, 0, 1, 5, + Qt::AlignHCenter); + ++row; + + const auto duration = itemBlock.node->duration(); + lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, duration, 3), + widget), row, 1, 1, 3, Qt::AlignLeft); + ++row; + + ::profiler::timestamp_t children_duration = 0; + for (auto child : itemBlock.children) + children_duration += easyBlock(child).tree.node->duration(); + + const auto self_duration = duration - children_duration; + const auto self_percent = + duration == 0 ? 100. : ::profiler_gui::percentReal(self_duration, duration); + lay->addWidget(new QLabel("Self:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString("%1 (%2%)") + .arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, + self_duration, 3)) + .arg(QString::number(self_percent, 'g', 3)), widget), + row, 1, 1, 3, Qt::AlignLeft); + ++row; + + break; + } + + case ::profiler::BlockType::Event: + { + const auto name = *itemBlock.node->name() != 0 ? itemBlock.node->name() : itemDesc.name(); + + lay->addWidget(new EasyBoldLabel("User defined event", widget), row, 0, 1, 2, Qt::AlignHCenter); + ++row; + + lay->addWidget(new QLabel("Name:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::toUnicode(name), widget), row, 1, Qt::AlignLeft); + ++row; + + break; + } + + case ::profiler::BlockType::Value: + { + lay->addWidget(new EasyBoldLabel("Arbitrary Value", widget), row, 0, 1, 2, Qt::AlignHCenter); + ++row; + + lay->addWidget(new QLabel("Name:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::toUnicode(itemDesc.name()), widget), row, 1, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("Value:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::valueString(*itemBlock.value), widget), row, 1, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("VIN:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString("0x%1").arg(itemBlock.value->value_id(), 0, 16), widget), row, 1, Qt::AlignLeft); + ++row; + + break; + } + + default: + { + delete widget; + return; + } + } + + if (itemBlock.per_thread_stats != nullptr) + { + if (itemDesc.type() == ::profiler::BlockType::Block) + { + const auto duration = itemBlock.node->duration(); + + lay->addWidget(new QLabel("Average:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, itemBlock.per_thread_stats->average_duration(), 3), widget), row, 1, 1, 3, Qt::AlignLeft); + ++row; + + // Calculate idle/active time + { + auto threadRoot = item->root(); + + ::profiler::block_index_t ind = 0; + auto it = ::std::lower_bound(threadRoot->sync.begin(), threadRoot->sync.end(), itemBlock.node->begin(), [](::profiler::block_index_t _cs_index, ::profiler::timestamp_t _val) + { + return EASY_GLOBALS.gui_blocks[_cs_index].tree.node->begin() < _val; + }); + + if (it != threadRoot->sync.end()) + { + ind = static_cast<::profiler::block_index_t>(it - threadRoot->sync.begin()); + if (ind > 0) + --ind; + } + else + { + ind = static_cast<::profiler::block_index_t>(threadRoot->sync.size()); + } + + ::profiler::timestamp_t idleTime = 0; + for (auto ncs = static_cast<::profiler::block_index_t>(threadRoot->sync.size()); ind < ncs; ++ind) + { + auto cs_index = threadRoot->sync[ind]; + const auto cs = EASY_GLOBALS.gui_blocks[cs_index].tree.node; + + if (cs->begin() > itemBlock.node->end()) + break; + + if (itemBlock.node->begin() <= cs->begin() && cs->end() <= itemBlock.node->end()) + idleTime += cs->duration(); + } + + const auto active_time = duration - idleTime; + const auto active_percent = duration == 0 ? 100. : ::profiler_gui::percentReal(active_time, duration); + lay->addWidget(new QLabel("Active time:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString("%1 (%2%)").arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, active_time, 3)).arg(QString::number(active_percent, 'g', 3)), widget), row, 1, 1, 3, Qt::AlignLeft); + ++row; + } + + lay->addWidget(new EasyBoldLabel("-------- Statistics --------", widget), row, 0, 1, 5, Qt::AlignHCenter); + lay->addWidget(new QLabel("per ", widget), row + 1, 0, Qt::AlignRight); + lay->addWidget(new QLabel("This %:", widget), row + 2, 0, Qt::AlignRight); + lay->addWidget(new QLabel("Sum %:", widget), row + 3, 0, Qt::AlignRight); + lay->addWidget(new QLabel("Sum self %:", widget), row + 4, 0, Qt::AlignRight); + lay->addWidget(new QLabel("N Calls:", widget), row + 5, 0, Qt::AlignRight); + + lay->addWidget(new QLabel("Thread", widget), row + 1, 1, Qt::AlignHCenter); + + auto percent = ::profiler_gui::percentReal(duration, item->root()->profiled_time); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(::profiler_gui::percent(itemBlock.per_thread_stats->total_duration, item->root()->profiled_time)), widget), row + 3, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(::profiler_gui::percent(itemBlock.per_thread_stats->total_duration - itemBlock.per_thread_stats->total_children_duration, item->root()->profiled_time)), widget), row + 4, 1, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row + 5, 1, Qt::AlignHCenter); + + int col = 1; + + if (itemBlock.per_frame_stats->parent_block != i && !::profiler_gui::is_max(itemBlock.per_frame_stats->parent_block)) + { + ++col; + auto frame_duration = easyBlocksTree(itemBlock.per_frame_stats->parent_block).node->duration(); + + lay->addWidget(new QLabel("Frame", widget), row + 1, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(itemBlock.per_frame_stats->total_duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 3, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(itemBlock.per_frame_stats->total_duration - itemBlock.per_frame_stats->total_children_duration, frame_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 4, col, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_frame_stats->calls_number), widget), row + 5, col, Qt::AlignHCenter); + } + + if (!::profiler_gui::is_max(itemBlock.per_parent_stats->parent_block))// != item->threadId()) + { + ++col; + auto parent_duration = easyBlocksTree(itemBlock.per_parent_stats->parent_block).node->duration(); + + lay->addWidget(new QLabel("Parent", widget), row + 1, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(duration, parent_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 2, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(itemBlock.per_parent_stats->total_duration, parent_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 3, col, Qt::AlignHCenter); + + percent = ::profiler_gui::percentReal(itemBlock.per_parent_stats->total_duration - itemBlock.per_parent_stats->total_children_duration, parent_duration); + lay->addWidget(new QLabel(0.005 < percent && percent < 0.5001 ? QString::number(percent, 'f', 2) : QString::number(static_cast(0.5 + percent)), widget), row + 4, col, Qt::AlignHCenter); + + lay->addWidget(new QLabel(QString::number(itemBlock.per_parent_stats->calls_number), widget), row + 5, col, Qt::AlignHCenter); + + ++col; + } + } + else + { + lay->addWidget(new QLabel("N calls/Thread:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString::number(itemBlock.per_thread_stats->calls_number), widget), row, 1, Qt::AlignLeft); + } + } + + m_popupWidget = new QGraphicsProxyWidget(); + m_popupWidget->setWidget(widget); + + break; + } + } + + if (m_popupWidget != nullptr) + { + auto effect = new QGraphicsDropShadowEffect(); + effect->setBlurRadius(5); + effect->setOffset(3, 3); + m_popupWidget->setGraphicsEffect(effect); + + scene()->addItem(m_popupWidget); + + auto br = m_popupWidget->boundingRect(); + if (scenePos.y() + br.height() > m_visibleSceneRect.bottom()) + scenePos.setY(::std::max(scenePos.y() - br.height(), m_visibleSceneRect.top())); + + if (scenePos.x() + br.width() > m_visibleSceneRect.right()) + scenePos.setX(::std::max(scenePos.x() - br.width(), m_visibleSceneRect.left())); + + m_popupWidget->setPos(scenePos); + m_popupWidget->setOpacity(0.95); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onHierarchyFlagChange(bool) +{ + bool changedSelection = false; + + if (!m_selectedBlocks.empty()) + { + changedSelection = true; + m_selectedBlocks.clear(); + } + + if (m_chronometerItem->isVisible()) + { + for (auto item : m_items) + { + if (!EASY_GLOBALS.only_current_thread_hierarchy || item->threadId() == EASY_GLOBALS.selected_thread) + item->getBlocks(m_chronometerItem->left(), m_chronometerItem->right(), m_selectedBlocks); + } + + if (!m_selectedBlocks.empty()) + { + changedSelection = true; + } + } + + if (changedSelection) + { + emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_chronometerItem->left()), position2time(m_chronometerItem->right()), m_chronometerItem->reverse()); + } +} + +void EasyGraphicsView::onSelectedThreadChange(::profiler::thread_id_t _id) +{ + if (m_pScrollbar == nullptr || m_pScrollbar->hystThread() == _id) + { + return; + } + + if (_id == 0) + { + m_pScrollbar->setHistogramSource(0, nullptr); + return; + } + + for (auto item : m_items) + { + if (item->threadId() == _id) + { + m_pScrollbar->setHistogramSource(_id, item->items(0)); + + bool changedSelection = false; + if (EASY_GLOBALS.only_current_thread_hierarchy) + { + if (!m_selectedBlocks.empty()) + { + changedSelection = true; + m_selectedBlocks.clear(); + } + + if (m_chronometerItem->isVisible()) + { + item->getBlocks(m_chronometerItem->left(), m_chronometerItem->right(), m_selectedBlocks); + if (!m_selectedBlocks.empty()) + changedSelection = true; + } + } + + if (changedSelection) + { + emit intervalChanged(m_selectedBlocks, m_beginTime, position2time(m_chronometerItem->left()), position2time(m_chronometerItem->right()), m_chronometerItem->reverse()); + } + + repaintScene(); + return; + } + } + + m_pScrollbar->setHistogramSource(0, nullptr); + repaintScene(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onSelectedBlockChange(unsigned int _block_index) +{ + if (!m_bUpdatingRect) + { + if (_block_index < EASY_GLOBALS.gui_blocks.size()) + { + // Scroll to item + + const auto& guiblock = EASY_GLOBALS.gui_blocks[_block_index]; + const auto thread_item = m_items[guiblock.graphics_item]; + const auto& item = thread_item->items(guiblock.graphics_item_level)[guiblock.graphics_item_index]; + + m_flickerSpeedX = m_flickerSpeedY = 0; + + m_bUpdatingRect = true; + verticalScrollBar()->setValue(static_cast(thread_item->levelY(guiblock.graphics_item_level) - m_visibleSceneRect.height() * 0.5)); + m_pScrollbar->setValue(item.left() + item.width() * 0.5 - m_pScrollbar->sliderHalfWidth()); + + if (EASY_GLOBALS.selecting_block_changes_thread && EASY_GLOBALS.selected_thread != thread_item->threadId()) + { + EASY_GLOBALS.selected_thread = thread_item->threadId(); + + m_pScrollbar->lock(); + emit EASY_GLOBALS.events.selectedThreadChanged(EASY_GLOBALS.selected_thread); + m_pScrollbar->unlock(); + } + + m_pScrollbar->setHistogramSource(EASY_GLOBALS.selected_thread, guiblock.tree.node->id()); + + m_bUpdatingRect = false; + } + else if (EASY_GLOBALS.selected_thread != 0) + { + for (auto item : m_items) + { + if (item->threadId() == EASY_GLOBALS.selected_thread) + { + m_pScrollbar->setHistogramSource(EASY_GLOBALS.selected_thread, item->items(0)); + break; + } + } + } + else + { + m_pScrollbar->setHistogramSource(0, nullptr); + } + + updateVisibleSceneRect(); + repaintScene(); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsView::onRefreshRequired() +{ + if (!m_bUpdatingRect) + { + repaintScene(); + } +} + +////////////////////////////////////////////////////////////////////////// + +EasyGraphicsViewWidget::EasyGraphicsViewWidget(QWidget* _parent) + : QWidget(_parent) + , m_scrollbar(new EasyGraphicsScrollbar(this)) + , m_view(new EasyGraphicsView(this)) + , m_threadNamesWidget(new EasyThreadNamesWidget(m_view, m_scrollbar->height(), this)) +{ + initWidget(); +} + +void EasyGraphicsViewWidget::initWidget() +{ + auto lay = new QGridLayout(this); + lay->setContentsMargins(0, 0, 0, 0); + lay->setSpacing(1); + lay->addWidget(m_threadNamesWidget, 0, 0, 2, 1); + lay->addWidget(m_view, 0, 1); + lay->addWidget(m_scrollbar, 1, 1); + setLayout(lay); + + m_view->setScrollbar(m_scrollbar); +} + +EasyGraphicsViewWidget::~EasyGraphicsViewWidget() +{ + +} + +EasyGraphicsView* EasyGraphicsViewWidget::view() +{ + return m_view; +} + +void EasyGraphicsViewWidget::clear() +{ + m_scrollbar->clear(); + m_threadNamesWidget->clear(); + m_view->clear(); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +void EasyThreadNameItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + auto const parentView = static_cast(scene()->parent()); + const auto view = parentView->view(); + const auto& items = view->getItems(); + if (items.empty()) + return; + + const auto visibleSceneRect = view->visibleSceneRect(); + const auto h = visibleSceneRect.height() + TIMELINE_ROW_SIZE - 2; + const auto w = parentView->width();//parentView->sceneRect().width(); + + EASY_STATIC_CONSTEXPR uint16_t OVERLAP = ::profiler_gui::THREADS_ROW_SPACING >> 1; + static const QBrush brushes[2] = {QColor::fromRgb(BACKGROUND_1), QColor::fromRgb(BACKGROUND_2)}; + int i = -1; + + QRectF rect; + + _painter->resetTransform(); + + // Draw thread names + auto default_font = _painter->font(); + _painter->setFont(EASY_GLOBALS.bg_font); + for (auto item : items) + { + ++i; + + auto br = item->boundingRect(); + auto top = item->y() + br.top() - visibleSceneRect.top() - OVERLAP; + auto hgt = br.height() + ::profiler_gui::THREADS_ROW_SPACING; + auto bottom = top + hgt; + + if (top > h || bottom < 0) + continue; + + if (item->threadId() == EASY_GLOBALS.selected_thread) + _painter->setBrush(QBrush(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_BACKGROUND))); + else + _painter->setBrush(brushes[i & 1]); + + if (top < 0) + { + hgt += top; + top = 0; + } + + const auto dh = top + hgt - h; + if (dh > 0) + hgt -= dh; + + rect.setRect(0, top, w, hgt); + + _painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + _painter->drawRect(rect); + + rect.translate(-5, 0); + _painter->setPen(::profiler_gui::TEXT_COLOR); + _painter->drawText(rect, Qt::AlignRight | Qt::AlignVCenter, item->threadName()); + } + + const auto rect_bottom = rect.bottom(); + if (rect_bottom < h) + { + ++i; + rect.translate(5, rect.height()); + rect.setHeight(h - rect_bottom); + _painter->setBrush(brushes[i & 1]); + _painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + _painter->drawRect(rect); + } + + // Draw separator between thread names area and information area + _painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + _painter->drawLine(QLineF(0, h, w, h)); + _painter->drawLine(QLineF(0, h + 2, w, h + 2)); + + // Draw information + _painter->setFont(EASY_GLOBALS.chronometer_font); + QFontMetricsF fm(EASY_GLOBALS.chronometer_font, parentView); + const qreal th = fm.height(); // Calculate displayed text height + const qreal time1 = view->chronoTime(); + const qreal time2 = view->chronoTimeAux(); + + auto y = h + 2; + + auto drawTimeText = [&rect, &w, &y, &fm, &_painter](qreal time, qreal th, QRgb color) + { + if (time > 0) + { + const QString text = ::profiler_gui::autoTimeStringReal(time); // Displayed text + rect.setRect(0, y, w, th); + + _painter->setPen(color); + _painter->drawText(rect, Qt::AlignCenter, text); + + y += th; + } + }; + + drawTimeText(time1, th, ::profiler_gui::CHRONOMETER_COLOR.rgb() & 0x00ffffff); + drawTimeText(time2, th, ::profiler_gui::CHRONOMETER_COLOR2.rgb() & 0x00ffffff); +} + +////////////////////////////////////////////////////////////////////////// + +EasyThreadNamesWidget::EasyThreadNamesWidget(EasyGraphicsView* _view, int _additionalHeight, QWidget* _parent) + : Parent(_parent) + , m_idleTime(0) + , m_view(_view) + , m_popupWidget(nullptr) + , m_maxLength(100) + , m_additionalHeight(_additionalHeight + 1) +{ + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + + setScene(new QGraphicsScene(this)); + + setCacheMode(QGraphicsView::CacheNone); + setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setFixedWidth(m_maxLength); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, [this](::profiler::thread_id_t){ repaintScene(); }); + connect(m_view, &EasyGraphicsView::treeChanged, this, &This::onTreeChange); + connect(m_view, &EasyGraphicsView::sceneUpdated, this, &This::repaintScene); + connect(m_view->verticalScrollBar(), &QScrollBar::valueChanged, verticalScrollBar(), &QScrollBar::setValue); + connect(m_view->verticalScrollBar(), &QScrollBar::rangeChanged, this, &This::setVerticalScrollbarRange); + connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout); +} + +EasyThreadNamesWidget::~EasyThreadNamesWidget() +{ + +} + +void EasyThreadNamesWidget::removePopup(bool _removeFromScene) +{ + if (m_popupWidget != nullptr) + { + auto widget = m_popupWidget->widget(); + widget->setParent(nullptr); + m_popupWidget->setWidget(nullptr); + delete widget; + + if (_removeFromScene) + scene()->removeItem(m_popupWidget); + + m_popupWidget = nullptr; + } +} + +void EasyThreadNamesWidget::clear() +{ + const QSignalBlocker b(this); + removePopup(); + scene()->clear(); + + m_maxLength = 100; + setFixedWidth(m_maxLength); + + m_idleTimer.stop(); + m_idleTime = 0; +} + +void EasyThreadNamesWidget::setVerticalScrollbarRange(int _minValue, int _maxValue) +{ + verticalScrollBar()->setRange(_minValue, _maxValue + m_additionalHeight); +} + +void EasyThreadNamesWidget::onTreeChange() +{ + const QSignalBlocker b(this); + removePopup(); + scene()->clear(); + + m_idleTimer.stop(); + m_idleTime = 0; + + QFontMetricsF fm(EASY_GLOBALS.bg_font, this); + qreal maxLength = 100; + const auto& graphicsItems = m_view->getItems(); + for (auto graphicsItem : graphicsItems) + maxLength = ::std::max(maxLength, (10 + fm.width(graphicsItem->threadName())) * ::profiler_gui::FONT_METRICS_FACTOR); + + auto vbar = verticalScrollBar(); + auto viewBar = m_view->verticalScrollBar(); + + setVerticalScrollbarRange(viewBar->minimum(), viewBar->maximum()); + vbar->setSingleStep(viewBar->singleStep()); + vbar->setPageStep(viewBar->pageStep()); + + auto r = m_view->sceneRect(); + setSceneRect(0, r.top(), maxLength, r.height() + m_additionalHeight); + + auto item = new EasyThreadNameItem(); + item->setPos(0, 0); + item->setBoundingRect(sceneRect()); + scene()->addItem(item); + + m_maxLength = static_cast(maxLength); + setFixedWidth(m_maxLength); + + m_idleTimer.start(IDLE_TIMER_INTERVAL); +} + +void EasyThreadNamesWidget::onIdleTimeout() +{ + static const uint16_t OVERLAP = ::profiler_gui::THREADS_ROW_SPACING >> 1; + + m_idleTime += IDLE_TIMER_INTERVAL; + + if (m_idleTime < IDLE_TIME) + { + removePopup(true); + return; + } + + if (m_popupWidget != nullptr) + return; + + auto visibleSceneRect = mapToScene(rect()).boundingRect(); + auto scenePos = mapToScene(mapFromGlobal(QCursor::pos())); + + if (scenePos.x() < visibleSceneRect.left() || scenePos.x() > visibleSceneRect.right()) + { + if (m_idleTime > 3000) + setFixedWidth(m_maxLength); + return; + } + + if (scenePos.y() < visibleSceneRect.top() || scenePos.y() > visibleSceneRect.bottom()) + { + if (m_idleTime > 3000) + setFixedWidth(m_maxLength); + return; + } + + auto const parentView = static_cast(scene()->parent()); + const auto view = parentView->view(); + + if (scenePos.y() > view->visibleSceneRect().bottom()) + { + if (m_idleTime > 3000) + setFixedWidth(m_maxLength); + return; + } + + const qreal y = scenePos.y() - visibleSceneRect.top(); + + const auto& items = view->getItems(); + if (items.empty()) + { + if (m_idleTime > 3000) + setFixedWidth(m_maxLength); + return; + } + + EasyGraphicsItem* intersectingItem = nullptr; + for (auto item : items) + { + auto br = item->boundingRect(); + auto top = item->y() + br.top() - visibleSceneRect.top() - OVERLAP; + auto hgt = br.height() + ::profiler_gui::THREADS_ROW_SPACING; + auto bottom = top + hgt; + + if (bottom < y || y < top) + continue; + + intersectingItem = item; + + break; + } + + if (intersectingItem != nullptr) + { + auto widget = new QWidget(nullptr, Qt::FramelessWindowHint); + if (widget == nullptr) + return; + + widget->setObjectName(QStringLiteral("ThreadsPopup")); + widget->setAttribute(Qt::WA_ShowWithoutActivating, true); + widget->setFocusPolicy(Qt::NoFocus); + + auto lay = new QGridLayout(widget); + if (lay == nullptr) + return; + + int row = 0; + + lay->setSpacing(2); + lay->addWidget(new EasyBoldLabel(intersectingItem->threadName(), widget), row, 0, 1, 2, Qt::AlignHCenter); + ++row; + + ::profiler::timestamp_t duration = 0; + const auto& root = *intersectingItem->root(); + if (!root.children.empty()) + duration = easyBlock(root.children.back()).tree.node->end() - easyBlock(root.children.front()).tree.node->begin(); + + lay->addWidget(new QLabel("Duration:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, duration, 3), widget), row, 1, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("Profiled:", widget), row, 0, Qt::AlignRight); + if (duration) + { + lay->addWidget(new QLabel(QString("%1 (%2%)").arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, root.profiled_time, 3)) + .arg(QString::number(100. * (double)root.profiled_time / (double)duration, 'f', 2)), widget), row, 1, Qt::AlignLeft); + } + else + { + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, root.profiled_time, 3), widget), row, 1, Qt::AlignLeft); + } + ++row; + + lay->addWidget(new QLabel("Wait:", widget), row, 0, Qt::AlignRight); + if (duration) + { + lay->addWidget(new QLabel(QString("%1 (%2%)").arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, root.wait_time, 3)) + .arg(QString::number(100. * (double)root.wait_time / (double)duration, 'f', 2)), widget), row, 1, Qt::AlignLeft); + } + else + { + lay->addWidget(new QLabel(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, root.wait_time, 3), widget), row, 1, Qt::AlignLeft); + } + ++row; + + const auto eventsSize = root.events.size(); + + lay->addWidget(new QLabel("Frames:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString::number(root.frames_number), widget), row, 1, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("Blocks:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString::number(root.blocks_number - eventsSize), widget), row, 1, Qt::AlignLeft); + ++row; + + lay->addWidget(new QLabel("Markers:", widget), row, 0, Qt::AlignRight); + lay->addWidget(new QLabel(QString::number(eventsSize), widget), row, 1, Qt::AlignLeft); + ++row; + + m_popupWidget = new QGraphicsProxyWidget(); + if (m_popupWidget != nullptr) + { + auto effect = new QGraphicsDropShadowEffect(); + effect->setBlurRadius(5); + effect->setOffset(3, 3); + m_popupWidget->setGraphicsEffect(effect); + + m_popupWidget->setWidget(widget); + scene()->addItem(m_popupWidget); + + auto br = m_popupWidget->boundingRect(); + + if (maximumWidth() < br.width()) + { + setFixedWidth(static_cast(br.width())); + visibleSceneRect.setWidth(br.width()); + } + + if (scenePos.y() + br.height() > visibleSceneRect.bottom()) + scenePos.setY(::std::max(scenePos.y() - br.height(), visibleSceneRect.top())); + + if (scenePos.x() + br.width() > visibleSceneRect.right()) + scenePos.setX(::std::max(scenePos.x() - br.width(), visibleSceneRect.left())); + + m_popupWidget->setPos(scenePos); + m_popupWidget->setOpacity(0.95); + } + } +} + +void EasyThreadNamesWidget::repaintScene() +{ + scene()->update(); +} + +void EasyThreadNamesWidget::mousePressEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + QMouseEvent e(_event->type(), _event->pos() - QPointF(sceneRect().width(), 0), _event->button(), _event->buttons() & ~Qt::RightButton, _event->modifiers()); + m_view->mousePressEvent(&e); + _event->accept(); +} + +void EasyThreadNamesWidget::mouseDoubleClickEvent(QMouseEvent* _event) +{ + static const auto OVERLAP = ::profiler_gui::THREADS_ROW_SPACING >> 1; + + m_idleTime = 0; + + auto y = mapToScene(_event->pos()).y(); + const auto& items = m_view->getItems(); + for (auto item : items) + { + auto br = item->boundingRect(); + auto top = item->y() + br.top() - OVERLAP; + auto bottom = top + br.height() + OVERLAP; + + if (y < top || y > bottom) + continue; + + const auto thread_id = item->threadId(); + if (thread_id != EASY_GLOBALS.selected_thread) + { + EASY_GLOBALS.selected_thread = thread_id; + emit EASY_GLOBALS.events.selectedThreadChanged(thread_id); + } + + break; + } + + _event->accept(); +} + +void EasyThreadNamesWidget::mouseReleaseEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + QMouseEvent e(_event->type(), _event->pos() - QPointF(sceneRect().width(), 0), _event->button(), _event->buttons() & ~Qt::RightButton, _event->modifiers()); + m_view->mouseReleaseEvent(&e); + _event->accept(); +} + +void EasyThreadNamesWidget::mouseMoveEvent(QMouseEvent* _event) +{ + m_idleTime = 0; + + QMouseEvent e(_event->type(), _event->pos() - QPointF(sceneRect().width(), 0), _event->button(), _event->buttons() & ~Qt::RightButton, _event->modifiers()); + m_view->mouseMoveEvent(&e); + _event->accept(); +} + +void EasyThreadNamesWidget::keyPressEvent(QKeyEvent* _event) +{ + m_idleTime = 0; + m_view->keyPressEvent(_event); +} + +void EasyThreadNamesWidget::keyReleaseEvent(QKeyEvent* _event) +{ + m_idleTime = 0; + m_view->keyReleaseEvent(_event); +} + +void EasyThreadNamesWidget::wheelEvent(QWheelEvent* _event) +{ + m_idleTime = 0; + + auto vbar = m_view->verticalScrollBar(); + if (vbar != nullptr) + { + _event->accept(); + vbar->setValue(vbar->value() - _event->delta()); + } +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/blocks_graphics_view.h b/3rdparty/easyprofiler/profiler_gui/blocks_graphics_view.h new file mode 100644 index 0000000..255862b --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/blocks_graphics_view.h @@ -0,0 +1,349 @@ +/************************************************************************ +* file name : blocks_graphics_view.h +* ----------------- : +* creation time : 2016/06/26 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of GraphicsScene and GraphicsView and +* : it's auxiliary classes for displyaing easy_profiler blocks tree. +* ----------------- : +* change log : * 2016/06/26 Victor Zarubkin: moved sources from graphics_view.h +* : and renamed classes from My* to Prof*. +* : +* : * 2016/06/29 Victor Zarubkin: Highly optimized painting performance and memory consumption. +* : +* : * 2016/06/30 Victor Zarubkin: Replaced doubles with floats (in ProfBlockItem) for less memory consumption. +* : +* : * 2016/09/15 Victor Zarubkin: Moved sources of EasyGraphicsItem and EasyChronometerItem to separate files. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_GRAPHICS_VIEW_H +#define EASY_GRAPHICS_VIEW_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "common_functions.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +class QGraphicsProxyWidget; +class EasyGraphicsView; +class EasyGraphicsItem; +class EasyGraphicsScrollbar; +class EasyChronometerItem; + +////////////////////////////////////////////////////////////////////////// + +#define EASY_QGRAPHICSITEM(ClassName) \ +class ClassName : public QGraphicsItem { \ + QRectF m_boundingRect; \ +public: \ + ClassName() : QGraphicsItem() {} \ + virtual ~ClassName() {} \ + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; \ + QRectF boundingRect() const override { return m_boundingRect; } \ + void setBoundingRect(qreal x, qreal y, qreal w, qreal h) { m_boundingRect.setRect(x, y, w, h); } \ + void setBoundingRect(const QRectF& _rect) { m_boundingRect = _rect; } \ +} + +EASY_QGRAPHICSITEM(EasyBackgroundItem); +EASY_QGRAPHICSITEM(EasyTimelineIndicatorItem); +EASY_QGRAPHICSITEM(EasyThreadNameItem); + +#undef EASY_QGRAPHICSITEM + +////////////////////////////////////////////////////////////////////////// + +struct EasyBoldLabel : public QLabel { + EasyBoldLabel(const QString& _text, QWidget* _parent = nullptr); + virtual ~EasyBoldLabel(); +}; + +////////////////////////////////////////////////////////////////////////// + +class EasyGraphicsView : public QGraphicsView +{ + Q_OBJECT + +private: + + using Parent = QGraphicsView; + using This = EasyGraphicsView; + using Items = ::std::vector; + //using Keys = ::std::unordered_set >; + + Items m_items; ///< Array of all EasyGraphicsItem items + //Keys m_keys; ///< Pressed keyboard keys + ::profiler_gui::TreeBlocks m_selectedBlocks; ///< Array of items which were selected by selection zone (EasyChronometerItem) + QTimer m_flickerTimer; ///< Timer for flicking behavior + QTimer m_idleTimer; ///< + QRectF m_visibleSceneRect; ///< Visible scene rectangle + ::profiler::timestamp_t m_beginTime; ///< Begin time of profiler session. Used to reduce values of all begin and end times of profiler blocks. + qreal m_sceneWidth; ///< + qreal m_scale; ///< Current scale + qreal m_offset; ///< Have to use manual offset for all scene content instead of using scrollbars because QScrollBar::value is 32-bit integer :( + qreal m_timelineStep; ///< + uint64_t m_idleTime; ///< + QPoint m_mousePressPos; ///< Last mouse global position (used by mousePressEvent and mouseMoveEvent) + QPoint m_mouseMovePath; ///< Mouse move path between press and release of any button + Qt::MouseButtons m_mouseButtons; ///< Pressed mouse buttons + EasyGraphicsScrollbar* m_pScrollbar; ///< Pointer to the graphics scrollbar widget + EasyChronometerItem* m_chronometerItem; ///< Pointer to the EasyChronometerItem which is displayed when you press right mouse button and move mouse left or right. This item is used to select blocks to display in tree widget. + EasyChronometerItem* m_chronometerItemAux; ///< Pointer to the EasyChronometerItem which is displayed when you double click left mouse button and move mouse left or right. This item is used only to measure time. + QGraphicsProxyWidget* m_popupWidget; ///< + int m_flickerSpeedX; ///< Current flicking speed x + int m_flickerSpeedY; ///< Current flicking speed y + int m_flickerCounterX; + int m_flickerCounterY; + bool m_bDoubleClick; ///< Is mouse buttons double clicked + bool m_bUpdatingRect; ///< Stub flag which is used to avoid excess calculations on some scene update (flicking, scaling and so on) + bool m_bEmpty; ///< Indicates whether scene is empty and has no items + +public: + + explicit EasyGraphicsView(QWidget* _parent = nullptr); + virtual ~EasyGraphicsView(); + + // Public virtual methods + + void wheelEvent(QWheelEvent* _event) override; + void mousePressEvent(QMouseEvent* _event) override; + void mouseDoubleClickEvent(QMouseEvent* _event) override; + void mouseReleaseEvent(QMouseEvent* _event) override; + void mouseMoveEvent(QMouseEvent* _event) override; + void keyPressEvent(QKeyEvent* _event) override; + void keyReleaseEvent(QKeyEvent* _event) override; + void resizeEvent(QResizeEvent* _event) override; + + void dragEnterEvent(QDragEnterEvent*) override {} + +public: + + // Public non-virtual methods + + qreal sceneWidth() const; + qreal chronoTime() const; + qreal chronoTimeAux() const; + + void setScrollbar(EasyGraphicsScrollbar* _scrollbar); + void clear(); + + void setTree(const ::profiler::thread_blocks_tree_t& _blocksTree); + + const Items& getItems() const; + +signals: + + // Signals + + void sceneUpdated(); + void treeChanged(); + void intervalChanged(const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _session_begin_time, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict); + +private: + + // Private non-virtual methods + + void removePopup(bool _removeFromScene = false); + + EasyChronometerItem* createChronometer(bool _main = true); + bool moveChrono(EasyChronometerItem* _chronometerItem, qreal _mouseX); + void initMode(); + int updateVisibleSceneRect(); + void updateTimelineStep(qreal _windowWidth); + void scaleTo(qreal _scale); + void scrollTo(const EasyGraphicsItem* _item); + void onWheel(qreal _mouseX, int _wheelDelta); + qreal setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, uint32_t& _maxDepthChild, qreal _y, short _level); + +private slots: + + // Private Slots + + void repaintScene(); + void onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta); + void onScrollbarValueChange(int); + void onGraphicsScrollbarValueChange(qreal); + void onFlickerTimeout(); + void onIdleTimeout(); + void onHierarchyFlagChange(bool _value); + void onSelectedThreadChange(::profiler::thread_id_t _id); + void onSelectedBlockChange(unsigned int _block_index); + void onRefreshRequired(); + void onThreadViewChanged(); + +public: + + // Public inline methods + + inline qreal scale() const + { + return m_scale; + } + + inline qreal offset() const + { + return m_offset; + } + + inline const QRectF& visibleSceneRect() const + { + return m_visibleSceneRect; + } + + inline qreal timelineStep() const + { + return m_timelineStep; + } + + inline qreal time2position(const profiler::timestamp_t& _time) const + { + return PROF_MICROSECONDS(qreal(_time - m_beginTime)); + //return PROF_MILLISECONDS(qreal(_time - m_beginTime)); + } + + inline ::profiler::timestamp_t position2time(qreal _pos) const + { + return PROF_FROM_MICROSECONDS(_pos); + //return PROF_FROM_MILLISECONDS(_pos); + } + +}; // END of class EasyGraphicsView. + +////////////////////////////////////////////////////////////////////////// + +class EasyThreadNamesWidget : public QGraphicsView +{ + Q_OBJECT + +private: + + typedef QGraphicsView Parent; + typedef EasyThreadNamesWidget This; + + QTimer m_idleTimer; ///< + uint64_t m_idleTime; ///< + EasyGraphicsView* m_view; ///< + QGraphicsProxyWidget* m_popupWidget; ///< + int m_maxLength; ///< + const int m_additionalHeight; ///< + +public: + + explicit EasyThreadNamesWidget(EasyGraphicsView* _view, int _additionalHeight, QWidget* _parent = nullptr); + virtual ~EasyThreadNamesWidget(); + + void mousePressEvent(QMouseEvent* _event) override; + void mouseDoubleClickEvent(QMouseEvent* _event) override; + void mouseReleaseEvent(QMouseEvent* _event) override; + void mouseMoveEvent(QMouseEvent* _event) override; + void keyPressEvent(QKeyEvent* _event) override; + void keyReleaseEvent(QKeyEvent* _event) override; + void wheelEvent(QWheelEvent* _event) override; + + void dragEnterEvent(QDragEnterEvent*) override {} + + void clear(); + + const EasyGraphicsView* view() const + { + return m_view; + } + +private: + + void removePopup(bool _removeFromScene = false); + +private slots: + + void setVerticalScrollbarRange(int _minValue, int _maxValue); + void onTreeChange(); + void onIdleTimeout(); + void repaintScene(); + +}; // END of class EasyThreadNamesWidget. + +////////////////////////////////////////////////////////////////////////// + +class EasyGraphicsViewWidget : public QWidget +{ + Q_OBJECT + +private: + + EasyGraphicsScrollbar* m_scrollbar; + EasyGraphicsView* m_view; + EasyThreadNamesWidget* m_threadNamesWidget; + +public: + + explicit EasyGraphicsViewWidget(QWidget* _parent = nullptr); + virtual ~EasyGraphicsViewWidget(); + + EasyGraphicsView* view(); + void clear(); + +private: + + void initWidget(); + +}; // END of class EasyGraphicsViewWidget. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_GRAPHICS_VIEW_H diff --git a/3rdparty/easyprofiler/profiler_gui/blocks_tree_widget.cpp b/3rdparty/easyprofiler/profiler_gui/blocks_tree_widget.cpp new file mode 100644 index 0000000..45e7858 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/blocks_tree_widget.cpp @@ -0,0 +1,1280 @@ +/************************************************************************ +* file name : blocks_tree_widget.cpp +* ----------------- : +* creation time : 2016/06/26 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyTreeWidget and it's auxiliary classes +* : for displyaing easy_profiler blocks tree. +* ----------------- : +* change log : * 2016/06/26 Victor Zarubkin: Moved sources from tree_view.h +* : and renamed classes from My* to Prof*. +* : +* : * 2016/06/27 Victor Zarubkin: Added possibility to colorize rows +* : with profiler blocks' colors. +* : Also added displaying frame statistics for blocks. +* : Disabled sorting by name to save order of threads displayed on graphics view. +* : +* : * 2016/06/29 Victor Zarubkin: Added clearSilent() method. +* : +* : * 2016/08/18 Victor Zarubkin: Moved sources of TreeWidgetItem into tree_widget_item.h/.cpp +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "blocks_tree_widget.h" +#include "globals.h" + +#ifdef _WIN32 +#include + +#ifdef __MINGW32__ +#include +#endif + +#endif + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +const int HIERARCHY_BUILDER_TIMER_INTERVAL = 40; + +const bool SIMPLIFIED_REGIME_COLUMNS[COL_COLUMNS_NUMBER] = { + true, //COL_NAME, + true, //COL_BEGIN, + true, //COL_DURATION, + true, //COL_SELF_DURATION, + false, //COL_DURATION_SUM_PER_PARENT, + false, //COL_DURATION_SUM_PER_FRAME, + true, //COL_DURATION_SUM_PER_THREAD, + true, //COL_SELF_DURATION_PERCENT, + false, //COL_PERCENT_PER_PARENT, + true, //COL_PERCENT_PER_FRAME, + false, //COL_PERCENT_SUM_PER_PARENT, + false, //COL_PERCENT_SUM_PER_FRAME, + true, //COL_PERCENT_SUM_PER_THREAD, + true, //COL_END, + true, //COL_MIN_PER_FRAME, + true, //COL_MAX_PER_FRAME, + true, //COL_AVERAGE_PER_FRAME, + true, //COL_NCALLS_PER_FRAME, + true, //COL_MIN_PER_THREAD, + true, //COL_MAX_PER_THREAD, + true, //COL_AVERAGE_PER_THREAD, + true, //COL_NCALLS_PER_THREAD, + false, //COL_MIN_PER_PARENT, + false, //COL_MAX_PER_PARENT, + false, //COL_AVERAGE_PER_PARENT, + false, //COL_NCALLS_PER_PARENT, + true, //COL_ACTIVE_TIME, + true //COL_ACTIVE_PERCENT, +}; + +////////////////////////////////////////////////////////////////////////// + +EasyTreeWidget::EasyTreeWidget(QWidget* _parent) + : Parent(_parent) + , m_beginTime(::std::numeric_limits::max()) + , m_lastFound(nullptr) + , m_progress(nullptr) + , m_hintLabel(nullptr) + , m_mode(EasyTreeMode_Plain) + , m_bLocked(false) + , m_bSilentExpandCollapse(false) +{ + memset(m_columnsHiddenStatus, 0, sizeof(m_columnsHiddenStatus)); + + setAutoFillBackground(false); + setAlternatingRowColors(true); + setItemsExpandable(true); + setAnimated(true); + setSortingEnabled(false); + setColumnCount(COL_COLUMNS_NUMBER); + setSelectionBehavior(QAbstractItemView::SelectRows); + + auto header_item = new QTreeWidgetItem(); + auto f = header()->font(); + f.setBold(true); + header()->setFont(f);// ::profiler_gui::EFont("Helvetica", 9, QFont::Bold)); + + header_item->setText(COL_NAME, "Name"); + + header_item->setText(COL_BEGIN, "Begin, ms"); + + header_item->setText(COL_DURATION, "Duration"); + header_item->setText(COL_SELF_DURATION, "Self dur."); + //header_item->setToolTip(COL_SELF_DURATION, ""); + header_item->setText(COL_DURATION_SUM_PER_PARENT, "Total / Parent"); + header_item->setText(COL_DURATION_SUM_PER_FRAME, "Total / Frame"); + header_item->setText(COL_DURATION_SUM_PER_THREAD, "Total / Thread"); + + header_item->setText(COL_SELF_DURATION_PERCENT, "Self %"); + header_item->setText(COL_PERCENT_PER_PARENT, "% / Parent"); + header_item->setText(COL_PERCENT_PER_FRAME, "% / Frame"); + header_item->setText(COL_PERCENT_SUM_PER_FRAME, "Sum % / Frame"); + header_item->setText(COL_PERCENT_SUM_PER_PARENT, "Sum % / Parent"); + header_item->setText(COL_PERCENT_SUM_PER_THREAD, "Sum % / Thread"); + + header_item->setText(COL_END, "End, ms"); + + header_item->setText(COL_MIN_PER_FRAME, "Min / Frame"); + header_item->setText(COL_MAX_PER_FRAME, "Max / Frame"); + header_item->setText(COL_AVERAGE_PER_FRAME, "Avg / Frame"); + header_item->setText(COL_NCALLS_PER_FRAME, "N Calls / Frame"); + + header_item->setText(COL_MIN_PER_PARENT, "Min / Parent"); + header_item->setText(COL_MAX_PER_PARENT, "Max / Parent"); + header_item->setText(COL_AVERAGE_PER_PARENT, "Avg / Parent"); + header_item->setText(COL_NCALLS_PER_PARENT, "N Calls / Parent"); + + header_item->setText(COL_MIN_PER_THREAD, "Min / Thread"); + header_item->setText(COL_MAX_PER_THREAD, "Max / Thread"); + header_item->setText(COL_AVERAGE_PER_THREAD, "Avg / Thread"); + header_item->setText(COL_NCALLS_PER_THREAD, "N Calls / Thread"); + + header_item->setText(COL_ACTIVE_TIME, "Active time"); + header_item->setText(COL_ACTIVE_PERCENT, "Active %"); + + auto color = QColor::fromRgb(::profiler::colors::DeepOrange900); + header_item->setForeground(COL_MIN_PER_THREAD, color); + header_item->setForeground(COL_MAX_PER_THREAD, color); + header_item->setForeground(COL_AVERAGE_PER_THREAD, color); + header_item->setForeground(COL_NCALLS_PER_THREAD, color); + header_item->setForeground(COL_PERCENT_SUM_PER_THREAD, color); + header_item->setForeground(COL_DURATION_SUM_PER_THREAD, color); + + color = QColor::fromRgb(::profiler::colors::Blue900); + header_item->setForeground(COL_MIN_PER_FRAME, color); + header_item->setForeground(COL_MAX_PER_FRAME, color); + header_item->setForeground(COL_AVERAGE_PER_FRAME, color); + header_item->setForeground(COL_NCALLS_PER_FRAME, color); + header_item->setForeground(COL_PERCENT_SUM_PER_FRAME, color); + header_item->setForeground(COL_DURATION_SUM_PER_FRAME, color); + header_item->setForeground(COL_PERCENT_PER_FRAME, color); + + color = QColor::fromRgb(::profiler::colors::Teal900); + header_item->setForeground(COL_MIN_PER_PARENT, color); + header_item->setForeground(COL_MAX_PER_PARENT, color); + header_item->setForeground(COL_AVERAGE_PER_PARENT, color); + header_item->setForeground(COL_NCALLS_PER_PARENT, color); + header_item->setForeground(COL_PERCENT_SUM_PER_PARENT, color); + header_item->setForeground(COL_DURATION_SUM_PER_PARENT, color); + header_item->setForeground(COL_PERCENT_PER_PARENT, color); + + setHeaderItem(header_item); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChange, Qt::QueuedConnection); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange, Qt::QueuedConnection); + connect(&m_fillTimer, &QTimer::timeout, this, &This::onFillTimerTimeout); + + loadSettings(); + + m_columnsHiddenStatus[0] = 0; + setColumnHidden(0, false); + + if (m_mode == EasyTreeMode_Full) + { + for (int i = 1; i < COL_COLUMNS_NUMBER; ++i) + m_columnsHiddenStatus[i] = isColumnHidden(i) ? 1 : 0; + } + else + { + for (int i = 1; i < COL_COLUMNS_NUMBER; ++i) + { + if (SIMPLIFIED_REGIME_COLUMNS[i]) + { + if (isColumnHidden(i)) + m_columnsHiddenStatus[i] = 1; + } + else if (!isColumnHidden(i)) + { + setColumnHidden(i, true); + } + } + } + + m_hintLabel = new QLabel("Use Right Mouse Button on the Diagram to build a hierarchy...\nPress and hold, move, release", this); + m_hintLabel->setAlignment(Qt::AlignCenter); + m_hintLabel->setStyleSheet("QLabel { color: gray; font: 12pt; }"); + + QTimer::singleShot(1500, this, &This::alignProgressBar); + + setItemDelegateForColumn(0, new EasyItemDelegate(this)); +} + +EasyTreeWidget::~EasyTreeWidget() +{ + saveSettings(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onFillTimerTimeout() +{ + if (m_hierarchyBuilder.done()) + { + m_fillTimer.stop(); + + ThreadedItems toplevelitems; + m_hierarchyBuilder.takeItems(m_items); + m_hierarchyBuilder.takeTopLevelItems(toplevelitems); + m_hierarchyBuilder.interrupt(); + { + const QSignalBlocker b(this); + for (auto& item : toplevelitems) + { + addTopLevelItem(item.second); + m_roots[item.first] = item.second; + } + } + + destroyProgressDialog(); + + m_bLocked = false; + m_inputBlocks.clear(); + + setSortingEnabled(true); + + sortByColumn(COL_BEGIN, Qt::AscendingOrder); // sort by begin time + if (m_mode == EasyTreeMode_Plain) // and after that, sort by frame % + sortByColumn(COL_PERCENT_PER_FRAME, Qt::DescendingOrder); + + //resizeColumnToContents(COL_NAME); + resizeColumnsToContents(); + + connect(this, &Parent::itemExpanded, this, &This::onItemExpand); + connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse); + connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange); + onSelectedThreadChange(EASY_GLOBALS.selected_thread); + onSelectedBlockChange(EASY_GLOBALS.selected_block); + } + else if (m_progress != nullptr) + { + m_progress->setValue(m_hierarchyBuilder.progress()); + } +} + +void EasyTreeWidget::setTree(const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree) +{ + clearSilent(); + + if (!_blocksTree.empty()) + { + m_bLocked = true; + m_hintLabel->hide(); + createProgressDialog(); + m_hierarchyBuilder.fillTree(m_beginTime, _blocksNumber, _blocksTree, m_mode); + m_fillTimer.start(HIERARCHY_BUILDER_TIMER_INTERVAL); + } + + //StubLocker l; + //ThreadedItems toplevelitems; + //FillTreeClass::setTreeInternal1(l, m_items, toplevelitems, m_beginTime, _blocksNumber, _blocksTree, m_bColorRows); + //{ + // const QSignalBlocker b(this); + // for (auto& item : toplevelitems) + // { + // addTopLevelItem(item.second); + // m_roots[item.first] = item.second; + // if (item.first == EASY_GLOBALS.selected_thread) + // item.second->setMain(true); + // } + //} +} + +void EasyTreeWidget::setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _session_begin_time, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict) +{ + clearSilent(); + + m_beginTime = _session_begin_time; + _left += m_beginTime;// - ::std::min(m_beginTime, 1000ULL); + _right += m_beginTime;// + 1000; + + m_inputBlocks = _blocks; + if (!m_inputBlocks.empty()) + { + m_bLocked = true; + m_hintLabel->hide(); + createProgressDialog(); + m_hierarchyBuilder.fillTreeBlocks(m_inputBlocks, _session_begin_time, _left, _right, _strict, m_mode); + m_fillTimer.start(HIERARCHY_BUILDER_TIMER_INTERVAL); + } + + //StubLocker l; + //ThreadedItems toplevelitems; + //FillTreeClass::setTreeInternal2(l, m_items, toplevelitems, m_beginTime, _blocks, _left, _right, _strict, m_bColorRows); + //{ + // const QSignalBlocker b(this); + // for (auto& item : toplevelitems) + // { + // addTopLevelItem(item.second); + // m_roots[item.first] = item.second; + // if (item.first == EASY_GLOBALS.selected_thread) + // item.second->setMain(true); + // } + //} + + //setSortingEnabled(true); + //sortByColumn(COL_BEGIN, Qt::AscendingOrder); + //resizeColumnToContents(COL_NAME); + + //connect(this, &Parent::itemExpanded, this, &This::onItemExpand); + //connect(this, &Parent::itemCollapsed, this, &This::onItemCollapse); + //onSelectedBlockChange(EASY_GLOBALS.selected_block); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::clearSilent(bool _global) +{ + const QSignalBlocker b(this); + + m_hierarchyBuilder.interrupt(); + destroyProgressDialog(); + m_hintLabel->show(); + + m_bLocked = false; + m_beginTime = ::std::numeric_limits::max(); + + setSortingEnabled(false); + disconnect(this, &Parent::itemExpanded, this, &This::onItemExpand); + disconnect(this, &Parent::itemCollapsed, this, &This::onItemCollapse); + disconnect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange); + m_lastFound = nullptr; + m_lastSearch.clear(); + + if (!_global) + { + if (EASY_GLOBALS.collapse_items_on_tree_close) +#ifdef EASY_TREE_WIDGET__USE_VECTOR + for (auto item : m_items) +#else + for (auto& item : m_items) +#endif + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + auto& gui_block = item->guiBlock(); + gui_block.expanded = false; + ::profiler_gui::set_max(gui_block.tree_item); +#else + item.second->guiBlock().expanded = false; +#endif + } +#ifdef EASY_TREE_WIDGET__USE_VECTOR + else for (auto item : m_items) + { + ::profiler_gui::set_max(item->guiBlock().tree_item); + } +#endif + } + + m_items.clear(); + m_roots.clear(); + + ::std::vector topLevelItems; + topLevelItems.reserve(static_cast(topLevelItemCount())); + for (int i = topLevelItemCount() - 1; i >= 0; --i) + topLevelItems.push_back(takeTopLevelItem(i)); + + auto deleter_thread = ::std::thread([](decltype(topLevelItems) _items) + { +#ifdef _WIN32 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); +#endif + + for (auto item : _items) + delete item; + + }, ::std::move(topLevelItems)); + + deleter_thread.detach(); + + //clear(); + + if (!_global) + emit EASY_GLOBALS.events.itemsExpandStateChanged(); +} + +////////////////////////////////////////////////////////////////////////// + +int EasyTreeWidget::findNext(const QString& _str, Qt::MatchFlags _flags) +{ + if (m_bLocked || _str.isEmpty()) + return 0; + + const bool isNewSearch = (m_lastSearch != _str); + auto itemsList = findItems(_str, Qt::MatchContains | Qt::MatchRecursive | _flags, COL_NAME); + + if (!isNewSearch) + { + if (!itemsList.empty()) + { + bool stop = false; + decltype(m_lastFound) next = nullptr; + for (auto item : itemsList) + { + if (item->parent() == nullptr) + continue; + + if (stop) + { + next = item; + break; + } + + stop = item == m_lastFound; + } + + m_lastFound = next == nullptr ? itemsList.front() : next; + } + else + { + m_lastFound = nullptr; + } + } + else + { + m_lastSearch = _str; + m_lastFound = !itemsList.empty() ? itemsList.front() : nullptr; + } + + if (m_lastFound != nullptr) + { + scrollToItem(m_lastFound, QAbstractItemView::PositionAtCenter); + setCurrentItem(m_lastFound); + } + + return itemsList.size(); +} + +int EasyTreeWidget::findPrev(const QString& _str, Qt::MatchFlags _flags) +{ + if (m_bLocked || _str.isEmpty()) + return 0; + + const bool isNewSearch = (m_lastSearch != _str); + auto itemsList = findItems(_str, Qt::MatchContains | Qt::MatchRecursive | _flags, COL_NAME); + + if (!isNewSearch) + { + if (!itemsList.empty()) + { + decltype(m_lastFound) prev = nullptr; + for (auto item : itemsList) + { + if (item->parent() == nullptr) + continue; + + if (item == m_lastFound) + break; + + prev = item; + } + + m_lastFound = prev == nullptr ? itemsList.back() : prev; + } + else + { + m_lastFound = nullptr; + } + } + else + { + m_lastSearch = _str; + m_lastFound = !itemsList.empty() ? itemsList.front() : nullptr; + } + + if (m_lastFound != nullptr) + { + scrollToItem(m_lastFound, QAbstractItemView::PositionAtCenter); + setCurrentItem(m_lastFound); + } + + return itemsList.size(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event) +{ + if (m_bLocked) + { + _event->accept(); + return; + } + + const auto col = currentColumn(); + auto item = static_cast(currentItem()); + QMenu menu; + menu.setToolTipsVisible(true); + QAction* action = nullptr; + + if (!m_items.empty()) + { + action = menu.addAction("Expand all"); + connect(action, &QAction::triggered, this, &This::onExpandAllClicked); + action->setIcon(QIcon(imagePath("expand"))); + + action = menu.addAction("Collapse all"); + connect(action, &QAction::triggered, this, &This::onCollapseAllClicked); + action->setIcon(QIcon(imagePath("collapse"))); + + if (item != nullptr && col >= 0) + { + menu.addSeparator(); + + action = menu.addAction("Expand all children"); + connect(action, &QAction::triggered, this, &This::onExpandAllChildrenClicked); + action->setIcon(QIcon(imagePath("expand"))); + + action = menu.addAction("Collapse all children"); + connect(action, &QAction::triggered, this, &This::onCollapseAllChildrenClicked); + action->setIcon(QIcon(imagePath("collapse"))); + } + + menu.addSeparator(); + } + + auto actionGroup = new QActionGroup(&menu); + actionGroup->setExclusive(true); + + auto actionHierarchy = new QAction("Hierarchy mode", actionGroup); + actionHierarchy->setCheckable(true); + actionHierarchy->setChecked(m_mode == EasyTreeMode_Full); + actionHierarchy->setToolTip("Display full blocks hierarchy"); + actionHierarchy->setData((quint32)EasyTreeMode_Full); + menu.addAction(actionHierarchy); + + auto actionPlain = new QAction("Plain mode", actionGroup); + actionPlain->setCheckable(true); + actionPlain->setChecked(m_mode == EasyTreeMode_Plain); + actionPlain->setToolTip("Display plain list of blocks per frame.\nSome columns are disabled with this mode."); + actionPlain->setData((quint32)EasyTreeMode_Plain); + menu.addAction(actionPlain); + + connect(actionHierarchy, &QAction::triggered, this, &This::onModeChange); + connect(actionPlain, &QAction::triggered, this, &This::onModeChange); + + menu.addSeparator(); + + if (item != nullptr && item->parent() != nullptr) + { + if (col >= 0) + { + switch (col) + { + case COL_MIN_PER_THREAD: + case COL_MIN_PER_PARENT: + case COL_MIN_PER_FRAME: + case COL_MAX_PER_THREAD: + case COL_MAX_PER_PARENT: + case COL_MAX_PER_FRAME: + { + auto& block = item->block(); + auto i = ::profiler_gui::numeric_max(); + switch (col) + { + case COL_MIN_PER_THREAD: i = block.per_thread_stats->min_duration_block; break; + case COL_MIN_PER_PARENT: i = block.per_parent_stats->min_duration_block; break; + case COL_MIN_PER_FRAME: i = block.per_frame_stats->min_duration_block; break; + case COL_MAX_PER_THREAD: i = block.per_thread_stats->max_duration_block; break; + case COL_MAX_PER_PARENT: i = block.per_parent_stats->max_duration_block; break; + case COL_MAX_PER_FRAME: i = block.per_frame_stats->max_duration_block; break; + } + + if (i != ::profiler_gui::numeric_max(i)) + { + menu.addSeparator(); + auto itemAction = new QAction("Jump to such item", nullptr); + itemAction->setData(i); + itemAction->setToolTip("Jump to item with min/max duration (depending on clicked column)"); + connect(itemAction, &QAction::triggered, this, &This::onJumpToItemClicked); + menu.addAction(itemAction); + } + + break; + } + + default: + break; + } + } + + const auto& desc = easyDescriptor(item->block().node->id()); + auto submenu = menu.addMenu("Block status"); + submenu->setToolTipsVisible(true); + +#define ADD_STATUS_ACTION(NameValue, StatusValue, ToolTipValue)\ + action = submenu->addAction(NameValue);\ + action->setCheckable(true);\ + action->setChecked(desc.status() == StatusValue);\ + action->setData(static_cast(StatusValue));\ + action->setToolTip(ToolTipValue);\ + connect(action, &QAction::triggered, this, &This::onBlockStatusChangeClicked) + + ADD_STATUS_ACTION("Off", ::profiler::OFF, "Do not profile this block."); + ADD_STATUS_ACTION("On", ::profiler::ON, "Profile this block\nif parent enabled children."); + ADD_STATUS_ACTION("Force-On", ::profiler::FORCE_ON, "Always profile this block even\nif it's parent disabled children."); + ADD_STATUS_ACTION("Off-recursive", ::profiler::OFF_RECURSIVE, "Do not profile neither this block\nnor it's children."); + ADD_STATUS_ACTION("On-without-children", ::profiler::ON_WITHOUT_CHILDREN, "Profile this block, but\ndo not profile it's children."); + ADD_STATUS_ACTION("Force-On-without-children", ::profiler::FORCE_ON_WITHOUT_CHILDREN, "Always profile this block, but\ndo not profile it's children."); +#undef ADD_STATUS_ACTION + + submenu->setEnabled(EASY_GLOBALS.connected); + if (!EASY_GLOBALS.connected) + submenu->setTitle(QString("%1 (connection needed)").arg(submenu->title())); + } + + auto hidemenu = menu.addMenu("Select columns"); + auto hdr = headerItem(); + + for (int i = 1; i < COL_COLUMNS_NUMBER; ++i) + { + auto columnAction = new QAction(hdr->text(i), nullptr); + columnAction->setData(i); + columnAction->setCheckable(true); + columnAction->setChecked(m_columnsHiddenStatus[i] == 0); + if ((m_mode == EasyTreeMode_Full || SIMPLIFIED_REGIME_COLUMNS[i])) + connect(columnAction, &QAction::triggered, this, &This::onHideShowColumn); + else + columnAction->setEnabled(false); + hidemenu->addAction(columnAction); + } + + menu.exec(QCursor::pos()); + + _event->accept(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::resizeEvent(QResizeEvent* _event) +{ + Parent::resizeEvent(_event); + alignProgressBar(); +} + +void EasyTreeWidget::moveEvent(QMoveEvent* _event) +{ + Parent::moveEvent(_event); + alignProgressBar(); +} + +void EasyTreeWidget::alignProgressBar() +{ + auto center = rect().center(); + auto pos = mapToGlobal(center); + + if (m_progress != nullptr) + m_progress->move(pos.x() - (m_progress->width() >> 1), pos.y() - (m_progress->height() >> 1)); + + m_hintLabel->move(center.x() - (m_hintLabel->width() >> 1), std::max(center.y() - (m_hintLabel->height() >> 1), header()->height())); +} + +void EasyTreeWidget::destroyProgressDialog() +{ + if (m_progress != nullptr) + { + m_progress->setValue(100); + m_progress->deleteLater(); + m_progress = nullptr; + } +} + +void EasyTreeWidget::createProgressDialog() +{ + destroyProgressDialog(); + + m_progress = new QProgressDialog("Building blocks hierarchy...", "", 0, 100, this, Qt::FramelessWindowHint); + m_progress->setAttribute(Qt::WA_TranslucentBackground); + m_progress->setCancelButton(nullptr); + m_progress->setValue(0); + m_progress->show(); + + alignProgressBar(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onJumpToItemClicked(bool) +{ + auto action = qobject_cast(sender()); + if (action == nullptr) + return; + + auto block_index = action->data().toUInt(); + EASY_GLOBALS.selected_block = block_index; + if (block_index < EASY_GLOBALS.gui_blocks.size()) + EASY_GLOBALS.selected_block_id = easyBlock(block_index).tree.node->id(); + else + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + emit EASY_GLOBALS.events.selectedBlockChanged(block_index); +} + +void EasyTreeWidget::onCollapseAllClicked(bool) +{ + const QSignalBlocker b(this); + + m_bSilentExpandCollapse = true; + collapseAll(); + m_bSilentExpandCollapse = false; + + if (EASY_GLOBALS.bind_scene_and_tree_expand_status) + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + for (auto item : m_items) + item->guiBlock().expanded = false; +#else + for (auto& item : m_items) + item.second->guiBlock().expanded = false; +#endif + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } +} + +void EasyTreeWidget::onExpandAllClicked(bool) +{ + const QSignalBlocker b(this); + + m_bSilentExpandCollapse = true; + expandAll(); + resizeColumnsToContents(); + m_bSilentExpandCollapse = false; + + if (EASY_GLOBALS.bind_scene_and_tree_expand_status) + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + for (auto item : m_items){ + auto& b = item->guiBlock(); +#else + for (auto& item : m_items){ + auto& b = item.second->guiBlock(); +#endif + b.expanded = !b.tree.children.empty(); + } + + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } +} + +void EasyTreeWidget::onCollapseAllChildrenClicked(bool) +{ + auto current = static_cast(currentItem()); + if (current != nullptr) + { + const QSignalBlocker b(this); + + m_bSilentExpandCollapse = true; + current->collapseAll(); + m_bSilentExpandCollapse = false; + + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } +} + +void EasyTreeWidget::onExpandAllChildrenClicked(bool) +{ + auto current = static_cast(currentItem()); + if (current != nullptr) + { + const QSignalBlocker b(this); + + m_bSilentExpandCollapse = true; + current->expandAll(); + resizeColumnsToContents(); + m_bSilentExpandCollapse = false; + + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onBlockStatusChangeClicked(bool _checked) +{ + if (!_checked) + return; + + auto item = static_cast(currentItem()); + if (item == nullptr) + return; + + auto action = qobject_cast(sender()); + if (action != nullptr) + { + auto& desc = easyDescriptor(item->block().node->id()); + desc.setStatus(static_cast<::profiler::EasyBlockStatus>(action->data().toUInt())); + emit EASY_GLOBALS.events.blockStatusChanged(desc.id(), desc.status()); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onItemExpand(QTreeWidgetItem* _item) +{ + if (!EASY_GLOBALS.bind_scene_and_tree_expand_status || _item->parent() == nullptr) + { + resizeColumnsToContents(); + return; + } + + static_cast(_item)->guiBlock().expanded = true; + + if (!m_bSilentExpandCollapse) + { + resizeColumnsToContents(); + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } +} + +void EasyTreeWidget::onItemCollapse(QTreeWidgetItem* _item) +{ + if (!EASY_GLOBALS.bind_scene_and_tree_expand_status || _item->parent() == nullptr) + return; + + static_cast(_item)->guiBlock().expanded = false; + + if (!m_bSilentExpandCollapse) + emit EASY_GLOBALS.events.itemsExpandStateChanged(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _previous) +{ + if (_previous != nullptr) + static_cast(_previous)->setBold(false); + + if (_item == nullptr) + { + ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + } + else + { + auto item = static_cast(_item); + item->setBold(true); + + EASY_GLOBALS.selected_block = item->block_index(); + if (EASY_GLOBALS.selected_block < EASY_GLOBALS.gui_blocks.size()) + EASY_GLOBALS.selected_block_id = easyBlock(EASY_GLOBALS.selected_block).tree.node->id(); + else + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + } + + disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); + emit EASY_GLOBALS.events.selectedBlockChanged(EASY_GLOBALS.selected_block); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onSelectedThreadChange(::profiler::thread_id_t _id) +{ + for (auto& it : m_roots) + { + auto item = it.second; + item->setMain(it.first == _id); + } + + // Calling update() or repaint() (or both!) does not work even if setUpdatesEnabled(true) have been set in constructor. + // Have to set focus to this widget to force update/repaint. :( + // TODO: Find valid solution instead of this workaround. + auto f = qApp->focusWidget(); + setFocus(); + if (f != nullptr) + f->setFocus(); +} + +void EasyTreeWidget::onSelectedBlockChange(uint32_t _block_index) +{ + disconnect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange); + + EasyTreeWidgetItem* item = nullptr; + + if (_block_index < EASY_GLOBALS.gui_blocks.size()) + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + const auto i = easyBlock(_block_index).tree_item; + if (i < m_items.size()) + item = m_items[i]; +#else + auto it = m_items.find(_block_index); + if (it != m_items.end()) + item = it->second; +#endif + } + + auto previous = static_cast(currentItem()); + if (previous != nullptr) + previous->setBold(false); + + if (item != nullptr) + { + //const QSignalBlocker b(this); + + if (EASY_GLOBALS.bind_scene_and_tree_expand_status) + { + m_bSilentExpandCollapse = true; + setCurrentItem(item); + scrollToItem(item, QAbstractItemView::PositionAtCenter); + if (item->guiBlock().expanded) + expandItem(item); + else + collapseItem(item); + resizeColumnsToContents(); + m_bSilentExpandCollapse = false; + + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + } + else + { + disconnect(this, &Parent::itemExpanded, this, &This::onItemExpand); + setCurrentItem(item); + scrollToItem(item, QAbstractItemView::PositionAtCenter); + resizeColumnsToContents(); + connect(this, &Parent::itemExpanded, this, &This::onItemExpand); + } + + item->setBold(true); + } + else + { + setCurrentItem(item); + } + + connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::resizeColumnsToContents() +{ + for (int i = 0; i < COL_COLUMNS_NUMBER; ++i) + { + resizeColumnToContents(i); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::onHideShowColumn(bool) +{ + auto action = qobject_cast(sender()); + if (action == nullptr) + return; + + const auto col = action->data().toInt(); + const bool hideCol = m_columnsHiddenStatus[col] == 0; + setColumnHidden(col, hideCol); + m_columnsHiddenStatus[col] = hideCol ? 1 : 0; +} + +void EasyTreeWidget::onModeChange(bool) +{ + auto action = qobject_cast(sender()); + if (action == nullptr) + return; + + const auto prev = m_mode; + m_mode = static_cast(action->data().toUInt()); + + if (m_mode == prev) + return; + + if (m_mode == EasyTreeMode_Full) + { + for (int i = 1; i < COL_COLUMNS_NUMBER; ++i) + setColumnHidden(i, m_columnsHiddenStatus[i] != 0); + } + else + { + for (int i = 1; i < COL_COLUMNS_NUMBER; ++i) + setColumnHidden(i, m_columnsHiddenStatus[i] != 0 || !SIMPLIFIED_REGIME_COLUMNS[i]); + } + + emit EASY_GLOBALS.events.blocksTreeModeChanged(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidget::loadSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("tree_widget"); + + auto val = settings.value("regime"); + if (!val.isNull()) + m_mode = static_cast(val.toUInt()); + + val = settings.value("columns"); + if (!val.isNull()) + { + auto byteArray = val.toByteArray(); + memcpy(m_columnsHiddenStatus, byteArray.constData(), ::std::min(sizeof(m_columnsHiddenStatus), (size_t)byteArray.size())); + } + + auto state = settings.value("headerState").toByteArray(); + if (!state.isEmpty()) + header()->restoreState(state); + + settings.endGroup(); +} + +void EasyTreeWidget::saveSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("tree_widget"); + settings.setValue("regime", static_cast(m_mode)); + settings.setValue("columns", QByteArray(m_columnsHiddenStatus, COL_COLUMNS_NUMBER)); + settings.setValue("headerState", header()->saveState()); + settings.endGroup(); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +EasyHierarchyWidget::EasyHierarchyWidget(QWidget* _parent) : Parent(_parent) + , m_tree(new EasyTreeWidget(this)) + , m_searchBox(new QLineEdit(this)) + , m_foundNumber(new QLabel("Found 0 matches", this)) + , m_searchButton(nullptr) + , m_bCaseSensitiveSearch(false) +{ + loadSettings(); + + m_searchBox->setFixedWidth(300); + m_searchBox->setContentsMargins(5, 0, 0, 0); + + auto menu = new QMenu(this); + m_searchButton = menu->menuAction(); + m_searchButton->setText("Find next"); + m_searchButton->setIcon(QIcon(imagePath("find-next"))); + m_searchButton->setData(true); + connect(m_searchButton, &QAction::triggered, this, &This::findNext); + + auto actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + + auto a = new QAction(tr("Find next"), actionGroup); + a->setCheckable(true); + a->setChecked(true); + connect(a, &QAction::triggered, this, &This::findNextFromMenu); + menu->addAction(a); + + a = new QAction(tr("Find previous"), actionGroup); + a->setCheckable(true); + connect(a, &QAction::triggered, this, &This::findPrevFromMenu); + menu->addAction(a); + + a = menu->addAction("Case sensitive"); + a->setCheckable(true); + a->setChecked(m_bCaseSensitiveSearch); + connect(a, &QAction::triggered, [this](bool _checked){ m_bCaseSensitiveSearch = _checked; }); + menu->addAction(a); + + auto tb = new QToolBar(this); + tb->setIconSize(::profiler_gui::ICONS_SIZE); + tb->setContentsMargins(0, 0, 0, 0); + tb->addAction(m_searchButton); + tb->addWidget(m_searchBox); + + auto searchbox = new QHBoxLayout(); + searchbox->setContentsMargins(0, 0, 5, 0); + searchbox->addWidget(tb); + searchbox->addStretch(100); + searchbox->addWidget(m_foundNumber, Qt::AlignRight); + + auto lay = new QVBoxLayout(this); + lay->setContentsMargins(1, 1, 1, 1); + lay->addLayout(searchbox); + lay->addWidget(m_tree); + + connect(m_searchBox, &QLineEdit::returnPressed, this, &This::onSeachBoxReturnPressed); +} + +EasyHierarchyWidget::~EasyHierarchyWidget() +{ + saveSettings(); +} + +void EasyHierarchyWidget::loadSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("EasyHierarchyWidget"); + + auto val = settings.value("case_sensitive"); + if (!val.isNull()) + m_bCaseSensitiveSearch = val.toBool(); + + settings.endGroup(); +} + +void EasyHierarchyWidget::saveSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("EasyHierarchyWidget"); + settings.setValue("case_sensitive", m_bCaseSensitiveSearch); + settings.endGroup(); +} + +void EasyHierarchyWidget::keyPressEvent(QKeyEvent* _event) +{ + if (_event->key() == Qt::Key_F3) + { + if (_event->modifiers() & Qt::ShiftModifier) + findPrev(true); + else + findNext(true); + } + + _event->accept(); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void EasyHierarchyWidget::contextMenuEvent(QContextMenuEvent* _event) +{ + m_tree->contextMenuEvent(_event); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +EasyTreeWidget* EasyHierarchyWidget::tree() +{ + return m_tree; +} + +void EasyHierarchyWidget::clear(bool _global) +{ + m_tree->clearSilent(_global); + m_foundNumber->setText(QString("Found 0 matches")); +} + +void EasyHierarchyWidget::onSeachBoxReturnPressed() +{ + if (m_searchButton->data().toBool() == true) + findNext(true); + else + findPrev(true); +} + +void EasyHierarchyWidget::findNext(bool) +{ + auto matches = m_tree->findNext(m_searchBox->text(), m_bCaseSensitiveSearch ? Qt::MatchCaseSensitive : Qt::MatchFlags()); + + if (matches == 1) + m_foundNumber->setText(QString("Found 1 match")); + else + m_foundNumber->setText(QString("Found %1 matches").arg(matches)); +} + +void EasyHierarchyWidget::findPrev(bool) +{ + auto matches = m_tree->findPrev(m_searchBox->text(), m_bCaseSensitiveSearch ? Qt::MatchCaseSensitive : Qt::MatchFlags()); + + if (matches == 1) + m_foundNumber->setText(QString("Found 1 match")); + else + m_foundNumber->setText(QString("Found %1 matches").arg(matches)); +} + +void EasyHierarchyWidget::findNextFromMenu(bool _checked) +{ + if (!_checked) + return; + + if (m_searchButton->data().toBool() == false) + { + m_searchButton->setData(true); + m_searchButton->setText(tr("Find next")); + m_searchButton->setIcon(QIcon(imagePath("find-next"))); + disconnect(m_searchButton, &QAction::triggered, this, &This::findPrev); + connect(m_searchButton, &QAction::triggered, this, &This::findNext); + } + + findNext(true); +} + +void EasyHierarchyWidget::findPrevFromMenu(bool _checked) +{ + if (!_checked) + return; + + if (m_searchButton->data().toBool() == true) + { + m_searchButton->setData(false); + m_searchButton->setText(tr("Find prev")); + m_searchButton->setIcon(QIcon(imagePath("find-prev"))); + disconnect(m_searchButton, &QAction::triggered, this, &This::findNext); + connect(m_searchButton, &QAction::triggered, this, &This::findPrev); + } + + findPrev(true); +} + +////////////////////////////////////////////////////////////////////////// diff --git a/3rdparty/easyprofiler/profiler_gui/blocks_tree_widget.h b/3rdparty/easyprofiler/profiler_gui/blocks_tree_widget.h new file mode 100644 index 0000000..f5d484e --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/blocks_tree_widget.h @@ -0,0 +1,219 @@ +/************************************************************************ +* file name : blocks_tree_widget.h +* ----------------- : +* creation time : 2016/06/26 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyTreeWidget and it's auxiliary classes +* : for displyaing EasyProfiler blocks tree. +* ----------------- : +* change log : * 2016/06/26 Victor Zarubkin: moved sources from tree_view.h +* : and renamed classes from My* to Prof*. +* : +* : * 2016/06/27 Victor Zarubkin: Added possibility to colorize rows +* : with profiler blocks' colors. +* : +* : * 2016/06/29 Victor Zarubkin: Added clearSilent() method. +* : +* : * 2016/08/18 Victor Zarubkin: Added loading blocks hierarchy in separate thread; +* : Moved sources of TreeWidgetItem into tree_widget_item.h/.cpp +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_TREE_WIDGET_H +#define EASY_TREE_WIDGET_H + +#include +#include + +#include "tree_widget_loader.h" +#include "tree_widget_item.h" + +#include + +////////////////////////////////////////////////////////////////////////// + +class EasyTreeWidget : public QTreeWidget +{ + Q_OBJECT + + typedef QTreeWidget Parent; + typedef EasyTreeWidget This; + +protected: + + EasyTreeWidgetLoader m_hierarchyBuilder; + Items m_items; + RootsMap m_roots; + ::profiler_gui::TreeBlocks m_inputBlocks; + QTimer m_fillTimer; + QString m_lastSearch; + QTreeWidgetItem* m_lastFound; + ::profiler::timestamp_t m_beginTime; + class QProgressDialog* m_progress; + class QLabel* m_hintLabel; + EasyTreeMode m_mode; + bool m_bLocked; + bool m_bSilentExpandCollapse; + char m_columnsHiddenStatus[COL_COLUMNS_NUMBER]; + +public: + + explicit EasyTreeWidget(QWidget* _parent = nullptr); + virtual ~EasyTreeWidget(); + + void contextMenuEvent(QContextMenuEvent* _event) override; + + void clearSilent(bool _global = false); + int findNext(const QString& _str, Qt::MatchFlags _flags); + int findPrev(const QString& _str, Qt::MatchFlags _flags); + +public slots: + + void setTree(const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree); + + void setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _session_begin_time, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict); + +protected: + + void resizeEvent(QResizeEvent* _event) override; + void moveEvent(QMoveEvent* _event) override; + +private slots: + + void onJumpToItemClicked(bool); + + void onCollapseAllClicked(bool); + + void onExpandAllClicked(bool); + + void onCollapseAllChildrenClicked(bool); + + void onExpandAllChildrenClicked(bool); + + void onItemExpand(QTreeWidgetItem* _item); + void onItemCollapse(QTreeWidgetItem* _item); + void onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem*); + + void onSelectedThreadChange(::profiler::thread_id_t _id); + + void onSelectedBlockChange(uint32_t _block_index); + + void onBlockStatusChangeClicked(bool); + + void resizeColumnsToContents(); + + void onHideShowColumn(bool); + void onModeChange(bool); + + void onFillTimerTimeout(); + +protected: + + void loadSettings(); + void saveSettings(); + void alignProgressBar(); + +private: + + void destroyProgressDialog(); + void createProgressDialog(); + +}; // END of class EasyTreeWidget. + +////////////////////////////////////////////////////////////////////////// + +class EasyHierarchyWidget : public QWidget +{ + Q_OBJECT + + typedef QWidget Parent; + typedef EasyHierarchyWidget This; + +private: + + EasyTreeWidget* m_tree; + class QLineEdit* m_searchBox; + class QLabel* m_foundNumber; + class QAction* m_searchButton; + bool m_bCaseSensitiveSearch; + +public: + + // Public virtual methods + + explicit EasyHierarchyWidget(QWidget* _parent = nullptr); + virtual ~EasyHierarchyWidget(); + void keyPressEvent(QKeyEvent* _event) override; + void contextMenuEvent(QContextMenuEvent* _event) override; + +public: + + // Public non-virtual methods + + EasyTreeWidget* tree(); + void clear(bool _global = false); + +private slots: + + // Private slots + + void onSeachBoxReturnPressed(); + void findNext(bool); + void findPrev(bool); + void findNextFromMenu(bool); + void findPrevFromMenu(bool); + +private: + + // Private non-virtual methods + + void loadSettings(); + void saveSettings(); + +}; // END of class EasyHierarchyWidget. + + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_TREE_WIDGET_H diff --git a/3rdparty/easyprofiler/profiler_gui/cmake_install.cmake b/3rdparty/easyprofiler/profiler_gui/cmake_install.cmake new file mode 100644 index 0000000..b537650 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/cmake_install.cmake @@ -0,0 +1,54 @@ +# Install script for directory: /home/alex/Work/C++Projects/easyprofiler/profiler_gui + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +if(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui") + file(RPATH_CHECK + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui" + RPATH "$ORIGIN:/home/alex/Work/Qt/5.8/gcc_64/lib") + endif() + file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/alex/Work/C++Projects/easyprofiler/bin/profiler_gui") + if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui" AND + NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui") + file(RPATH_CHANGE + FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui" + OLD_RPATH "/home/alex/Work/Qt/5.8/gcc_64/lib:/home/alex/Work/C++Projects/easyprofiler/bin:" + NEW_RPATH "$ORIGIN:/home/alex/Work/Qt/5.8/gcc_64/lib") + if(CMAKE_INSTALL_DO_STRIP) + execute_process(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/profiler_gui") + endif() + endif() +endif() + diff --git a/3rdparty/easyprofiler/profiler_gui/common_functions.cpp b/3rdparty/easyprofiler/profiler_gui/common_functions.cpp new file mode 100644 index 0000000..9e337d9 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/common_functions.cpp @@ -0,0 +1,345 @@ +/************************************************************************ +* file name : common_functions.cpp +* ----------------- : +* creation time : 2017/12/06 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementaion of common functions used by different UI widgets. +* ----------------- : +* change log : * 2017/12/06 Victor Zarubkin: Initial commit. Moved sources from common_types.h +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include "common_functions.h" + +namespace profiler_gui { + + ////////////////////////////////////////////////////////////////////////// + + qreal timeFactor(qreal _interval) + { + if (_interval < 1) // interval in nanoseconds + return 1e3; + + if (_interval < 1e3) // interval in microseconds + return 1; + + if (_interval < 1e6) // interval in milliseconds + return 1e-3; + + // interval in seconds + return 1e-6; + } + + ////////////////////////////////////////////////////////////////////////// + + QString autoTimeStringReal(qreal _interval, int _precision) + { + if (_interval < 1) // interval in nanoseconds + return QString("%1 ns").arg(static_cast(_interval * 1e3)); + + if (_interval < 1e3) // interval in microseconds + return QString("%1 us").arg(_interval, 0, 'f', _precision); + + if (_interval < 1e6) // interval in milliseconds + return QString("%1 ms").arg(_interval * 1e-3, 0, 'f', _precision); + + // interval in seconds + return QString("%1 s").arg(_interval * 1e-6, 0, 'f', _precision); + } + + QString autoTimeStringInt(qreal _interval) + { + if (_interval < 1) // interval in nanoseconds + return QString("%1 ns").arg(static_cast(_interval * 1e3 + 0.5)); + + if (_interval < 1e3) // interval in microseconds + return QString("%1 us").arg(static_cast(_interval + 0.5)); + + if (_interval < 1e6) // interval in milliseconds + return QString("%1 ms").arg(static_cast(_interval * 1e-3 + 0.5)); + + // interval in seconds + return QString("%1 s").arg(static_cast(_interval * 1e-6 + 0.5)); + } + + QString autoTimeStringRealNs(::profiler::timestamp_t _interval, int _precision) + { + if (_interval < 1000) // interval in nanoseconds + return QString("%1 ns").arg(_interval); + + if (_interval < 1000000) // interval in microseconds + return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision); + + if (_interval < 1000000000U) // interval in milliseconds + return QString("%1 ms").arg(_interval * 1e-6, 0, 'f', _precision); + + // interval in seconds + return QString("%1 s").arg(_interval * 1e-9, 0, 'f', _precision); + } + + QString autoTimeStringIntNs(::profiler::timestamp_t _interval) + { + if (_interval < 1000) // interval in nanoseconds + return QString("%1 ns").arg(_interval); + + if (_interval < 1000000) // interval in microseconds + return QString("%1 us").arg(static_cast(_interval * 1e-3 + 0.5)); + + if (_interval < 1000000000U) // interval in milliseconds + return QString("%1 ms").arg(static_cast(_interval * 1e-6 + 0.5)); + + // interval in seconds + return QString("%1 s").arg(static_cast(_interval * 1e-9 + 0.5)); + } + + ////////////////////////////////////////////////////////////////////////// + + QString timeStringReal(TimeUnits _units, qreal _interval, int _precision) + { + switch (_units) + { + case TimeUnits_ms:{ + const char fmt = _interval <= 1 ? 'g' : 'f'; + return QString("%1 ms").arg(_interval * 1e-3, 0, fmt, _precision); + } + + case TimeUnits_us: + return QString("%1 us").arg(_interval, 0, 'f', _precision); + + case TimeUnits_ns: + return QString("%1 ns").arg(static_cast(_interval * 1e3 + 0.5)); + + case TimeUnits_auto: + default: + return autoTimeStringReal(_interval, _precision); + } + } + + QString timeStringRealNs(TimeUnits _units, ::profiler::timestamp_t _interval, int _precision) + { + switch (_units) + { + case TimeUnits_ms:{ + const char fmt = _interval <= 1000 ? 'g' : 'f'; + return QString("%1 ms").arg(_interval * 1e-6, 0, fmt, _precision); + } + + case TimeUnits_us: + return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision); + + case TimeUnits_ns: + return QString("%1 ns").arg(_interval); + + case TimeUnits_auto: + default: + return autoTimeStringRealNs(_interval, _precision); + } + } + + QString timeStringInt(TimeUnits _units, qreal _interval) + { + switch (_units) + { + case TimeUnits_ms: + return QString("%1 ms").arg(static_cast(_interval * 1e-3 + 0.5)); + + case TimeUnits_us: + return QString("%1 us").arg(static_cast(_interval + 0.5)); + + case TimeUnits_ns: + return QString("%1 ns").arg(static_cast(_interval * 1e3 + 0.5)); + + case TimeUnits_auto: + default: + return autoTimeStringInt(_interval); + } + } + + QString timeStringIntNs(TimeUnits _units, ::profiler::timestamp_t _interval) + { + switch (_units) + { + case TimeUnits_ms: + return QString("%1 ms").arg(static_cast(_interval * 1e-6 + 0.5)); + + case TimeUnits_us: + return QString("%1 us").arg(static_cast(_interval * 1e-3 + 0.5)); + + case TimeUnits_ns: + return QString("%1 ns").arg(_interval); + + case TimeUnits_auto: + default: + return autoTimeStringIntNs(_interval); + } + } + + ////////////////////////////////////////////////////////////////////////// + + QFont EFont(QFont::StyleHint _hint, const char* _family, int _size, int _weight) + { + QFont f; + f.setStyleHint(_hint, QFont::PreferMatch); + f.setFamily(_family); + f.setPointSize(_size); + f.setWeight(_weight); + return f; + } + + ////////////////////////////////////////////////////////////////////////// + + QString valueTypeString(::profiler::DataType _dataType) + { + switch (_dataType) + { + case ::profiler::DataType::Bool: return QStringLiteral("bool"); + case ::profiler::DataType::Char: return QStringLiteral("char"); + case ::profiler::DataType::Int8: return QStringLiteral("int8"); + case ::profiler::DataType::Uint8: return QStringLiteral("unsigned int8"); + case ::profiler::DataType::Int16: return QStringLiteral("int16"); + case ::profiler::DataType::Uint16: return QStringLiteral("unsigned int16"); + case ::profiler::DataType::Int32: return QStringLiteral("int32"); + case ::profiler::DataType::Uint32: return QStringLiteral("unsigned int32"); + case ::profiler::DataType::Int64: return QStringLiteral("int64"); + case ::profiler::DataType::Uint64: return QStringLiteral("unsigned int64"); + case ::profiler::DataType::Float: return QStringLiteral("float"); + case ::profiler::DataType::Double: return QStringLiteral("double"); + case ::profiler::DataType::String: return QStringLiteral("string"); + default: return QStringLiteral("unknown"); + } + } + + QString valueTypeString(const ::profiler::ArbitraryValue& _serializedValue) + { + const auto type = _serializedValue.type(); + if (_serializedValue.isArray() && type != ::profiler::DataType::String) + return valueTypeString(type) + QStringLiteral("[]"); + return valueTypeString(type); + } + + QString valueString(const ::profiler::ArbitraryValue& _serializedValue) + { + if (_serializedValue.isArray()) + { + if (_serializedValue.type() == ::profiler::DataType::String) + return _serializedValue.data(); + return QStringLiteral("[...] array"); + } + + switch (_serializedValue.type()) + { + case ::profiler::DataType::Bool: return _serializedValue.toValue()->value() ? QStringLiteral("true") : QStringLiteral("false"); + case ::profiler::DataType::Char: return QChar(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int8: return QChar(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint8: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int16: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint16: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int32: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint32: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int64: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint64: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Float: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::Double: return QString::number(_serializedValue.toValue()->value()); + case ::profiler::DataType::String: return _serializedValue.data(); + default: return QStringLiteral("Unknown"); + } + } + + double value2real(const ::profiler::ArbitraryValue& _serializedValue, int _index) + { + if (_serializedValue.isArray()) + { + switch (_serializedValue.type()) + { + case ::profiler::DataType::Bool: + { + const auto value = _serializedValue.toArray()->at(_index); + return value ? 1 : 0; + } + + case ::profiler::DataType::Char: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Int8: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Uint8: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Int16: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Uint16: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Int32: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Uint32: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Int64: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Uint64: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Float: return static_cast(_serializedValue.toArray()->at(_index)); + case ::profiler::DataType::Double: return _serializedValue.toArray()->at(_index); + case ::profiler::DataType::String: return static_cast(_serializedValue.data()[_index]); + default: return 0; + } + } + + switch (_serializedValue.type()) + { + case ::profiler::DataType::Bool: + { + const auto value = _serializedValue.toValue()->value(); + return value ? 1 : 0; + } + + case ::profiler::DataType::Char: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int8: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint8: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int16: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint16: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int32: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint32: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Int64: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Uint64: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Float: return static_cast(_serializedValue.toValue()->value()); + case ::profiler::DataType::Double: return _serializedValue.toValue()->value(); + case ::profiler::DataType::String: return static_cast(_serializedValue.data()[_index]); + default: return 0; + } + } + + ////////////////////////////////////////////////////////////////////////// + +} // end of namespace profiler_gui. diff --git a/3rdparty/easyprofiler/profiler_gui/common_functions.h b/3rdparty/easyprofiler/profiler_gui/common_functions.h new file mode 100644 index 0000000..7528962 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/common_functions.h @@ -0,0 +1,205 @@ +/************************************************************************ +* file name : common_functions.h +* ----------------- : +* creation time : 2017/12/06 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains common functions used by different UI widgets. +* ----------------- : +* change log : * 2017/12/06 Victor Zarubkin: Initial commit. Moved sources from common_types.h +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER_GUI_COMMON_FUNCTIONS_H +#define EASY_PROFILER_GUI_COMMON_FUNCTIONS_H + +#include +#include +#include +#include +#include "common_types.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#define PROF_MICROSECONDS(timestamp) ((timestamp) * 1e-3) +//#define PROF_MICROSECONDS(timestamp) (timestamp) + +#define PROF_FROM_MICROSECONDS(to_timestamp) ((to_timestamp) * 1e3) +//#define PROF_FROM_MICROSECONDS(to_timestamp) (to_timestamp) + +#define PROF_MILLISECONDS(timestamp) ((timestamp) * 1e-6) +//#define PROF_MILLISECONDS(timestamp) ((timestamp) * 1e-3) + +#define PROF_FROM_MILLISECONDS(to_timestamp) ((to_timestamp) * 1e6) +//#define PROF_FROM_MILLISECONDS(to_timestamp) ((to_timestamp) * 1e3) + +#define PROF_NANOSECONDS(timestamp) (timestamp) +//#define PROF_NANOSECONDS(timestamp) ((timestamp) * 1000) + +////////////////////////////////////////////////////////////////////////// + +EASY_FORCE_INLINE qreal units2microseconds(qreal _value) { + return _value; + //return _value * 1e3; +} + +EASY_FORCE_INLINE qreal microseconds2units(qreal _value) { + return _value; + //return _value * 1e-3; +} + +#ifdef EASY_CONSTEXPR_AVAILABLE +template +EASY_FORCE_INLINE EASY_CONSTEXPR_FCN typename ::std::underlying_type::type int_cast(TEnum _enumValue) { + return static_cast::type>(_enumValue); +} +#else +# define int_cast(_enumValue) static_cast<::std::underlying_type::type>(_enumValue) +#endif + +////////////////////////////////////////////////////////////////////////// + +namespace profiler_gui { + +////////////////////////////////////////////////////////////////////////// + +template inline +EASY_CONSTEXPR_FCN T numeric_max() { + return ::std::numeric_limits::max(); +} + +template inline +EASY_CONSTEXPR_FCN T numeric_max(T) { + return ::std::numeric_limits::max(); +} + +template inline +EASY_CONSTEXPR_FCN bool is_max(const T& _value) { + return _value == ::std::numeric_limits::max(); +} + +template inline +void set_max(T& _value) { + _value = ::std::numeric_limits::max(); +} + +////////////////////////////////////////////////////////////////////////// + +inline EASY_CONSTEXPR_FCN QRgb toRgb(uint32_t _red, uint32_t _green, uint32_t _blue) { + return (_red << 16) + (_green << 8) + _blue; +} + +inline EASY_CONSTEXPR_FCN QRgb fromProfilerRgb(uint32_t _red, uint32_t _green, uint32_t _blue) { + return _red == 0 && _green == 0 && _blue == 0 ? ::profiler::colors::Default : toRgb(_red, _green, _blue) | 0x00141414; +} + +EASY_FORCE_INLINE EASY_CONSTEXPR_FCN qreal colorSum(::profiler::color_t _color) { + return 255. - (((_color & 0x00ff0000) >> 16) * 0.299 + ((_color & 0x0000ff00) >> 8) * 0.587 + (_color & 0x000000ff) * 0.114); +} + +inline EASY_CONSTEXPR_FCN bool isLightColor(::profiler::color_t _color) { + return colorSum(_color) < 76.5 || ((_color & 0xff000000) >> 24) < 0x80; +} + +inline EASY_CONSTEXPR_FCN bool isLightColor(::profiler::color_t _color, qreal _maxSum) { + return colorSum(_color) < _maxSum || ((_color & 0xff000000) >> 24) < 0x80; +} + +inline EASY_CONSTEXPR_FCN ::profiler::color_t textColorForFlag(bool _is_light) { + return _is_light ? ::profiler::colors::Dark : ::profiler::colors::CreamWhite; +} + +inline EASY_CONSTEXPR_FCN ::profiler::color_t textColorForRgb(::profiler::color_t _color) { + return isLightColor(_color) ? ::profiler::colors::Dark : ::profiler::colors::CreamWhite; +} + +////////////////////////////////////////////////////////////////////////// + +qreal timeFactor(qreal _interval); + +QString autoTimeStringReal(qreal _interval, int _precision = 1); +QString autoTimeStringInt(qreal _interval); +QString autoTimeStringRealNs(::profiler::timestamp_t _interval, int _precision = 1); +QString autoTimeStringIntNs(::profiler::timestamp_t _interval); + +QString timeStringReal(TimeUnits _units, qreal _interval, int _precision = 1); +QString timeStringRealNs(TimeUnits _units, ::profiler::timestamp_t _interval, int _precision = 1); +QString timeStringInt(TimeUnits _units, qreal _interval); +QString timeStringIntNs(TimeUnits _units, ::profiler::timestamp_t _interval); + +////////////////////////////////////////////////////////////////////////// + +inline double percentReal(::profiler::timestamp_t _partial, ::profiler::timestamp_t _total) { + return _total != 0 ? 100. * static_cast(_partial) / static_cast(_total) : 0.; +} + +inline int percent(::profiler::timestamp_t _partial, ::profiler::timestamp_t _total) { + return static_cast(0.5 + percentReal(_partial, _total)); +} + +////////////////////////////////////////////////////////////////////////// + +QFont EFont(QFont::StyleHint _hint, const char* _family, int _size, int _weight = -1); + +inline QFont EFont(const char* _family, int _size, int _weight = -1) { + return EFont(QFont::Helvetica, _family, _size, _weight); +} + +////////////////////////////////////////////////////////////////////////// + +QString valueTypeString(::profiler::DataType _dataType); +QString valueTypeString(const ::profiler::ArbitraryValue& _serializedValue); +QString valueString(const ::profiler::ArbitraryValue& _serializedValue); +double value2real(const ::profiler::ArbitraryValue& _serializedValue, int _index = 0); + +////////////////////////////////////////////////////////////////////////// + +} // END of namespace profiler_gui. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_GUI_COMMON_FUNCTIONS_H diff --git a/3rdparty/easyprofiler/profiler_gui/common_types.h b/3rdparty/easyprofiler/profiler_gui/common_types.h new file mode 100644 index 0000000..c272703 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/common_types.h @@ -0,0 +1,205 @@ +/************************************************************************ +* file name : common_types.h +* ----------------- : +* creation time : 2016/07/31 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of common types for both GraphicsView +* : and TreeWidget. +* ----------------- : +* change log : * 2016/07/31 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER__GUI_COMMON_TYPES_H +#define EASY_PROFILER__GUI_COMMON_TYPES_H + +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler_gui { + +#define EASY_GRAPHICS_ITEM_RECURSIVE_PAINT +//#undef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + +#pragma pack(push, 1) +struct EasyBlockItem Q_DECL_FINAL +{ + qreal x; ///< x coordinate of the item (this is made qreal=double to avoid mistakes on very wide scene) + float w; ///< Width of the item + ::profiler::block_index_t block; ///< Index of profiler block + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + ::profiler::block_index_t neighbours; ///< Number of neighbours (parent.children.size()) + uint32_t children_begin; ///< Index of first child item on the next sublevel + int8_t state; ///< 0 = no change, 1 = paint, -1 = do not paint +#else + ::profiler::block_index_t max_depth_child; ///< Index of child with maximum tree depth + uint32_t children_begin; ///< Index of first child item on the next sublevel +#endif + + // Possible optimizations: + // 1) We can save 1 more byte per block if we will use char instead of short + real time calculations for "totalHeight" var; + // 2) We can save 12 bytes per block if "x" and "w" vars will be removed (all this information exist inside BlocksTree), + // but this requires runtime x-coodinate calculation because BlocksTree has x value in nanoseconds. + + inline void setPos(qreal _x, float _w) { x = _x; w = _w; } + inline qreal left() const { return x; } + inline qreal right() const { return x + w; } + inline float width() const { return w; } + +}; // END of struct EasyBlockItem. + +//#define EASY_TREE_WIDGET__USE_VECTOR +struct EasyBlock Q_DECL_FINAL +{ + ::profiler::BlocksTree tree; +#ifdef EASY_TREE_WIDGET__USE_VECTOR + uint32_t tree_item; +#endif + uint32_t graphics_item_index; + uint8_t graphics_item_level; + uint8_t graphics_item; + bool expanded; + + EasyBlock() = default; + + EasyBlock(EasyBlock&& that) + : tree(::std::move(that.tree)) +#ifdef EASY_TREE_WIDGET__USE_VECTOR + , tree_item(that.tree_item) +#endif + , graphics_item_index(that.graphics_item_index) + , graphics_item_level(that.graphics_item_level) + , graphics_item(that.graphics_item) + , expanded(that.expanded) + { + } + +private: + + EasyBlock(const EasyBlock&) = delete; +}; +#pragma pack(pop) + +typedef ::std::vector EasyItems; +typedef ::std::vector EasyBlocks; + +////////////////////////////////////////////////////////////////////////// + +struct EasySelectedBlock Q_DECL_FINAL +{ + const ::profiler::BlocksTreeRoot* root; + ::profiler::block_index_t tree; + + EasySelectedBlock() : root(nullptr), tree(0xffffffff) + { + } + + EasySelectedBlock(const ::profiler::BlocksTreeRoot* _root, const ::profiler::block_index_t _tree) + : root(_root) + , tree(_tree) + { + } + +}; // END of struct EasySelectedBlock. + +typedef ::std::vector TreeBlocks; + +////////////////////////////////////////////////////////////////////////// + +enum TimeUnits : int8_t +{ + TimeUnits_ms = 0, + TimeUnits_us, + TimeUnits_ns, + TimeUnits_auto + +}; // END of enum TimeUnits. + +////////////////////////////////////////////////////////////////////////// + +} // END of namespace profiler_gui. + +template +struct Overload +{ + template + static EASY_CONSTEXPR_FCN auto of(TReturn (TClass::*method)(Args...)) -> decltype(method) + { + return method; + } + + template + static EASY_CONSTEXPR_FCN auto of(TReturn (*func)(Args...)) -> decltype(func) + { + return func; + } +}; + +template <> +struct Overload +{ + template + static EASY_CONSTEXPR_FCN auto of(TReturn (TClass::*method)()) -> decltype(method) + { + return method; + } + + template + static EASY_CONSTEXPR_FCN auto of(TReturn (*func)()) -> decltype(func) + { + return func; + } +}; + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER__GUI_COMMON_TYPES_H diff --git a/3rdparty/easyprofiler/profiler_gui/descriptors_tree_widget.cpp b/3rdparty/easyprofiler/profiler_gui/descriptors_tree_widget.cpp new file mode 100644 index 0000000..4d4c813 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/descriptors_tree_widget.cpp @@ -0,0 +1,982 @@ +/************************************************************************ +* file name : descriptors_tree_widget.cpp +* ----------------- : +* creation time : 2016/09/17 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyDescTreeWidget and it's auxiliary classes +* : for displyaing EasyProfiler blocks descriptors tree. +* ----------------- : +* change log : * 2016/09/17 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "descriptors_tree_widget.h" +#include "arbitrary_value_inspector.h" +#include "treeview_first_column_delegate.h" +#include "globals.h" + +#ifdef _WIN32 +#include + +#ifdef __MINGW32__ +#include +#endif + +#endif + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +enum DescColumns +{ + DESC_COL_FILE_LINE = 0, + DESC_COL_TYPE, + DESC_COL_NAME, + DESC_COL_STATUS, + + DESC_COL_COLUMNS_NUMBER +}; + +////////////////////////////////////////////////////////////////////////// + +::profiler::EasyBlockStatus nextStatus(::profiler::EasyBlockStatus _status) +{ + switch (_status) + { + case ::profiler::OFF: + return ::profiler::ON; + + case ::profiler::ON: + return ::profiler::FORCE_ON; + + case ::profiler::FORCE_ON: + return ::profiler::OFF_RECURSIVE; + + case ::profiler::OFF_RECURSIVE: + return ::profiler::ON_WITHOUT_CHILDREN; + + case ::profiler::ON_WITHOUT_CHILDREN: + return ::profiler::FORCE_ON_WITHOUT_CHILDREN; + + case ::profiler::FORCE_ON_WITHOUT_CHILDREN: + return ::profiler::OFF; + } + + return ::profiler::OFF; +} + +const char* statusText(::profiler::EasyBlockStatus _status) +{ + switch (_status) + { + case ::profiler::OFF: + return "OFF"; + + case ::profiler::ON: + return "ON"; + + case ::profiler::FORCE_ON: + return "FORCE_ON"; + + case ::profiler::OFF_RECURSIVE: + return "OFF_RECURSIVE"; + + case ::profiler::ON_WITHOUT_CHILDREN: + return "ON_WITHOUT_CHILDREN"; + + case ::profiler::FORCE_ON_WITHOUT_CHILDREN: + return "FORCE_ON_WITHOUT_CHILDREN"; + } + + return ""; +} + +::profiler::color_t statusColor(::profiler::EasyBlockStatus _status) +{ + switch (_status) + { + case ::profiler::OFF: + return ::profiler::colors::Red900; + + case ::profiler::ON: + return ::profiler::colors::LightGreen900; + + case ::profiler::FORCE_ON: + return ::profiler::colors::LightGreen900; + + case ::profiler::OFF_RECURSIVE: + return ::profiler::colors::Red900; + + case ::profiler::ON_WITHOUT_CHILDREN: + return ::profiler::colors::Lime900; + + case ::profiler::FORCE_ON_WITHOUT_CHILDREN: + return ::profiler::colors::Lime900; + } + + return ::profiler::colors::Black; +} + +////////////////////////////////////////////////////////////////////////// + +EasyDescWidgetItem::EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent) + : Parent(_parent, QTreeWidgetItem::UserType) + , m_desc(_desc) + , m_type(EasyDescWidgetItem::Type::File) +{ + +} + +EasyDescWidgetItem::~EasyDescWidgetItem() +{ + +} + +bool EasyDescWidgetItem::operator < (const Parent& _other) const +{ + const auto col = treeWidget()->sortColumn(); + + switch (col) + { + case DESC_COL_FILE_LINE: + { + if (parent() != nullptr) + return data(col, Qt::UserRole).toInt() < _other.data(col, Qt::UserRole).toInt(); + } + } + + return Parent::operator < (_other); +} + +QVariant EasyDescWidgetItem::data(int _column, int _role) const +{ + if (_column == DESC_COL_TYPE) + { + if (_role == Qt::ToolTipRole) + { + switch (m_type) + { + case Type::File: return QStringLiteral("File"); + case Type::Event: return QStringLiteral("Event"); + case Type::Block: return QStringLiteral("Block"); + case Type::Value: return QStringLiteral("Arbitrary Value"); + } + } + else if (_role == Qt::DisplayRole) + { + switch (m_type) + { + case Type::File: return QStringLiteral("F"); + case Type::Event: return QStringLiteral("E"); + case Type::Block: return QStringLiteral("B"); + case Type::Value: return QStringLiteral("V"); + } + } + } + + return QTreeWidgetItem::data(_column, _role); +} + +////////////////////////////////////////////////////////////////////////// + +EasyDescTreeWidget::EasyDescTreeWidget(QWidget* _parent) + : Parent(_parent) + , m_lastFound(nullptr) + , m_lastSearchColumn(-1) + , m_searchColumn(DESC_COL_NAME) + , m_bLocked(false) +{ + setAutoFillBackground(false); + setAlternatingRowColors(true); + setItemsExpandable(true); + setAnimated(true); + setSortingEnabled(false); + setColumnCount(DESC_COL_COLUMNS_NUMBER); + setSelectionBehavior(QAbstractItemView::SelectRows); + + auto header_item = new QTreeWidgetItem(); + header_item->setText(DESC_COL_FILE_LINE, "File/Line"); + header_item->setText(DESC_COL_TYPE, "Type"); + header_item->setText(DESC_COL_NAME, "Name"); + header_item->setText(DESC_COL_STATUS, "Status"); + setHeaderItem(header_item); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::blockStatusChanged, this, &This::onBlockStatusChange); + connect(this, &Parent::itemExpanded, this, &This::onItemExpand); + connect(this, &Parent::itemDoubleClicked, this, &This::onDoubleClick); + connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange); + + loadSettings(); + + setItemDelegateForColumn(0, new EasyTreeViewFirstColumnItemDelegate(this)); +} + +EasyDescTreeWidget::~EasyDescTreeWidget() +{ + if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && !::profiler_gui::is_max(EASY_GLOBALS.selected_block_id)) + { + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + emit EASY_GLOBALS.events.refreshRequired(); + } + + saveSettings(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::setSearchColumn(int column) +{ + m_searchColumn = column; +} + +int EasyDescTreeWidget::searchColumn() const +{ + return m_searchColumn; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::contextMenuEvent(QContextMenuEvent* _event) +{ + _event->accept(); + + QMenu menu; + menu.setToolTipsVisible(true); + auto action = menu.addAction("Expand all"); + action->setIcon(QIcon(imagePath("expand"))); + connect(action, &QAction::triggered, this, &This::expandAll); + + action = menu.addAction("Collapse all"); + action->setIcon(QIcon(imagePath("collapse"))); + connect(action, &QAction::triggered, this, &This::collapseAll); + + auto item = currentItem(); + if (item != nullptr && item->parent() != nullptr && currentColumn() >= DESC_COL_TYPE) + { + const auto& desc = easyDescriptor(static_cast(item)->desc()); + + menu.addSeparator(); + auto submenu = menu.addMenu("Change status"); + submenu->setToolTipsVisible(true); + +#define ADD_STATUS_ACTION(NameValue, StatusValue, ToolTipValue)\ + action = submenu->addAction(NameValue);\ + action->setCheckable(true);\ + action->setChecked(desc.status() == StatusValue);\ + action->setData(static_cast(StatusValue));\ + action->setToolTip(ToolTipValue);\ + connect(action, &QAction::triggered, this, &This::onBlockStatusChangeClicked) + + ADD_STATUS_ACTION("Off", ::profiler::OFF, "Do not profile this block."); + ADD_STATUS_ACTION("On", ::profiler::ON, "Profile this block\nif parent enabled children."); + ADD_STATUS_ACTION("Force-On", ::profiler::FORCE_ON, "Always profile this block even\nif it's parent disabled children."); + ADD_STATUS_ACTION("Off-recursive", ::profiler::OFF_RECURSIVE, "Do not profile neither this block\nnor it's children."); + ADD_STATUS_ACTION("On-without-children", ::profiler::ON_WITHOUT_CHILDREN, "Profile this block, but\ndo not profile it's children."); + ADD_STATUS_ACTION("Force-On-without-children", ::profiler::FORCE_ON_WITHOUT_CHILDREN, "Always profile this block, but\ndo not profile it's children."); +#undef ADD_STATUS_ACTION + + submenu->setEnabled(EASY_GLOBALS.connected); + if (!EASY_GLOBALS.connected) + submenu->setTitle(QString("%1 (connection needed)").arg(submenu->title())); + } + + menu.exec(QCursor::pos()); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::clearSilent(bool _global) +{ + const QSignalBlocker b(this); + + setSortingEnabled(false); + m_lastFound = nullptr; + m_lastSearch.clear(); + + m_highlightItems.clear(); + m_items.clear(); + + ::std::vector topLevelItems; + topLevelItems.reserve(topLevelItemCount()); + for (int i = topLevelItemCount() - 1; i >= 0; --i) + { + const bool expanded = !_global && topLevelItem(i)->isExpanded(); + auto item = takeTopLevelItem(i); + if (expanded) + m_expandedFilesTemp.insert(item->text(DESC_COL_FILE_LINE).toStdString()); + topLevelItems.push_back(item); + } + + auto deleter_thread = ::std::thread([](decltype(topLevelItems) _items) + { +#ifdef _WIN32 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); +#endif + + for (auto item : _items) + delete item; + + }, ::std::move(topLevelItems)); + + deleter_thread.detach(); + + //clear(); +} + +////////////////////////////////////////////////////////////////////////// + +struct FileItems +{ + using Items = ::std::unordered_map >; + Items children; + QTreeWidgetItem* item = nullptr; +}; + +void EasyDescTreeWidget::build() +{ + auto f = font(); + f.setBold(true); + + typedef ::std::unordered_map<::std::string, FileItems> Files; + Files fileItems; + + m_items.resize(EASY_GLOBALS.descriptors.size()); + memset(m_items.data(), 0, sizeof(void*) * m_items.size()); + + const QSignalBlocker b(this); + ::profiler::block_id_t id = 0; + for (auto desc : EASY_GLOBALS.descriptors) + { + if (desc != nullptr) + { + auto& p = fileItems[desc->file()]; + if (p.item == nullptr) + { + auto item = new EasyDescWidgetItem(0); + item->setText(DESC_COL_FILE_LINE, QString(desc->file()).remove(QRegExp("^(\\.{2}\\\\+|\\/+)+"))); + item->setType(EasyDescWidgetItem::Type::File); + p.item = item; + } + + auto it = p.children.find(desc->line()); + if (it == p.children.end()) + { + auto item = new EasyDescWidgetItem(desc->id(), p.item); + item->setText(DESC_COL_FILE_LINE, QString::number(desc->line())); + item->setData(DESC_COL_FILE_LINE, Qt::UserRole, desc->line()); + item->setText(DESC_COL_NAME, desc->name()); + + switch (desc->type()) + { + case ::profiler::BlockType::Block: + item->setType(EasyDescWidgetItem::Type::Block); + break; + + case ::profiler::BlockType::Event: + item->setType(EasyDescWidgetItem::Type::Event); + break; + + case ::profiler::BlockType::Value: + item->setType(EasyDescWidgetItem::Type::Value); + break; + } + + item->setFont(DESC_COL_STATUS, f); + item->setText(DESC_COL_STATUS, statusText(desc->status())); + item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc->status()))); + + m_items[id] = item; + p.children.insert(::std::make_pair(desc->line(), item)); + } + else + { + m_items[id] = it->second; + } + } + + ++id; + } + + for (auto& p : fileItems) + { + addTopLevelItem(p.second.item); + if (m_expandedFilesTemp.find(p.first) != m_expandedFilesTemp.end()) + p.second.item->setExpanded(true); + } + + m_expandedFilesTemp.clear(); + setSortingEnabled(true); + sortByColumn(DESC_COL_FILE_LINE, Qt::AscendingOrder); + resizeColumnsToContents(); + QTimer::singleShot(100, [this](){ onSelectedBlockChange(EASY_GLOBALS.selected_block); }); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::onItemExpand(QTreeWidgetItem*) +{ + resizeColumnsToContents(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::onDoubleClick(QTreeWidgetItem* _item, int _column) +{ + if (!EASY_GLOBALS.connected) + return; + + if (_column >= DESC_COL_TYPE && _item->parent() != nullptr) + { + auto item = static_cast(_item); + auto& desc = easyDescriptor(item->desc()); + desc.setStatus(nextStatus(desc.status())); + + item->setText(DESC_COL_STATUS, statusText(desc.status())); + item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc.status()))); + + m_bLocked = true; + emit EASY_GLOBALS.events.blockStatusChanged(desc.id(), desc.status()); + m_bLocked = false; + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _prev) +{ + if (_prev != nullptr) + { + auto f = font(); + for (int i = 0; i < DESC_COL_STATUS; ++i) + _prev->setFont(i, f); + } + + if (_item != nullptr) + { + auto f = font(); + f.setBold(true); + for (int i = 0; i < DESC_COL_STATUS; ++i) + _item->setFont(i, f); + + if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && _item->parent() != nullptr) + { + const auto id = static_cast(_item)->desc(); + if (EASY_GLOBALS.selected_block_id != id) + { + EASY_GLOBALS.selected_block_id = id; + emit EASY_GLOBALS.events.selectedBlockIdChanged(id); + } + } + } + else if (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && !::profiler_gui::is_max(EASY_GLOBALS.selected_block_id)) + { + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + emit EASY_GLOBALS.events.selectedBlockIdChanged(EASY_GLOBALS.selected_block_id); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::onBlockStatusChangeClicked(bool _checked) +{ + if (!_checked || !EASY_GLOBALS.connected) + return; + + auto item = currentItem(); + if (item == nullptr || item->parent() == nullptr) + return; + + auto action = qobject_cast(sender()); + if (action != nullptr) + { + auto& desc = easyDescriptor(static_cast(item)->desc()); + desc.setStatus(static_cast<::profiler::EasyBlockStatus>(action->data().toUInt())); + item->setText(DESC_COL_STATUS, statusText(desc.status())); + item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc.status()))); + + m_bLocked = true; + emit EASY_GLOBALS.events.blockStatusChanged(desc.id(), desc.status()); + m_bLocked = false; + } +} + +void EasyDescTreeWidget::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status) +{ + if (m_bLocked) + return; + + auto item = m_items[_id]; + if (item == nullptr) + return; + + auto& desc = easyDescriptor(item->desc()); + item->setText(DESC_COL_STATUS, statusText(desc.status())); + item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc.status()))); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::resizeColumnsToContents() +{ + for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i) + resizeColumnToContents(i); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::onSelectedBlockChange(uint32_t _block_index) +{ + if (::profiler_gui::is_max(_block_index)) + { + setCurrentItem(nullptr); + return; + } + + auto item = m_items[easyBlocksTree(_block_index).node->id()]; + if (item == nullptr) + return; + + scrollToItem(item, QAbstractItemView::PositionAtCenter); + setCurrentItem(item); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyDescTreeWidget::resetHighlight() +{ + for (auto item : m_highlightItems) { + for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i) + item->setBackground(i, Qt::NoBrush); + } + m_highlightItems.clear(); +} + +void EasyDescTreeWidget::loadSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("desc_tree_widget"); + + auto val = settings.value("searchColumn"); + if (!val.isNull()) + m_searchColumn = val.toInt(); + + settings.endGroup(); +} + +void EasyDescTreeWidget::saveSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("desc_tree_widget"); + + settings.setValue("searchColumn", m_searchColumn); + + settings.endGroup(); +} + +////////////////////////////////////////////////////////////////////////// + +int EasyDescTreeWidget::findNext(const QString& _str, Qt::MatchFlags _flags) +{ + if (_str.isEmpty()) + { + resetHighlight(); + m_lastSearchColumn = m_searchColumn; + return 0; + } + + const bool isNewSearch = (m_lastSearchColumn != m_searchColumn || m_lastSearch != _str); + auto itemsList = findItems(_str, Qt::MatchContains | Qt::MatchRecursive | _flags, m_searchColumn); + + if (!isNewSearch) + { + if (!itemsList.empty()) + { + bool stop = false; + decltype(m_lastFound) next = nullptr; + for (auto item : itemsList) + { + if (stop) + { + next = item; + break; + } + + stop = item == m_lastFound; + } + + m_lastFound = next == nullptr ? itemsList.front() : next; + } + else + { + m_lastFound = nullptr; + } + } + else + { + resetHighlight(); + + m_lastSearchColumn = m_searchColumn; + m_lastSearch = _str; + m_lastFound = !itemsList.empty() ? itemsList.front() : nullptr; + + for (auto item : itemsList) + { + m_highlightItems.push_back(item); + for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i) + item->setBackgroundColor(i, QColor::fromRgba(0x80000000 | (0x00ffffff & ::profiler::colors::Yellow))); + } + } + + if (m_lastFound != nullptr) + { + scrollToItem(m_lastFound, QAbstractItemView::PositionAtCenter); + setCurrentItem(m_lastFound); + } + + return itemsList.size(); +} + +int EasyDescTreeWidget::findPrev(const QString& _str, Qt::MatchFlags _flags) +{ + if (_str.isEmpty()) + { + resetHighlight(); + m_lastSearchColumn = m_searchColumn; + return 0; + } + + const bool isNewSearch = (m_lastSearchColumn != m_searchColumn || m_lastSearch != _str); + auto itemsList = findItems(_str, Qt::MatchContains | Qt::MatchRecursive | _flags, m_searchColumn); + + if (!isNewSearch) + { + if (!itemsList.empty()) + { + decltype(m_lastFound) prev = nullptr; + for (auto item : itemsList) + { + if (item == m_lastFound) + break; + + prev = item; + } + + m_lastFound = prev == nullptr ? itemsList.back() : prev; + } + else + { + m_lastFound = nullptr; + } + } + else + { + resetHighlight(); + + m_lastSearchColumn = m_searchColumn; + m_lastSearch = _str; + m_lastFound = !itemsList.empty() ? itemsList.front() : nullptr; + + m_highlightItems.reserve(itemsList.size()); + for (auto item : itemsList) + { + m_highlightItems.push_back(item); + for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i) + item->setBackgroundColor(i, QColor::fromRgba(0x80000000 | (0x00ffffff & ::profiler::colors::Yellow))); + } + } + + if (m_lastFound != nullptr) + { + scrollToItem(m_lastFound, QAbstractItemView::PositionAtCenter); + setCurrentItem(m_lastFound); + } + + return itemsList.size(); +} + +////////////////////////////////////////////////////////////////////////// + +EasyDescWidget::EasyDescWidget(QWidget* _parent) : Parent(_parent) + , m_tree(new EasyDescTreeWidget(this)) + , m_values(new EasyArbitraryValuesWidget(this)) + , m_searchBox(new QLineEdit(this)) + , m_foundNumber(new QLabel("Found 0 matches", this)) + , m_searchButton(nullptr) + , m_bCaseSensitiveSearch(false) +{ + loadSettings(); + + m_searchBox->setFixedWidth(300); + m_searchBox->setContentsMargins(5, 0, 0, 0); + + auto tb = new QToolBar(this); + tb->setIconSize(::profiler_gui::ICONS_SIZE); + auto refreshButton = tb->addAction(QIcon(imagePath("reload")), tr("Refresh blocks list")); + refreshButton->setEnabled(EASY_GLOBALS.connected); + refreshButton->setToolTip(tr("Refresh blocks list.\nConnection needed.")); + connect(refreshButton, &QAction::triggered, &EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::blocksRefreshRequired); + + + + auto menu = new QMenu(this); + m_searchButton = menu->menuAction(); + m_searchButton->setText("Find next"); + m_searchButton->setIcon(QIcon(imagePath("find-next"))); + m_searchButton->setData(true); + connect(m_searchButton, &QAction::triggered, this, &This::findNext); + + auto actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + + auto a = new QAction(tr("Find next"), actionGroup); + a->setCheckable(true); + a->setChecked(true); + connect(a, &QAction::triggered, this, &This::findNextFromMenu); + menu->addAction(a); + + a = new QAction(tr("Find previous"), actionGroup); + a->setCheckable(true); + connect(a, &QAction::triggered, this, &This::findPrevFromMenu); + menu->addAction(a); + + a = menu->addAction("Case sensitive"); + a->setCheckable(true); + a->setChecked(m_bCaseSensitiveSearch); + connect(a, &QAction::triggered, [this](bool _checked){ m_bCaseSensitiveSearch = _checked; }); + menu->addAction(a); + + menu->addSeparator(); + auto headerItem = m_tree->headerItem(); + actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + for (int i = 0; i < DESC_COL_STATUS; ++i) + { + if (i == DESC_COL_TYPE) + continue; + + a = new QAction(QStringLiteral("Search by ") + headerItem->text(i), actionGroup); + a->setData(i); + a->setCheckable(true); + if (i == m_tree->searchColumn()) + a->setChecked(true); + connect(a, &QAction::triggered, this, &This::onSearchColumnChange); + + menu->addAction(a); + } + + tb->addSeparator(); + tb->addAction(m_searchButton); + tb->addWidget(m_searchBox); + + auto searchbox = new QHBoxLayout(); + searchbox->setContentsMargins(0, 0, 5, 0); + searchbox->addWidget(tb); + searchbox->addStretch(100); + searchbox->addWidget(m_foundNumber, Qt::AlignRight); + + auto lay = new QVBoxLayout(this); + lay->setContentsMargins(1, 1, 1, 1); + lay->addLayout(searchbox); + lay->addWidget(m_tree); + lay->addWidget(m_values); + + connect(m_searchBox, &QLineEdit::returnPressed, this, &This::onSeachBoxReturnPressed); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::connectionChanged, refreshButton, &QAction::setEnabled); +} + +EasyDescWidget::~EasyDescWidget() +{ + saveSettings(); +} + +void EasyDescWidget::loadSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("EasyDescWidget"); + + auto val = settings.value("case_sensitive"); + if (!val.isNull()) + m_bCaseSensitiveSearch = val.toBool(); + + settings.endGroup(); +} + +void EasyDescWidget::saveSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("EasyDescWidget"); + settings.setValue("case_sensitive", m_bCaseSensitiveSearch); + settings.endGroup(); +} + +void EasyDescWidget::keyPressEvent(QKeyEvent* _event) +{ + if (_event->key() == Qt::Key_F3) + { + if (_event->modifiers() & Qt::ShiftModifier) + findPrev(true); + else + findNext(true); + } + + _event->accept(); +} + +void EasyDescWidget::contextMenuEvent(QContextMenuEvent* _event) +{ + m_tree->contextMenuEvent(_event); +} + +void EasyDescWidget::build() +{ + m_tree->clearSilent(false); + m_foundNumber->setText(QString("Found 0 matches")); + m_tree->build(); + m_values->rebuild(); +} + +void EasyDescWidget::clear() +{ + m_tree->clearSilent(true); + m_foundNumber->setText(QString("Found 0 matches")); + m_values->clear(); +} + +void EasyDescWidget::onSeachBoxReturnPressed() +{ + if (m_searchButton->data().toBool() == true) + findNext(true); + else + findPrev(true); +} + +void EasyDescWidget::onSearchColumnChange(bool) +{ + auto action = qobject_cast(sender()); + if (action != nullptr) + m_tree->setSearchColumn(action->data().toInt()); +} + +void EasyDescWidget::findNext(bool) +{ + auto matches = m_tree->findNext(m_searchBox->text(), m_bCaseSensitiveSearch ? Qt::MatchCaseSensitive : Qt::MatchFlags()); + + if (matches == 1) + m_foundNumber->setText(QString("Found 1 match")); + else + m_foundNumber->setText(QString("Found %1 matches").arg(matches)); +} + +void EasyDescWidget::findPrev(bool) +{ + auto matches = m_tree->findPrev(m_searchBox->text(), m_bCaseSensitiveSearch ? Qt::MatchCaseSensitive : Qt::MatchFlags()); + + if (matches == 1) + m_foundNumber->setText(QString("Found 1 match")); + else + m_foundNumber->setText(QString("Found %1 matches").arg(matches)); +} + +void EasyDescWidget::findNextFromMenu(bool _checked) +{ + if (!_checked) + return; + + if (m_searchButton->data().toBool() == false) + { + m_searchButton->setData(true); + m_searchButton->setText(tr("Find next")); + m_searchButton->setIcon(QIcon(imagePath("find-next"))); + disconnect(m_searchButton, &QAction::triggered, this, &This::findPrev); + connect(m_searchButton, &QAction::triggered, this, &This::findNext); + } + + findNext(true); +} + +void EasyDescWidget::findPrevFromMenu(bool _checked) +{ + if (!_checked) + return; + + if (m_searchButton->data().toBool() == true) + { + m_searchButton->setData(false); + m_searchButton->setText(tr("Find prev")); + m_searchButton->setIcon(QIcon(imagePath("find-prev"))); + disconnect(m_searchButton, &QAction::triggered, this, &This::findNext); + connect(m_searchButton, &QAction::triggered, this, &This::findPrev); + } + + findPrev(true); +} + +////////////////////////////////////////////////////////////////////////// diff --git a/3rdparty/easyprofiler/profiler_gui/descriptors_tree_widget.h b/3rdparty/easyprofiler/profiler_gui/descriptors_tree_widget.h new file mode 100644 index 0000000..3a00d67 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/descriptors_tree_widget.h @@ -0,0 +1,234 @@ +/************************************************************************ +* file name : descriptors_tree_widget.h +* ----------------- : +* creation time : 2016/09/17 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyDescTreeWidget and it's auxiliary classes +* : for displyaing EasyProfiler blocks descriptors tree. +* ----------------- : +* change log : * 2016/09/17 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_DESCRIPTORS_WIDGET_H +#define EASY_DESCRIPTORS_WIDGET_H + +#include +#include +#include + +#include +#include + +#include + +////////////////////////////////////////////////////////////////////////// + +class EasyDescWidgetItem : public QTreeWidgetItem +{ + using Parent = QTreeWidgetItem; + using This = EasyDescWidgetItem; + +public: + + enum class Type : uint8_t + { + File, + Event, + Block, + Value + }; + +private: + + ::profiler::block_id_t m_desc; + Type m_type; + +public: + + explicit EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent = nullptr); + virtual ~EasyDescWidgetItem(); + + bool operator < (const Parent& _other) const override; + QVariant data(int _column, int _role) const override; + +public: + + // Public inline methods + + inline ::profiler::block_id_t desc() const + { + return m_desc; + } + + inline void setType(Type _type) + { + m_type = _type; + } + +}; // END of class EasyDescWidgetItem. + +////////////////////////////////////////////////////////////////////////// + +class EasyDescTreeWidget : public QTreeWidget +{ + Q_OBJECT + + typedef QTreeWidget Parent; + typedef EasyDescTreeWidget This; + + typedef ::std::vector Items; + typedef ::std::vector TreeItems; + typedef ::std::unordered_set<::std::string> ExpandedFiles; + +protected: + + ExpandedFiles m_expandedFilesTemp; + Items m_items; + TreeItems m_highlightItems; + QString m_lastSearch; + QTreeWidgetItem* m_lastFound; + int m_lastSearchColumn; + int m_searchColumn; + bool m_bLocked; + +public: + + // Public virtual methods + + explicit EasyDescTreeWidget(QWidget* _parent = nullptr); + virtual ~EasyDescTreeWidget(); + void contextMenuEvent(QContextMenuEvent* _event) override; + +public: + + // Public non-virtual methods + + int findNext(const QString& _str, Qt::MatchFlags _flags); + int findPrev(const QString& _str, Qt::MatchFlags _flags); + void setSearchColumn(int column); + int searchColumn() const; + +public slots: + + void clearSilent(bool _global = false); + void build(); + +private slots: + + void onBlockStatusChangeClicked(bool); + void onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _prev); + void onItemExpand(QTreeWidgetItem* _item); + void onDoubleClick(QTreeWidgetItem* _item, int _column); + void onSelectedBlockChange(uint32_t _block_index); + void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); + void resizeColumnsToContents(); + +private: + + // Private methods + + void resetHighlight(); + void loadSettings(); + void saveSettings(); + +}; // END of class EasyDescTreeWidget. + +////////////////////////////////////////////////////////////////////////// + +class EasyDescWidget : public QWidget +{ + Q_OBJECT + + typedef QWidget Parent; + typedef EasyDescWidget This; + +private: + + EasyDescTreeWidget* m_tree; + class EasyArbitraryValuesWidget* m_values; + class QLineEdit* m_searchBox; + class QLabel* m_foundNumber; + class QAction* m_searchButton; + bool m_bCaseSensitiveSearch; + +public: + + // Public virtual methods + + explicit EasyDescWidget(QWidget* _parent = nullptr); + virtual ~EasyDescWidget(); + void keyPressEvent(QKeyEvent* _event) override; + void contextMenuEvent(QContextMenuEvent* _event) override; + +public: + + // Public non-virtual methods + + void build(); + void clear(); + +private slots: + + void onSeachBoxReturnPressed(); + void findNext(bool); + void findPrev(bool); + void findNextFromMenu(bool); + void findPrevFromMenu(bool); + void onSearchColumnChange(bool); + +private: + + // Private non-virtual slots + + void loadSettings(); + void saveSettings(); + +}; // END of class EasyDescWidget. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_DESCRIPTORS_WIDGET_H diff --git a/3rdparty/easyprofiler/profiler_gui/easy_chronometer_item.cpp b/3rdparty/easyprofiler/profiler_gui/easy_chronometer_item.cpp new file mode 100644 index 0000000..357833e --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_chronometer_item.cpp @@ -0,0 +1,396 @@ +/************************************************************************ +* file name : easy_chronometer_item.cpp +* ----------------- : +* creation time : 2016/09/15 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyChronometerItem. +* ----------------- : +* change log : * 2016/09/15 Victor Zarubkin: moved sources from blocks_graphics_view.cpp +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include "blocks_graphics_view.h" +#include "easy_chronometer_item.h" +#include "globals.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +EasyChronometerItem::EasyChronometerItem(bool _main) + : Parent() + , m_color(::profiler_gui::CHRONOMETER_COLOR) + , m_left(0) + , m_right(0) + , m_bMain(_main) + , m_bReverse(false) + , m_bHoverIndicator(false) + , m_bHoverLeftBorder(false) + , m_bHoverRightBorder(false) +{ + m_indicator.reserve(3); +} + +EasyChronometerItem::~EasyChronometerItem() +{ +} + +QRectF EasyChronometerItem::boundingRect() const +{ + return m_boundingRect; +} + +void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + auto const sceneView = view(); + const auto currentScale = sceneView->scale(); + const auto offset = sceneView->offset(); + const auto visibleSceneRect = sceneView->visibleSceneRect(); + auto sceneLeft = offset, sceneRight = offset + visibleSceneRect.width() / currentScale; + + if (m_bMain) + m_indicator.clear(); + + if (m_left > sceneRight || m_right < sceneLeft) + { + // This item is out of screen + + if (m_bMain) + { + const int size = m_bHoverIndicator ? 12 : 10; + auto vcenter = visibleSceneRect.top() + visibleSceneRect.height() * 0.5; + auto color = QColor::fromRgb(m_color.rgb()); + auto pen = _painter->pen(); + pen.setColor(color); + + m_indicator.clear(); + if (m_left > sceneRight) + { + sceneRight = (sceneRight - offset) * currentScale; + m_indicator.push_back(QPointF(sceneRight - size, vcenter - size)); + m_indicator.push_back(QPointF(sceneRight, vcenter)); + m_indicator.push_back(QPointF(sceneRight - size, vcenter + size)); + } + else + { + sceneLeft = (sceneLeft - offset) * currentScale; + m_indicator.push_back(QPointF(sceneLeft + size, vcenter - size)); + m_indicator.push_back(QPointF(sceneLeft, vcenter)); + m_indicator.push_back(QPointF(sceneLeft + size, vcenter + size)); + } + + _painter->save(); + _painter->setTransform(QTransform::fromTranslate(-x(), -y()), true); + _painter->setBrush(m_bHoverIndicator ? QColor::fromRgb(0xffff0000) : color); + _painter->setPen(pen); + _painter->drawPolygon(m_indicator); + _painter->restore(); + } + + return; + } + + auto selectedInterval = width(); + QRectF rect((m_left - offset) * currentScale, visibleSceneRect.top(), ::std::max(selectedInterval * currentScale, 1.0), visibleSceneRect.height()); + selectedInterval = units2microseconds(selectedInterval); + + const QString text = ::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, selectedInterval); // Displayed text + const auto textRect = QFontMetricsF(EASY_GLOBALS.chronometer_font, sceneView).boundingRect(text); // Calculate displayed text boundingRect + const auto rgb = m_color.rgb() & 0x00ffffff; + + + + // Paint!-------------------------- + _painter->save(); + + // instead of scrollbar we're using manual offset + _painter->setTransform(QTransform::fromTranslate(-x(), -y()), true); + + if (m_left < sceneLeft) + rect.setLeft(0); + + if (m_right > sceneRight) + rect.setWidth((sceneRight - offset) * currentScale - rect.left()); + + // draw transparent rectangle + auto vcenter = rect.top() + rect.height() * 0.5; + QLinearGradient g(rect.left(), vcenter, rect.right(), vcenter); + g.setColorAt(0, m_color); + g.setColorAt(0.2, QColor::fromRgba(0x14000000 | rgb)); + g.setColorAt(0.8, QColor::fromRgba(0x14000000 | rgb)); + g.setColorAt(1, m_color); + _painter->setBrush(g); + _painter->setPen(Qt::NoPen); + _painter->drawRect(rect); + + // draw left and right borders + _painter->setBrush(Qt::NoBrush); + if (m_bMain && !m_bReverse) + { + QPen p(QColor::fromRgba(0xd0000000 | rgb)); + p.setStyle(Qt::DotLine); + _painter->setPen(p); + } + else + { + _painter->setPen(QColor::fromRgba(0xd0000000 | rgb)); + } + + if (m_left > sceneLeft) + { + if (m_bHoverLeftBorder) + { + // Set bold if border is hovered + QPen p = _painter->pen(); + p.setWidth(3); + _painter->setPen(p); + } + + _painter->drawLine(QPointF(rect.left(), rect.top()), QPointF(rect.left(), rect.bottom())); + } + + if (m_right < sceneRight) + { + if (m_bHoverLeftBorder) + { + // Restore width + QPen p = _painter->pen(); + p.setWidth(1); + _painter->setPen(p); + } + else if (m_bHoverRightBorder) + { + // Set bold if border is hovered + QPen p = _painter->pen(); + p.setWidth(3); + _painter->setPen(p); + } + + _painter->drawLine(QPointF(rect.right(), rect.top()), QPointF(rect.right(), rect.bottom())); + + // This is not necessary because another setPen() invoked for draw text + //if (m_bHoverRightBorder) + //{ + // // Restore width + // QPen p = _painter->pen(); + // p.setWidth(1); + // _painter->setPen(p); + //} + } + + // draw text + _painter->setCompositionMode(QPainter::CompositionMode_Difference); // This lets the text to be visible on every background + _painter->setRenderHint(QPainter::TextAntialiasing); + _painter->setPen(0x00ffffff - rgb); + _painter->setFont(EASY_GLOBALS.chronometer_font); + + int textFlags = 0; + switch (EASY_GLOBALS.chrono_text_position) + { + case ::profiler_gui::ChronoTextPosition_Top: + textFlags = Qt::AlignTop | Qt::AlignHCenter; + if (!m_bMain) rect.setTop(rect.top() + textRect.height() * 0.75); + break; + + case ::profiler_gui::ChronoTextPosition_Center: + textFlags = Qt::AlignCenter; + if (!m_bMain) rect.setTop(rect.top() + textRect.height() * 1.5); + break; + + case ::profiler_gui::ChronoTextPosition_Bottom: + textFlags = Qt::AlignBottom | Qt::AlignHCenter; + if (!m_bMain) rect.setHeight(rect.height() - textRect.height() * 0.75); + break; + } + + const auto textRect_width = textRect.width() * ::profiler_gui::FONT_METRICS_FACTOR; + if (textRect_width < rect.width()) + { + // Text will be drawed inside rectangle + _painter->drawText(rect, textFlags, text); + _painter->restore(); + return; + } + + const auto w = textRect_width / currentScale; + if (m_right + w < sceneRight) + { + // Text will be drawed to the right of rectangle + rect.translate(rect.width(), 0); + textFlags &= ~Qt::AlignHCenter; + textFlags |= Qt::AlignLeft; + } + else if (m_left - w > sceneLeft) + { + // Text will be drawed to the left of rectangle + rect.translate(-rect.width(), 0); + textFlags &= ~Qt::AlignHCenter; + textFlags |= Qt::AlignRight; + } + //else // Text will be drawed inside rectangle + + _painter->drawText(rect, textFlags | Qt::TextDontClip, text); + + _painter->restore(); + // END Paint!~~~~~~~~~~~~~~~~~~~~~~ +} + +void EasyChronometerItem::hide() +{ + m_bHoverIndicator = false; + m_bHoverLeftBorder = false; + m_bHoverRightBorder = false; + m_bReverse = false; + Parent::hide(); +} + +bool EasyChronometerItem::indicatorContains(const QPointF& _pos) const +{ + if (m_indicator.empty()) + return false; + + const auto itemX = toItem(_pos.x()); + return m_indicator.containsPoint(QPointF(itemX, _pos.y()), Qt::OddEvenFill); +} + +void EasyChronometerItem::setHoverLeft(bool _hover) +{ + m_bHoverLeftBorder = _hover; +} + +void EasyChronometerItem::setHoverRight(bool _hover) +{ + m_bHoverRightBorder = _hover; +} + +bool EasyChronometerItem::hoverLeft(qreal _x) const +{ + const auto dx = fabs(_x - m_left) * view()->scale(); + return dx < 4; +} + +bool EasyChronometerItem::hoverRight(qreal _x) const +{ + const auto dx = fabs(_x - m_right) * view()->scale(); + return dx < 4; +} + +QPointF EasyChronometerItem::toItem(const QPointF& _pos) const +{ + const auto sceneView = view(); + return QPointF((_pos.x() - sceneView->offset()) * sceneView->scale() - x(), _pos.y()); +} + +qreal EasyChronometerItem::toItem(qreal _x) const +{ + const auto sceneView = view(); + return (_x - sceneView->offset()) * sceneView->scale() - x(); +} + +void EasyChronometerItem::setColor(const QColor& _color) +{ + m_color = _color; +} + +void EasyChronometerItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h) +{ + m_boundingRect.setRect(x, y, w, h); +} + +void EasyChronometerItem::setBoundingRect(const QRectF& _rect) +{ + m_boundingRect = _rect; +} + +void EasyChronometerItem::setLeftRight(qreal _left, qreal _right) +{ + if (_left < _right) + { + m_left = _left; + m_right = _right; + } + else + { + m_left = _right; + m_right = _left; + } +} + +void EasyChronometerItem::setReverse(bool _reverse) +{ + m_bReverse = _reverse; +} + +void EasyChronometerItem::setHoverIndicator(bool _hover) +{ + m_bHoverIndicator = _hover; +} + +const EasyGraphicsView* EasyChronometerItem::view() const +{ + return static_cast(scene()->parent()); +} + +EasyGraphicsView* EasyChronometerItem::view() +{ + return static_cast(scene()->parent()); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/easy_chronometer_item.h b/3rdparty/easyprofiler/profiler_gui/easy_chronometer_item.h new file mode 100644 index 0000000..1c20865 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_chronometer_item.h @@ -0,0 +1,171 @@ +/************************************************************************ +* file name : easy_chronometer_item.h +* ----------------- : +* creation time : 2016/09/15 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyChronometerItem - an item +* : used to display selected interval on graphics scene. +* ----------------- : +* change log : * 2016/09/15 Victor Zarubkin: moved sources from blocks_graphics_view.h +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_CHRONOMETER_ITEM_H +#define EASY_CHRONOMETER_ITEM_H + +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +class QWidget; +class QPainter; +class QStyleOptionGraphicsItem; +class EasyGraphicsView; + +class EasyChronometerItem : public QGraphicsItem +{ + typedef QGraphicsItem Parent; + typedef EasyChronometerItem This; + + QPolygonF m_indicator; ///< Indicator displayed when this chrono item is out of screen (displaying only for main item) + QRectF m_boundingRect; ///< boundingRect (see QGraphicsItem) + QColor m_color; ///< Color of the item + qreal m_left, m_right; ///< Left and right bounds of the selection zone + bool m_bMain; ///< Is this chronometer main (true, by default) + bool m_bReverse; ///< + bool m_bHoverIndicator; ///< Mouse hover above indicator + bool m_bHoverLeftBorder; + bool m_bHoverRightBorder; + +public: + + explicit EasyChronometerItem(bool _main = true); + virtual ~EasyChronometerItem(); + + // Public virtual methods + + QRectF boundingRect() const override; + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; + +public: + + // Public non-virtual methods + + void hide(); + + void setColor(const QColor& _color); + + void setBoundingRect(qreal x, qreal y, qreal w, qreal h); + void setBoundingRect(const QRectF& _rect); + + void setLeftRight(qreal _left, qreal _right); + + void setReverse(bool _reverse); + + void setHoverIndicator(bool _hover); + + bool indicatorContains(const QPointF& _pos) const; + + void setHoverLeft(bool _hover); + void setHoverRight(bool _hover); + + bool hoverLeft(qreal _x) const; + bool hoverRight(qreal _x) const; + + QPointF toItem(const QPointF& _pos) const; + qreal toItem(qreal _x) const; + + inline bool hoverIndicator() const + { + return m_bHoverIndicator; + } + + inline bool hoverLeft() const + { + return m_bHoverLeftBorder; + } + + inline bool hoverRight() const + { + return m_bHoverRightBorder; + } + + inline bool reverse() const + { + return m_bReverse; + } + + inline qreal left() const + { + return m_left; + } + + inline qreal right() const + { + return m_right; + } + + inline qreal width() const + { + return m_right - m_left; + } + +private: + + ///< Returns pointer to the EasyGraphicsView widget. + const EasyGraphicsView* view() const; + EasyGraphicsView* view(); + +}; // END of class EasyChronometerItem. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_CHRONOMETER_ITEM_H diff --git a/3rdparty/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp b/3rdparty/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp new file mode 100644 index 0000000..9cdde8b --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_frame_rate_viewer.cpp @@ -0,0 +1,339 @@ +/************************************************************************ +* file name : easy_frame_rate_viewer.cpp +* ----------------- : +* creation time : 2017/04/02 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : This file contains implementation of EasyFrameRateViewer widget. +* ----------------- : +* change log : * 2017/04/02 Victor Zarubkin: Initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include +#include +#include "easy_frame_rate_viewer.h" +#include "globals.h" + +const int INTERVAL_WIDTH = 20; + +////////////////////////////////////////////////////////////////////////// + +EasyFPSGraphicsItem::EasyFPSGraphicsItem() : Parent(nullptr) +{ + +} + +EasyFPSGraphicsItem::~EasyFPSGraphicsItem() +{ + +} + +////////////////////////////////////////////////////////////////////////// + +QRectF EasyFPSGraphicsItem::boundingRect() const +{ + return m_boundingRect; +} + +void EasyFPSGraphicsItem::setBoundingRect(const QRectF& _boundingRect) +{ + m_boundingRect = _boundingRect; +} + +void EasyFPSGraphicsItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h) +{ + m_boundingRect.setRect(x, y, w, h); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyFPSGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + if (m_frames.empty()) + return; + + const auto fontMetrics = QFontMetrics(scene()->font()); + const int fontHeight = fontMetrics.height() + 2; + const qreal h = m_boundingRect.height() - (fontHeight << 1) - 4; + if (h < 0) + return; + + const qreal halfWidth = m_boundingRect.width() * 0.5 - INTERVAL_WIDTH; + const int halfMax = static_cast(0.5 + halfWidth / INTERVAL_WIDTH); + const int half = static_cast(m_frames.size() / 2); + const qreal top = fontHeight, bottom = h + 4 + fontHeight; + qreal y; + + _painter->save(); + + _painter->drawLine(QPointF(0, top), QPointF(m_boundingRect.width(), top)); + _painter->drawLine(QPointF(0, bottom), QPointF(m_boundingRect.width(), bottom)); + + _painter->setPen(Qt::lightGray); + y = m_boundingRect.height() * 0.5; + _painter->drawLine(QPointF(0, y), QPointF(m_boundingRect.width(), y)); + y -= h * 0.25; + _painter->drawLine(QPointF(0, y), QPointF(m_boundingRect.width(), y)); + y += h * 0.5; + _painter->drawLine(QPointF(0, y), QPointF(m_boundingRect.width(), y)); + + m_points1.reserve(m_frames.size()); + m_points2.reserve(m_frames.size()); + int n = 0; + qreal x = m_boundingRect.width() * 0.5 + std::min(halfMax, half) * INTERVAL_WIDTH, localMax = 0, localMin = 1e30; + const qreal xCurrent = x; + for (int i = static_cast(m_frames.size()) - 1; i > -1 && x >= 0; --i, x -= INTERVAL_WIDTH, ++n) + { + const auto& val = m_frames[i]; + + if (val.first > localMax) + localMax = val.first; + if (val.first < localMin) + localMin = val.first; + m_points1.emplace_back(x, static_cast(val.first) + 1e-3); + + if (val.second > localMax) + localMax = val.second; + if (val.second < localMin) + localMin = val.second; + m_points2.emplace_back(x, static_cast(val.second) + 1e-3); + + _painter->drawLine(QPointF(x, top + 1), QPointF(x, bottom - 1)); + } + + const auto delta = std::max(localMax - localMin, 1e-3); + _painter->setPen(Qt::black); + + qreal frameTime = std::max(localMax, 1.); + _painter->drawText(5, 0, m_boundingRect.width() - 10, fontHeight, Qt::AlignVCenter | Qt::AlignLeft, QString("Slowest %1 FPS (%2)") + .arg(static_cast(1e6 / frameTime)).arg(::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, localMax, 1))); + + frameTime = std::max(m_frames.back().first, 1U); + _painter->drawText(5, 0, xCurrent - 5, fontHeight, Qt::AlignVCenter | Qt::AlignRight, QString("Max current %1 FPS (%2)") + .arg(static_cast(1e6 / frameTime)).arg(::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, m_frames.back().first, 1))); + + frameTime = std::max(m_frames.back().second, 1U); + _painter->drawText(5, bottom, xCurrent - 5, fontHeight, Qt::AlignVCenter | Qt::AlignRight, QString("Avg current %1 FPS (%2)") + .arg(static_cast(1e6 / frameTime)).arg(::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, m_frames.back().second, 1))); + + frameTime = std::max(localMin, 1.); + _painter->drawText(5, bottom, m_boundingRect.width() - 10, fontHeight, Qt::AlignVCenter | Qt::AlignLeft, QString("Fastest %1 FPS (%2)") + .arg(static_cast(1e6 / frameTime)).arg(::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, localMin, 1))); + + if (localMin < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < localMax) + { + y = fontHeight + 2 + h * (1. - (EASY_GLOBALS.frame_time - localMin) / delta); + _painter->setPen(Qt::DashLine); + _painter->drawLine(QPointF(0, y), QPointF(m_boundingRect.width(), y)); + } + + for (int i = 0; i < n; ++i) + { + auto& point1 = m_points1[i]; + point1.setY(fontHeight + 2 + h * (1. - (point1.y() - localMin) / delta)); + + auto& point2 = m_points2[i]; + point2.setY(fontHeight + 2 + h * (1. - (point2.y() - localMin) / delta)); + } + + _painter->setRenderHint(QPainter::Antialiasing, true); + + QPen pen(QColor::fromRgba(0x80ff0000)); + pen.setWidth(EASY_GLOBALS.fps_widget_line_width); + _painter->setPen(pen); + if (n > 1) + { + _painter->drawPolyline(m_points1.data(), n); + + pen.setColor(QColor::fromRgba(0x800000ff)); + _painter->setPen(pen); + _painter->drawPolyline(m_points2.data(), n); + } + else + { + _painter->drawPoint(m_points1.back()); + + pen.setColor(QColor::fromRgba(0x800000ff)); + _painter->setPen(pen); + _painter->drawPoint(m_points2.back()); + } + + const auto txtTop = ::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, localMin + delta * 0.75, 1); + const auto txtMid = ::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, localMin + delta * 0.5, 1); + const auto txtBtm = ::profiler_gui::timeStringReal(EASY_GLOBALS.time_units, localMin + delta * 0.25, 1); + + _painter->setPen(Qt::NoPen); + _painter->setBrush(Qt::white); + _painter->drawRect(0, top + 1, std::max({fontMetrics.width(txtTop), fontMetrics.width(txtMid), fontMetrics.width(txtBtm)}) + 8, bottom - top - 1); + + _painter->setPen(Qt::black); + _painter->setBrush(Qt::NoBrush); + + y = m_boundingRect.height() * 0.5; + _painter->drawText(5, y - (fontHeight >> 1), m_boundingRect.width(), fontHeight, Qt::AlignVCenter | Qt::AlignLeft, txtMid); + + y -= h * 0.25; + _painter->drawText(5, y - (fontHeight >> 1), m_boundingRect.width(), fontHeight, Qt::AlignVCenter | Qt::AlignLeft, txtTop); + + y += h * 0.5; + _painter->drawText(5, y - (fontHeight >> 1), m_boundingRect.width(), fontHeight, Qt::AlignVCenter | Qt::AlignLeft, txtBtm); + + _painter->restore(); + + m_points1.clear(); + m_points2.clear(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyFPSGraphicsItem::clear() +{ + m_frames.clear(); +} + +void EasyFPSGraphicsItem::addPoint(uint32_t _maxFrameTime, uint32_t _avgFrameTime) +{ + m_frames.emplace_back(_maxFrameTime, _avgFrameTime); + if (static_cast(m_frames.size()) > EASY_GLOBALS.max_fps_history) + m_frames.pop_front(); +} + +////////////////////////////////////////////////////////////////////////// + +EasyFrameRateViewer::EasyFrameRateViewer(QWidget* _parent) : Parent(_parent), m_fpsItem(nullptr) +{ + setCacheMode(QGraphicsView::CacheNone); + //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + setOptimizationFlag(QGraphicsView::DontSavePainterState, true); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setContentsMargins(0, 0, 0, 0); + setScene(new QGraphicsScene(this)); + scene()->setSceneRect(0, 0, 50, 50); + + m_fpsItem = new EasyFPSGraphicsItem(); + m_fpsItem->setPos(0, 0); + m_fpsItem->setBoundingRect(0, 0, 50, 50); + scene()->addItem(m_fpsItem); + + centerOn(0, 0); + + // Dirty hack for QDockWidget stupid initial size policy :( + setFixedHeight(10); // Set very small height to enable appropriate minimum height on the application startup + QTimer::singleShot(100, [this] + { + // Now set appropriate minimum height + setMinimumHeight((QFontMetrics(scene()->font()).height() + 3) * 6); + setMaximumHeight(minimumHeight() * 20); + }); +} + +EasyFrameRateViewer::~EasyFrameRateViewer() +{ + +} + +void EasyFrameRateViewer::clear() +{ + m_fpsItem->clear(); + scene()->update(); +} + +void EasyFrameRateViewer::addPoint(uint32_t _maxFrameTime, uint32_t _avgFrameTime) +{ + m_fpsItem->addPoint(_maxFrameTime, _avgFrameTime); + scene()->update(); +} + +void EasyFrameRateViewer::resizeEvent(QResizeEvent* _event) +{ + Parent::resizeEvent(_event); + + auto size = _event->size(); + m_fpsItem->setBoundingRect(0, 0, size.width(), size.height()); + + scene()->setSceneRect(m_fpsItem->boundingRect()); + scene()->update(); +} + +void EasyFrameRateViewer::hideEvent(QHideEvent* _event) +{ + Parent::hideEvent(_event); + EASY_GLOBALS.fps_enabled = isVisible(); + clear(); +} + +void EasyFrameRateViewer::showEvent(QShowEvent* _event) +{ + Parent::showEvent(_event); + EASY_GLOBALS.fps_enabled = isVisible(); + clear(); +} + +void EasyFrameRateViewer::contextMenuEvent(QContextMenuEvent* _event) +{ + QMenu menu; + QAction* action = nullptr; + + action = menu.addAction(QIcon(imagePath("delete")), "Clear"); + connect(action, &QAction::triggered, [this](bool){ clear(); }); + + action = menu.addAction("Close"); + connect(action, &QAction::triggered, [this](bool){ parentWidget()->hide(); }); + + menu.exec(QCursor::pos()); + + _event->accept(); +} + +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/easy_frame_rate_viewer.h b/3rdparty/easyprofiler/profiler_gui/easy_frame_rate_viewer.h new file mode 100644 index 0000000..ca07303 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_frame_rate_viewer.h @@ -0,0 +1,126 @@ +/************************************************************************ +* file name : easy_frame_rate_viewer.cpp +* ----------------- : +* creation time : 2017/04/02 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : This file contains declaration of EasyFrameRateViewer widget. +* ----------------- : +* change log : * 2017/04/02 Victor Zarubkin: Initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY__FRAME_RATE_VIEWER__H +#define EASY__FRAME_RATE_VIEWER__H + +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// + +class EasyFPSGraphicsItem : public QGraphicsItem +{ + typedef QGraphicsItem Parent; + typedef EasyFPSGraphicsItem This; + typedef std::deque > FrameTimes; + + std::vector m_points1, m_points2; + FrameTimes m_frames; + QRectF m_boundingRect; + +public: + + explicit EasyFPSGraphicsItem(); + virtual ~EasyFPSGraphicsItem(); + + QRectF boundingRect() const override; + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; + + void setBoundingRect(const QRectF& _boundingRect); + void setBoundingRect(qreal x, qreal y, qreal w, qreal h); + + void clear(); + void addPoint(uint32_t _maxFrameTime, uint32_t _avgFrameTime); + +}; // END of class EasyFPSGraphicsItem. + +////////////////////////////////////////////////////////////////////////// + +class EasyFrameRateViewer : public QGraphicsView +{ + Q_OBJECT + +private: + + typedef QGraphicsView Parent; + typedef EasyFrameRateViewer This; + + EasyFPSGraphicsItem* m_fpsItem; + +public: + + explicit EasyFrameRateViewer(QWidget* _parent = nullptr); + virtual ~EasyFrameRateViewer(); + + void resizeEvent(QResizeEvent* _event) override; + void hideEvent(QHideEvent* _event) override; + void showEvent(QShowEvent* _event) override; + void contextMenuEvent(QContextMenuEvent* _event) override; + +public slots: + + void clear(); + void addPoint(uint32_t _maxFrameTime, uint32_t _avgFrameTime); + +}; // END of class EasyFrameRateViewer. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY__FRAME_RATE_VIEWER__H diff --git a/3rdparty/easyprofiler/profiler_gui/easy_graphics_item.cpp b/3rdparty/easyprofiler/profiler_gui/easy_graphics_item.cpp new file mode 100644 index 0000000..1c51fff --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_graphics_item.cpp @@ -0,0 +1,1460 @@ +/************************************************************************ +* file name : easy_graphics_item.cpp +* ----------------- : +* creation time : 2016/09/15 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyGraphicsItem. +* ----------------- : +* change log : * 2016/09/15 Victor Zarubkin: Moved sources from blocks_graphics_view.cpp +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include "easy_graphics_item.h" +#include "blocks_graphics_view.h" +#include "globals.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +enum BlockItemState : int8_t +{ + BLOCK_ITEM_DO_PAINT_FIRST = -2, + BLOCK_ITEM_DO_NOT_PAINT = -1, + BLOCK_ITEM_UNCHANGED, + BLOCK_ITEM_DO_PAINT +}; + +////////////////////////////////////////////////////////////////////////// + +EASY_CONSTEXPR int MIN_SYNC_SPACING = 1; +EASY_CONSTEXPR int MIN_SYNC_SIZE = 3; +EASY_CONSTEXPR int EVENT_HEIGHT = 4; +EASY_CONSTEXPR QRgb BORDERS_COLOR = ::profiler::colors::Grey600 & 0x00ffffff;// 0x00686868; + +inline QRgb selectedItemBorderColor(::profiler::color_t _color) { + return ::profiler_gui::isLightColor(_color, 192) ? ::profiler::colors::Black : ::profiler::colors::RichRed; +} + +const QPen HIGHLIGHTER_PEN = ([]() -> QPen { QPen p(::profiler::colors::Black); p.setStyle(Qt::DotLine); p.setWidth(2); return p; })(); + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +EasyGraphicsItem::EasyGraphicsItem(uint8_t _index, const::profiler::BlocksTreeRoot& _root) + : QGraphicsItem(nullptr) + , m_threadName(::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, _root, EASY_GLOBALS.hex_thread_id)) + , m_pRoot(&_root) + , m_index(_index) +{ +} + +EasyGraphicsItem::~EasyGraphicsItem() +{ +} + +void EasyGraphicsItem::validateName() +{ + m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, *m_pRoot, EASY_GLOBALS.hex_thread_id); +} + +const EasyGraphicsView* EasyGraphicsItem::view() const +{ + return static_cast(scene()->parent()); +} + +////////////////////////////////////////////////////////////////////////// + +QRectF EasyGraphicsItem::boundingRect() const +{ + return m_boundingRect; +} + +////////////////////////////////////////////////////////////////////////// + +struct EasyPainterInformation EASY_FINAL +{ + const QRectF visibleSceneRect; + QRectF rect; + QBrush brush; + const qreal visibleBottom; + const qreal currentScale; + const qreal offset; + const qreal sceneLeft; + const qreal sceneRight; + const qreal dx; + QRgb previousColor; + QRgb textColor; + Qt::PenStyle previousPenStyle; + bool is_light; + bool selectedItemsWasPainted; + + explicit EasyPainterInformation(const EasyGraphicsView* sceneView) + : visibleSceneRect(sceneView->visibleSceneRect()) + , visibleBottom(visibleSceneRect.bottom() - 1) + , currentScale(sceneView->scale()) + , offset(sceneView->offset()) + , sceneLeft(offset) + , sceneRight(offset + visibleSceneRect.width() / currentScale) + , dx(offset * currentScale) + , previousColor(0) + , textColor(0) + , previousPenStyle(Qt::NoPen) + , is_light(false) + , selectedItemsWasPainted(false) + { + brush.setStyle(Qt::SolidPattern); + } + + EasyPainterInformation() = delete; +}; + +#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT +void EasyGraphicsItem::paintChildren(const float _minWidth, const int _narrowSizeHalf, const uint8_t _levelsNumber, QPainter* _painter, struct EasyPainterInformation& p, ::profiler_gui::EasyBlockItem& _item, const ::profiler_gui::EasyBlock& _itemBlock, RightBounds& _rightBounds, uint8_t _level, int8_t _mode) +{ + if (_level >= _levelsNumber || _itemBlock.tree.children.empty()) + return; + + const auto top = levelY(_level); + if (top > p.visibleBottom) + return; + + qreal& prevRight = _rightBounds[_level]; + auto& level = m_levels[_level]; + const short next_level = _level + 1; + + uint32_t neighbours = (uint32_t)_itemBlock.tree.children.size(); + uint32_t last = neighbours - 1; + uint32_t neighbour = 0; + + if (_mode == BLOCK_ITEM_DO_PAINT_FIRST) + { + neighbour = last = _item.max_depth_child; + neighbours = neighbour + 1; + } + + for (uint32_t i = _item.children_begin + neighbour; neighbour < neighbours; ++i, ++neighbour) + { + auto& item = level[i]; + + if (item.left() > p.sceneRight) + break; // This is first totally invisible item. No need to check other items. + + if (item.right() < p.sceneLeft) + continue; // This item is not visible + + const auto& itemBlock = easyBlock(item.block); + const uint16_t totalHeight = itemBlock.tree.depth * ::profiler_gui::GRAPHICS_ROW_SIZE_FULL + ::profiler_gui::GRAPHICS_ROW_SIZE; + if ((top + totalHeight) < p.visibleSceneRect.top()) + continue; // This item is not visible + + const auto item_width = ::std::max(item.width(), _minWidth); + auto x = item.left() * p.currentScale - p.dx; + auto w = item_width * p.currentScale; + //const auto right = x + w; + if ((x + w) <= prevRight) + { + // This item is not visible + if (!(EASY_GLOBALS.hide_narrow_children && w < EASY_GLOBALS.blocks_narrow_size)) + paintChildren(_minWidth, _narrowSizeHalf, _levelsNumber, _painter, p, item, itemBlock, _rightBounds, next_level, BLOCK_ITEM_DO_PAINT_FIRST); + continue; + } + + if (x < prevRight) + { + w -= prevRight - x; + x = prevRight; + } + + if (EASY_GLOBALS.hide_minsize_blocks && w < EASY_GLOBALS.blocks_size_min) + continue; // Hide blocks (except top-level blocks) which width is less than 1 pixel + + const auto& itemDesc = easyDescriptor(itemBlock.tree.node->id()); + + int h = 0; + bool do_paint_children = false; + if ((EASY_GLOBALS.hide_narrow_children && w < EASY_GLOBALS.blocks_narrow_size) || !itemBlock.expanded) + { + // Items which width is less than 20 will be painted as big rectangles which are hiding it's children + + //x = item.left() * p.currentScale - p.dx; + h = totalHeight; + const auto dh = top + h - p.visibleBottom; + if (dh > 0) + h -= dh; + + if (item.block == EASY_GLOBALS.selected_block) + p.selectedItemsWasPainted = true; + + const bool colorChange = (p.previousColor != itemDesc.color()); + if (colorChange) + { + // Set background color brush for rectangle + p.previousColor = itemDesc.color(); + //p.inverseColor = 0xffffffff - p.previousColor; + p.is_light = ::profiler_gui::isLightColor(p.previousColor); + p.textColor = ::profiler_gui::textColorForFlag(p.is_light); + p.brush.setColor(QColor::fromRgba(p.previousColor)); + _painter->setBrush(p.brush); + } + + if (EASY_GLOBALS.highlight_blocks_with_same_id && (EASY_GLOBALS.selected_block_id == itemBlock.tree.node->id() + || (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && EASY_GLOBALS.selected_block_id == itemDesc.id()))) + { + if (p.previousPenStyle != Qt::DotLine) + { + p.previousPenStyle = Qt::DotLine; + _painter->setPen(HIGHLIGHTER_PEN); + } + } + else if (EASY_GLOBALS.draw_graphics_items_borders) + { + if (p.previousPenStyle != Qt::SolidLine)// || colorChange) + { + // Restore pen for item which is wide enough to paint borders + p.previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR);//BORDERS_COLOR & inverseColor); + } + } + else if (p.previousPenStyle != Qt::NoPen) + { + p.previousPenStyle = Qt::NoPen; + _painter->setPen(Qt::NoPen); + } + + const auto wprev = w; + decltype(w) dw = 0; + if (item.left() < p.sceneLeft) + { + // if item left border is out of screen then attach text to the left border of the screen + // to ensure text is always visible for items presenting on the screen. + w += (item.left() - p.sceneLeft) * p.currentScale; + x = p.sceneLeft * p.currentScale - p.dx - 2; + w += 2; + dw = 2; + } + + if (item.right() > p.sceneRight) + { + w -= (item.right() - p.sceneRight) * p.currentScale; + w += 2; + dw += 2; + } + + if (w < EASY_GLOBALS.blocks_size_min) + w = EASY_GLOBALS.blocks_size_min; + + // Draw rectangle + p.rect.setRect(x, top, w, h); + _painter->drawRect(p.rect); + + prevRight = p.rect.right() + EASY_GLOBALS.blocks_spacing; + //skip_children(next_level, item.children_begin); + if (wprev < EASY_GLOBALS.blocks_narrow_size) + continue; + + if (dw > 1) + { + w -= dw; + x += 2; + } + } + else + { + if (item.block == EASY_GLOBALS.selected_block) + p.selectedItemsWasPainted = true; + + const bool colorChange = (p.previousColor != itemDesc.color()); + if (colorChange) + { + // Set background color brush for rectangle + p.previousColor = itemDesc.color(); + //p.inverseColor = 0xffffffff - p.previousColor; + p.is_light = ::profiler_gui::isLightColor(p.previousColor); + p.textColor = ::profiler_gui::textColorForFlag(p.is_light); + p.brush.setColor(QColor::fromRgba(p.previousColor)); + _painter->setBrush(p.brush); + } + + if (EASY_GLOBALS.highlight_blocks_with_same_id && (EASY_GLOBALS.selected_block_id == itemBlock.tree.node->id() + || (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && EASY_GLOBALS.selected_block_id == itemDesc.id()))) + { + if (p.previousPenStyle != Qt::DotLine) + { + p.previousPenStyle = Qt::DotLine; + _painter->setPen(HIGHLIGHTER_PEN); + } + } + else if (EASY_GLOBALS.draw_graphics_items_borders) + { + if (p.previousPenStyle != Qt::SolidLine)// || colorChange) + { + // Restore pen for item which is wide enough to paint borders + p.previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR);// BORDERS_COLOR & inverseColor); + } + } + else if (p.previousPenStyle != Qt::NoPen) + { + p.previousPenStyle = Qt::NoPen; + _painter->setPen(Qt::NoPen); + } + + // Draw rectangle + //x = item.left() * currentScale - p.dx; + h = ::profiler_gui::GRAPHICS_ROW_SIZE; + const auto dh = top + h - p.visibleBottom; + if (dh > 0) + h -= dh; + + const auto wprev = w; + decltype(w) dw = 0; + if (item.left() < p.sceneLeft) + { + // if item left border is out of screen then attach text to the left border of the screen + // to ensure text is always visible for items presenting on the screen. + w += (item.left() - p.sceneLeft) * p.currentScale; + x = p.sceneLeft * p.currentScale - p.dx - 2; + w += 2; + dw = 2; + } + + if (item.right() > p.sceneRight) + { + w -= (item.right() - p.sceneRight) * p.currentScale; + w += 2; + dw += 2; + } + + if (w < EASY_GLOBALS.blocks_size_min) + w = EASY_GLOBALS.blocks_size_min; + + p.rect.setRect(x, top, w, h); + _painter->drawRect(p.rect); + + prevRight = p.rect.right() + EASY_GLOBALS.blocks_spacing; + if (wprev < EASY_GLOBALS.blocks_narrow_size) + { + paintChildren(_minWidth, _narrowSizeHalf, _levelsNumber, _painter, p, item, itemBlock, _rightBounds, next_level, wprev < _narrowSizeHalf ? BLOCK_ITEM_DO_PAINT_FIRST : BLOCK_ITEM_DO_PAINT); + continue; + } + + if (dw > 1) + { + w -= dw; + x += 2; + } + + do_paint_children = true; + } + + // Draw text----------------------------------- + p.rect.setRect(x + 1, top, w - 1, h); + + // text will be painted with inverse color + //auto textColor = inverseColor < 0x00808080 ? profiler::colors::Black : profiler::colors::White; + //if (textColor == previousColor) textColor = 0; + _painter->setPen(p.textColor); + + if (item.block == EASY_GLOBALS.selected_block) + _painter->setFont(EASY_GLOBALS.selected_item_font); + + // drawing text + auto name = easyBlockName(itemBlock.tree, itemDesc); + _painter->drawText(p.rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name)); + + // restore previous pen color + if (p.previousPenStyle == Qt::NoPen) + _painter->setPen(Qt::NoPen); + else if (p.previousPenStyle == Qt::DotLine) + { + _painter->setPen(HIGHLIGHTER_PEN); + } + else + _painter->setPen(BORDERS_COLOR);// BORDERS_COLOR & inverseColor); // restore pen for rectangle painting + + // restore font + if (item.block == EASY_GLOBALS.selected_block) + _painter->setFont(EASY_GLOBALS.items_font); + // END Draw text~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if (do_paint_children) + paintChildren(_minWidth, _narrowSizeHalf, _levelsNumber, _painter, p, item, itemBlock, _rightBounds, next_level, _mode); + } +} +#endif + +void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + const bool gotItems = !m_levels.empty() && !m_levels.front().empty(); + const bool gotSync = !m_pRoot->sync.empty(); + + if (!gotItems && !gotSync) + { + return; + } + + EasyPainterInformation p(view()); + + _painter->save(); + _painter->setFont(EASY_GLOBALS.items_font); + + // Reset indices of first visible item for each layer + const auto levelsNumber = levels(); + m_rightBounds[0] = -1e100; + for (uint8_t i = 1; i < levelsNumber; ++i) { + ::profiler_gui::set_max(m_levelsIndexes[i]); + m_rightBounds[i] = -1e100; + } + + + // Search for first visible top-level item + if (gotItems) + { + auto& level0 = m_levels.front(); + auto first = ::std::lower_bound(level0.begin(), level0.end(), p.sceneLeft, [](const ::profiler_gui::EasyBlockItem& _item, qreal _value) + { + return _item.left() < _value; + }); + + if (first != level0.end()) + { + m_levelsIndexes[0] = first - level0.begin(); + if (m_levelsIndexes[0] > 0) + m_levelsIndexes[0] -= 1; + } + else + { + m_levelsIndexes[0] = static_cast(level0.size() - 1); + } + } + + + + // This is to make _painter->drawText() work properly + // (it seems there is a bug in Qt5.6 when drawText called for big coordinates, + // drawRect at the same time called for actually same coordinates + // works fine without using this additional shifting) + //const auto dx = p.offset * p.currentScale; + + // Shifting coordinates to current screen offset + _painter->setTransform(QTransform::fromTranslate(0, -y()), true); + + + + if (EASY_GLOBALS.draw_graphics_items_borders) + { + p.previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR); + } + else + { + _painter->setPen(Qt::NoPen); + } + + + const auto MIN_WIDTH = EASY_GLOBALS.enable_zero_length ? 0.f : 0.25f; + + + // Iterate through layers and draw visible items + if (gotItems) + { + const int narrow_size_half = EASY_GLOBALS.blocks_narrow_size >> 1; + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + static const auto MAX_CHILD_INDEX = ::profiler_gui::numeric_max(); + auto const dont_skip_children = [this, &levelsNumber](short next_level, decltype(::profiler_gui::EasyBlockItem::children_begin) children_begin, int8_t _state) + { + if (next_level < levelsNumber && children_begin != MAX_CHILD_INDEX) + { + if (m_levelsIndexes[next_level] == MAX_CHILD_INDEX) + { + // Mark first potentially visible child item on next sublevel + m_levelsIndexes[next_level] = children_begin; + } + + // Mark children items that we want to draw them + m_levels[next_level][children_begin].state = _state; + } + }; +#endif + + //size_t iterations = 0; +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + for (uint8_t l = 0; l < levelsNumber; ++l) +#else + for (uint8_t l = 0; l < 1; ++l) +#endif + { + auto& level = m_levels[l]; + const short next_level = l + 1; + + const auto top = levelY(l); + if (top > p.visibleBottom) + break; + + //qreal& prevRight = m_rightBounds[l]; + qreal prevRight = -1e100; + uint32_t neighbour = 0; + for (uint32_t i = m_levelsIndexes[l], end = static_cast(level.size()); i < end; ++i, ++neighbour) + { + //++iterations; + + auto& item = level[i]; + + if (item.left() > p.sceneRight) + break; // This is first totally invisible item. No need to check other items. + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + char state = BLOCK_ITEM_DO_PAINT; + if (item.state != BLOCK_ITEM_UNCHANGED) + { + neighbour = 0; // first block in parent's children list + state = item.state; + item.state = BLOCK_ITEM_DO_NOT_PAINT; + } +#endif + + if (item.right() < p.sceneLeft) + continue; // This item is not visible + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + if (state == BLOCK_ITEM_DO_NOT_PAINT) + { + // This item is not visible + if (neighbour < item.neighbours) + i += item.neighbours - neighbour - 1; // Skip all neighbours + continue; + } + + if (state == BLOCK_ITEM_DO_PAINT_FIRST && item.children_begin == MAX_CHILD_INDEX && next_level < levelsNumber && neighbour < (item.neighbours-1)) + // Paint only first child which has own children + continue; // This item has no children and would not be painted +#endif + + const auto& itemBlock = easyBlock(item.block); + const uint16_t totalHeight = itemBlock.tree.depth * ::profiler_gui::GRAPHICS_ROW_SIZE_FULL + ::profiler_gui::GRAPHICS_ROW_SIZE; + if ((top + totalHeight) < p.visibleSceneRect.top()) + continue; // This item is not visible + + const auto item_width = ::std::max(item.width(), MIN_WIDTH); + auto x = item.left() * p.currentScale - p.dx; + auto w = item_width * p.currentScale; + if ((x + w) <= prevRight) + { + // This item is not visible +#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + if (!EASY_GLOBALS.hide_narrow_children || w >= EASY_GLOBALS.blocks_narrow_size) + paintChildren(MIN_WIDTH, narrow_size_half, levelsNumber, _painter, p, item, itemBlock, m_rightBounds, next_level, BLOCK_ITEM_DO_PAINT_FIRST); +#else + if (!(EASY_GLOBALS.hide_narrow_children && w < EASY_GLOBALS.blocks_narrow_size) && l > 0) + dont_skip_children(next_level, item.children_begin, BLOCK_ITEM_DO_PAINT_FIRST); +#endif + continue; + } + + if (x < prevRight) + { + w -= prevRight - x; + x = prevRight; + } + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + if (EASY_GLOBALS.hide_minsize_blocks && w < EASY_GLOBALS.blocks_size_min && l > 0) + continue; // Hide blocks (except top-level blocks) which width is less than 1 pixel + + if (state == BLOCK_ITEM_DO_PAINT_FIRST && neighbour < item.neighbours) + { + // Paint only first child which has own children + i += item.neighbours - neighbour - 1; // Skip all neighbours + } +#endif + + const auto& itemDesc = easyDescriptor(itemBlock.tree.node->id()); + int h = 0; + +#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + bool do_paint_children = false; +#endif + + if ((EASY_GLOBALS.hide_narrow_children && w < EASY_GLOBALS.blocks_narrow_size) || !itemBlock.expanded) + { + // Items which width is less than 20 will be painted as big rectangles which are hiding it's children + + //x = item.left() * p.currentScale - p.dx; + h = totalHeight; + const auto dh = top + h - p.visibleBottom; + if (dh > 0) + h -= dh; + + if (item.block == EASY_GLOBALS.selected_block) + p.selectedItemsWasPainted = true; + + const bool colorChange = (p.previousColor != itemDesc.color()); + if (colorChange) + { + // Set background color brush for rectangle + p.previousColor = itemDesc.color(); + //p.inverseColor = 0xffffffff - p.previousColor; + p.is_light = ::profiler_gui::isLightColor(p.previousColor); + p.textColor = ::profiler_gui::textColorForFlag(p.is_light); + p.brush.setColor(QColor::fromRgba(p.previousColor)); + _painter->setBrush(p.brush); + } + + if (EASY_GLOBALS.highlight_blocks_with_same_id && (EASY_GLOBALS.selected_block_id == itemBlock.tree.node->id() + || (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && EASY_GLOBALS.selected_block_id == itemDesc.id()))) + { + if (p.previousPenStyle != Qt::DotLine) + { + p.previousPenStyle = Qt::DotLine; + _painter->setPen(HIGHLIGHTER_PEN); + } + } + else if (EASY_GLOBALS.draw_graphics_items_borders) + { + if (p.previousPenStyle != Qt::SolidLine)// || colorChange) + { + // Restore pen for item which is wide enough to paint borders + p.previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR);//BORDERS_COLOR & inverseColor); + } + } + else if (p.previousPenStyle != Qt::NoPen) + { + p.previousPenStyle = Qt::NoPen; + _painter->setPen(Qt::NoPen); + } + + const auto wprev = w; + decltype(w) dw = 0; + if (item.left() < p.sceneLeft) + { + // if item left border is out of screen then attach text to the left border of the screen + // to ensure text is always visible for items presenting on the screen. + w += (item.left() - p.sceneLeft) * p.currentScale; + x = p.sceneLeft * p.currentScale - p.dx - 2; + w += 2; + dw = 2; + } + + if (item.right() > p.sceneRight) + { + w -= (item.right() - p.sceneRight) * p.currentScale; + w += 2; + dw += 2; + } + + if (w < EASY_GLOBALS.blocks_size_min) + w = EASY_GLOBALS.blocks_size_min; + + // Draw rectangle + p.rect.setRect(x, top, w, h); + _painter->drawRect(p.rect); + + prevRight = p.rect.right() + EASY_GLOBALS.blocks_spacing; + //skip_children(next_level, item.children_begin); + if (wprev < EASY_GLOBALS.blocks_narrow_size) + continue; + + if (dw > 1) { + w -= dw; + x += 2; + } + } + else + { + if (item.block == EASY_GLOBALS.selected_block) + p.selectedItemsWasPainted = true; + + const bool colorChange = (p.previousColor != itemDesc.color()); + if (colorChange) + { + // Set background color brush for rectangle + p.previousColor = itemDesc.color(); + //p.inverseColor = 0xffffffff - p.previousColor; + p.is_light = ::profiler_gui::isLightColor(p.previousColor); + p.textColor = ::profiler_gui::textColorForFlag(p.is_light); + p.brush.setColor(QColor::fromRgba(p.previousColor)); + _painter->setBrush(p.brush); + } + + if (EASY_GLOBALS.highlight_blocks_with_same_id && (EASY_GLOBALS.selected_block_id == itemBlock.tree.node->id() + || (::profiler_gui::is_max(EASY_GLOBALS.selected_block) && EASY_GLOBALS.selected_block_id == itemDesc.id()))) + { + if (p.previousPenStyle != Qt::DotLine) + { + p.previousPenStyle = Qt::DotLine; + _painter->setPen(HIGHLIGHTER_PEN); + } + } + else if (EASY_GLOBALS.draw_graphics_items_borders) + { + if (p.previousPenStyle != Qt::SolidLine)// || colorChange) + { + // Restore pen for item which is wide enough to paint borders + p.previousPenStyle = Qt::SolidLine; + _painter->setPen(BORDERS_COLOR);// BORDERS_COLOR & inverseColor); + } + } + else if (p.previousPenStyle != Qt::NoPen) + { + p.previousPenStyle = Qt::NoPen; + _painter->setPen(Qt::NoPen); + } + + // Draw rectangle + //x = item.left() * currentScale - p.dx; + h = ::profiler_gui::GRAPHICS_ROW_SIZE; + const auto dh = top + h - p.visibleBottom; + if (dh > 0) + h -= dh; + + const auto wprev = w; + decltype(w) dw = 0; + if (item.left() < p.sceneLeft) + { + // if item left border is out of screen then attach text to the left border of the screen + // to ensure text is always visible for items presenting on the screen. + w += (item.left() - p.sceneLeft) * p.currentScale; + x = p.sceneLeft * p.currentScale - p.dx - 2; + w += 2; + dw = 2; + } + + if (item.right() > p.sceneRight) + { + w -= (item.right() - p.sceneRight) * p.currentScale; + w += 2; + dw += 2; + } + + if (w < EASY_GLOBALS.blocks_size_min) + w = EASY_GLOBALS.blocks_size_min; + + p.rect.setRect(x, top, w, h); + _painter->drawRect(p.rect); + + prevRight = p.rect.right() + EASY_GLOBALS.blocks_spacing; + if (wprev < EASY_GLOBALS.blocks_narrow_size) + { +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + dont_skip_children(next_level, item.children_begin, wprev < narrow_size_half ? BLOCK_ITEM_DO_PAINT_FIRST : BLOCK_ITEM_DO_PAINT); +#else + paintChildren(MIN_WIDTH, narrow_size_half, levelsNumber, _painter, p, item, itemBlock, m_rightBounds, next_level, wprev < narrow_size_half ? BLOCK_ITEM_DO_PAINT_FIRST : BLOCK_ITEM_DO_PAINT); +#endif + continue; + } + +#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + dont_skip_children(next_level, item.children_begin, BLOCK_ITEM_DO_PAINT); +#endif + + if (dw > 1) { + w -= dw; + x += 2; + } + +#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + do_paint_children = true; +#endif + } + + // Draw text----------------------------------- + p.rect.setRect(x + 1, top, w - 1, h); + + // text will be painted with inverse color + //auto textColor = inverseColor < 0x00808080 ? profiler::colors::Black : profiler::colors::White; + //if (textColor == previousColor) textColor = 0; + _painter->setPen(p.textColor); + + if (item.block == EASY_GLOBALS.selected_block) + _painter->setFont(EASY_GLOBALS.selected_item_font); + + // drawing text + auto name = easyBlockName(itemBlock.tree, itemDesc); + _painter->drawText(p.rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name)); + + // restore previous pen color + if (p.previousPenStyle == Qt::NoPen) + _painter->setPen(Qt::NoPen); + else if (p.previousPenStyle == Qt::DotLine) + { + _painter->setPen(HIGHLIGHTER_PEN); + } + else + _painter->setPen(BORDERS_COLOR);// BORDERS_COLOR & inverseColor); // restore pen for rectangle painting + + // restore font + if (item.block == EASY_GLOBALS.selected_block) + _painter->setFont(EASY_GLOBALS.items_font); + // END Draw text~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + if (do_paint_children) + paintChildren(MIN_WIDTH, narrow_size_half, levelsNumber, _painter, p, item, itemBlock, m_rightBounds, next_level, BLOCK_ITEM_DO_PAINT); +#endif + } + } + + if (EASY_GLOBALS.selected_block < EASY_GLOBALS.gui_blocks.size()) + { + const auto& guiblock = EASY_GLOBALS.gui_blocks[EASY_GLOBALS.selected_block]; + if (guiblock.graphics_item == m_index) + { + const auto& item = m_levels[guiblock.graphics_item_level][guiblock.graphics_item_index]; + if (item.left() < p.sceneRight && item.right() > p.sceneLeft) + { + const auto& itemBlock = easyBlock(item.block); + const auto item_width = ::std::max(item.width(), MIN_WIDTH); + auto top = levelY(guiblock.graphics_item_level); + auto w = ::std::max(item_width * p.currentScale, 1.0); + decltype(top) h = (!itemBlock.expanded || + (w < EASY_GLOBALS.blocks_narrow_size && EASY_GLOBALS.hide_narrow_children)) + ? (itemBlock.tree.depth * ::profiler_gui::GRAPHICS_ROW_SIZE_FULL + ::profiler_gui::GRAPHICS_ROW_SIZE) + : ::profiler_gui::GRAPHICS_ROW_SIZE; + + auto dh = top + h - p.visibleBottom; + if (dh < h) + { + if (dh > 0) + h -= dh; + + const auto& itemDesc = easyDescriptor(itemBlock.tree.node->id()); + + QPen pen(Qt::SolidLine); + pen.setJoinStyle(Qt::MiterJoin); + pen.setColor(selectedItemBorderColor(itemDesc.color()));//Qt::red); + pen.setWidth(3); + _painter->setPen(pen); + + if (!p.selectedItemsWasPainted) + { + p.brush.setColor(QColor::fromRgba(itemDesc.color()));// SELECTED_ITEM_COLOR); + _painter->setBrush(p.brush); + } + else + { + _painter->setBrush(Qt::NoBrush); + } + + auto x = item.left() * p.currentScale - p.dx; + decltype(w) dw = 0; + if (item.left() < p.sceneLeft) + { + // if item left border is out of screen then attach text to the left border of the screen + // to ensure text is always visible for items presenting on the screen. + w += (item.left() - p.sceneLeft) * p.currentScale; + x = p.sceneLeft * p.currentScale - p.dx - 2; + w += 2; + dw = 2; + } + + if (item.right() > p.sceneRight) + { + w -= (item.right() - p.sceneRight) * p.currentScale; + w += 2; + dw += 2; + } + + p.rect.setRect(x, top, w, h); + _painter->drawRect(p.rect); + + if (!p.selectedItemsWasPainted && w > EASY_GLOBALS.blocks_narrow_size) + { + if (dw > 1) { + w -= dw; + x += 2; + } + + // Draw text----------------------------------- + p.rect.setRect(x + 1, top, w - 1, h); + + // text will be painted with inverse color + //auto textColor = 0x00ffffff - previousColor; + //if (textColor == previousColor) textColor = 0; + p.textColor = ::profiler_gui::textColorForRgb(itemDesc.color());// SELECTED_ITEM_COLOR); + _painter->setPen(p.textColor); + + _painter->setFont(EASY_GLOBALS.selected_item_font); + + // drawing text + auto name = easyBlockName(itemBlock.tree, itemDesc); + _painter->drawText(p.rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name)); + // END Draw text~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + } + } + } + } + + //printf("%u: %llu\n", m_index, iterations); + } + + + + if (gotSync) + { + const auto sceneView = view(); + auto firstSync = ::std::lower_bound(m_pRoot->sync.begin(), m_pRoot->sync.end(), p.sceneLeft, [&sceneView](::profiler::block_index_t _index, qreal _value) + { + return sceneView->time2position(easyBlocksTree(_index).node->begin()) < _value; + }); + + if (firstSync != m_pRoot->sync.end()) + { + if (firstSync != m_pRoot->sync.begin()) + --firstSync; + } + else if (!m_pRoot->sync.empty()) + { + firstSync = m_pRoot->sync.begin() + m_pRoot->sync.size() - 1; + } + //firstSync = m_pRoot->sync.begin(); + + p.previousColor = 0; + qreal prevRight = -1e100; + const qreal top = y() + 1 - EVENT_HEIGHT; + if (top + EVENT_HEIGHT < p.visibleBottom) + { + _painter->setPen(BORDERS_COLOR); + + for (auto it = firstSync, end = m_pRoot->sync.end(); it != end; ++it) + { + const auto& item = easyBlocksTree(*it); + auto left = sceneView->time2position(item.node->begin()); + + if (left > p.sceneRight) + break; // This is first totally invisible item. No need to check other items. + + decltype(left) width = sceneView->time2position(item.node->end()) - left; + if (left + width < p.sceneLeft) // This item is not visible + continue; + + left *= p.currentScale; + left -= p.dx; + width *= p.currentScale; + if (left + width <= prevRight) // This item is not visible + continue; + + if (left < prevRight) + { + width -= prevRight - left; + left = prevRight; + } + + if (width < MIN_SYNC_SIZE) + width = MIN_SYNC_SIZE; + + const ::profiler::thread_id_t tid = EASY_GLOBALS.version < ::profiler_gui::V130 ? item.node->id() : item.cs->tid(); + const bool self_thread = tid != 0 && EASY_GLOBALS.profiler_blocks.find(tid) != EASY_GLOBALS.profiler_blocks.end(); + + ::profiler::color_t color = 0; + if (self_thread) + color = ::profiler::colors::Coral; + else if (item.node->id() == 0) + color = ::profiler::colors::Black; + else + color = ::profiler::colors::RedA400; + + if (p.previousColor != color) + { + p.previousColor = color; + _painter->setBrush(QColor::fromRgb(color)); + } + + p.rect.setRect(left, top, width, EVENT_HEIGHT); + _painter->drawRect(p.rect); + prevRight = left + width + MIN_SYNC_SPACING; + } + } + } + + + + if (EASY_GLOBALS.enable_event_markers && !m_pRoot->events.empty()) + { + const auto sceneView = view(); + auto first = ::std::lower_bound(m_pRoot->events.begin(), m_pRoot->events.end(), p.offset, [&sceneView](::profiler::block_index_t _index, qreal _value) + { + return sceneView->time2position(easyBlocksTree(_index).node->begin()) < _value; + }); + + if (first != m_pRoot->events.end()) + { + if (first != m_pRoot->events.begin()) + --first; + } + else if (!m_pRoot->events.empty()) + { + first = m_pRoot->events.begin() + m_pRoot->events.size() - 1; + } + + p.previousColor = 0; + qreal prevRight = -1e100; + const qreal top = y() + boundingRect().height() - 1; + if (top + EVENT_HEIGHT < p.visibleBottom) + { + _painter->setPen(BORDERS_COLOR); + + for (auto it = first, end = m_pRoot->events.end(); it != end; ++it) + { + const auto& item = easyBlocksTree(*it); + auto left = sceneView->time2position(item.node->begin()); + + if (left > p.sceneRight) + break; // This is first totally invisible item. No need to check other items. + + decltype(left) width = MIN_WIDTH; + if (left + width < p.sceneLeft) // This item is not visible + continue; + + left *= p.currentScale; + left -= p.dx; + width *= p.currentScale; + if (width < 2) + width = 2; + + if (left + width <= prevRight) // This item is not visible + continue; + + if (left < prevRight) + { + width -= prevRight - left; + left = prevRight; + } + + if (width < 2) + width = 2; + + ::profiler::color_t color = easyDescriptor(item.node->id()).color(); + if (p.previousColor != color) + { + p.previousColor = color; + _painter->setBrush(QColor::fromRgb(color)); + } + + p.rect.setRect(left, top, width, EVENT_HEIGHT); + _painter->drawRect(p.rect); + prevRight = left + width + 2; + } + } + } + + + + _painter->restore(); +} + +////////////////////////////////////////////////////////////////////////// + +const ::profiler::BlocksTreeRoot* EasyGraphicsItem::root() const +{ + return m_pRoot; +} + +const QString& EasyGraphicsItem::threadName() const +{ + return m_threadName; +} + +////////////////////////////////////////////////////////////////////////// + +QRect EasyGraphicsItem::getRect() const +{ + return view()->mapFromScene(m_boundingRect).boundingRect(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsItem::getBlocks(qreal _left, qreal _right, ::profiler_gui::TreeBlocks& _blocks) const +{ + // Search for first visible top-level item + auto& level0 = m_levels.front(); + auto first = ::std::lower_bound(level0.begin(), level0.end(), _left, [](const ::profiler_gui::EasyBlockItem& _item, qreal _value) + { + return _item.left() < _value; + }); + + size_t itemIndex = 0; + if (first != level0.end()) + { + itemIndex = first - level0.begin(); + if (itemIndex > 0) + itemIndex -= 1; + } + else + { + itemIndex = level0.size() - 1; + } + + // Add all visible top-level items into array of visible blocks + for (size_t i = itemIndex, end = level0.size(); i < end; ++i) + { + const auto& item = level0[i]; + + if (item.left() > _right) + { + // First invisible item. No need to check other items. + break; + } + + if (item.right() < _left) + { + // This item is not visible yet + // This is just to be sure + continue; + } + + _blocks.emplace_back(m_pRoot, item.block); + } +} + +////////////////////////////////////////////////////////////////////////// + +const ::profiler_gui::EasyBlock* EasyGraphicsItem::intersect(const QPointF& _pos, ::profiler::block_index_t& _blockIndex) const +{ + if (m_levels.empty() || m_levels.front().empty()) + { + return nullptr; + } + + const auto& level0 = m_levels.front(); + const auto top = y(); + + if (top > _pos.y()) + { + return nullptr; + } + + EASY_STATIC_CONSTEXPR auto OVERLAP = (::profiler_gui::THREADS_ROW_SPACING >> 1) + 2; + const auto bottom = top + m_levels.size() * ::profiler_gui::GRAPHICS_ROW_SIZE_FULL + OVERLAP; + if (bottom < _pos.y()) + { + return nullptr; + } + + const unsigned int levelIndex = static_cast(_pos.y() - top) / ::profiler_gui::GRAPHICS_ROW_SIZE_FULL; + if (levelIndex >= m_levels.size()) + { + // The Y position is out of blocks range + + if (EASY_GLOBALS.enable_event_markers && !m_pRoot->events.empty()) + { + // If event indicators are enabled then try to intersect with one of event indicators + + const auto& sceneView = view(); + auto first = ::std::lower_bound(m_pRoot->events.begin(), m_pRoot->events.end(), _pos.x(), [&sceneView](::profiler::block_index_t _index, qreal _value) + { + return sceneView->time2position(easyBlocksTree(_index).node->begin()) < _value; + }); + + if (first != m_pRoot->events.end()) + { + if (first != m_pRoot->events.begin()) + --first; + } + else if (!m_pRoot->events.empty()) + { + first = m_pRoot->events.begin() + m_pRoot->events.size() - 1; + } + + const auto MIN_WIDTH = EASY_GLOBALS.enable_zero_length ? 0.f : 0.25f; + const auto currentScale = sceneView->scale(); + const auto dw = 5. / currentScale; + + for (auto it = first, end = m_pRoot->events.end(); it != end; ++it) + { + _blockIndex = *it; + const auto& item = easyBlock(_blockIndex); + auto left = sceneView->time2position(item.tree.node->begin()); + + if (left - dw > _pos.x()) + break; // This is first totally invisible item. No need to check other items. + + decltype(left) width = MIN_WIDTH; + if (left + width + dw < _pos.x()) // This item is not visible + continue; + + return &item; + } + } + + return nullptr; + } + + // The Y position is inside blocks range + + const auto MIN_WIDTH = EASY_GLOBALS.enable_zero_length ? 0.f : 0.25f; + + const auto currentScale = view()->scale(); + const auto dw = 5. / currentScale; + unsigned int i = 0; + size_t itemIndex = ::std::numeric_limits::max(); + size_t firstItem = 0, lastItem = static_cast(level0.size()); + while (i <= levelIndex) + { + const auto& level = m_levels[i]; + + // Search for first visible item + auto first = ::std::lower_bound(level.begin() + firstItem, level.begin() + lastItem, _pos.x(), [](const ::profiler_gui::EasyBlockItem& _item, qreal _value) + { + return _item.left() < _value; + }); + + if (first != level.end()) + { + itemIndex = first - level.begin(); + if (itemIndex != 0) + --itemIndex; + } + else + { + itemIndex = level.size() - 1; + } + + for (auto size = level.size(); itemIndex < size; ++itemIndex) + { + const auto& item = level[itemIndex]; + static const auto MAX_CHILD_INDEX = ::profiler_gui::numeric_max(item.children_begin); + + if (item.left() - dw > _pos.x()) + { + return nullptr; + } + + const auto item_width = ::std::max(item.width(), MIN_WIDTH); + if (item.left() + item_width + dw < _pos.x()) + { + continue; + } + + const auto w = item_width * currentScale; + const auto& guiItem = easyBlock(item.block); + if (i == levelIndex || (w < EASY_GLOBALS.blocks_narrow_size && EASY_GLOBALS.hide_narrow_children) || !guiItem.expanded) + { + _blockIndex = item.block; + return &guiItem; + } + + if (item.children_begin == MAX_CHILD_INDEX) + { + if (itemIndex != 0) + { + auto j = itemIndex; + firstItem = 0; + do { + + --j; + const auto& item2 = level[j]; + if (item2.children_begin != MAX_CHILD_INDEX) + { + firstItem = item2.children_begin; + break; + } + + } while (j != 0); + } + else + { + firstItem = 0; + } + } + else + { + firstItem = item.children_begin; + } + + lastItem = m_levels[i + 1].size(); + for (auto j = itemIndex + 1; j < size; ++j) + { + const auto& item2 = level[j]; + if (item2.children_begin != MAX_CHILD_INDEX) + { + lastItem = item2.children_begin; + break; + } + } + + break; + } + + ++i; + } + + return nullptr; +} + +const ::profiler_gui::EasyBlock* EasyGraphicsItem::intersectEvent(const QPointF& _pos) const +{ + if (m_pRoot->sync.empty()) + { + return nullptr; + } + + const auto top = y() - EVENT_HEIGHT; + if (top > _pos.y()) + { + return nullptr; + } + + const auto bottom = top + EVENT_HEIGHT + 2; + if (bottom < _pos.y()) + { + return nullptr; + } + + const auto sceneView = view(); + auto firstSync = ::std::lower_bound(m_pRoot->sync.begin(), m_pRoot->sync.end(), _pos.x(), [&sceneView](::profiler::block_index_t _index, qreal _value) + { + return sceneView->time2position(easyBlocksTree(_index).node->begin()) < _value; + }); + + if (firstSync == m_pRoot->sync.end()) + firstSync = m_pRoot->sync.begin() + m_pRoot->sync.size() - 1; + else if (firstSync != m_pRoot->sync.begin()) + --firstSync; + + const auto dw = 4. / view()->scale(); + for (auto it = firstSync, end = m_pRoot->sync.end(); it != end; ++it) + { + const auto& item = easyBlock(*it); + + const auto left = sceneView->time2position(item.tree.node->begin()) - dw; + if (left > _pos.x()) + break; + + const auto right = sceneView->time2position(item.tree.node->end()) + dw; + if (right < _pos.x()) + continue; + + return &item; + } + + return nullptr; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h) +{ + m_boundingRect.setRect(x, y, w, h); +} + +void EasyGraphicsItem::setBoundingRect(const QRectF& _rect) +{ + m_boundingRect = _rect; +} + +////////////////////////////////////////////////////////////////////////// + +::profiler::thread_id_t EasyGraphicsItem::threadId() const +{ + return m_pRoot->thread_id; +} + +////////////////////////////////////////////////////////////////////////// + +uint8_t EasyGraphicsItem::levels() const +{ + return static_cast(m_levels.size()); +} + +float EasyGraphicsItem::levelY(uint8_t _level) const +{ + return y() + static_cast(_level) * static_cast(::profiler_gui::GRAPHICS_ROW_SIZE_FULL); +} + +void EasyGraphicsItem::setLevels(uint8_t _levels) +{ + typedef decltype(m_levelsIndexes) IndexesT; + static const auto MAX_CHILD_INDEX = ::profiler_gui::numeric_max(); + + m_levels.resize(_levels); + m_levelsIndexes.resize(_levels, MAX_CHILD_INDEX); + m_rightBounds.resize(_levels, -1e100); +} + +void EasyGraphicsItem::reserve(uint8_t _level, unsigned int _items) +{ + m_levels[_level].reserve(_items); +} + +////////////////////////////////////////////////////////////////////////// + +const EasyGraphicsItem::Children& EasyGraphicsItem::items(uint8_t _level) const +{ + return m_levels[_level]; +} + +const ::profiler_gui::EasyBlockItem& EasyGraphicsItem::getItem(uint8_t _level, unsigned int _index) const +{ + return m_levels[_level][_index]; +} + +::profiler_gui::EasyBlockItem& EasyGraphicsItem::getItem(uint8_t _level, unsigned int _index) +{ + return m_levels[_level][_index]; +} + +unsigned int EasyGraphicsItem::addItem(uint8_t _level) +{ + m_levels[_level].emplace_back(); + return static_cast(m_levels[_level].size() - 1); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/easy_graphics_item.h b/3rdparty/easyprofiler/profiler_gui/easy_graphics_item.h new file mode 100644 index 0000000..a980e58 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_graphics_item.h @@ -0,0 +1,195 @@ +/************************************************************************ +* file name : easy_graphics_item.h +* ----------------- : +* creation time : 2016/09/15 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyGraphicsItem - an item +* : used to draw profiler blocks on graphics scene. +* ----------------- : +* change log : * 2016/09/15 Victor Zarubkin: moved sources from blocks_graphics_view.h/.cpp +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_GRAPHICS_ITEM_H +#define EASY_GRAPHICS_ITEM_H + +#include + +#include +#include +#include + +#include + +#include "common_types.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +class EasyGraphicsView; + +class EasyGraphicsItem : public QGraphicsItem +{ + typedef ::profiler_gui::EasyItems Children; + typedef ::std::vector DrawIndexes; + typedef ::std::vector RightBounds; + typedef ::std::vector Sublevels; + + DrawIndexes m_levelsIndexes; ///< Indexes of first item on each level from which we must start painting + RightBounds m_rightBounds; ///< + Sublevels m_levels; ///< Arrays of items for each level + + QRectF m_boundingRect; ///< boundingRect (see QGraphicsItem) + QString m_threadName; ///< + const ::profiler::BlocksTreeRoot* m_pRoot; ///< Pointer to the root profiler block (thread block). Used by ProfTreeWidget to restore hierarchy. + uint8_t m_index; ///< This item's index in the list of items of EasyGraphicsView + +public: + + explicit EasyGraphicsItem(uint8_t _index, const::profiler::BlocksTreeRoot& _root); + virtual ~EasyGraphicsItem(); + + // Public virtual methods + + QRectF boundingRect() const override; + + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; + +public: + + // Public non-virtual methods + + void validateName(); + + const ::profiler::BlocksTreeRoot* root() const; + const QString& threadName() const; + + QRect getRect() const; + + void setBoundingRect(qreal x, qreal y, qreal w, qreal h); + void setBoundingRect(const QRectF& _rect); + + ::profiler::thread_id_t threadId() const; + + ///< Returns number of levels + uint8_t levels() const; + + float levelY(uint8_t _level) const; + + /** \brief Sets number of levels. + + \note Must be set before doing anything else. + + \param _levels Desired number of levels */ + void setLevels(uint8_t _levels); + + /** \brief Reserves memory for desired number of items on specified level. + + \param _level Index of the level + \param _items Desired number of items on this level */ + void reserve(uint8_t _level, unsigned int _items); + + /**\brief Returns reference to the array of items of specified level. + + \param _level Index of the level */ + const Children& items(uint8_t _level) const; + + /**\brief Returns reference to the item with required index on specified level. + + \param _level Index of the level + \param _index Index of required item */ + const ::profiler_gui::EasyBlockItem& getItem(uint8_t _level, unsigned int _index) const; + + /**\brief Returns reference to the item with required index on specified level. + + \param _level Index of the level + \param _index Index of required item */ + ::profiler_gui::EasyBlockItem& getItem(uint8_t _level, unsigned int _index); + + /** \brief Adds new item to required level. + + \param _level Index of the level + + \retval Index of the new created item */ + unsigned int addItem(uint8_t _level); + + /** \brief Finds top-level blocks which are intersects with required selection zone. + + \note Found blocks will be added into the array of selected blocks. + + \param _left Left bound of the selection zone + \param _right Right bound of the selection zone + \param _blocks Reference to the array of selected blocks */ + void getBlocks(qreal _left, qreal _right, ::profiler_gui::TreeBlocks& _blocks) const; + + const ::profiler_gui::EasyBlock* intersect(const QPointF& _pos, ::profiler::block_index_t& _blockIndex) const; + const ::profiler_gui::EasyBlock* intersectEvent(const QPointF& _pos) const; + +private: + + ///< Returns pointer to the EasyGraphicsView widget. + const EasyGraphicsView* view() const; + +#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT + void paintChildren(const float _minWidth, const int _narrowSizeHalf, const uint8_t _levelsNumber, QPainter* _painter, struct EasyPainterInformation& p, ::profiler_gui::EasyBlockItem& _item, const ::profiler_gui::EasyBlock& _itemBlock, RightBounds& _rightBounds, uint8_t _level, int8_t _mode); +#endif + +public: + + // Public inline methods + + ///< Returns this item's index in the list of graphics items of EasyGraphicsView + inline uint8_t index() const + { + return m_index; + } + +}; // END of class EasyGraphicsItem. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_GRAPHICS_ITEM_H diff --git a/3rdparty/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp b/3rdparty/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp new file mode 100644 index 0000000..c7dee10 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_graphics_scrollbar.cpp @@ -0,0 +1,2078 @@ +/************************************************************************ +* file name : easy_graphics_scrollbar.cpp +* ----------------- : +* creation time : 2016/07/04 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : . +* ----------------- : +* change log : * 2016/07/04 Victor Zarubkin: Initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "easy_graphics_scrollbar.h" +#include "globals.h" + + +// TODO: use profiler_core/spin_lock.h + +#if defined(_WIN32) && defined(EASY_GUI_USE_CRITICAL_SECTION) +# include +# ifdef min +# undef min +# endif +# ifdef max +# undef max +# endif + +namespace profiler_gui { + void spin_lock::lock() { + EnterCriticalSection((CRITICAL_SECTION*)m_lock); + } + + void spin_lock::unlock() { + LeaveCriticalSection((CRITICAL_SECTION*)m_lock); + } + + spin_lock::spin_lock() : m_lock(new CRITICAL_SECTION) { + InitializeCriticalSection((CRITICAL_SECTION*)m_lock); + } + + spin_lock::~spin_lock() { + DeleteCriticalSection((CRITICAL_SECTION*)m_lock); + delete ((CRITICAL_SECTION*)m_lock); + } +} +#endif + +////////////////////////////////////////////////////////////////////////// + +EASY_CONSTEXPR int DEFAULT_TOP = -40; +EASY_CONSTEXPR int DEFAULT_HEIGHT = 80; +EASY_CONSTEXPR int INDICATOR_SIZE = 6; +EASY_CONSTEXPR int INDICATOR_SIZE_x2 = INDICATOR_SIZE << 1; +EASY_CONSTEXPR int HIST_COLUMN_MIN_HEIGHT = 2; +EASY_CONSTEXPR int WORKER_THREAD_CHECK_INTERVAL = 40; +EASY_CONSTEXPR int BOUNDARY_TIMER_INTERVAL = 100; + +////////////////////////////////////////////////////////////////////////// + +using estd::sqr; + +inline qreal calculate_color1(qreal h, qreal, qreal k) +{ + return std::min(h * k, 0.9999999); +} + +inline qreal calculate_color2(qreal, qreal duration, qreal k) +{ + return std::min(sqr(sqr(duration)) * k, 0.9999999); +} + +////////////////////////////////////////////////////////////////////////// + +EasyGraphicsSliderItem::EasyGraphicsSliderItem(bool _main) : Parent(), m_halfwidth(0), m_bMain(_main) +{ + m_indicator.reserve(3); + + if (_main) + { + m_indicator.push_back(QPointF(0, DEFAULT_TOP + INDICATOR_SIZE)); + m_indicator.push_back(QPointF(-INDICATOR_SIZE, DEFAULT_TOP)); + m_indicator.push_back(QPointF(INDICATOR_SIZE, DEFAULT_TOP)); + } + else + { + m_indicator.push_back(QPointF(0, DEFAULT_TOP + DEFAULT_HEIGHT - INDICATOR_SIZE)); + m_indicator.push_back(QPointF(-INDICATOR_SIZE, DEFAULT_TOP + DEFAULT_HEIGHT)); + m_indicator.push_back(QPointF(INDICATOR_SIZE, DEFAULT_TOP + DEFAULT_HEIGHT)); + } + + setWidth(1); + setBrush(Qt::SolidPattern); +} + +EasyGraphicsSliderItem::~EasyGraphicsSliderItem() +{ + +} + +void EasyGraphicsSliderItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget) +{ + if (static_cast(scene()->parent())->bindMode()) + { + return; + } + + const auto currentScale = static_cast(scene()->parent())->getWindowScale(); + const auto br = rect(); + + qreal w = width() * currentScale; + QRectF r(br.left() * currentScale, br.top() + INDICATOR_SIZE, w, br.height() - INDICATOR_SIZE_x2); + const auto r_right = r.right(); + const auto r_bottom = r.bottom(); + auto b = brush(); + + _painter->save(); + _painter->setTransform(QTransform::fromScale(1.0 / currentScale, 1), true); + _painter->setBrush(b); + + if (w > 1) + { + _painter->setPen(Qt::NoPen); + _painter->drawRect(r); + + // Draw left and right borders + auto cmode = _painter->compositionMode(); + if (m_bMain) _painter->setCompositionMode(QPainter::CompositionMode_Exclusion); + _painter->setPen(QColor::fromRgba(0xe0000000 | b.color().rgb())); + _painter->drawLine(QPointF(r.left(), r.top()), QPointF(r.left(), r_bottom)); + _painter->drawLine(QPointF(r_right, r.top()), QPointF(r_right, r_bottom)); + if (!m_bMain) _painter->setCompositionMode(cmode); + } + else + { + _painter->setPen(QColor::fromRgba(0xe0000000 | b.color().rgb())); + _painter->drawLine(QPointF(r.left(), r.top()), QPointF(r.left(), r_bottom)); + if (m_bMain) _painter->setCompositionMode(QPainter::CompositionMode_Exclusion); + } + + // Draw triangle indicators for small slider + _painter->setTransform(QTransform::fromTranslate(r.left() + w * 0.5, 0), true); + _painter->setPen(b.color().rgb()); + _painter->drawPolygon(m_indicator); + + _painter->restore(); +} + +qreal EasyGraphicsSliderItem::width() const +{ + return m_halfwidth * 2.0; +} + +qreal EasyGraphicsSliderItem::halfwidth() const +{ + return m_halfwidth; +} + +void EasyGraphicsSliderItem::setWidth(qreal _width) +{ + m_halfwidth = _width * 0.5; + setRect(-m_halfwidth, DEFAULT_TOP, _width, DEFAULT_HEIGHT); +} + +void EasyGraphicsSliderItem::setHalfwidth(qreal _halfwidth) +{ + m_halfwidth = _halfwidth; + setRect(-m_halfwidth, DEFAULT_TOP, m_halfwidth * 2.0, DEFAULT_HEIGHT); +} + +void EasyGraphicsSliderItem::setColor(QRgb _color) +{ + setColor(QColor::fromRgba(_color)); +} + +void EasyGraphicsSliderItem::setColor(const QColor& _color) +{ + auto b = brush(); + b.setColor(_color); + setBrush(b); +} + +////////////////////////////////////////////////////////////////////////// + +EasyHistogramItem::EasyHistogramItem() : Parent(nullptr) + , m_threadDuration(0) + , m_threadProfiledTime(0) + , m_threadWaitTime(0) + , m_pSource(nullptr) + , m_workerImage(nullptr) + , m_topDuration(0) + , m_maxDuration(0) + , m_minDuration(0) + , m_imageOrigin(0) + , m_imageScale(1) + , m_workerImageOrigin(0) + , m_workerImageScale(1) + , m_workerTopDuration(0) + , m_workerBottomDuration(0) + , m_blockTotalDuraion(0) + , m_timer(::std::bind(&This::onTimeout, this)) + , m_boundaryTimer([this](){ updateImage(); }, true) + , m_pProfilerThread(nullptr) + , m_threadId(0) + , m_blockId(::profiler_gui::numeric_max()) + , m_timeouts(0) + , m_timeUnits(::profiler_gui::TimeUnits_auto) + , m_regime(Hist_Pointer) + , m_bPermitImageUpdate(false) +{ + m_bReady = ATOMIC_VAR_INIT(false); +} + +EasyHistogramItem::~EasyHistogramItem() +{ + m_bReady.store(true, ::std::memory_order_release); + if (m_workerThread.joinable()) + m_workerThread.join(); + delete m_workerImage; +} + +QRectF EasyHistogramItem::boundingRect() const +{ + return m_boundingRect; +} + +void EasyHistogramItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget) +{ + if (!m_bPermitImageUpdate || (m_regime == Hist_Pointer && m_pSource == nullptr) || (m_regime == Hist_Id && (m_threadId == 0 || ::profiler_gui::is_max(m_blockId)))) + return; + + if (m_regime == Hist_Pointer) + paintByPtr(_painter); + else + paintById(_painter); +} + +void EasyHistogramItem::paintBusyIndicator(QPainter* _painter, qreal _current_scale) +{ + const auto width = m_boundingRect.width() * _current_scale; + const auto h = _painter->fontMetrics().height(); + + _painter->setPen(::profiler_gui::TEXT_COLOR); + _painter->drawText(QRectF(0, m_boundingRect.top(), width, m_boundingRect.height() - h), + Qt::AlignCenter, "Generating image"); + _painter->drawText(QRectF(0, m_boundingRect.top() + h, width, m_boundingRect.height() - h), + Qt::AlignCenter, QString(m_timeouts, QChar('.'))); +} + +void EasyHistogramItem::paintMouseIndicator(QPainter* _painter, qreal _top, qreal _bottom, qreal _width, qreal _height, qreal _top_width, qreal _mouse_y, qreal _delta_time, int _font_h) +{ + if (_font_h != 0 && _top < _mouse_y && _mouse_y < _bottom) + { + const int half_font_h = _font_h >> 1; + + _painter->setPen(Qt::blue); + + const auto mouseStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration + _delta_time * (_bottom - _mouse_y) / _height, 3); + qreal mouseIndicatorRight = _width; + if (_mouse_y < _top + half_font_h) + mouseIndicatorRight = _top_width; + + qreal mouseIndicatorLeft = 0; + const QRectF rect(0, _mouse_y - _font_h, _width, _font_h << 1); + if (_mouse_y > _bottom - half_font_h) + { + _painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, mouseStr); + } + else if (_mouse_y < _top + half_font_h) + { + _painter->drawText(rect, Qt::AlignLeft | Qt::AlignBottom, mouseStr); + } + else + { + _painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, mouseStr); + mouseIndicatorLeft = _painter->fontMetrics().width(mouseStr) + 3; + } + + _painter->drawLine(QLineF(mouseIndicatorLeft, _mouse_y, mouseIndicatorRight, _mouse_y)); + } +} + +void EasyHistogramItem::paintByPtr(QPainter* _painter) +{ + const auto widget = static_cast(scene()->parent()); + const bool bindMode = widget->bindMode(); + const auto currentScale = widget->getWindowScale(); + const auto bottom = m_boundingRect.bottom(); + const auto width = m_boundingRect.width() * currentScale; + const auto dtime = m_topDuration - m_bottomDuration; + const auto maxColumnHeight = m_boundingRect.height(); + const auto coeff = (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); + + QRectF rect; + QBrush brush(Qt::SolidPattern); + //QRgb previousColor = 0; + + _painter->save(); + _painter->setTransform(QTransform::fromScale(1.0 / currentScale, 1), true); + + if (!m_pSource->empty()) + { + _painter->setPen(Qt::NoPen); + + if (!bindMode) + _painter->drawImage(0, m_boundingRect.top(), m_mainImage); + else + { + const auto range = widget->sliderWidth(); + const auto minimum = widget->value(); + const auto slider_k = widget->range() / range; + + /*if (false)//slider_k < 8) + { + _painter->setTransform(QTransform::fromScale(slider_k, 1), true); + _painter->drawImage((widget->minimum() - minimum) * currentScale, m_boundingRect.top(), m_mainImage); + _painter->setTransform(QTransform::fromScale(1. / slider_k, 1), true); + } + else*/ + { + const auto deltaScale = slider_k / m_imageScale; + _painter->setTransform(QTransform::fromScale(deltaScale, 1), true); + _painter->drawImage((widget->minimum() + m_imageOrigin - minimum) * currentScale * m_imageScale, m_boundingRect.top(), m_mainImage); + _painter->setTransform(QTransform::fromScale(1. / deltaScale, 1), true); + } + + /*if (false) + { + const bool gotFrame = EASY_GLOBALS.frame_time > 1e-6f; + qreal frameCoeff = 1; + if (gotFrame) + { + if (EASY_GLOBALS.frame_time <= m_bottomDuration) + frameCoeff = m_boundingRect.height(); + else + frameCoeff = 0.9 / EASY_GLOBALS.frame_time; + } + + auto const calculate_color = gotFrame ? calculate_color2 : calculate_color1; + auto const k = gotFrame ? sqr(sqr(frameCoeff)) : 1.0 / m_boundingRect.height(); + + const auto& items = *m_pSource; + const auto maximum = minimum + range; + const auto realScale = currentScale * slider_k; + const auto offset = minimum * realScale; + + auto first = ::std::lower_bound(items.begin(), items.end(), minimum, [](const ::profiler_gui::EasyBlockItem& _item, qreal _value) + { + return _item.left() < _value; + }); + + if (first != items.end()) + { + if (first != items.begin()) + --first; + } + else + { + first = items.begin() + items.size() - 1; + } + + qreal previous_x = -1e30, previous_h = -1e30; + for (auto it = first, end = items.end(); it != end; ++it) + { + // Draw rectangle + + if (it->left() > maximum) + break; + + if (it->right() < minimum) + continue; + + const qreal item_x = it->left() * realScale - offset; + const qreal item_w = ::std::max(it->width() * realScale, 1.0); + const qreal item_r = item_x + item_w; + const qreal h = it->width() <= m_bottomDuration ? HIST_COLUMN_MIN_HEIGHT : + (it->width() > m_topDuration ? maxColumnHeight : (HIST_COLUMN_MIN_HEIGHT + (it->width() - m_bottomDuration) * coeff)); + + if (h < previous_h && item_r < previous_x) + continue; + + const auto col = calculate_color(h, it->width(), k); + const auto color = 0x00ffffff & QColor::fromHsvF((1.0 - col) * 0.375, 0.85, 0.85).rgb(); + + if (previousColor != color) + { + // Set background color brush for rectangle + previousColor = color; + brush.setColor(QColor::fromRgba(0xc0000000 | color)); + _painter->setBrush(brush); + } + + rect.setRect(item_x, bottom - h, item_w, h); + _painter->drawRect(rect); + + previous_x = item_r; + previous_h = h; + } + }*/ + } + } + + //if (!m_bReady.load(::std::memory_order_acquire)) + // paintBusyIndicator(_painter, currentScale); + + qreal top_width = width, bottom_width = width; + int font_h = 0; + if (!m_topDurationStr.isEmpty()) + { + rect.setRect(0, m_boundingRect.top() - INDICATOR_SIZE, width - 3, m_boundingRect.height() + INDICATOR_SIZE_x2); + + if (m_timeUnits != EASY_GLOBALS.time_units) + { + m_timeUnits = EASY_GLOBALS.time_units; + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + } + + auto fm = _painter->fontMetrics(); + font_h = fm.height(); + //bottom_width -= fm.width(m_bottomDurationStr) + 7; + top_width -= fm.width(m_topDurationStr) + 7; + + _painter->setPen(m_topDuration < m_maxDuration ? QColor(Qt::darkRed) : ::profiler_gui::TEXT_COLOR); + _painter->drawText(rect, Qt::AlignRight | Qt::AlignTop, m_topDurationStr); + + rect.setRect(0, bottom, width - 3, font_h); + _painter->setPen(m_bottomDuration > m_minDuration ? QColor(Qt::darkRed) : ::profiler_gui::TEXT_COLOR); + _painter->drawText(rect, Qt::AlignRight | Qt::AlignTop, m_bottomDurationStr); + } + + _painter->setPen(Qt::darkGray); + _painter->drawLine(QLineF(0, bottom, bottom_width, bottom)); + _painter->drawLine(QLineF(0, m_boundingRect.top(), top_width, m_boundingRect.top())); + + paintMouseIndicator(_painter, m_boundingRect.top(), bottom, width, maxColumnHeight - HIST_COLUMN_MIN_HEIGHT, top_width, m_mouseY, dtime, font_h); + + if (m_bottomDuration < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topDuration) + { + // Draw marker displaying expected frame_time step + const auto h = bottom - (EASY_GLOBALS.frame_time - m_bottomDuration) * coeff; + _painter->setPen(Qt::DashLine); + + auto w = width; + const auto boundary = INDICATOR_SIZE - font_h; + if (h < (m_boundingRect.top() - boundary)) + w = top_width; + else if (h > (bottom + boundary)) + w = bottom_width; + + _painter->drawLine(QLineF(0, h, w, h)); + } + + _painter->setPen(::profiler_gui::TEXT_COLOR); + rect.setRect(0, bottom + 2, width, widget->defaultFontHeight()); + const auto eventsSize = m_pProfilerThread->events.size(); + _painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | duration: %2 | profiled: %3 (%4%) | wait: %5 (%6%) | %7 frames | %8 blocks | %9 markers") + .arg(m_threadName) + .arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, m_threadDuration)) + .arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, m_threadProfiledTime)) + .arg(m_threadDuration ? QString::number(100. * (double)m_threadProfiledTime / (double)m_threadDuration, 'f', 2) : QString("0")) + .arg(::profiler_gui::timeStringRealNs(EASY_GLOBALS.time_units, m_threadWaitTime)) + .arg(m_threadDuration ? QString::number(100. * (double)m_threadWaitTime / (double)m_threadDuration, 'f', 2) : QString("0")) + .arg(m_pProfilerThread->frames_number) + .arg(m_pProfilerThread->blocks_number - eventsSize) + .arg(eventsSize)); + + _painter->drawText(rect, Qt::AlignLeft, bindMode ? " MODE: zoom" : " MODE: overview"); + + _painter->restore(); +} + +void EasyHistogramItem::paintById(QPainter* _painter) +{ + const auto widget = static_cast(scene()->parent()); + const bool bindMode = widget->bindMode(); + const auto currentScale = widget->getWindowScale(); + const auto bottom = m_boundingRect.bottom(); + const auto width = m_boundingRect.width() * currentScale; + const auto dtime = m_topDuration - m_bottomDuration; + const auto maxColumnHeight = m_boundingRect.height(); + const auto coeff = (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); + + QRectF rect; + QBrush brush(Qt::SolidPattern); + //QRgb previousColor = 0; + + _painter->save(); + _painter->setTransform(QTransform::fromScale(1.0 / currentScale, 1), true); + + const auto& items = m_selectedBlocks; + if (!items.empty()) + { + _painter->setPen(Qt::NoPen); + + if (!bindMode) + _painter->drawImage(0, m_boundingRect.top(), m_mainImage); + else + { + const auto range = widget->sliderWidth(); + auto minimum = widget->value(); + const auto slider_k = widget->range() / range; + + /*if (false)//slider_k < 8) + { + _painter->setTransform(QTransform::fromScale(slider_k, 1), true); + _painter->drawImage((widget->minimum() - minimum) * currentScale, m_boundingRect.top(), m_mainImage); + _painter->setTransform(QTransform::fromScale(1. / slider_k, 1), true); + } + else*/ + { + const auto deltaScale = slider_k / m_imageScale; + _painter->setTransform(QTransform::fromScale(deltaScale, 1), true); + _painter->drawImage((widget->minimum() + m_imageOrigin - minimum) * currentScale * m_imageScale, m_boundingRect.top(), m_mainImage); + _painter->setTransform(QTransform::fromScale(1. / deltaScale, 1), true); + } + + /*if (false) + { + minimum *= 1e3; + const auto maximum = minimum + range * 1e3; + const auto realScale = currentScale * slider_k; + const auto offset = minimum * realScale; + + auto first = ::std::lower_bound(items.begin(), items.end(), minimum + EASY_GLOBALS.begin_time, [](::profiler::block_index_t _item, qreal _value) + { + return easyBlock(_item).tree.node->begin() < _value; + }); + + if (first != items.end()) + { + if (first != items.begin()) + --first; + } + else + { + first = items.begin() + (items.size() - 1); + } + + auto last = ::std::upper_bound(first, items.end(), maximum + EASY_GLOBALS.begin_time, [](qreal _value, ::profiler::block_index_t _item) + { + return _value < easyBlock(_item).tree.node->begin(); + }); + + const auto n = static_cast(::std::distance(first, last)); + + if (n > 0) + { + const bool gotFrame = EASY_GLOBALS.frame_time > 1e-6f; + qreal frameCoeff = 1; + if (gotFrame) + { + if (EASY_GLOBALS.frame_time <= m_bottomDuration) + frameCoeff = m_boundingRect.height(); + else + frameCoeff = 0.9 / EASY_GLOBALS.frame_time; + } + + auto const calculate_color = gotFrame ? calculate_color2 : calculate_color1; + auto const k = gotFrame ? sqr(sqr(frameCoeff)) : 1.0 / m_boundingRect.height(); + + const auto draw = [this, &previousColor, &brush, &_painter](qreal x, qreal y, qreal w, qreal h, QRgb color) + { + m_spin.lock(); + + if (previousColor != color) + { + // Set background color brush for rectangle + previousColor = color; + brush.setColor(QColor::fromRgba(0xc0000000 | color)); + _painter->setBrush(brush); + } + + _painter->drawRect(QRectF(x, y, w, h)); + + m_spin.unlock(); + }; + + ::std::vector<::std::thread> threads; + const auto n_threads = ::std::min(n, ::std::thread::hardware_concurrency()); + threads.reserve(n_threads); + const auto n_items = n / n_threads; + for (uint32_t i = 0; i < n_threads; ++i) + { + auto begin = first + i * n_items; + threads.emplace_back([this, &draw, &maximum, &minimum, &realScale, &offset, &coeff, &calculate_color, &k, &bottom, &maxColumnHeight](decltype(begin) it, decltype(begin) end) + { + qreal previous_x = -1e30, previous_h = -1e30; + + //for (auto it = first, end = items.end(); it != end; ++it) + for (; it != end; ++it) + { + // Draw rectangle + const auto item = easyBlock(*it).tree.node; + + const auto beginTime = item->begin() - EASY_GLOBALS.begin_time; + if (beginTime > maximum) + break; + + const auto endTime = item->end() - EASY_GLOBALS.begin_time; + if (endTime < minimum) + continue; + + const qreal duration = item->duration() * 1e-3; + const qreal item_x = (beginTime * realScale - offset) * 1e-3; + const qreal item_w = ::std::max(duration * realScale, 1.0); + const qreal item_r = item_x + item_w; + const qreal h = duration <= m_bottomDuration ? HIST_COLUMN_MIN_HEIGHT : + (duration > m_topDuration ? maxColumnHeight : (HIST_COLUMN_MIN_HEIGHT + (duration - m_bottomDuration) * coeff)); + + if (h < previous_h && item_r < previous_x) + continue; + + const auto col = calculate_color(h, duration, k); + const auto color = 0x00ffffff & QColor::fromHsvF((1.0 - col) * 0.375, 0.85, 0.85).rgb(); + + draw(item_x, bottom - h, item_w, h, color); + //if (previousColor != color) + //{ + // // Set background color brush for rectangle + // previousColor = color; + // brush.setColor(QColor::fromRgba(0xc0000000 | color)); + // _painter->setBrush(brush); + //} + + //rect.setRect(item_x, bottom - h, item_w, h); + //_painter->drawRect(rect); + + previous_x = item_r; + previous_h = h; + } + }, begin, i == (n_threads - 1) ? items.end() : begin + n_items); + } + + for (auto& t : threads) + t.join(); + } + }*/ + } + } + + //if (!m_bReady.load(::std::memory_order_acquire)) + // paintBusyIndicator(_painter, currentScale); + + qreal top_width = width, bottom_width = width; + int font_h = 0; + if (!m_topDurationStr.isEmpty()) + { + rect.setRect(0, m_boundingRect.top() - INDICATOR_SIZE, width - 3, m_boundingRect.height() + INDICATOR_SIZE_x2); + + if (m_timeUnits != EASY_GLOBALS.time_units) + { + m_timeUnits = EASY_GLOBALS.time_units; + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + } + + auto fm = _painter->fontMetrics(); + font_h = fm.height(); + //bottom_width -= fm.width(m_bottomDurationStr) + 7; + top_width -= fm.width(m_topDurationStr) + 7; + + _painter->setPen(m_topDuration < m_maxDuration ? QColor(Qt::darkRed) : ::profiler_gui::TEXT_COLOR); + _painter->drawText(rect, Qt::AlignRight | Qt::AlignTop, m_topDurationStr); + + rect.setRect(0, bottom, width - 3, font_h); + _painter->setPen(m_bottomDuration > m_minDuration ? QColor(Qt::darkRed) : ::profiler_gui::TEXT_COLOR); + _painter->drawText(rect, Qt::AlignRight | Qt::AlignTop, m_bottomDurationStr); + } + + _painter->setPen(Qt::darkGray); + _painter->drawLine(QLineF(0, bottom, bottom_width, bottom)); + _painter->drawLine(QLineF(0, m_boundingRect.top(), top_width, m_boundingRect.top())); + + paintMouseIndicator(_painter, m_boundingRect.top(), bottom, width, maxColumnHeight - HIST_COLUMN_MIN_HEIGHT, top_width, m_mouseY, dtime, font_h); + + if (m_bottomDuration < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topDuration) + { + // Draw marker displaying required frame_time step + const auto h = bottom - (EASY_GLOBALS.frame_time - m_bottomDuration) * coeff; + _painter->setPen(Qt::DashLine); + + auto w = width; + const auto boundary = INDICATOR_SIZE - font_h; + if (h < (m_boundingRect.top() - boundary)) + w = top_width; + else if (h >(bottom + boundary)) + w = bottom_width; + + _painter->drawLine(QLineF(0, h, w, h)); + } + + _painter->setPen(::profiler_gui::TEXT_COLOR); + rect.setRect(0, bottom + 2, width, widget->defaultFontHeight()); + + if (!m_selectedBlocks.empty()) + { + _painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | %3 calls | %4% of thread profiled time") + .arg(m_threadName).arg(m_blockName).arg(m_selectedBlocks.size()) + .arg(m_threadProfiledTime ? QString::number(100. * (double)m_blockTotalDuraion / (double)m_threadProfiledTime, 'f', 2) : QString("100"))); + } + else + { + _painter->drawText(rect, Qt::AlignHCenter | Qt::TextDontClip, QString("%1 | %2 | 0 calls").arg(m_threadName).arg(m_blockName)); + } + + _painter->drawText(rect, Qt::AlignLeft, bindMode ? " MODE: zoom" : " MODE: overview"); + + _painter->restore(); +} + +::profiler::thread_id_t EasyHistogramItem::threadId() const +{ + return m_threadId; +} + +void EasyHistogramItem::setBoundingRect(const QRectF& _rect) +{ + m_boundingRect = _rect; +} + +void EasyHistogramItem::setBoundingRect(qreal x, qreal y, qreal w, qreal h) +{ + m_boundingRect.setRect(x, y, w, h); +} + +void EasyHistogramItem::rebuildSource(HistRegime _regime) +{ + if (m_regime == _regime) + rebuildSource(); +} + +void EasyHistogramItem::rebuildSource() +{ + if (m_regime == Hist_Id) + { + m_regime = Hist_Pointer; + setSource(m_threadId, m_blockId); + } + else + { + m_regime = Hist_Id; + setSource(m_threadId, m_pSource); + } +} + +void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items) +{ + if (m_regime == Hist_Pointer && m_threadId == _thread_id && m_pSource == _items) + return; + + m_timer.stop(); + m_boundaryTimer.stop(); + + m_bReady.store(true, ::std::memory_order_release); + if (m_workerThread.joinable()) + m_workerThread.join(); + + m_blockName.clear(); + m_blockTotalDuraion = 0; + + delete m_workerImage; + m_workerImage = nullptr; + m_imageOriginUpdate = m_imageOrigin = 0; + m_imageScaleUpdate = m_imageScale = 1; + + m_selectedBlocks.clear(); + { ::profiler::BlocksTree::children_t().swap(m_selectedBlocks); } + + m_bPermitImageUpdate = false; + m_regime = Hist_Pointer; + m_pSource = _items; + m_threadId = _thread_id; + ::profiler_gui::set_max(m_blockId); + + if (m_pSource != nullptr) + { + if (m_pSource->empty()) + { + m_pSource = nullptr; + } + else + { + const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id]; + m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root, EASY_GLOBALS.hex_thread_id); + + if (root.children.empty()) + m_threadDuration = 0; + else + m_threadDuration = easyBlock(root.children.back()).tree.node->end() - easyBlock(root.children.front()).tree.node->begin(); + + m_threadProfiledTime = root.profiled_time; + m_threadWaitTime = root.wait_time; + m_pProfilerThread = &root; + m_timeUnits = EASY_GLOBALS.time_units; + + m_bReady.store(false, ::std::memory_order_release); + m_workerThread = ::std::thread([this](const ::profiler_gui::EasyItems* _source) + { + m_maxDuration = 0; + m_minDuration = 1e30; + + bool empty = true; + for (const auto& item : *_source) + { + if (m_bReady.load(::std::memory_order_acquire)) + return; + + if (easyDescriptor(easyBlock(item.block).tree.node->id()).type() == ::profiler::BlockType::Event) + continue; + + const auto w = item.width(); + + if (w > m_maxDuration) + m_maxDuration = w; + + if (w < m_minDuration) + m_minDuration = w; + + empty = false; + } + + if ((m_maxDuration - m_minDuration) < 1e-3) + { + if (m_minDuration > 0.1) + { + m_minDuration -= 0.1; + } + else + { + m_maxDuration = 0.1; + m_minDuration = 0; + } + } + + m_topDuration = m_maxDuration; + m_bottomDuration = m_minDuration; + + if (!empty) + { + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + } + else + { + m_topDurationStr.clear(); + m_bottomDurationStr.clear(); + } + + m_bReady.store(true, ::std::memory_order_release); + + }, m_pSource); + + m_timeouts = 3; + m_timer.start(WORKER_THREAD_CHECK_INTERVAL); + show(); + } + } + + if (m_pSource == nullptr) + { + m_pProfilerThread = nullptr; + m_topDurationStr.clear(); + m_bottomDurationStr.clear(); + m_threadName.clear(); + hide(); + } +} + +void EasyHistogramItem::setSource(::profiler::thread_id_t _thread_id, ::profiler::block_id_t _block_id) +{ + if (m_regime == Hist_Id && m_threadId == _thread_id && m_blockId == _block_id) + return; + + m_bPermitImageUpdate = false; // Set to false because m_workerThread have to parse input data first. This will be set to true when m_workerThread finish - see onTimeout() + m_regime = Hist_Id; + + m_timer.stop(); + m_boundaryTimer.stop(); + + m_bReady.store(true, ::std::memory_order_release); + if (m_workerThread.joinable()) + m_workerThread.join(); + + m_pSource = nullptr; + m_topDurationStr.clear(); + m_bottomDurationStr.clear(); + m_blockName.clear(); + m_blockTotalDuraion = 0; + + delete m_workerImage; + m_workerImage = nullptr; + m_imageOriginUpdate = m_imageOrigin = 0; + m_imageScaleUpdate = m_imageScale = 1; + + m_selectedBlocks.clear(); + { ::profiler::BlocksTree::children_t().swap(m_selectedBlocks); } + + m_threadId = _thread_id; + m_blockId = _block_id; + + if (m_threadId != 0 && !::profiler_gui::is_max(m_blockId)) + { + m_blockName = ::profiler_gui::toUnicode(easyDescriptor(m_blockId).name()); + + const auto& root = EASY_GLOBALS.profiler_blocks[_thread_id]; + m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, root, EASY_GLOBALS.hex_thread_id); + m_pProfilerThread = &root; + m_timeUnits = EASY_GLOBALS.time_units; + + if (root.children.empty()) + { + m_threadDuration = 0; + m_threadProfiledTime = 0; + m_threadWaitTime = 0; + + m_topDuration = m_maxDuration = 0; + m_bottomDuration = m_minDuration = 1e30; + + m_bPermitImageUpdate = true; + + m_bReady.store(true, ::std::memory_order_release); + } + else + { + m_threadDuration = easyBlock(root.children.back()).tree.node->end() - easyBlock(root.children.front()).tree.node->begin(); + m_threadProfiledTime = root.profiled_time; + m_threadWaitTime = root.wait_time; + + m_bReady.store(false, ::std::memory_order_release); + m_workerThread = ::std::thread([this](decltype(root) profiler_thread, ::profiler::block_index_t selected_block, bool _showOnlyTopLevelBlocks) + { + typedef ::std::vector<::std::pair<::profiler::block_index_t, ::profiler::block_index_t> > Stack; + + m_maxDuration = 0; + m_minDuration = 1e30; + //const auto& profiler_thread = EASY_GLOBALS.profiler_blocks[m_threadId]; + Stack stack; + stack.reserve(profiler_thread.depth); + + const bool has_selected_block = !::profiler_gui::is_max(selected_block); + + for (auto frame : profiler_thread.children) + { + const auto& frame_block = easyBlock(frame).tree; + if (frame_block.node->id() == m_blockId || (!has_selected_block && m_blockId == easyDescriptor(frame_block.node->id()).id())) + { + m_selectedBlocks.push_back(frame); + + const auto w = frame_block.node->duration(); + if (w > m_maxDuration) + m_maxDuration = w; + + if (w < m_minDuration) + m_minDuration = w; + + m_blockTotalDuraion += w; + } + + if (_showOnlyTopLevelBlocks) + continue; + + stack.push_back(::std::make_pair(frame, 0U)); + while (!stack.empty()) + { + if (m_bReady.load(::std::memory_order_acquire)) + return; + + auto& top = stack.back(); + const auto& top_children = easyBlock(top.first).tree.children; + const auto stack_size = stack.size(); + for (auto end = top_children.size(); top.second < end; ++top.second) + { + if (m_bReady.load(::std::memory_order_acquire)) + return; + + const auto child_index = top_children[top.second]; + const auto& child = easyBlock(child_index).tree; + if (child.node->id() == m_blockId || (!has_selected_block && m_blockId == easyDescriptor(child.node->id()).id())) + { + m_selectedBlocks.push_back(child_index); + + const auto w = child.node->duration(); + if (w > m_maxDuration) + m_maxDuration = w; + + if (w < m_minDuration) + m_minDuration = w; + + m_blockTotalDuraion += w; + } + + if (!child.children.empty()) + { + ++top.second; + stack.push_back(::std::make_pair(child_index, 0U)); + break; + } + } + + if (stack_size == stack.size()) + { + stack.pop_back(); + } + } + } + + if (m_selectedBlocks.empty()) + { + m_topDurationStr.clear(); + m_bottomDurationStr.clear(); + } + else + { + if (has_selected_block) + { + const auto& item = easyBlock(selected_block).tree; + if (*item.node->name() != 0) + m_blockName = ::profiler_gui::toUnicode(item.node->name()); + } + + m_maxDuration *= 1e-3; + m_minDuration *= 1e-3; + + if ((m_maxDuration - m_minDuration) < 1e-3) + { + if (m_minDuration > 0.1) + { + m_minDuration -= 0.1; + } + else + { + m_maxDuration = 0.1; + m_minDuration = 0; + } + } + + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_maxDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_minDuration, 3); + } + + + + m_topDuration = m_maxDuration; + m_bottomDuration = m_minDuration; + + m_bReady.store(true, ::std::memory_order_release); + + }, std::ref(root), EASY_GLOBALS.selected_block, EASY_GLOBALS.display_only_frames_on_histogram); + + m_timeouts = 3; + m_timer.start(WORKER_THREAD_CHECK_INTERVAL); + } + + show(); + } + else + { + m_pProfilerThread = nullptr; + m_threadName.clear(); + hide(); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::validateName() +{ + if (m_threadName.isEmpty()) + return; + m_threadName = ::profiler_gui::decoratedThreadName(EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.profiler_blocks[m_threadId], EASY_GLOBALS.hex_thread_id); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::onTimeout() +{ + if (!isVisible()) + { + m_timer.stop(); + return; + } + + if (++m_timeouts > 8) + m_timeouts = 3; + + if (m_bReady.load(::std::memory_order_acquire)) + { + m_timer.stop(); + if (!m_bPermitImageUpdate) + { + // Worker thread have finished parsing input data (when setSource(_block_id) was called) + m_bPermitImageUpdate = true; // From now we can update an image + updateImage(); + } + else + { + // Image updated + + if (m_workerThread.joinable()) + m_workerThread.join(); + + m_workerImage->swap(m_mainImage); + delete m_workerImage; + m_workerImage = nullptr; + + m_imageOriginUpdate = m_imageOrigin = m_workerImageOrigin; + m_imageScaleUpdate = m_imageScale = m_workerImageScale; + + if (EASY_GLOBALS.auto_adjust_histogram_height && !m_topDurationStr.isEmpty()) + { + m_topDuration = m_workerTopDuration; + m_bottomDuration = m_workerBottomDuration; + + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + } + } + } + + scene()->update(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::pickTopBoundary(qreal _y) +{ + if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_topDurationStr.isEmpty()) + { + m_topDuration = m_bottomDuration + (m_topDuration - m_bottomDuration) * (m_boundingRect.bottom() - _y) / (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT); + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + m_boundaryTimer.stop(); + updateImage(); + scene()->update(); // to update top-boundary text right now + } +} + +void EasyHistogramItem::increaseTopBoundary() +{ + if (m_bPermitImageUpdate && m_topDuration < m_maxDuration && !m_topDurationStr.isEmpty()) + { + auto step = 0.05 * (m_maxDuration - m_bottomDuration); + if (m_topDuration < (m_bottomDuration + 1.25 * step)) + step = 0.1 * (m_topDuration - m_bottomDuration); + + m_topDuration = std::min(m_maxDuration, m_topDuration + step); + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + updateImage(); + scene()->update(); // to update top-boundary text right now + + m_boundaryTimer.stop(); + m_boundaryTimer.start(BOUNDARY_TIMER_INTERVAL); + } +} + +void EasyHistogramItem::decreaseTopBoundary() +{ + if (m_bPermitImageUpdate && m_topDuration > m_bottomDuration && !m_topDurationStr.isEmpty()) + { + auto step = 0.05 * (m_maxDuration - m_bottomDuration); + if (m_topDuration < (m_bottomDuration + 1.25 * step)) + step = std::max(0.1 * (m_topDuration - m_bottomDuration), 0.3); + + if (m_topDuration > (m_bottomDuration + 1.25 * step)) + { + m_topDuration = std::max(m_bottomDuration + step, m_topDuration - step); + m_topDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_topDuration, 3); + scene()->update(); // to update top-boundary text right now + + m_boundaryTimer.stop(); + m_boundaryTimer.start(BOUNDARY_TIMER_INTERVAL); + } + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::pickBottomBoundary(qreal _y) +{ + if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_bottomDurationStr.isEmpty()) + { + m_bottomDuration = m_bottomDuration + (m_topDuration - m_bottomDuration) * (m_boundingRect.bottom() - _y) / (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + m_boundaryTimer.stop(); + updateImage(); + scene()->update(); // to update top-boundary text right now + } +} + +void EasyHistogramItem::increaseBottomBoundary() +{ + if (m_bPermitImageUpdate && m_bottomDuration < m_topDuration && !m_bottomDurationStr.isEmpty()) + { + auto step = 0.05 * (m_topDuration - m_minDuration); + if (m_bottomDuration > (m_topDuration - 1.25 * step)) + step = 0.1 * (m_topDuration - m_bottomDuration); + + if (m_bottomDuration < (m_topDuration - 1.25 * step)) + { + m_bottomDuration = std::min(m_topDuration - step, m_bottomDuration + step); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + scene()->update(); // to update bottom-boundary text right now + + m_boundaryTimer.stop(); + m_boundaryTimer.start(BOUNDARY_TIMER_INTERVAL); + } + } +} + +void EasyHistogramItem::decreaseBottomBoundary() +{ + if (m_bPermitImageUpdate && m_bottomDuration > m_minDuration && !m_bottomDurationStr.isEmpty()) + { + auto step = 0.05 * (m_topDuration - m_minDuration); + if (m_bottomDuration > (m_topDuration - 1.25 * step)) + step = std::max(0.1 * (m_topDuration - m_bottomDuration), 0.3); + + m_bottomDuration = std::max(m_minDuration, m_bottomDuration - step); + m_bottomDurationStr = ::profiler_gui::timeStringReal(m_timeUnits, m_bottomDuration, 3); + scene()->update(); // to update top-boundary text right now + + m_boundaryTimer.stop(); + m_boundaryTimer.start(BOUNDARY_TIMER_INTERVAL); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::setMouseY(qreal _mouseY) +{ + m_mouseY = _mouseY; +} + +void EasyHistogramItem::pickFrameTime(qreal _y) const +{ + if (m_bPermitImageUpdate && m_boundingRect.top() < _y && _y < m_boundingRect.bottom() && !m_topDurationStr.isEmpty()) + { + EASY_GLOBALS.frame_time = m_bottomDuration + (m_topDuration - m_bottomDuration) * (m_boundingRect.bottom() - _y) / (m_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT); + emit EASY_GLOBALS.events.expectedFrameTimeChanged(); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::onValueChanged() +{ + const auto widget = static_cast(scene()->parent()); + + if (!widget->bindMode()) + return; + + m_boundaryTimer.stop(); + + const auto sliderWidth_inv = 1.0 / widget->sliderWidth(); + const auto k = widget->range() * sliderWidth_inv; + + const auto deltaScale = m_imageScaleUpdate < k ? (k / m_imageScaleUpdate) : (m_imageScaleUpdate / k); + if (deltaScale > 4) { + updateImage(); + return; + } + + const auto deltaOffset = (widget->value() - m_imageOriginUpdate) * sliderWidth_inv; + if (deltaOffset < 1.5 || deltaOffset > 4.5) { + updateImage(); + return; + } + + m_boundaryTimer.start(BOUNDARY_TIMER_INTERVAL); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::onModeChanged() +{ + if (!m_bPermitImageUpdate) + return; + + const auto widget = static_cast(scene()->parent()); + + if (!widget->bindMode() && EASY_GLOBALS.auto_adjust_histogram_height) + { + m_topDuration = m_maxDuration; + m_bottomDuration = m_minDuration; + } + + m_boundaryTimer.stop(); + updateImage(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyHistogramItem::cancelImageUpdate() +{ + if (!m_bPermitImageUpdate) + return; + + m_bReady.store(true, ::std::memory_order_release); + if (m_workerThread.joinable()) + m_workerThread.join(); + m_bReady.store(false, ::std::memory_order_release); + + delete m_workerImage; + m_workerImage = nullptr; + + m_imageOriginUpdate = m_imageOrigin; + m_imageScaleUpdate = m_imageScale; + + m_timer.stop(); +} + +void EasyHistogramItem::updateImage() +{ + if (!m_bPermitImageUpdate) + return; + + const auto widget = static_cast(scene()->parent()); + + m_bReady.store(true, ::std::memory_order_release); + if (m_workerThread.joinable()) + m_workerThread.join(); + m_bReady.store(false, ::std::memory_order_release); + + delete m_workerImage; + m_workerImage = nullptr; + + m_imageScaleUpdate = widget->range() / widget->sliderWidth(); + m_imageOriginUpdate = widget->bindMode() ? (widget->value() - widget->sliderWidth() * 3) : widget->minimum(); + + m_workerThread = ::std::thread([this](QRectF _boundingRect, HistRegime _regime, qreal _current_scale, + qreal _minimum, qreal _maximum, qreal _range, qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, + bool _bindMode, float _frame_time, ::profiler::timestamp_t _begin_time, qreal _origin, bool _autoAdjustHist) + { + updateImage(_boundingRect, _regime, _current_scale, _minimum, _maximum, _range, _value, _width, _top_duration, _bottom_duration, _bindMode, _frame_time, _begin_time, _origin, _autoAdjustHist); + m_bReady.store(true, ::std::memory_order_release); + }, m_boundingRect, m_regime, widget->getWindowScale(), widget->minimum(), widget->maximum(), widget->range(), widget->value(), widget->sliderWidth(), + m_topDuration, m_bottomDuration, widget->bindMode(), EASY_GLOBALS.frame_time, EASY_GLOBALS.begin_time, m_imageOriginUpdate, EASY_GLOBALS.auto_adjust_histogram_height); + + m_timeouts = 3; + m_timer.start(WORKER_THREAD_CHECK_INTERVAL); +} + +void EasyHistogramItem::updateImage(QRectF _boundingRect, HistRegime _regime, qreal _current_scale, + qreal _minimum, qreal _maximum, qreal _range, + qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, + bool _bindMode, float _frame_time, ::profiler::timestamp_t _begin_time, + qreal _origin, bool _autoAdjustHist) +{ + const auto bottom = _boundingRect.height();//_boundingRect.bottom(); + const auto screenWidth = _boundingRect.width() * _current_scale; + const auto maxColumnHeight = _boundingRect.height(); + const auto viewScale = _range / _width; + + if (_bindMode) + { + m_workerImageScale = viewScale; + m_workerImageOrigin = _value - _width * 3; + m_workerImage = new QImage(screenWidth * 7 + 0.5, _boundingRect.height(), QImage::Format_ARGB32); + } + else + { + m_workerImageScale = 1; + m_workerImageOrigin = _minimum; + m_workerImage = new QImage(screenWidth + 0.5, _boundingRect.height(), QImage::Format_ARGB32); + } + + m_workerImage->fill(0); + QPainter p(m_workerImage); + p.setPen(Qt::NoPen); + + QRectF rect; + QBrush brush(Qt::SolidPattern); + QRgb previousColor = 0; + + qreal previous_x = -1e30, previous_h = -1e30, offset = 0.; + auto realScale = _current_scale; + + const bool gotFrame = _frame_time > 1e-6f; + qreal frameCoeff = 1; + if (gotFrame) + { + if (_frame_time <= _bottom_duration) + frameCoeff = _boundingRect.height(); + else + frameCoeff = 0.9 / _frame_time; + } + + auto const calculate_color = gotFrame ? calculate_color2 : calculate_color1; + auto const k = gotFrame ? sqr(sqr(frameCoeff)) : 1.0 / _boundingRect.height(); + + if (_regime == Hist_Pointer) + { + const auto& items = *m_pSource; + if (items.empty()) + return; + + auto first = items.begin(); + + if (_bindMode) + { + _minimum = m_workerImageOrigin; + _maximum = m_workerImageOrigin + _width * 7; + realScale *= viewScale; + offset = _minimum * realScale; + + first = ::std::lower_bound(items.begin(), items.end(), _minimum, [](const ::profiler_gui::EasyBlockItem& _item, qreal _value) + { + return _item.left() < _value; + }); + + if (first != items.end()) + { + if (first != items.begin()) + --first; + } + else + { + first = items.begin() + items.size() - 1; + } + + if (_autoAdjustHist) + { + const auto maxVal = _value + _width; + decltype(_top_duration) maxDuration = 0; + decltype(_bottom_duration) minDuration = 1e30; + size_t iterations = 0; + for (auto it = first, end = items.end(); it != end; ++it) + { + // Draw rectangle + if (it->left() > maxVal) + break; + + if (it->right() < _value) + continue; + + if (maxDuration < it->width()) + maxDuration = it->width(); + + if (minDuration > it->width()) + minDuration = it->width(); + + ++iterations; + } + + if (iterations) + { + _top_duration = maxDuration; + _bottom_duration = minDuration; + + if ((_top_duration - _bottom_duration) < 1e-3) + { + if (_bottom_duration > 0.1) + { + _bottom_duration -= 0.1; + } + else + { + _top_duration = 0.1; + _bottom_duration = 0; + } + } + } + } + } + + const auto dtime = _top_duration - _bottom_duration; + const auto coeff = (_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); + + for (auto it = first, end = items.end(); it != end; ++it) + { + // Draw rectangle + if (it->left() > _maximum) + break; + + if (it->right() < _minimum) + continue; + + const qreal item_x = it->left() * realScale - offset; + const qreal item_w = ::std::max(it->width() * realScale, 1.0); + const qreal item_r = item_x + item_w; + const qreal h = it->width() <= _bottom_duration ? HIST_COLUMN_MIN_HEIGHT : + (it->width() > _top_duration ? maxColumnHeight : (HIST_COLUMN_MIN_HEIGHT + (it->width() - _bottom_duration) * coeff)); + + if (h < previous_h && item_r < previous_x) + continue; + + const auto col = calculate_color(h, it->width(), k); + const auto color = 0x00ffffff & QColor::fromHsvF((1.0 - col) * 0.375, 0.85, 0.85).rgb(); + + if (previousColor != color) + { + // Set background color brush for rectangle + previousColor = color; + brush.setColor(QColor::fromRgba(0xc0000000 | color)); + p.setBrush(brush); + } + + rect.setRect(item_x, bottom - h, item_w, h); + p.drawRect(rect); + + previous_x = item_r; + previous_h = h; + } + } + else + { + auto first = m_selectedBlocks.begin(); + + if (_bindMode) + { + _minimum = m_workerImageOrigin; + _maximum = m_workerImageOrigin + _width * 7; + realScale *= viewScale; + offset = _minimum * 1e3 * realScale; + + first = ::std::lower_bound(m_selectedBlocks.begin(), m_selectedBlocks.end(), _minimum * 1e3 + _begin_time, [](::profiler::block_index_t _item, qreal _value) + { + return easyBlock(_item).tree.node->begin() < _value; + }); + + if (first != m_selectedBlocks.end()) + { + if (first != m_selectedBlocks.begin()) + --first; + } + else + { + first = m_selectedBlocks.begin() + m_selectedBlocks.size() - 1; + } + + _minimum *= 1e3; + _maximum *= 1e3; + + if (_autoAdjustHist) + { + const auto minVal = _value * 1e3, maxVal = (_value + _width) * 1e3; + decltype(_top_duration) maxDuration = 0; + decltype(_bottom_duration) minDuration = 1e30; + size_t iterations = 0; + for (auto it = first, end = m_selectedBlocks.end(); it != end; ++it) + { + const auto item = easyBlock(*it).tree.node; + + const auto beginTime = item->begin() - _begin_time; + if (beginTime > maxVal) + break; + + const auto endTime = item->end() - _begin_time; + if (endTime < minVal) + continue; + + const qreal duration = item->duration() * 1e-3; + + if (maxDuration < duration) + maxDuration = duration; + + if (minDuration > duration) + minDuration = duration; + + ++iterations; + } + + if (iterations) + { + _top_duration = maxDuration; + _bottom_duration = minDuration; + + if ((_top_duration - _bottom_duration) < 1e-3) + { + if (_bottom_duration > 0.1) + { + _bottom_duration -= 0.1; + } + else + { + _top_duration = 0.1; + _bottom_duration = 0; + } + } + } + } + } + else + { + _minimum *= 1e3; + _maximum *= 1e3; + } + + const auto dtime = _top_duration - _bottom_duration; + const auto coeff = (_boundingRect.height() - HIST_COLUMN_MIN_HEIGHT) / (dtime > 1e-3 ? dtime : 1.); + + for (auto it = first, end = m_selectedBlocks.end(); it != end; ++it) + { + // Draw rectangle + const auto item = easyBlock(*it).tree.node; + + const auto beginTime = item->begin() - _begin_time; + if (beginTime > _maximum) + break; + + const auto endTime = item->end() - _begin_time; + if (endTime < _minimum) + continue; + + const qreal duration = item->duration() * 1e-3; + const qreal item_x = (beginTime * realScale - offset) * 1e-3; + const qreal item_w = ::std::max(duration * realScale, 1.0); + const qreal item_r = item_x + item_w; + const auto h = duration <= _bottom_duration ? HIST_COLUMN_MIN_HEIGHT : + (duration > _top_duration ? maxColumnHeight : (HIST_COLUMN_MIN_HEIGHT + (duration - _bottom_duration) * coeff)); + + if (h < previous_h && item_r < previous_x) + continue; + + const auto col = calculate_color(h, duration, k); + const auto color = 0x00ffffff & QColor::fromHsvF((1.0 - col) * 0.375, 0.85, 0.85).rgb(); + + if (previousColor != color) + { + // Set background color brush for rectangle + previousColor = color; + brush.setColor(QColor::fromRgba(0xc0000000 | color)); + p.setBrush(brush); + } + + rect.setRect(item_x, bottom - h, item_w, h); + p.drawRect(rect); + + previous_x = item_r; + previous_h = h; + } + } + + m_workerTopDuration = _top_duration; + m_workerBottomDuration = _bottom_duration; +} + +////////////////////////////////////////////////////////////////////////// + +EasyGraphicsScrollbar::EasyGraphicsScrollbar(QWidget* _parent) + : Parent(_parent) + , m_minimumValue(0) + , m_maximumValue(500) + , m_value(10) + , m_windowScale(1) + , m_mouseButtons(Qt::NoButton) + , m_slider(nullptr) + , m_chronometerIndicator(nullptr) + , m_histogramItem(nullptr) + , m_defaultFontHeight(0) + , m_bScrolling(false) + , m_bBindMode(false) + , m_bLocked(false) +{ + setCacheMode(QGraphicsView::CacheNone); + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + setOptimizationFlag(QGraphicsView::DontSavePainterState, true); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setContentsMargins(0, 0, 0, 0); + + auto selfScene = new QGraphicsScene(this); + m_defaultFontHeight = QFontMetrics(selfScene->font()).height(); + selfScene->setSceneRect(0, DEFAULT_TOP, 500, DEFAULT_HEIGHT + m_defaultFontHeight + 2); + setFixedHeight(DEFAULT_HEIGHT + m_defaultFontHeight + 2); + + setScene(selfScene); + + m_histogramItem = new EasyHistogramItem(); + m_histogramItem->setPos(0, 0); + m_histogramItem->setBoundingRect(0, DEFAULT_TOP + INDICATOR_SIZE, scene()->width(), DEFAULT_HEIGHT - INDICATOR_SIZE_x2); + selfScene->addItem(m_histogramItem); + m_histogramItem->hide(); + + m_chronometerIndicator = new EasyGraphicsSliderItem(false); + m_chronometerIndicator->setPos(0, 0); + m_chronometerIndicator->setColor(0x40000000 | ::profiler_gui::CHRONOMETER_COLOR.rgba()); + selfScene->addItem(m_chronometerIndicator); + m_chronometerIndicator->hide(); + + m_slider = new EasyGraphicsSliderItem(true); + m_slider->setPos(0, 0); + m_slider->setColor(0x40c0c0c0); + selfScene->addItem(m_slider); + m_slider->hide(); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, [this]() + { + if (m_histogramItem->isVisible()) + { + m_histogramItem->updateImage(); + scene()->update(); + } + }); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::autoAdjustHistogramChanged, [this]() + { + if (m_histogramItem->isVisible()) + m_histogramItem->onModeChanged(); + }); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::displayOnlyFramesOnHistogramChanged, [this]() + { + if (m_histogramItem->isVisible()) + m_histogramItem->rebuildSource(EasyHistogramItem::Hist_Id); + }); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::threadNameDecorationChanged, this, &This::onThreadViewChanged); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::hexThreadIdChanged, this, &This::onThreadViewChanged); + + centerOn(0, 0); +} + +EasyGraphicsScrollbar::~EasyGraphicsScrollbar() +{ + +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::onThreadViewChanged() +{ + if (m_histogramItem->isVisible()) + { + m_histogramItem->validateName(); + scene()->update(); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::clear() +{ + setHistogramSource(0, nullptr); + hideChrono(); + setRange(0, 100); + setSliderWidth(2); + setValue(0); +} + +////////////////////////////////////////////////////////////////////////// + +bool EasyGraphicsScrollbar::bindMode() const +{ + return m_bBindMode; +} + +qreal EasyGraphicsScrollbar::getWindowScale() const +{ + return m_windowScale; +} + +::profiler::thread_id_t EasyGraphicsScrollbar::hystThread() const +{ + return m_histogramItem->threadId(); +} + +qreal EasyGraphicsScrollbar::minimum() const +{ + return m_minimumValue; +} + +qreal EasyGraphicsScrollbar::maximum() const +{ + return m_maximumValue; +} + +qreal EasyGraphicsScrollbar::range() const +{ + return m_maximumValue - m_minimumValue; +} + +qreal EasyGraphicsScrollbar::value() const +{ + return m_value; +} + +qreal EasyGraphicsScrollbar::sliderWidth() const +{ + return m_slider->width(); +} + +qreal EasyGraphicsScrollbar::sliderHalfWidth() const +{ + return m_slider->halfwidth(); +} + +int EasyGraphicsScrollbar::defaultFontHeight() const +{ + return m_defaultFontHeight; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::setValue(qreal _value) +{ + using estd::clamp; + m_value = clamp(m_minimumValue, _value, ::std::max(m_minimumValue, m_maximumValue - m_slider->width())); + m_slider->setX(m_value + m_slider->halfwidth()); + emit valueChanged(m_value); + + if (m_histogramItem->isVisible()) + m_histogramItem->onValueChanged(); +} + +void EasyGraphicsScrollbar::setRange(qreal _minValue, qreal _maxValue) +{ + const auto oldRange = range(); + const auto oldValue = oldRange < 1e-3 ? 0.0 : m_value / oldRange; + + m_minimumValue = _minValue; + m_maximumValue = _maxValue; + const auto range = this->range(); + scene()->setSceneRect(_minValue, DEFAULT_TOP, range, DEFAULT_HEIGHT + m_defaultFontHeight + 4); + + m_histogramItem->cancelImageUpdate(); + m_histogramItem->setBoundingRect(_minValue, DEFAULT_TOP + INDICATOR_SIZE, range, DEFAULT_HEIGHT - INDICATOR_SIZE_x2); + + emit rangeChanged(); + + setValue(_minValue + oldValue * range); + + onWindowWidthChange(width()); + + if (m_histogramItem->isVisible()) + m_histogramItem->updateImage(); +} + +void EasyGraphicsScrollbar::setSliderWidth(qreal _width) +{ + m_slider->setWidth(_width); + setValue(m_value); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::setChronoPos(qreal _left, qreal _right) +{ + m_chronometerIndicator->setWidth(_right - _left); + m_chronometerIndicator->setX(_left + m_chronometerIndicator->halfwidth()); +} + +void EasyGraphicsScrollbar::showChrono() +{ + m_chronometerIndicator->show(); +} + +void EasyGraphicsScrollbar::hideChrono() +{ + m_chronometerIndicator->hide(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::setHistogramSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items) +{ + if (m_bLocked) + return; + + m_histogramItem->setSource(_thread_id, _items); + m_slider->setVisible(m_histogramItem->isVisible()); + scene()->update(); +} + +void EasyGraphicsScrollbar::setHistogramSource(::profiler::thread_id_t _thread_id, ::profiler::block_id_t _block_id) +{ + if (m_bLocked) + return; + + m_histogramItem->setSource(_thread_id, _block_id); + m_slider->setVisible(m_histogramItem->isVisible()); + scene()->update(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::mousePressEvent(QMouseEvent* _event) +{ + _event->accept(); + + m_mouseButtons = _event->buttons(); + + if (m_mouseButtons & Qt::LeftButton) + { + if (_event->modifiers() & Qt::ControlModifier) + { + m_histogramItem->pickBottomBoundary(mapToScene(_event->pos()).y()); + } + else if (_event->modifiers() & Qt::ShiftModifier) + { + m_histogramItem->pickTopBoundary(mapToScene(_event->pos()).y()); + } + else + { + m_bScrolling = true; + m_mousePressPos = _event->pos(); + if (!m_bBindMode) + setValue(mapToScene(m_mousePressPos).x() - m_minimumValue - m_slider->halfwidth()); + } + } + + if (m_mouseButtons & Qt::RightButton) + { + if (_event->modifiers()) + { + m_histogramItem->pickFrameTime(mapToScene(_event->pos()).y()); + } + else + { + m_bBindMode = !m_bBindMode; + if (m_histogramItem->isVisible()) + m_histogramItem->onModeChanged(); + } + } + + //QGraphicsView::mousePressEvent(_event); +} + +void EasyGraphicsScrollbar::mouseReleaseEvent(QMouseEvent* _event) +{ + m_mouseButtons = _event->buttons(); + m_bScrolling = false; + _event->accept(); + //QGraphicsView::mouseReleaseEvent(_event); +} + +void EasyGraphicsScrollbar::mouseMoveEvent(QMouseEvent* _event) +{ + const auto pos = _event->pos(); + + if (m_mouseButtons & Qt::LeftButton) + { + const auto delta = pos - m_mousePressPos; + m_mousePressPos = pos; + + if (m_bScrolling) + { + auto realScale = m_windowScale; + if (m_bBindMode) + realScale *= -range() / sliderWidth(); + setValue(m_value + delta.x() / realScale); + } + } + + if (m_histogramItem->isVisible()) + { + m_histogramItem->setMouseY(mapToScene(pos).y()); + scene()->update(); + } +} + +void EasyGraphicsScrollbar::wheelEvent(QWheelEvent* _event) +{ + _event->accept(); + + if (_event->modifiers() & Qt::ShiftModifier) + { + // Shift + mouse wheel will change histogram top boundary + + if (m_histogramItem->isVisible()) + { + if (_event->delta() > 0) + m_histogramItem->increaseTopBoundary(); + else + m_histogramItem->decreaseTopBoundary(); + } + + return; + } + + if (_event->modifiers() & Qt::ControlModifier) + { + // Ctrl + mouse wheel will change histogram bottom boundary + + if (m_histogramItem->isVisible()) + { + if (_event->delta() > 0) + m_histogramItem->increaseBottomBoundary(); + else + m_histogramItem->decreaseBottomBoundary(); + } + + return; + } + + if (!m_bBindMode) + { + const auto w = m_slider->halfwidth() * (_event->delta() < 0 ? ::profiler_gui::SCALING_COEFFICIENT : ::profiler_gui::SCALING_COEFFICIENT_INV); + setValue(mapToScene(_event->pos()).x() - m_minimumValue - w); + emit wheeled(w * m_windowScale, _event->delta()); + } + else + { + const auto x = (mapToScene(_event->pos()).x() - m_minimumValue) * m_windowScale; + emit wheeled(x, _event->delta()); + } +} + +void EasyGraphicsScrollbar::resizeEvent(QResizeEvent* _event) +{ + onWindowWidthChange(_event->size().width()); + if (m_histogramItem->isVisible()) + m_histogramItem->updateImage(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyGraphicsScrollbar::onWindowWidthChange(qreal _width) +{ + const auto oldScale = m_windowScale; + const auto scrollingRange = range(); + + if (scrollingRange < 1e-3) + { + m_windowScale = 1; + } + else + { + m_windowScale = _width / scrollingRange; + } + + scale(m_windowScale / oldScale, 1); +} + +////////////////////////////////////////////////////////////////////////// diff --git a/3rdparty/easyprofiler/profiler_gui/easy_graphics_scrollbar.h b/3rdparty/easyprofiler/profiler_gui/easy_graphics_scrollbar.h new file mode 100644 index 0000000..06a8ec7 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_graphics_scrollbar.h @@ -0,0 +1,342 @@ +/************************************************************************ +* file name : easy_graphics_scrollbar.h +* ----------------- : +* creation time : 2016/07/04 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : This file contains declaration of +* ----------------- : +* change log : * 2016/07/04 Victor Zarubkin: Initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY__GRAPHICS_SCROLLBAR__H +#define EASY__GRAPHICS_SCROLLBAR__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "easy_qtimer.h" +#include "common_types.h" + +////////////////////////////////////////////////////////////////////////// + +// TODO: use profiler_core/spin_lock.h + +#define EASY_GUI_USE_CRITICAL_SECTION // Use CRITICAL_SECTION instead of std::atomic_flag +#if defined(_WIN32) && defined(EASY_GUI_USE_CRITICAL_SECTION) +namespace profiler_gui { + // std::atomic_flag on Windows works slower than critical section, so we will use it instead of std::atomic_flag... + // By the way, Windows critical sections are slower than std::atomic_flag on Unix. + class spin_lock { void* m_lock; public: + void lock(); + void unlock(); + spin_lock(); + ~spin_lock(); + }; +#else +namespace profiler_gui { + // std::atomic_flag on Unix works fine and very fast (almost instant!) + class spin_lock { + ::std::atomic_flag m_lock; public: + + void lock() { + while (m_lock.test_and_set(::std::memory_order_acquire)); + } + + void unlock() { + m_lock.clear(::std::memory_order_release); + } + + spin_lock() { + m_lock.clear(); + } + }; +#endif + +} // END of namespace profiler_gui. + +////////////////////////////////////////////////////////////////////////// + +class EasyGraphicsSliderItem : public QGraphicsRectItem +{ + typedef QGraphicsRectItem Parent; + typedef EasyGraphicsSliderItem This; + +private: + + QPolygonF m_indicator; + qreal m_halfwidth; + bool m_bMain; + +public: + + explicit EasyGraphicsSliderItem(bool _main); + virtual ~EasyGraphicsSliderItem(); + + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; + + qreal width() const; + qreal halfwidth() const; + + void setWidth(qreal _width); + void setHalfwidth(qreal _halfwidth); + + void setColor(QRgb _color); + void setColor(const QColor& _color); + +}; // END of class EasyGraphicsSliderItem. + +////////////////////////////////////////////////////////////////////////// + +class EasyHistogramItem : public QGraphicsItem +{ + typedef QGraphicsItem Parent; + typedef EasyHistogramItem This; + +public: + + enum HistRegime : uint8_t { Hist_Pointer, Hist_Id }; + +private: + + QRectF m_boundingRect; + qreal m_topDuration; + qreal m_bottomDuration; + qreal m_maxDuration; + qreal m_minDuration; + qreal m_mouseY; + qreal m_imageOrigin; + qreal m_imageScale; + qreal m_imageOriginUpdate; + qreal m_imageScaleUpdate; + qreal m_workerImageOrigin; + qreal m_workerImageScale; + qreal m_workerTopDuration; + qreal m_workerBottomDuration; + ::profiler::timestamp_t m_blockTotalDuraion; + QString m_topDurationStr; + QString m_bottomDurationStr; + QString m_threadName; + QString m_blockName; + ::profiler::BlocksTree::children_t m_selectedBlocks; + QImage m_mainImage; + EasyQTimer m_timer; + EasyQTimer m_boundaryTimer; + ::std::thread m_workerThread; + ::profiler::timestamp_t m_threadDuration; + ::profiler::timestamp_t m_threadProfiledTime; + ::profiler::timestamp_t m_threadWaitTime; + const ::profiler_gui::EasyItems* m_pSource; + QImage* m_workerImage; + const ::profiler::BlocksTreeRoot* m_pProfilerThread; + ::profiler::thread_id_t m_threadId; + ::profiler::block_index_t m_blockId; + int m_timeouts; + ::profiler_gui::TimeUnits m_timeUnits; + HistRegime m_regime; + bool m_bPermitImageUpdate; ///< Is false when m_workerThread is parsing input dataset (when setSource(_block_id) is called) + ::profiler_gui::spin_lock m_spin; + ::std::atomic_bool m_bReady; + +public: + + explicit EasyHistogramItem(); + virtual ~EasyHistogramItem(); + + // Public virtual methods + + QRectF boundingRect() const override; + void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override; + +public: + + // Public non-virtual methods + + ::profiler::thread_id_t threadId() const; + + void setBoundingRect(const QRectF& _rect); + void setBoundingRect(qreal x, qreal y, qreal w, qreal h); + + void setSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems* _items); + void setSource(::profiler::thread_id_t _thread_id, ::profiler::block_id_t _block_id); + void rebuildSource(HistRegime _regime); + void rebuildSource(); + void validateName(); + void updateImage(); + void cancelImageUpdate(); + + void pickTopBoundary(qreal _y); + void increaseTopBoundary(); + void decreaseTopBoundary(); + + void pickBottomBoundary(qreal _y); + void increaseBottomBoundary(); + void decreaseBottomBoundary(); + + void setMouseY(qreal _mouseY); + void pickFrameTime(qreal _y) const; + + void onValueChanged(); + void onModeChanged(); + +private: + + void paintBusyIndicator(QPainter* _painter, qreal _current_scale); + void paintMouseIndicator(QPainter* _painter, qreal _top, qreal _bottom, qreal _width, qreal _height, qreal _top_width, qreal _mouse_y, qreal _delta_time, int _font_h); + void paintByPtr(QPainter* _painter); + void paintById(QPainter* _painter); + void onTimeout(); + void updateImage(QRectF _boundingRect, HistRegime _regime, qreal _current_scale, + qreal _minimum, qreal _maximum, qreal _range, + qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, bool _bindMode, + float _frame_time, ::profiler::timestamp_t _begin_time, qreal _origin, bool _autoAdjustHist); + +}; // END of class EasyHistogramItem. + +////////////////////////////////////////////////////////////////////////// + +class EasyGraphicsScrollbar : public QGraphicsView +{ + Q_OBJECT + +private: + + typedef QGraphicsView Parent; + typedef EasyGraphicsScrollbar This; + + qreal m_minimumValue; + qreal m_maximumValue; + qreal m_value; + qreal m_windowScale; + QPoint m_mousePressPos; + Qt::MouseButtons m_mouseButtons; + EasyGraphicsSliderItem* m_slider; + EasyGraphicsSliderItem* m_chronometerIndicator; + EasyHistogramItem* m_histogramItem; + int m_defaultFontHeight; + bool m_bScrolling; + bool m_bBindMode; + bool m_bLocked; + +public: + + explicit EasyGraphicsScrollbar(QWidget* _parent = nullptr); + virtual ~EasyGraphicsScrollbar(); + + // Public virtual methods + + void mousePressEvent(QMouseEvent* _event) override; + void mouseReleaseEvent(QMouseEvent* _event) override; + void mouseMoveEvent(QMouseEvent* _event) override; + void wheelEvent(QWheelEvent* _event) override; + void resizeEvent(QResizeEvent* _event) override; + + void dragEnterEvent(QDragEnterEvent*) override {} + +public: + + // Public non-virtual methods + + void clear(); + + bool bindMode() const; + qreal getWindowScale() const; + ::profiler::thread_id_t hystThread() const; + + qreal minimum() const; + qreal maximum() const; + qreal range() const; + qreal value() const; + qreal sliderWidth() const; + qreal sliderHalfWidth() const; + int defaultFontHeight() const; + + void setValue(qreal _value); + void setRange(qreal _minValue, qreal _maxValue); + void setSliderWidth(qreal _width); + void setChronoPos(qreal _left, qreal _right); + void showChrono(); + void hideChrono(); + + void setHistogramSource(::profiler::thread_id_t _thread_id, const::profiler_gui::EasyItems* _items); + void setHistogramSource(::profiler::thread_id_t _thread_id, ::profiler::block_id_t _block_id); + + inline void setHistogramSource(::profiler::thread_id_t _thread_id, const ::profiler_gui::EasyItems& _items) + { + setHistogramSource(_thread_id, &_items); + } + + inline void lock() + { + m_bLocked = true; + } + + inline void unlock() + { + m_bLocked = false; + } + +signals: + + void rangeChanged(); + void valueChanged(qreal _value); + void wheeled(qreal _mouseX, int _wheelDelta); + +private slots: + + void onThreadViewChanged(); + void onWindowWidthChange(qreal _width); + +}; // END of class EasyGraphicsScrollbar. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY__GRAPHICS_SCROLLBAR__H diff --git a/3rdparty/easyprofiler/profiler_gui/easy_qtimer.cpp b/3rdparty/easyprofiler/profiler_gui/easy_qtimer.cpp new file mode 100644 index 0000000..4eb1740 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_qtimer.cpp @@ -0,0 +1,85 @@ +/************************************************************************ +* file name : easy_qtimer.h +* ----------------- : +* creation time : 2016/12/05 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : This file contains implementation of EasyQTimer class used to +* : connect QTimer to non-QObject classes. +* ----------------- : +* change log : * 2016/12/05 Victor Zarubkin: Initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include "easy_qtimer.h" + +////////////////////////////////////////////////////////////////////////// + +EasyQTimer::EasyQTimer() + : QObject() +{ + connect(&m_timer, &QTimer::timeout, [this](){ m_handler(); }); +} + +EasyQTimer::EasyQTimer(::std::function&& _handler, bool _isSignleShot) + : QObject() + , m_handler(::std::forward<::std::function&&>(_handler)) +{ + m_timer.setSingleShot(_isSignleShot); + connect(&m_timer, &QTimer::timeout, [this](){ m_handler(); }); +} + +EasyQTimer::~EasyQTimer() +{ + +} + +void EasyQTimer::setHandler(::std::function&& _handler) +{ + m_handler = _handler; +} + +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/easy_qtimer.h b/3rdparty/easyprofiler/profiler_gui/easy_qtimer.h new file mode 100644 index 0000000..818e628 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/easy_qtimer.h @@ -0,0 +1,89 @@ +/************************************************************************ +* file name : easy_qtimer.h +* ----------------- : +* creation time : 2016/12/05 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : This file contains declaration of EasyQTimer class used to +* : connect QTimer to non-QObject classes. +* ----------------- : +* change log : * 2016/12/05 Victor Zarubkin: Initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY__QTIMER__H +#define EASY__QTIMER__H + +#include +#include + +////////////////////////////////////////////////////////////////////////// + +class EasyQTimer : public QObject +{ + Q_OBJECT + +private: + + QTimer m_timer; + ::std::function m_handler; + +public: + + EasyQTimer(); + EasyQTimer(::std::function&& _handler, bool _isSignleShot = false); + virtual ~EasyQTimer(); + + void setHandler(::std::function&& _handler); + + inline void start(int msec) { m_timer.start(msec); } + inline void stop() { if (m_timer.isActive()) m_timer.stop(); } + inline bool isActive() const { return m_timer.isActive(); } + +}; // END of class EasyQTimer. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY__QTIMER__H diff --git a/3rdparty/easyprofiler/profiler_gui/globals.cpp b/3rdparty/easyprofiler/profiler_gui/globals.cpp new file mode 100644 index 0000000..4487849 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/globals.cpp @@ -0,0 +1,122 @@ +/************************************************************************ +* file name : globals.cpp +* ----------------- : +* creation time : 2016/08/03 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of global constants and variables for profiler gui. +* ----------------- : +* change log : * 2016/08/03 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#define IGNORE_GLOBALS_DECLARATION +#include "globals.h" +#undef IGNORE_GLOBALS_DECLARATION + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler_gui { + + EasyGlobals& EasyGlobals::instance() + { + // It's okay even without C++11 "magic statics" feature because first call happens + // on application initialization - there is only one thread and no data races occur. + static EasyGlobals globals; + return globals; + } + + EasyGlobals::EasyGlobals() + : theme("default") + , bg_font(::profiler_gui::EFont("DejaVu Sans", 10, QFont::Bold)) + , chronometer_font(::profiler_gui::EFont("DejaVu Sans", 16, QFont::Bold)) + , items_font(::profiler_gui::EFont("DejaVu Sans", 10, QFont::Medium)) + , selected_item_font(::profiler_gui::EFont("DejaVu Sans", 10, QFont::Medium)) + , scene_left(0) + , scene_right(100) + , begin_time(0) + , selected_thread(0U) + , selected_block(::profiler_gui::numeric_max()) + , selected_block_id(::profiler_gui::numeric_max()) + , version(0) + , frame_time(16700) + , blocks_spacing(0) + , blocks_size_min(2) + , blocks_narrow_size(20) + , max_fps_history(90) + , fps_timer_interval(500) + , fps_widget_line_width(2) + , chrono_text_position(ChronoTextPosition_Top) + , time_units(TimeUnits_ms) + , connected(false) + , fps_enabled(true) + , use_decorated_thread_name(false) + , hex_thread_id(false) + , enable_event_markers(true) + , enable_statistics(true) + , enable_zero_length(true) + , add_zero_blocks_to_hierarchy(false) + , draw_graphics_items_borders(true) + , hide_narrow_children(false) + , hide_minsize_blocks(false) + , display_only_relevant_stats(true) + , collapse_items_on_tree_close(false) + , all_items_expanded_by_default(true) + , only_current_thread_hierarchy(false) + , highlight_blocks_with_same_id(true) + , selecting_block_changes_thread(true) + , auto_adjust_histogram_height(true) + , display_only_frames_on_histogram(false) + , bind_scene_and_tree_expand_status(true) + { + + } + +} // END of namespace profiler_gui. + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/globals.h b/3rdparty/easyprofiler/profiler_gui/globals.h new file mode 100644 index 0000000..6f346be --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/globals.h @@ -0,0 +1,273 @@ +/************************************************************************ +* file name : globals.h +* ----------------- : +* creation time : 2016/08/03 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of global constants and variables for profiler gui. +* ----------------- : +* change log : * 2016/08/03 Victor Zarubkin: initial commit. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER__GUI_GLOBALS_H +#define EASY_PROFILER__GUI_GLOBALS_H + +#include +#include +#include +#include +#include +#include +#include "common_functions.h" +#include "globals_qobjects.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler_gui { + + const QString ORGANAZATION_NAME = "EasyProfiler"; + const QString APPLICATION_NAME = "Easy profiler gui application"; + + const QColor CHRONOMETER_COLOR = QColor::fromRgba(0x40000000 | (::profiler::colors::RichBlue & 0x00ffffff));// 0x402020c0); + const QColor CHRONOMETER_COLOR2 = QColor::fromRgba(0x40000000 | (::profiler::colors::Dark & 0x00ffffff));// 0x40408040); + const QColor TEXT_COLOR = QColor::fromRgb(0xff504040); + const QColor SYSTEM_BORDER_COLOR = QColor::fromRgb(0xffcccccc); + EASY_CONSTEXPR QRgb SELECTED_THREAD_BACKGROUND = 0xffe0e060; + EASY_CONSTEXPR QRgb SELECTED_THREAD_FOREGROUND = 0xffffffff - (SELECTED_THREAD_BACKGROUND & 0x00ffffff); + + EASY_CONSTEXPR qreal SCALING_COEFFICIENT = 1.25; + EASY_CONSTEXPR qreal SCALING_COEFFICIENT_INV = 1.0 / SCALING_COEFFICIENT; + + EASY_CONSTEXPR uint32_t V130 = 0x01030000; + + Q_CONSTEXPR QSize ICONS_SIZE {28, 28}; + EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SIZE = 20; + EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SPACING = 0; + EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SIZE_FULL = GRAPHICS_ROW_SIZE + GRAPHICS_ROW_SPACING; + EASY_CONSTEXPR uint16_t THREADS_ROW_SPACING = 10; + +#ifdef _WIN32 + EASY_CONSTEXPR qreal FONT_METRICS_FACTOR = 1.05; +#else + EASY_CONSTEXPR qreal FONT_METRICS_FACTOR = 1.; +#endif + + ////////////////////////////////////////////////////////////////////////// + + template + inline auto toUnicode(const T& _inputString) -> decltype(QTextCodec::codecForLocale()->toUnicode(_inputString)) + { + return QTextCodec::codecForLocale()->toUnicode(_inputString); + } + + ////////////////////////////////////////////////////////////////////////// + + inline QString decoratedThreadName(bool _use_decorated_thread_name, const::profiler::BlocksTreeRoot& _root, const QString& _unicodeThreadWord, bool _hex = false) + { + if (_root.got_name()) + { + QString rootname(toUnicode(_root.name())); + if (!_use_decorated_thread_name || rootname.contains(_unicodeThreadWord, Qt::CaseInsensitive)) + { + if (_hex) + return QString("%1 0x%2").arg(rootname).arg(_root.thread_id, 0, 16); + return QString("%1 %2").arg(rootname).arg(_root.thread_id); + } + + if (_hex) + return QString("%1 Thread 0x%2").arg(rootname).arg(_root.thread_id, 0, 16); + return QString("%1 Thread %2").arg(rootname).arg(_root.thread_id); + } + + if (_hex) + return QString("Thread 0x%1").arg(_root.thread_id, 0, 16); + return QString("Thread %1").arg(_root.thread_id); + } + + inline QString decoratedThreadName(bool _use_decorated_thread_name, const ::profiler::BlocksTreeRoot& _root, bool _hex = false) + { + if (_root.got_name()) + { + QString rootname(toUnicode(_root.name())); + if (!_use_decorated_thread_name || rootname.contains(toUnicode("thread"), Qt::CaseInsensitive)) + { + if (_hex) + return QString("%1 0x%2").arg(rootname).arg(_root.thread_id, 0, 16); + return QString("%1 %2").arg(rootname).arg(_root.thread_id); + } + + if (_hex) + return QString("%1 Thread 0x%2").arg(rootname).arg(_root.thread_id, 0, 16); + return QString("%1 Thread %2").arg(rootname).arg(_root.thread_id); + } + + if (_hex) + return QString("Thread 0x%1").arg(_root.thread_id, 0, 16); + return QString("Thread %1").arg(_root.thread_id); + } + + ////////////////////////////////////////////////////////////////////////// + + enum ChronometerTextPosition : int8_t + { + ChronoTextPosition_Center = 0, + ChronoTextPosition_Top, + ChronoTextPosition_Bottom, + + }; // END of enum ChronometerTextPosition. + + ////////////////////////////////////////////////////////////////////////// + + struct EasyGlobals Q_DECL_FINAL + { + static EasyGlobals& instance(); + + EasyGlobalSignals events; ///< Global signals + ::profiler::thread_blocks_tree_t profiler_blocks; ///< Profiler blocks tree loaded from file + ::profiler::descriptors_list_t descriptors; ///< Profiler block descriptors list + EasyBlocks gui_blocks; ///< Profiler graphics blocks builded by GUI + + QString theme; ///< Current UI theme name + QFont bg_font; ///< Font for blocks_graphics_view + QFont chronometer_font; ///< Font for easy_chronometer_item + QFont items_font; ///< Font for easy_graphics_item + QFont selected_item_font; ///< Font for easy_graphics_item + + double scene_left; ///< Graphics scene left boundary + double scene_right; ///< Graphics scene right boundary + ::profiler::timestamp_t begin_time; ///< + ::profiler::thread_id_t selected_thread; ///< Current selected thread id + ::profiler::block_index_t selected_block; ///< Current selected profiler block index + ::profiler::block_id_t selected_block_id; ///< Current selected profiler block id + uint32_t version; ///< Opened file version (files may have different format) + float frame_time; ///< Expected frame time value in microseconds to be displayed at minimap on graphics scrollbar + int blocks_spacing; ///< Minimum blocks spacing on diagram + int blocks_size_min; ///< Minimum blocks size on diagram + int blocks_narrow_size; ///< Width indicating narrow blocks + int max_fps_history; ///< Max frames history displayed in FPS Monitor + int fps_timer_interval; ///< Interval in milliseconds for sending network requests to the profiled application (used by FPS Monitor) + int fps_widget_line_width; ///< Line width in pixels of FPS lines for FPS Monitor + ChronometerTextPosition chrono_text_position; ///< Selected interval text position + TimeUnits time_units; ///< Units type for time (milliseconds, microseconds, nanoseconds or auto-definition) + bool connected; ///< Is connected to source (to be able to capture profiling information) + bool fps_enabled; ///< Is FPS Monitor enabled + bool use_decorated_thread_name; ///< Add "Thread" to the name of each thread (if there is no one) + bool hex_thread_id; ///< Use hex view for thread-id instead of decimal + bool enable_event_markers; ///< Enable event indicators painting (These are narrow rectangles at the bottom of each thread) + bool enable_statistics; ///< Enable gathering and using statistics (Disable if you want to consume less memory) + bool enable_zero_length; ///< Enable zero length blocks (if true, then such blocks will have width == 1 pixel on each scale) + bool add_zero_blocks_to_hierarchy; ///< Enable adding zero blocks into hierarchy tree + bool draw_graphics_items_borders; ///< Draw borders for graphics blocks or not + bool hide_narrow_children; ///< Hide children for narrow graphics blocks (See blocks_narrow_size) + bool hide_minsize_blocks; ///< Hide blocks which screen size is less than blocks_size_min + bool display_only_relevant_stats; ///< Display only relevant information in ProfTreeWidget (excludes min, max, average times if there are only 1 calls number) + bool collapse_items_on_tree_close; ///< Collapse all items which were displayed in the hierarchy tree after tree close/reset + bool all_items_expanded_by_default; ///< Expand all items after file is opened + bool only_current_thread_hierarchy; ///< Build hierarchy tree for current thread only + bool highlight_blocks_with_same_id; ///< Highlight all blocks with same id on diagram + bool selecting_block_changes_thread; ///< If true then current selected thread will change every time you select block + bool auto_adjust_histogram_height; ///< Automatically adjust histogram height to the visible region + bool display_only_frames_on_histogram; ///< Display only top-level blocks on histogram when drawing histogram by block id + bool bind_scene_and_tree_expand_status; /** \brief If true then items on graphics scene and in the tree (blocks hierarchy) are binded on each other + so expanding/collapsing items on scene also expands/collapse items in the tree. */ + + private: + + EasyGlobals(); + + }; // END of struct EasyGlobals. + + ////////////////////////////////////////////////////////////////////////// + +} // END of namespace profiler_gui. + +#ifndef IGNORE_GLOBALS_DECLARATION +#define EASY_GLOBALS ::profiler_gui::EasyGlobals::instance() + +inline ::profiler_gui::EasyBlock& easyBlock(::profiler::block_index_t i) { + return EASY_GLOBALS.gui_blocks[i]; +} + +inline ::profiler::SerializedBlockDescriptor& easyDescriptor(::profiler::block_id_t i) { + return *EASY_GLOBALS.descriptors[i]; +} + +EASY_FORCE_INLINE const ::profiler::BlocksTree& easyBlocksTree(::profiler::block_index_t i) { + return easyBlock(i).tree; +} + +EASY_FORCE_INLINE const char* easyBlockName(const ::profiler::BlocksTree& _block) { + const char* name = _block.node->name(); + return *name != 0 ? name : easyDescriptor(_block.node->id()).name(); +} + +EASY_FORCE_INLINE const char* easyBlockName(const ::profiler::BlocksTree& _block, const ::profiler::SerializedBlockDescriptor& _desc) { + const char* name = _block.node->name(); + return *name != 0 ? name : _desc.name(); +} + +EASY_FORCE_INLINE const char* easyBlockName(::profiler::block_index_t i) { + return easyBlockName(easyBlock(i).tree); +} + +inline qreal sceneX(profiler::timestamp_t _time) { + return PROF_MICROSECONDS(qreal(_time - EASY_GLOBALS.begin_time)); +} + +inline QString imagePath(const QString& _resource) { + return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(_resource); +} + +inline QString imagePath(const char* _resource) { + return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(_resource); +} +#endif + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER__GUI_GLOBALS_H diff --git a/3rdparty/easyprofiler/profiler_gui/globals_qobjects.cpp b/3rdparty/easyprofiler/profiler_gui/globals_qobjects.cpp new file mode 100644 index 0000000..62319b1 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/globals_qobjects.cpp @@ -0,0 +1,72 @@ +/************************************************************************ +* file name : globals_qobjects.cpp +* ----------------- : +* creation time : 2016/08/08 +* authors : Victor Zarubkin, Sergey Yagovtsev +* email : v.s.zarubkin@gmail.com, yse.sey@gmail.com +* ----------------- : +* description : The file contains implementation of EasyGlobalSignals QObject class. +* ----------------- : +* change log : * 2016/08/08 Sergey Yagovtsev: moved sources from globals.cpp +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include "globals_qobjects.h" + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +namespace profiler_gui { + + EasyGlobalSignals::EasyGlobalSignals() : QObject() + { + } + + EasyGlobalSignals::~EasyGlobalSignals() + { + } + +} // END of namespace profiler_gui. + +////////////////////////////////////////////////////////////////////////// diff --git a/3rdparty/easyprofiler/profiler_gui/globals_qobjects.h b/3rdparty/easyprofiler/profiler_gui/globals_qobjects.h new file mode 100644 index 0000000..348aede --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/globals_qobjects.h @@ -0,0 +1,95 @@ +/************************************************************************ +* file name : globals_qobjects.h +* ----------------- : +* creation time : 2016/08/08 +* authors : Victor Zarubkin, Sergey Yagovtsev +* email : v.s.zarubkin@gmail.com, yse.sey@gmail.com +* ----------------- : +* description : The file contains declaration of EasyGlobalSignals QObject class. +* ----------------- : +* change log : * 2016/08/08 Sergey Yagovtsev: moved sources from globals.h +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_GLOBALS_QOBJECTS_H +#define EASY_GLOBALS_QOBJECTS_H + +#include +#include + +namespace profiler_gui { + + class EasyGlobalSignals Q_DECL_FINAL : public QObject + { + Q_OBJECT + + public: + + EasyGlobalSignals(); + virtual ~EasyGlobalSignals(); + + signals: + + void selectedThreadChanged(::profiler::thread_id_t _id); + void selectedBlockChanged(uint32_t _block_index); + void selectedBlockIdChanged(::profiler::block_id_t _id); + void itemsExpandStateChanged(); + void blockStatusChanged(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); + void connectionChanged(bool _connected); + void blocksRefreshRequired(bool); + void expectedFrameTimeChanged(); + void autoAdjustHistogramChanged(); + void displayOnlyFramesOnHistogramChanged(); + void hierarchyFlagChanged(bool); + void threadNameDecorationChanged(); + void hexThreadIdChanged(); + void refreshRequired(); + void blocksTreeModeChanged(); + void sceneSizeChanged(); + + }; // END of class EasyGlobalSignals. + +} // END of namespace profiler_gui. + +#endif // EASY_GLOBALS_QOBJECTS_H diff --git a/3rdparty/easyprofiler/profiler_gui/images/attribution.txt b/3rdparty/easyprofiler/profiler_gui/images/attribution.txt new file mode 100644 index 0000000..e346622 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/attribution.txt @@ -0,0 +1,43 @@ +logo.svg - Icon made by Freepik from www.flaticon.com + +default/off.svg - Icon made by Freepik from www.flaticon.com +default/open-folder.svg - Icon made by Freepik from www.flaticon.com +default/open-folder2.svg - Icon made by Freepik from www.flaticon.com +default/reload-folder2.svg - Icon made by Freepik from www.flaticon.com +default/reload.svg - Icon made by Freepik from www.flaticon.com +default/expand.svg - Icon made by Freepik from www.flaticon.com +default/collapse.svg - Icon made by Freepik from www.flaticon.com +default/colors.svg - Icon made by Freepik from www.flaticon.com +default/colors-black.svg - Icon made by Freepik from www.flaticon.com +default/save.svg - Icon made by Freepik from www.flaticon.com +default/statistics.svg - Icon made by Freepik from www.flaticon.com +default/statistics2.svg - Icon made by Freepik from www.flaticon.com +default/lan.svg - Icon made by Freepik from www.flaticon.com +default/lan_on.svg - Icon made by Freepik from www.flaticon.com +default/wifi.svg - Icon made by Freepik from www.flaticon.com +default/wifi_on.svg - Icon made by Freepik from www.flaticon.com +default/play.svg - Icon made by Google from www.flaticon.com +default/stop.svg - Icon made by Google from www.flaticon.com +default/delete.svg - Icon made by Google from www.flaticon.com +default/list.svg - Icon made by Freepik from www.flaticon.com +default/search-prev.svg - Icon made by Freepik from www.flaticon.com +default/search-next.svg - Icon made by Freepik from www.flaticon.com +default/settings.svg - Icon made by Freepik from www.flaticon.com +default/check.svg - Icon made by Kirill Kazachek from www.flaticon.com +default/check-disabled.svg - Icon made by Kirill Kazachek from www.flaticon.com +default/close-white.svg - Icon made by Cole Bemis from www.flaticon.com +default/close-white-hover.svg - Icon made by Cole Bemis from www.flaticon.com +default/close-white-pressed.svg - Icon made by Cole Bemis from www.flaticon.com +default/maximize-white.svg - Icon made by Freepik from www.flaticon.com +default/maximize-white-hover.svg - Icon made by Freepik from www.flaticon.com +default/maximize-white-pressed.svg - Icon made by Freepik from www.flaticon.com +default/minimize-white.svg - Icon made by Freepik from www.flaticon.com +default/minimize-white-pressed.svg - Icon made by Freepik from www.flaticon.com +default/arrow-down.svg - Icon made by Freepik from www.flaticon.com +default/arrow-down-hover.svg - Icon made by Freepik from www.flaticon.com +default/arrow-down-disabled.svg - Icon made by Freepik from www.flaticon.com +default/arrow-up.svg - Icon made by Freepik from www.flaticon.com +default/arrow-up-hover.svg - Icon made by Freepik from www.flaticon.com +default/arrow-up-disabled.svg - Icon made by Freepik from www.flaticon.com +default/arrow-left.svg - Icon made by Freepik from www.flaticon.com +default/arrow-right.svg - Icon made by Freepik from www.flaticon.com diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down-disabled.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down-disabled.svg new file mode 100644 index 0000000..46d7c82 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down-disabled.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down-hover.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down-hover.svg new file mode 100644 index 0000000..e16736a --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down-hover.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down.svg new file mode 100644 index 0000000..13d0004 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-down.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-left.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-left.svg new file mode 100644 index 0000000..7c452e6 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-left.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-right.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-right.svg new file mode 100644 index 0000000..199bfc8 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-right.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up-disabled.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up-disabled.svg new file mode 100644 index 0000000..4581ed1 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up-disabled.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up-hover.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up-hover.svg new file mode 100644 index 0000000..da0da91 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up-hover.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up.svg b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up.svg new file mode 100644 index 0000000..2120ab9 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/arrow-up.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/check-disabled.svg b/3rdparty/easyprofiler/profiler_gui/images/default/check-disabled.svg new file mode 100644 index 0000000..53eb1f9 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/check-disabled.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/check.svg b/3rdparty/easyprofiler/profiler_gui/images/default/check.svg new file mode 100644 index 0000000..cc1eb65 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/check.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/close-white-hover.svg b/3rdparty/easyprofiler/profiler_gui/images/default/close-white-hover.svg new file mode 100644 index 0000000..d78f3d0 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/close-white-hover.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/close-white-pressed.svg b/3rdparty/easyprofiler/profiler_gui/images/default/close-white-pressed.svg new file mode 100644 index 0000000..6602d1c --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/close-white-pressed.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/close-white.svg b/3rdparty/easyprofiler/profiler_gui/images/default/close-white.svg new file mode 100644 index 0000000..cec4875 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/close-white.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/collapse.svg b/3rdparty/easyprofiler/profiler_gui/images/default/collapse.svg new file mode 100644 index 0000000..3bf9ed4 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/collapse.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/colors-black.svg b/3rdparty/easyprofiler/profiler_gui/images/default/colors-black.svg new file mode 100644 index 0000000..13c8182 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/colors-black.svg @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/colors.svg b/3rdparty/easyprofiler/profiler_gui/images/default/colors.svg new file mode 100644 index 0000000..a8d580a --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/colors.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/delete-old.svg b/3rdparty/easyprofiler/profiler_gui/images/default/delete-old.svg new file mode 100644 index 0000000..6502e27 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/delete-old.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/delete.svg b/3rdparty/easyprofiler/profiler_gui/images/default/delete.svg new file mode 100644 index 0000000..35a8016 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/delete.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/expand.svg b/3rdparty/easyprofiler/profiler_gui/images/default/expand.svg new file mode 100644 index 0000000..44ccaa3 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/expand.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/lan.svg b/3rdparty/easyprofiler/profiler_gui/images/default/lan.svg new file mode 100644 index 0000000..0f0124d --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/lan.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/lan_on.svg b/3rdparty/easyprofiler/profiler_gui/images/default/lan_on.svg new file mode 100644 index 0000000..41da421 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/lan_on.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/list.svg b/3rdparty/easyprofiler/profiler_gui/images/default/list.svg new file mode 100644 index 0000000..38ac6ed --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/list.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white-hover.svg b/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white-hover.svg new file mode 100644 index 0000000..92f8257 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white-hover.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white-pressed.svg b/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white-pressed.svg new file mode 100644 index 0000000..73a95d0 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white-pressed.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white.svg b/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white.svg new file mode 100644 index 0000000..d6d86c9 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/maximize-white.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white-hover.svg b/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white-hover.svg new file mode 100644 index 0000000..828901c --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white-hover.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white-pressed.svg b/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white-pressed.svg new file mode 100644 index 0000000..f575f28 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white-pressed.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white.svg b/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white.svg new file mode 100644 index 0000000..24c65de --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/minimize-white.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/off.svg b/3rdparty/easyprofiler/profiler_gui/images/default/off.svg new file mode 100644 index 0000000..57ce672 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/off.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/open-folder.svg b/3rdparty/easyprofiler/profiler_gui/images/default/open-folder.svg new file mode 100644 index 0000000..7500c16 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/open-folder.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/open-folder2.svg b/3rdparty/easyprofiler/profiler_gui/images/default/open-folder2.svg new file mode 100644 index 0000000..70cc9c5 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/open-folder2.svg @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/play.svg b/3rdparty/easyprofiler/profiler_gui/images/default/play.svg new file mode 100644 index 0000000..8bbdf01 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/play.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/radio-indicator-disabled.svg b/3rdparty/easyprofiler/profiler_gui/images/default/radio-indicator-disabled.svg new file mode 100644 index 0000000..cb9540e --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/radio-indicator-disabled.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/radio-indicator.svg b/3rdparty/easyprofiler/profiler_gui/images/default/radio-indicator.svg new file mode 100644 index 0000000..76e0974 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/radio-indicator.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/reload-folder2.svg b/3rdparty/easyprofiler/profiler_gui/images/default/reload-folder2.svg new file mode 100644 index 0000000..1f6d7a6 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/reload-folder2.svg @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/reload.svg b/3rdparty/easyprofiler/profiler_gui/images/default/reload.svg new file mode 100644 index 0000000..796319e --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/reload.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/save.svg b/3rdparty/easyprofiler/profiler_gui/images/default/save.svg new file mode 100644 index 0000000..e81c739 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/save.svg @@ -0,0 +1,73 @@ + + +image/svg+xml \ No newline at end of file diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/search-next.svg b/3rdparty/easyprofiler/profiler_gui/images/default/search-next.svg new file mode 100644 index 0000000..e9ff44d --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/search-next.svg @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/search-prev.svg b/3rdparty/easyprofiler/profiler_gui/images/default/search-prev.svg new file mode 100644 index 0000000..8dbd6fb --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/search-prev.svg @@ -0,0 +1,23 @@ + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/settings.svg b/3rdparty/easyprofiler/profiler_gui/images/default/settings.svg new file mode 100644 index 0000000..783969c --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/settings.svg @@ -0,0 +1,39 @@ + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/statistics.svg b/3rdparty/easyprofiler/profiler_gui/images/default/statistics.svg new file mode 100644 index 0000000..bbb4428 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/statistics.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/statistics2.svg b/3rdparty/easyprofiler/profiler_gui/images/default/statistics2.svg new file mode 100644 index 0000000..3f5c3ad --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/statistics2.svg @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/stop.svg b/3rdparty/easyprofiler/profiler_gui/images/default/stop.svg new file mode 100644 index 0000000..a914d1e --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/stop.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/wifi.svg b/3rdparty/easyprofiler/profiler_gui/images/default/wifi.svg new file mode 100644 index 0000000..cb04ace --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/wifi.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/default/wifi_on.svg b/3rdparty/easyprofiler/profiler_gui/images/default/wifi_on.svg new file mode 100644 index 0000000..461e2b7 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/default/wifi_on.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/images/logo.ico b/3rdparty/easyprofiler/profiler_gui/images/logo.ico new file mode 100644 index 0000000..9d72f93 Binary files /dev/null and b/3rdparty/easyprofiler/profiler_gui/images/logo.ico differ diff --git a/3rdparty/easyprofiler/profiler_gui/images/logo.svg b/3rdparty/easyprofiler/profiler_gui/images/logo.svg new file mode 100644 index 0000000..87756e5 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/images/logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/3rdparty/easyprofiler/profiler_gui/main.cpp b/3rdparty/easyprofiler/profiler_gui/main.cpp new file mode 100644 index 0000000..fb5a0bb --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/main.cpp @@ -0,0 +1,74 @@ +/************************************************************************ +* file name : main.cpp +* ----------------- : +* creation time : 2016/04/29 +* authors : Sergey Yagovtsev, Victor Zarubkin +* email : yse.sey@gmail.com, v.s.zarubkin@gmail.com +* ----------------- : +* description : Main file for EasyProfiler GUI. +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include +#include "main_window.h" +#include "globals.h" + +#if defined(_WIN32) && defined (_BUILD_RELEASE_) +#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") +#endif + +int main(int argc, char **argv) +{ + auto now = ::std::chrono::duration_cast(::std::chrono::system_clock::now().time_since_epoch()).count() >> 1; + srand((unsigned int)now); + + QApplication app(argc, argv); + + //Instanciate easy globals after QApplication to allow creation of global fonts, and on the main thread to avoid data races + profiler_gui::EasyGlobals::instance(); + + EasyMainWindow window; + window.show(); + + return app.exec(); +} diff --git a/3rdparty/easyprofiler/profiler_gui/main_window.cpp b/3rdparty/easyprofiler/profiler_gui/main_window.cpp new file mode 100644 index 0000000..be8c970 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/main_window.cpp @@ -0,0 +1,2982 @@ +/************************************************************************ +* file name : main_window.cpp +* ----------------- : +* creation time : 2016/06/26 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of MainWindow for easy_profiler GUI. +* ----------------- : +* change log : * 2016/06/26 Victor Zarubkin: Initial commit. +* : +* : * 2016/06/27 Victor Zarubkin: Passing blocks number to EasyTreeWidget::setTree(). +* : +* : * 2016/06/29 Victor Zarubkin: Added menu with tests. +* : +* : * 2016/06/30 Sergey Yagovtsev: Open file by command line argument +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main_window.h" +#include "blocks_tree_widget.h" +#include "blocks_graphics_view.h" +#include "descriptors_tree_widget.h" +#include "easy_frame_rate_viewer.h" +#include "globals.h" + +#include +#include + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +#define EASY_DEFAULT_WINDOW_TITLE "EasyProfiler" + +const int LOADER_TIMER_INTERVAL = 40; +const auto NETWORK_CACHE_FILE = "easy_profiler_stream.cache"; + +////////////////////////////////////////////////////////////////////////// + +inline const QStringList& UI_themes() +{ + static const QStringList themes { + "default" + }; + + return themes; +} + +////////////////////////////////////////////////////////////////////////// + +inline void clear_stream(std::stringstream& _stream) +{ +#if defined(__GNUC__) && __GNUC__ < 5 + // gcc 4 has a known bug which has been solved in gcc 5: + // std::stringstream has no swap() method :( + _stream.str(std::string()); +#else + std::stringstream().swap(_stream); +#endif +} + +inline void loadTheme(const QString& _theme) +{ + QFile file(QStringLiteral(":/themes/") + _theme); + if (file.open(QFile::ReadOnly | QFile::Text)) + { + QTextStream in(&file); + QString style = in.readAll(); + if (!style.isEmpty()) + qApp->setStyleSheet(style); + } +} + +////////////////////////////////////////////////////////////////////////// + +EasyDockWidget::EasyDockWidget(const QString& title, QWidget* parent) : QDockWidget(title, parent) +{ + auto floatingButton = new QPushButton(); + floatingButton->setObjectName("EasyDockWidgetFloatButton"); + floatingButton->setProperty("floating", isFloating()); + connect(floatingButton, &QPushButton::clicked, [this, floatingButton] { + setFloating(!isFloating()); + floatingButton->setProperty("floating", isFloating()); + floatingButton->style()->unpolish(floatingButton); + floatingButton->style()->polish(floatingButton); + floatingButton->update(); + }); + + auto closeButton = new QPushButton(); + closeButton->setObjectName("EasyDockWidgetCloseButton"); + connect(closeButton, &QPushButton::clicked, [this] { + close(); + }); + + auto caption = new QWidget(this); + caption->setObjectName("EasyDockWidgetTitle"); + + auto lay = new QHBoxLayout(caption); + lay->setContentsMargins(0, 0, 0, 0); + lay->setSpacing(2); + lay->addWidget(new QLabel(title)); + lay->addStretch(100); + lay->addWidget(floatingButton); + lay->addWidget(closeButton); + + setTitleBarWidget(caption); +} + +EasyDockWidget::~EasyDockWidget() +{ +} + +EasyMainWindow::EasyMainWindow() : Parent(), m_theme("default"), m_lastAddress("localhost"), m_lastPort(::profiler::DEFAULT_PORT) +{ + { QIcon icon(":/images/logo"); if (!icon.isNull()) QApplication::setWindowIcon(icon); } + + setObjectName("ProfilerGUI_MainWindow"); + setWindowTitle(EASY_DEFAULT_WINDOW_TITLE); + setDockNestingEnabled(true); + setAcceptDrops(true); + resize(800, 600); + setStatusBar(nullptr); + + loadSettings(); + loadTheme(m_theme); + + m_graphicsView = new EasyDockWidget("Diagram", this); + m_graphicsView->setObjectName("ProfilerGUI_Diagram"); + m_graphicsView->setMinimumHeight(50); + m_graphicsView->setAllowedAreas(Qt::AllDockWidgetAreas); + + auto graphicsView = new EasyGraphicsViewWidget(this); + m_graphicsView->setWidget(graphicsView); + + m_treeWidget = new EasyDockWidget("Hierarchy", this); + m_treeWidget->setObjectName("ProfilerGUI_Hierarchy"); + m_treeWidget->setMinimumHeight(50); + m_treeWidget->setAllowedAreas(Qt::AllDockWidgetAreas); + + auto treeWidget = new EasyHierarchyWidget(this); + m_treeWidget->setWidget(treeWidget); + + m_fpsViewer = new EasyDockWidget("FPS Monitor", this); + m_fpsViewer->setObjectName("ProfilerGUI_FPS"); + m_fpsViewer->setWidget(new EasyFrameRateViewer(this)); + m_fpsViewer->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); + + addDockWidget(Qt::TopDockWidgetArea, m_graphicsView); + addDockWidget(Qt::BottomDockWidgetArea, m_treeWidget); + addDockWidget(Qt::TopDockWidgetArea, m_fpsViewer); + +#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 + auto descTree = new EasyDescWidget(); + m_descTreeWidget = new EasyDockWidget("Blocks"); + m_descTreeWidget->setObjectName("ProfilerGUI_Blocks"); + m_descTreeWidget->setMinimumHeight(50); + m_descTreeWidget->setAllowedAreas(Qt::AllDockWidgetAreas); + m_descTreeWidget->setWidget(descTree); + addDockWidget(Qt::BottomDockWidgetArea, m_descTreeWidget); +#endif + + + auto toolbar = addToolBar("FileToolbar"); + toolbar->setIconSize(::profiler_gui::ICONS_SIZE); + toolbar->setObjectName("ProfilerGUI_FileToolbar"); + toolbar->setContentsMargins(1, 0, 1, 0); + + m_loadActionMenu = new QMenu(this); + auto action = m_loadActionMenu->menuAction(); + action->setText("Open file"); + action->setIcon(QIcon(imagePath("open"))); + connect(action, &QAction::triggered, this, &This::onOpenFileClicked); + toolbar->addAction(action); + + for (const auto& f : m_lastFiles) + { + action = new QAction(f, this); + connect(action, &QAction::triggered, this, &This::onOpenFileClicked); + m_loadActionMenu->addAction(action); + } + + m_saveAction = toolbar->addAction(QIcon(imagePath("save")), tr("Save"), this, SLOT(onSaveFileClicked(bool))); + m_deleteAction = toolbar->addAction(QIcon(imagePath("delete")), tr("Clear all"), this, SLOT(onDeleteClicked(bool))); + + m_saveAction->setEnabled(false); + m_deleteAction->setEnabled(false); + + + + toolbar = addToolBar("ProfileToolbar"); + toolbar->setIconSize(::profiler_gui::ICONS_SIZE); + toolbar->setObjectName("ProfilerGUI_ProfileToolbar"); + toolbar->setContentsMargins(1, 0, 1, 0); + + toolbar->addAction(QIcon(imagePath("list")), tr("Blocks"), this, SLOT(onEditBlocksClicked(bool))); + m_captureAction = toolbar->addAction(QIcon(imagePath("start")), tr("Capture"), this, SLOT(onCaptureClicked(bool))); + m_captureAction->setEnabled(false); + + toolbar->addSeparator(); + m_connectAction = toolbar->addAction(QIcon(imagePath("connect")), tr("Connect"), this, SLOT(onConnectClicked(bool))); + + auto lbl = new QLabel("Address:", toolbar); + lbl->setContentsMargins(5, 0, 2, 0); + toolbar->addWidget(lbl); + m_addressEdit = new QLineEdit(); + m_addressEdit->setToolTip("Enter IP-address or host name"); + //QRegExp rx("^0*(2(5[0-5]|[0-4]\\d)|1?\\d{1,2})(\\.0*(2(5[0-5]|[0-4]\\d)|1?\\d{1,2})){3}$"); + //m_addressEdit->setValidator(new QRegExpValidator(rx, m_addressEdit)); + m_addressEdit->setText(m_lastAddress); + m_addressEdit->setFixedWidth((m_addressEdit->fontMetrics().width(QString("255.255.255.255")) * 3) / 2); + toolbar->addWidget(m_addressEdit); + + lbl = new QLabel("Port:", toolbar); + lbl->setContentsMargins(5, 0, 2, 0); + toolbar->addWidget(lbl); + m_portEdit = new QLineEdit(); + m_portEdit->setValidator(new QIntValidator(1, 65535, m_portEdit)); + m_portEdit->setText(QString::number(m_lastPort)); + m_portEdit->setFixedWidth(m_portEdit->fontMetrics().width(QString("000000")) + 10); + toolbar->addWidget(m_portEdit); + + connect(m_addressEdit, &QLineEdit::returnPressed, [this] { onConnectClicked(true); }); + connect(m_portEdit, &QLineEdit::returnPressed, [this] { onConnectClicked(true); }); + + + + toolbar = addToolBar("SetupToolbar"); + toolbar->setIconSize(::profiler_gui::ICONS_SIZE); + toolbar->setObjectName("ProfilerGUI_SetupToolbar"); + toolbar->setContentsMargins(1, 0, 1, 0); + + toolbar->addAction(QIcon(imagePath("expand")), "Expand all", this, SLOT(onExpandAllClicked(bool))); + toolbar->addAction(QIcon(imagePath("collapse")), "Collapse all", this, SLOT(onCollapseAllClicked(bool))); + + toolbar->addSeparator(); + auto menu = new QMenu("Settings", this); + menu->setToolTipsVisible(true); + + QToolButton* toolButton = new QToolButton(toolbar); + toolButton->setIcon(QIcon(imagePath("settings"))); + toolButton->setMenu(menu); + toolButton->setPopupMode(QToolButton::InstantPopup); + toolbar->addWidget(toolButton); + + action = menu->addAction("Statistics enabled"); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.enable_statistics); + connect(action, &QAction::triggered, this, &This::onEnableDisableStatistics); + if (EASY_GLOBALS.enable_statistics) + { + auto f = action->font(); + f.setBold(true); + action->setFont(f); + action->setIcon(QIcon(imagePath("stats"))); + } + else + { + action->setText("Statistics disabled"); + action->setIcon(QIcon(imagePath("stats-off"))); + } + + + action = menu->addAction("Only frames on histogram"); + action->setToolTip("Display only top-level blocks on histogram."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.display_only_frames_on_histogram); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.display_only_frames_on_histogram = _checked; + emit EASY_GLOBALS.events.displayOnlyFramesOnHistogramChanged(); + }); + + + menu->addSeparator(); + auto submenu = menu->addMenu("View"); + submenu->setToolTipsVisible(true); + action = submenu->addAction("Draw items' borders"); + action->setToolTip("Draw borders for blocks on diagram.\nThis reduces performance."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.draw_graphics_items_borders); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.draw_graphics_items_borders = _checked; refreshDiagram(); }); + + action = submenu->addAction("Overlap narrow children"); + action->setToolTip("Children blocks will be overlaped by narrow\nparent blocks. See also \'Blocks narrow size\'.\nThis improves performance."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.hide_narrow_children); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.hide_narrow_children = _checked; refreshDiagram(); }); + + action = submenu->addAction("Hide min-size blocks"); + action->setToolTip("Hides blocks which screen size\nis less than \'Min blocks size\'."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.hide_minsize_blocks); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.hide_minsize_blocks = _checked; refreshDiagram(); }); + + action = submenu->addAction("Build hierarchy only for current thread"); + action->setToolTip("Hierarchy tree will be built\nfor blocks from current thread only.\nThis improves performance\nand saves a lot of memory."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.only_current_thread_hierarchy); + connect(action, &QAction::triggered, this, &This::onHierarchyFlagChange); + + action = submenu->addAction("Add zero blocks to hierarchy"); + action->setToolTip("Zero duration blocks will be added into hierarchy tree.\nThis reduces performance and increases memory consumption."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.add_zero_blocks_to_hierarchy); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.add_zero_blocks_to_hierarchy = _checked; + emit EASY_GLOBALS.events.hierarchyFlagChanged(_checked); + }); + + action = submenu->addAction("Enable zero duration blocks on diagram"); + action->setToolTip("If checked then allows diagram to paint zero duration blocks\nwith 1px width on each scale. Otherwise, such blocks will be resized\nto 250ns duration."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.enable_zero_length); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.enable_zero_length = _checked; refreshDiagram(); }); + + action = submenu->addAction("Highlight similar blocks"); + action->setToolTip("Highlight all visible blocks which are similar\nto the current selected block.\nThis reduces performance."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.highlight_blocks_with_same_id); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.highlight_blocks_with_same_id = _checked; refreshDiagram(); }); + + action = submenu->addAction("Collapse blocks on tree reset"); + action->setToolTip("This collapses all blocks on diagram\nafter hierarchy tree reset."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.collapse_items_on_tree_close); + connect(action, &QAction::triggered, this, &This::onCollapseItemsAfterCloseChanged); + + action = submenu->addAction("Expand all on file open"); + action->setToolTip("If checked then all blocks on diagram\nwill be initially expanded."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.all_items_expanded_by_default); + connect(action, &QAction::triggered, this, &This::onAllItemsExpandedByDefaultChange); + + action = submenu->addAction("Bind diagram and tree expand"); + action->setToolTip("Expanding/collapsing blocks at diagram expands/collapses\nblocks at hierarchy tree and wise versa."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.bind_scene_and_tree_expand_status); + connect(action, &QAction::triggered, this, &This::onBindExpandStatusChange); + + action = submenu->addAction("Selecting block changes current thread"); + action->setToolTip("Automatically select thread while selecting a block.\nIf not checked then you will have to select current thread\nmanually double clicking on thread name on a diagram."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.selecting_block_changes_thread); + connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.selecting_block_changes_thread = _checked; }); + + action = submenu->addAction("Draw event markers"); + action->setToolTip("Display event markers under the blocks\n(even if event-blocks are not visible).\nThis slightly reduces performance."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.enable_event_markers); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.enable_event_markers = _checked; + refreshDiagram(); + }); + + action = submenu->addAction("Automatically adjust histogram height"); + action->setToolTip("You do not need to adjust boundaries manually,\nbut this restricts you from adjusting boundaries at all (zoom mode).\nYou can still adjust boundaries in overview mode though."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.auto_adjust_histogram_height); + connect(action, &QAction::triggered, [](bool _checked) + { + EASY_GLOBALS.auto_adjust_histogram_height = _checked; + emit EASY_GLOBALS.events.autoAdjustHistogramChanged(); + }); + + action = submenu->addAction("Use decorated thread names"); + action->setToolTip("Add \'Thread\' word into thread name if there is no one already.\nExamples: \'Render\' will change to \'Render Thread\'\n\'WorkerThread\' will not change."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.use_decorated_thread_name); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.use_decorated_thread_name = _checked; + emit EASY_GLOBALS.events.threadNameDecorationChanged(); + }); + + action = submenu->addAction("Display hex thread id"); + action->setToolTip("Display hex thread id instead of decimal."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.hex_thread_id); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.hex_thread_id = _checked; + emit EASY_GLOBALS.events.hexThreadIdChanged(); + }); + + submenu->addSeparator(); + auto actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + + action = new QAction("Chrono text at top", actionGroup); + action->setToolTip("Draw duration of selected interval\nat the top of the screen."); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::ChronoTextPosition_Top)); + if (EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Top) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged); + + action = new QAction("Chrono text at center", actionGroup); + action->setToolTip("Draw duration of selected interval\nat the center of the screen."); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::ChronoTextPosition_Center)); + if (EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Center) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged); + + action = new QAction("Chrono text at bottom", actionGroup); + action->setToolTip("Draw duration of selected interval\nat the bottom of the screen."); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::ChronoTextPosition_Bottom)); + if (EASY_GLOBALS.chrono_text_position == ::profiler_gui::ChronoTextPosition_Bottom) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onChronoTextPosChanged); + + submenu->addSeparator(); + auto w = new QWidget(submenu); + auto l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Min blocks spacing, px", w), 0, Qt::AlignLeft); + auto spinbox = new QSpinBox(w); + spinbox->setRange(0, 400); + spinbox->setValue(EASY_GLOBALS.blocks_spacing); + spinbox->setFixedWidth(70); + connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(onSpacingChange(int))); + l->addWidget(spinbox); + w->setLayout(l); + auto waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + submenu->addAction(waction); + + w = new QWidget(submenu); + l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Min blocks size, px", w), 0, Qt::AlignLeft); + spinbox = new QSpinBox(w); + spinbox->setRange(1, 400); + spinbox->setValue(EASY_GLOBALS.blocks_size_min); + spinbox->setFixedWidth(70); + connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(onMinSizeChange(int))); + l->addWidget(spinbox); + w->setLayout(l); + waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + submenu->addAction(waction); + + w = new QWidget(submenu); + l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Blocks narrow size, px", w), 0, Qt::AlignLeft); + spinbox = new QSpinBox(w); + spinbox->setRange(1, 400); + spinbox->setValue(EASY_GLOBALS.blocks_narrow_size); + spinbox->setFixedWidth(70); + connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(onNarrowSizeChange(int))); + l->addWidget(spinbox); + w->setLayout(l); + waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + submenu->addAction(waction); + + + + + submenu = menu->addMenu("FPS Monitor"); + w = new QWidget(submenu); + l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Request interval, ms", w), 0, Qt::AlignLeft); + spinbox = new QSpinBox(w); + spinbox->setRange(1, 600000); + spinbox->setValue(EASY_GLOBALS.fps_timer_interval); + spinbox->setFixedWidth(70); + connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(onFpsIntervalChange(int))); + l->addWidget(spinbox); + w->setLayout(l); + waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + submenu->addAction(waction); + + w = new QWidget(submenu); + l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Max history size", w), 0, Qt::AlignLeft); + spinbox = new QSpinBox(w); + spinbox->setRange(2, 200); + spinbox->setValue(EASY_GLOBALS.max_fps_history); + spinbox->setFixedWidth(70); + connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(onFpsHistoryChange(int))); + l->addWidget(spinbox); + w->setLayout(l); + waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + submenu->addAction(waction); + + w = new QWidget(submenu); + l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Line width, px", w), 0, Qt::AlignLeft); + spinbox = new QSpinBox(w); + spinbox->setRange(1, 6); + spinbox->setValue(EASY_GLOBALS.fps_widget_line_width); + spinbox->setFixedWidth(70); + connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(onFpsMonitorLineWidthChange(int))); + l->addWidget(spinbox); + w->setLayout(l); + waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + submenu->addAction(waction); + + + + + submenu = menu->addMenu("Units"); + actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + action = new QAction("Auto", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_auto)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_auto) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + action = new QAction("Milliseconds", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_ms)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_ms) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + action = new QAction("Microseconds", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_us)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_us) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + action = new QAction("Nanoseconds", actionGroup); + action->setCheckable(true); + action->setData(static_cast(::profiler_gui::TimeUnits_ns)); + if (EASY_GLOBALS.time_units == ::profiler_gui::TimeUnits_ns) + action->setChecked(true); + submenu->addAction(action); + connect(action, &QAction::triggered, this, &This::onUnitsChanged); + + + submenu = menu->addMenu("Remote"); + m_eventTracingEnableAction = submenu->addAction("Event tracing enabled"); + m_eventTracingEnableAction->setCheckable(true); + m_eventTracingEnableAction->setEnabled(false); + connect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange); + + m_eventTracingPriorityAction = submenu->addAction("Low priority event tracing"); + m_eventTracingPriorityAction->setCheckable(true); + m_eventTracingPriorityAction->setChecked(EASY_OPTION_LOW_PRIORITY_EVENT_TRACING); + m_eventTracingPriorityAction->setEnabled(false); + connect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange); + + + submenu = menu->addMenu("Encoding"); + actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + + auto default_codec_mib = QTextCodec::codecForLocale()->mibEnum(); + { + QList actions; + + for (int mib : QTextCodec::availableMibs()) + { + auto codec = QTextCodec::codecForMib(mib)->name(); + + action = new QAction(codec, actionGroup); + action->setData(mib); + action->setCheckable(true); + if (mib == default_codec_mib) + action->setChecked(true); + + actions.push_back(action); + connect(action, &QAction::triggered, this, &This::onEncodingChanged); + } + + qSort(actions.begin(), actions.end(), [](QAction* lhs, QAction* rhs) { + return lhs->text().compare(rhs->text(), Qt::CaseInsensitive) < 0; + }); + + submenu->addActions(actions); + } + + + + menu->addSeparator(); + submenu = menu->addMenu("Theme"); + actionGroup = new QActionGroup(this); + actionGroup->setExclusive(true); + + for (const auto& theme : UI_themes()) + { + action = new QAction(theme, actionGroup); + action->setCheckable(true); + action->setChecked(action->text() == EASY_GLOBALS.theme); + connect(action, &QAction::triggered, this, &EasyMainWindow::onThemeChange); + submenu->addAction(action); + } + + + auto tb_height = toolbar->height() + 4; + toolbar = addToolBar("FrameToolbar"); + toolbar->setIconSize(::profiler_gui::ICONS_SIZE); + toolbar->setObjectName("ProfilerGUI_FrameToolbar"); + toolbar->setContentsMargins(1, 0, 1, 0); + toolbar->setMinimumHeight(tb_height); + + lbl = new QLabel("Expected frame time:", toolbar); + lbl->setContentsMargins(5, 2, 2, 2); + toolbar->addWidget(lbl); + + m_frameTimeEdit = new QLineEdit(); + m_frameTimeEdit->setFixedWidth(70); + auto val = new QDoubleValidator(m_frameTimeEdit); + val->setLocale(QLocale::c()); + val->setBottom(0); + m_frameTimeEdit->setValidator(val); + m_frameTimeEdit->setText(QString::number(EASY_GLOBALS.frame_time * 1e-3)); + connect(m_frameTimeEdit, &QLineEdit::editingFinished, this, &This::onFrameTimeEditFinish); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, this, &This::onFrameTimeChanged); + toolbar->addWidget(m_frameTimeEdit); + + lbl = new QLabel("ms", toolbar); + lbl->setContentsMargins(5, 2, 1, 1); + toolbar->addWidget(lbl); + + + connect(graphicsView->view(), &EasyGraphicsView::intervalChanged, treeWidget->tree(), &EasyTreeWidget::setTreeBlocks); + connect(&m_readerTimer, &QTimer::timeout, this, &This::onFileReaderTimeout); + connect(&m_listenerTimer, &QTimer::timeout, this, &This::onListenerTimerTimeout); + connect(&m_fpsRequestTimer, &QTimer::timeout, this, &This::onFrameTimeRequestTimeout); + + + loadGeometry(); + + if(QCoreApplication::arguments().size() > 1) + { + auto opened_filename = QCoreApplication::arguments().at(1); + loadFile(opened_filename); + } + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::blockStatusChanged, this, &This::onBlockStatusChange); + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::blocksRefreshRequired, this, &This::onGetBlockDescriptionsClicked); +} + +EasyMainWindow::~EasyMainWindow() +{ +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::dragEnterEvent(QDragEnterEvent* drag_event) +{ + if (drag_event->mimeData()->hasUrls()) + drag_event->acceptProposedAction(); +} + +void EasyMainWindow::dragMoveEvent(QDragMoveEvent* drag_event) +{ + if (drag_event->mimeData()->hasUrls()) + drag_event->acceptProposedAction(); +} + +void EasyMainWindow::dragLeaveEvent(QDragLeaveEvent* drag_event) +{ + drag_event->accept(); +} + +void EasyMainWindow::dropEvent(QDropEvent* drop_event) +{ + const auto& urls = drop_event->mimeData()->urls(); + if (!urls.empty()) + { + if (m_bNetworkFileRegime) + { + // Warn user about unsaved network information and suggest to save + auto result = QMessageBox::question(this, "Unsaved session", "You have unsaved data!\nSave before opening new file?", QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel); + if (result == QMessageBox::Yes) + { + onSaveFileClicked(true); + } + else if (result != QMessageBox::No) + { + // User cancelled opening new file + return; + } + } + + loadFile(urls.front().toLocalFile()); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onThemeChange(bool) +{ + auto action = qobject_cast(sender()); + if (action == nullptr) + return; + + auto newTheme = action->text(); + if (m_theme != newTheme) + { + m_theme = std::move(newTheme); + QMessageBox::information(this, "Theme", "You should restart the application to apply the theme."); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onOpenFileClicked(bool) +{ + auto action = qobject_cast(sender()); + if (action == nullptr) + return; + + QString filename; + + if (action == m_loadActionMenu->menuAction()) + filename = QFileDialog::getOpenFileName(this, "Open EasyProfiler File", m_lastFiles.empty() ? QString() : m_lastFiles.front(), "EasyProfiler File (*.prof);;All Files (*.*)"); + else + filename = action->text(); + + if (!filename.isEmpty()) + { + if (m_bNetworkFileRegime) + { + // Warn user about unsaved network information and suggest to save + auto result = QMessageBox::question(this, "Unsaved session", "You have unsaved data!\nSave before opening new file?", QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel); + if (result == QMessageBox::Yes) + { + onSaveFileClicked(true); + } + else if (result != QMessageBox::No) + { + // User cancelled opening new file + return; + } + } + + loadFile(filename); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::addFileToList(const QString& filename) +{ + m_lastFiles.push_front(filename); + + auto action = new QAction(filename, this); + connect(action, &QAction::triggered, this, &This::onOpenFileClicked); + auto fileActions = m_loadActionMenu->actions(); + if (fileActions.empty()) + m_loadActionMenu->addAction(action); + else + m_loadActionMenu->insertAction(fileActions.front(), action); + + if (m_lastFiles.size() > 10) + { + // Keep 10 files at the list + m_lastFiles.pop_back(); + m_loadActionMenu->removeAction(fileActions.back()); + delete fileActions.back(); + } + + m_bOpenedCacheFile = filename.contains(NETWORK_CACHE_FILE); + + if (m_bOpenedCacheFile) + setWindowTitle(QString(EASY_DEFAULT_WINDOW_TITLE " - [%1] - UNSAVED network cache file").arg(m_lastFiles.front())); + else + setWindowTitle(QString(EASY_DEFAULT_WINDOW_TITLE " - [%1]").arg(m_lastFiles.front())); +} + +void EasyMainWindow::loadFile(const QString& filename) +{ + const auto i = filename.lastIndexOf(QChar('/')); + const auto j = filename.lastIndexOf(QChar('\\')); + + createProgressDialog(QString("Loading %1...").arg(filename.mid(::std::max(i, j) + 1))); + + m_readerTimer.start(LOADER_TIMER_INTERVAL); + m_reader.load(filename); +} + +void EasyMainWindow::readStream(::std::stringstream& data) +{ + createProgressDialog(tr("Reading from stream...")); + m_readerTimer.start(LOADER_TIMER_INTERVAL); + m_reader.load(data); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onSaveFileClicked(bool) +{ + if (m_serializedBlocks.empty()) + return; + + QString lastFile = m_lastFiles.empty() ? QString() : m_lastFiles.front(); + + const auto i = lastFile.lastIndexOf(QChar('/')); + const auto j = lastFile.lastIndexOf(QChar('\\')); + auto k = ::std::max(i, j); + + QString dir; + if (k > 0) + dir = lastFile.mid(0, ++k); + + if (m_bNetworkFileRegime) + { + // Current file is network cache file, use current system time as output file name + + if (!dir.isEmpty()) + dir += QDateTime::currentDateTime().toString("/yyyy-MM-dd_HH-mm-ss.prof"); + else + dir = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss.prof"); + } + else if (m_bOpenedCacheFile) + { + // Opened old network cache file, use it's last modification time as output file name + + QFileInfo fileInfo(lastFile); + if (!fileInfo.exists()) + { + // Can not open the file! + + QMessageBox::warning(this, "Warning", "Cannot open source file.\nSaving incomplete.", QMessageBox::Close); + + m_lastFiles.pop_front(); + auto action = m_loadActionMenu->actions().front(); + m_loadActionMenu->removeAction(action); + delete action; + + return; + } + + if (!dir.isEmpty()) + dir += fileInfo.lastModified().toString("/yyyy-MM-dd_HH-mm-ss.prof"); + else + dir = fileInfo.lastModified().toString("yyyy-MM-dd_HH-mm-ss.prof"); + } + else + { + dir = lastFile; + } + + auto filename = QFileDialog::getSaveFileName(this, "Save EasyProfiler File", dir, "EasyProfiler File (*.prof);;All Files (*.*)"); + if (!filename.isEmpty()) + { + // Check if the same file has been selected + { + QFileInfo fileInfo1(m_bNetworkFileRegime ? QString(NETWORK_CACHE_FILE) : lastFile), fileInfo2(filename); + if (fileInfo1.exists() && fileInfo2.exists() && fileInfo1 == fileInfo2) + { + // Selected the same file - do nothing + return; + } + } + + bool inOk = false, outOk = false; + int8_t retry1 = -1; + while (++retry1 < 4) + { + ::std::ifstream inFile(m_bNetworkFileRegime ? NETWORK_CACHE_FILE : lastFile.toStdString().c_str(), ::std::fstream::binary); + if (!inFile.is_open()) + { + ::std::this_thread::sleep_for(::std::chrono::milliseconds(500)); + continue; + } + + inOk = true; + + int8_t retry2 = -1; + while (++retry2 < 4) + { + ::std::ofstream outFile(filename.toStdString(), ::std::fstream::binary); + if (!outFile.is_open()) + { + ::std::this_thread::sleep_for(::std::chrono::milliseconds(500)); + continue; + } + + outFile << inFile.rdbuf(); + outOk = true; + break; + } + + break; + } + + if (outOk) + { + if (m_bNetworkFileRegime) + { + // Remove temporary network cahche file + QFile::remove(QString(NETWORK_CACHE_FILE)); + } + else if (m_bOpenedCacheFile) + { + // Remove old temporary network cahche file + + QFile::remove(lastFile.toStdString().c_str()); + + m_lastFiles.pop_front(); + auto action = m_loadActionMenu->actions().front(); + m_loadActionMenu->removeAction(action); + delete action; + } + + addFileToList(filename); + + m_bNetworkFileRegime = false; + } + else if (inOk) + { + QMessageBox::warning(this, "Warning", "Cannot open destination file.\nSaving incomplete.", QMessageBox::Close); + } + else + { + if (m_bNetworkFileRegime) + QMessageBox::warning(this, "Warning", "Cannot open network cache file.\nSaving incomplete.", QMessageBox::Close); + else + QMessageBox::warning(this, "Warning", "Cannot open source file.\nSaving incomplete.", QMessageBox::Close); + } + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::clear() +{ + static_cast(m_treeWidget->widget())->clear(true); + static_cast(m_graphicsView->widget())->clear(); + +#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 + static_cast(m_descTreeWidget->widget())->clear(); +#endif + if (m_dialogDescTree != nullptr) + m_dialogDescTree->clear(); + + EASY_GLOBALS.selected_thread = 0; + ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + EASY_GLOBALS.profiler_blocks.clear(); + EASY_GLOBALS.descriptors.clear(); + EASY_GLOBALS.gui_blocks.clear(); + + m_serializedBlocks.clear(); + m_serializedDescriptors.clear(); + + m_saveAction->setEnabled(false); + m_deleteAction->setEnabled(false); + + if (m_bNetworkFileRegime) + QFile::remove(QString(NETWORK_CACHE_FILE)); + + m_bNetworkFileRegime = false; + m_bOpenedCacheFile = false; + + setWindowTitle(EASY_DEFAULT_WINDOW_TITLE); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::refreshDiagram() +{ + static_cast(m_graphicsView->widget())->view()->scene()->update(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onDeleteClicked(bool) +{ + int button = QMessageBox::Yes; + if (m_bNetworkFileRegime) + button = QMessageBox::question(this, "Clear all profiled data", "All profiled data and network cache file\nare going to be deleted!\nContinue?", QMessageBox::Yes, QMessageBox::No); + + if (button == QMessageBox::Yes) + clear(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onExitClicked(bool) +{ + close(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onEncodingChanged(bool) +{ + auto action = qobject_cast(sender()); + if (action == nullptr) + return; + + const int mib = action->data().toInt(); + auto codec = QTextCodec::codecForMib(mib); + if (codec != nullptr) + QTextCodec::setCodecForLocale(codec); +} + +void EasyMainWindow::onChronoTextPosChanged(bool) +{ + auto _sender = qobject_cast(sender()); + EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(_sender->data().toInt()); + refreshDiagram(); +} + +void EasyMainWindow::onUnitsChanged(bool) +{ + auto _sender = qobject_cast(sender()); + EASY_GLOBALS.time_units = static_cast<::profiler_gui::TimeUnits>(_sender->data().toInt()); +} + +void EasyMainWindow::onEnableDisableStatistics(bool _checked) +{ + EASY_GLOBALS.enable_statistics = _checked; + + auto action = qobject_cast(sender()); + if (action != nullptr) + { + auto f = action->font(); + f.setBold(_checked); + action->setFont(f); + + if (_checked) + { + action->setText("Statistics enabled"); + action->setIcon(QIcon(imagePath("stats"))); + } + else + { + action->setText("Statistics disabled"); + action->setIcon(QIcon(imagePath("stats-off"))); + } + } +} + +void EasyMainWindow::onCollapseItemsAfterCloseChanged(bool _checked) +{ + EASY_GLOBALS.collapse_items_on_tree_close = _checked; +} + +void EasyMainWindow::onAllItemsExpandedByDefaultChange(bool _checked) +{ + EASY_GLOBALS.all_items_expanded_by_default = _checked; +} + +void EasyMainWindow::onBindExpandStatusChange(bool _checked) +{ + EASY_GLOBALS.bind_scene_and_tree_expand_status = _checked; +} + +void EasyMainWindow::onHierarchyFlagChange(bool _checked) +{ + EASY_GLOBALS.only_current_thread_hierarchy = _checked; + emit EASY_GLOBALS.events.hierarchyFlagChanged(_checked); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onExpandAllClicked(bool) +{ + for (auto& block : EASY_GLOBALS.gui_blocks) + block.expanded = true; + + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + + auto tree = static_cast(m_treeWidget->widget())->tree(); + const QSignalBlocker b(tree); + tree->expandAll(); +} + +void EasyMainWindow::onCollapseAllClicked(bool) +{ + for (auto& block : EASY_GLOBALS.gui_blocks) + block.expanded = false; + + emit EASY_GLOBALS.events.itemsExpandStateChanged(); + + auto tree = static_cast(m_treeWidget->widget())->tree(); + const QSignalBlocker b(tree); + tree->collapseAll(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onSpacingChange(int _value) +{ + EASY_GLOBALS.blocks_spacing = _value; + refreshDiagram(); +} + +void EasyMainWindow::onMinSizeChange(int _value) +{ + EASY_GLOBALS.blocks_size_min = _value; + refreshDiagram(); +} + +void EasyMainWindow::onNarrowSizeChange(int _value) +{ + EASY_GLOBALS.blocks_narrow_size = _value; + refreshDiagram(); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onFpsIntervalChange(int _value) +{ + EASY_GLOBALS.fps_timer_interval = _value; + + if (m_fpsRequestTimer.isActive()) + m_fpsRequestTimer.stop(); + + if (EASY_GLOBALS.connected) + m_fpsRequestTimer.start(_value); +} + +void EasyMainWindow::onFpsHistoryChange(int _value) +{ + EASY_GLOBALS.max_fps_history = _value; +} + +void EasyMainWindow::onFpsMonitorLineWidthChange(int _value) +{ + EASY_GLOBALS.fps_widget_line_width = _value; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onEditBlocksClicked(bool) +{ + if (m_descTreeDialog != nullptr) + { + m_descTreeDialog->raise(); + return; + } + + m_descTreeDialog = new QDialog(); + m_descTreeDialog->setAttribute(Qt::WA_DeleteOnClose, true); + m_descTreeDialog->setWindowTitle(EASY_DEFAULT_WINDOW_TITLE); + m_descTreeDialog->resize(800, 600); + connect(m_descTreeDialog, &QDialog::finished, this, &This::onDescTreeDialogClose); + + auto l = new QVBoxLayout(m_descTreeDialog); + m_dialogDescTree = new EasyDescWidget(m_descTreeDialog); + l->addWidget(m_dialogDescTree); + m_descTreeDialog->setLayout(l); + + m_dialogDescTree->build(); + m_descTreeDialog->show(); +} + +void EasyMainWindow::onDescTreeDialogClose(int) +{ + disconnect(m_descTreeDialog, &QDialog::finished, this, &This::onDescTreeDialogClose); + m_dialogDescTree = nullptr; + m_descTreeDialog = nullptr; +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::closeEvent(QCloseEvent* close_event) +{ + if (m_bNetworkFileRegime) + { + // Warn user about unsaved network information and suggest to save + if (QMessageBox::Yes == QMessageBox::question(this, "Unsaved session", "You have unsaved data!\nSave before exit?", QMessageBox::Yes, QMessageBox::No)) + { + onSaveFileClicked(true); + } + } + + saveSettingsAndGeometry(); + + if (m_descTreeDialog != nullptr) + { + m_descTreeDialog->reject(); + m_descTreeDialog = nullptr; + m_dialogDescTree = nullptr; + } + + Parent::closeEvent(close_event); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::loadSettings() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("main"); + + auto last_files = settings.value("last_files"); + if (!last_files.isNull()) + m_lastFiles = last_files.toStringList(); + + auto last_addr = settings.value("ip_address"); + if (!last_addr.isNull()) + m_lastAddress = last_addr.toString(); + + auto last_port = settings.value("port"); + if (!last_port.isNull()) + m_lastPort = (uint16_t)last_port.toUInt(); + + + auto val = settings.value("chrono_text_position"); + if (!val.isNull()) + EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(val.toInt()); + + val = settings.value("time_units"); + if (!val.isNull()) + EASY_GLOBALS.time_units = static_cast<::profiler_gui::TimeUnits>(val.toInt()); + + + val = settings.value("frame_time"); + if (!val.isNull()) + EASY_GLOBALS.frame_time = val.toFloat(); + + val = settings.value("blocks_spacing"); + if (!val.isNull()) + EASY_GLOBALS.blocks_spacing = val.toInt(); + + val = settings.value("blocks_size_min"); + if (!val.isNull()) + EASY_GLOBALS.blocks_size_min = val.toInt(); + + val = settings.value("blocks_narrow_size"); + if (!val.isNull()) + EASY_GLOBALS.blocks_narrow_size = val.toInt(); + + + auto flag = settings.value("draw_graphics_items_borders"); + if (!flag.isNull()) + EASY_GLOBALS.draw_graphics_items_borders = flag.toBool(); + + flag = settings.value("hide_narrow_children"); + if (!flag.isNull()) + EASY_GLOBALS.hide_narrow_children = flag.toBool(); + + flag = settings.value("hide_minsize_blocks"); + if (!flag.isNull()) + EASY_GLOBALS.hide_minsize_blocks = flag.toBool(); + + flag = settings.value("collapse_items_on_tree_close"); + if (!flag.isNull()) + EASY_GLOBALS.collapse_items_on_tree_close = flag.toBool(); + + flag = settings.value("all_items_expanded_by_default"); + if (!flag.isNull()) + EASY_GLOBALS.all_items_expanded_by_default = flag.toBool(); + + flag = settings.value("only_current_thread_hierarchy"); + if (!flag.isNull()) + EASY_GLOBALS.only_current_thread_hierarchy = flag.toBool(); + + flag = settings.value("enable_zero_length"); + if (!flag.isNull()) + EASY_GLOBALS.enable_zero_length = flag.toBool(); + + flag = settings.value("add_zero_blocks_to_hierarchy"); + if (!flag.isNull()) + EASY_GLOBALS.add_zero_blocks_to_hierarchy = flag.toBool(); + + + flag = settings.value("highlight_blocks_with_same_id"); + if (!flag.isNull()) + EASY_GLOBALS.highlight_blocks_with_same_id = flag.toBool(); + + flag = settings.value("bind_scene_and_tree_expand_status"); + if (!flag.isNull()) + EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool(); + + flag = settings.value("selecting_block_changes_thread"); + if (!flag.isNull()) + EASY_GLOBALS.selecting_block_changes_thread = flag.toBool(); + + flag = settings.value("enable_event_indicators"); + if (!flag.isNull()) + EASY_GLOBALS.enable_event_markers = flag.toBool(); + + flag = settings.value("auto_adjust_histogram_height"); + if (!flag.isNull()) + EASY_GLOBALS.auto_adjust_histogram_height = flag.toBool(); + + flag = settings.value("display_only_frames_on_histogram"); + if (!flag.isNull()) + EASY_GLOBALS.display_only_frames_on_histogram = flag.toBool(); + + flag = settings.value("use_decorated_thread_name"); + if (!flag.isNull()) + EASY_GLOBALS.use_decorated_thread_name = flag.toBool(); + + flag = settings.value("hex_thread_id"); + if (!flag.isNull()) + EASY_GLOBALS.hex_thread_id = flag.toBool(); + + flag = settings.value("fps_timer_interval"); + if (!flag.isNull()) + EASY_GLOBALS.fps_timer_interval = flag.toInt(); + + flag = settings.value("max_fps_history"); + if (!flag.isNull()) + EASY_GLOBALS.max_fps_history = flag.toInt(); + + flag = settings.value("fps_widget_line_width"); + if (!flag.isNull()) + EASY_GLOBALS.fps_widget_line_width = flag.toInt(); + + flag = settings.value("enable_statistics"); + if (!flag.isNull()) + EASY_GLOBALS.enable_statistics = flag.toBool(); + + QString encoding = settings.value("encoding", "UTF-8").toString(); + auto default_codec_mib = QTextCodec::codecForName(encoding.toStdString().c_str())->mibEnum(); + auto default_codec = QTextCodec::codecForMib(default_codec_mib); + QTextCodec::setCodecForLocale(default_codec); + + auto theme = settings.value("theme"); + if (theme.isValid()) + { + EASY_GLOBALS.theme = m_theme = theme.toString(); + } + else + { + m_theme = EASY_GLOBALS.theme; + } + + settings.endGroup(); +} + +void EasyMainWindow::loadGeometry() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("main"); + + auto geometry = settings.value("geometry").toByteArray(); + if (!geometry.isEmpty()) + restoreGeometry(geometry); + + auto state = settings.value("windowState").toByteArray(); + if (!state.isEmpty()) + restoreState(state); + + settings.endGroup(); +} + +void EasyMainWindow::saveSettingsAndGeometry() +{ + QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME); + settings.beginGroup("main"); + + settings.setValue("geometry", this->saveGeometry()); + settings.setValue("windowState", this->saveState()); + settings.setValue("last_files", m_lastFiles); + settings.setValue("ip_address", m_lastAddress); + settings.setValue("port", (quint32)m_lastPort); + settings.setValue("chrono_text_position", static_cast(EASY_GLOBALS.chrono_text_position)); + settings.setValue("time_units", static_cast(EASY_GLOBALS.time_units)); + settings.setValue("frame_time", EASY_GLOBALS.frame_time); + settings.setValue("blocks_spacing", EASY_GLOBALS.blocks_spacing); + settings.setValue("blocks_size_min", EASY_GLOBALS.blocks_size_min); + settings.setValue("blocks_narrow_size", EASY_GLOBALS.blocks_narrow_size); + settings.setValue("draw_graphics_items_borders", EASY_GLOBALS.draw_graphics_items_borders); + settings.setValue("hide_narrow_children", EASY_GLOBALS.hide_narrow_children); + settings.setValue("hide_minsize_blocks", EASY_GLOBALS.hide_minsize_blocks); + settings.setValue("collapse_items_on_tree_close", EASY_GLOBALS.collapse_items_on_tree_close); + settings.setValue("all_items_expanded_by_default", EASY_GLOBALS.all_items_expanded_by_default); + settings.setValue("only_current_thread_hierarchy", EASY_GLOBALS.only_current_thread_hierarchy); + settings.setValue("enable_zero_length", EASY_GLOBALS.enable_zero_length); + settings.setValue("add_zero_blocks_to_hierarchy", EASY_GLOBALS.add_zero_blocks_to_hierarchy); + settings.setValue("highlight_blocks_with_same_id", EASY_GLOBALS.highlight_blocks_with_same_id); + settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status); + settings.setValue("selecting_block_changes_thread", EASY_GLOBALS.selecting_block_changes_thread); + settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_markers); + settings.setValue("auto_adjust_histogram_height", EASY_GLOBALS.auto_adjust_histogram_height); + settings.setValue("display_only_frames_on_histogram", EASY_GLOBALS.display_only_frames_on_histogram); + settings.setValue("use_decorated_thread_name", EASY_GLOBALS.use_decorated_thread_name); + settings.setValue("hex_thread_id", EASY_GLOBALS.hex_thread_id); + settings.setValue("enable_statistics", EASY_GLOBALS.enable_statistics); + settings.setValue("fps_timer_interval", EASY_GLOBALS.fps_timer_interval); + settings.setValue("max_fps_history", EASY_GLOBALS.max_fps_history); + settings.setValue("fps_widget_line_width", EASY_GLOBALS.fps_widget_line_width); + settings.setValue("encoding", QTextCodec::codecForLocale()->name()); + settings.setValue("theme", m_theme); + + settings.endGroup(); +} + +void EasyMainWindow::destroyProgressDialog() +{ + if (m_progress != nullptr) + { + m_progress->setValue(100); + m_progress->deleteLater(); + m_progress = nullptr; + } +} + +void EasyMainWindow::createProgressDialog(const QString& text) +{ + destroyProgressDialog(); + + m_progress = new QProgressDialog(text, QStringLiteral("Cancel"), 0, 100, this); + connect(m_progress, &QProgressDialog::canceled, this, &This::onFileReaderCancel); + + m_progress->setFixedWidth(300); + m_progress->setWindowTitle(EASY_DEFAULT_WINDOW_TITLE); + m_progress->setModal(true); + m_progress->setValue(0); + m_progress->show(); +} + +void EasyMainWindow::setDisconnected(bool _showMessage) +{ + if (m_fpsRequestTimer.isActive()) + m_fpsRequestTimer.stop(); + + if (_showMessage) + QMessageBox::warning(this, "Warning", "Connection was lost", QMessageBox::Close); + + EASY_GLOBALS.connected = false; + m_captureAction->setEnabled(false); + m_connectAction->setIcon(QIcon(imagePath("connect"))); + m_connectAction->setText(tr("Connect")); + + m_eventTracingEnableAction->setEnabled(false); + m_eventTracingPriorityAction->setEnabled(false); + + m_addressEdit->setEnabled(true); + m_portEdit->setEnabled(true); + + emit EASY_GLOBALS.events.connectionChanged(false); + +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onFrameTimeRequestTimeout() +{ + if (EASY_GLOBALS.fps_enabled && EASY_GLOBALS.connected && (m_listener.regime() == LISTENER_IDLE || m_listener.regime() == LISTENER_CAPTURE)) + { + if (m_listener.requestFrameTime()) + { + QTimer::singleShot(100, this, &This::checkFrameTimeReady); + } + else if (!m_listener.connected()) + { + m_listener.closeSocket(); + setDisconnected(); + } + } +} + +void EasyMainWindow::checkFrameTimeReady() +{ + if (EASY_GLOBALS.fps_enabled && EASY_GLOBALS.connected && (m_listener.regime() == LISTENER_IDLE || m_listener.regime() == LISTENER_CAPTURE)) + { + uint32_t maxTime = 0, avgTime = 0; + if (m_listener.frameTime(maxTime, avgTime)) + { + static_cast(m_fpsViewer->widget())->addPoint(maxTime, avgTime); + } + else if (m_fpsRequestTimer.isActive()) + { + QTimer::singleShot(100, this, &This::checkFrameTimeReady); + } + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onListenerTimerTimeout() +{ + if (!m_listener.connected()) + { + if (m_listener.regime() == LISTENER_CAPTURE_RECEIVE) + m_listener.finalizeCapture(); + if (m_listenerDialog) + m_listenerDialog->reject(); + } + else if (m_listener.regime() == LISTENER_CAPTURE_RECEIVE) + { + if (m_listener.captured()) + { + if (m_listenerTimer.isActive()) + m_listenerTimer.stop(); + + m_listener.finalizeCapture(); + + m_listenerDialog->accept(); + m_listenerDialog = nullptr; + + if (m_listener.size() != 0) + { + readStream(m_listener.data()); + m_listener.clearData(); + } + } + } +} + +void EasyMainWindow::onListenerDialogClose(int _result) +{ + if (m_listener.regime() != LISTENER_CAPTURE_RECEIVE || !m_listener.connected()) + { + if (m_listenerTimer.isActive()) + m_listenerTimer.stop(); + } + + disconnect(m_listenerDialog, &QDialog::finished, this, &This::onListenerDialogClose); + m_listenerDialog = nullptr; + + switch (m_listener.regime()) + { + case LISTENER_CAPTURE: + { + m_listenerDialog = new QMessageBox(QMessageBox::Information, "Receiving data...", "This process may take some time.", QMessageBox::Cancel, this); + m_listenerDialog->setAttribute(Qt::WA_DeleteOnClose, true); + m_listenerDialog->show(); + + m_listener.stopCapture(); + + if (m_listener.regime() != LISTENER_CAPTURE_RECEIVE) + { + m_listenerDialog->reject(); + m_listenerDialog = nullptr; + } + else + { + connect(m_listenerDialog, &QDialog::finished, this, &This::onListenerDialogClose); + m_listenerTimer.start(250); + } + + break; + } + + case LISTENER_CAPTURE_RECEIVE: + { + if (!m_listener.captured()) + { + if (_result == QDialog::Accepted) + { + m_listenerDialog = new QMessageBox(QMessageBox::Information, "Receiving data...", "This process may take some time.", QMessageBox::Cancel, this); + connect(m_listenerDialog, &QDialog::finished, this, &This::onListenerDialogClose); + m_listenerDialog->setAttribute(Qt::WA_DeleteOnClose, true); + m_listenerDialog->show(); + } + else + { + m_listener.finalizeCapture(); + m_listener.clearData(); + + if (m_listener.connected()) + { + // make reconnect to clear socket buffers + const std::string address = m_listener.address(); + const auto port = m_listener.port(); + + profiler::net::EasyProfilerStatus reply(false, false, false); + if (m_listener.reconnect(address.c_str(), port, reply)) + { + disconnect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange); + disconnect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange); + + m_eventTracingEnableAction->setChecked(reply.isEventTracingEnabled); + m_eventTracingPriorityAction->setChecked(reply.isLowPriorityEventTracing); + + connect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange); + connect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange); + + if (reply.isProfilerEnabled) + { + // Connected application is already profiling. + // Show capture dialog immediately + onCaptureClicked(true); + } + } + } + } + + break; + } + + if (m_listenerTimer.isActive()) + m_listenerTimer.stop(); + + m_listener.finalizeCapture(); + + if (m_listener.size() != 0) + { + readStream(m_listener.data()); + m_listener.clearData(); + } + + break; + } + + case LISTENER_DESCRIBE: + { + break; + } + + default: + return; + } + + if (!m_listener.connected()) + { + m_listener.closeSocket(); + setDisconnected(); + } +} + + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onFileReaderTimeout() +{ + if (m_reader.done()) + { + auto nblocks = m_reader.size(); + if (nblocks != 0) + { + static_cast(m_treeWidget->widget())->clear(true); + + ::profiler::SerializedData serialized_blocks; + ::profiler::SerializedData serialized_descriptors; + ::profiler::descriptors_list_t descriptors; + ::profiler::blocks_t blocks; + ::profiler::thread_blocks_tree_t threads_map; + QString filename; + uint32_t descriptorsNumberInFile = 0; + uint32_t version = 0; + m_reader.get(serialized_blocks, serialized_descriptors, descriptors, blocks, threads_map, descriptorsNumberInFile, version, filename); + + if (threads_map.size() > 0xff) + { + if (m_reader.isFile()) + qWarning() << "Warning: file " << filename << " contains " << threads_map.size() << " threads!"; + else + qWarning() << "Warning: input stream contains " << threads_map.size() << " threads!"; + qWarning() << "Warning: Currently, maximum number of displayed threads is 255! Some threads will not be displayed."; + } + + m_bNetworkFileRegime = !m_reader.isFile(); + if (!m_bNetworkFileRegime) + { + auto index = m_lastFiles.indexOf(filename, 0); + if (index == -1) + { + // This file is totally new. Add it to the list. + addFileToList(filename); + } + else + { + if (index != 0) + { + // This file has been already loaded. Move it to the front. + m_lastFiles.move(index, 0); + auto fileActions = m_loadActionMenu->actions(); + auto action = fileActions.at(index); + m_loadActionMenu->removeAction(action); + m_loadActionMenu->insertAction(fileActions.front(), action); + } + + m_bOpenedCacheFile = filename.contains(NETWORK_CACHE_FILE); + + if (m_bOpenedCacheFile) + setWindowTitle(QString(EASY_DEFAULT_WINDOW_TITLE " - [%1] - UNSAVED network cache file").arg(filename)); + else + setWindowTitle(QString(EASY_DEFAULT_WINDOW_TITLE " - [%1]").arg(filename)); + } + } + else + { + m_bOpenedCacheFile = false; + setWindowTitle(EASY_DEFAULT_WINDOW_TITLE " - UNSAVED network cache"); + } + + m_serializedBlocks = ::std::move(serialized_blocks); + m_serializedDescriptors = ::std::move(serialized_descriptors); + m_descriptorsNumberInFile = descriptorsNumberInFile; + EASY_GLOBALS.selected_thread = 0; + EASY_GLOBALS.version = version; + ::profiler_gui::set_max(EASY_GLOBALS.selected_block); + ::profiler_gui::set_max(EASY_GLOBALS.selected_block_id); + EASY_GLOBALS.profiler_blocks.swap(threads_map); + EASY_GLOBALS.descriptors.swap(descriptors); + + EASY_GLOBALS.gui_blocks.clear(); + EASY_GLOBALS.gui_blocks.resize(nblocks); + memset(EASY_GLOBALS.gui_blocks.data(), 0, sizeof(::profiler_gui::EasyBlock) * nblocks); + for (decltype(nblocks) i = 0; i < nblocks; ++i) { + auto& guiblock = EASY_GLOBALS.gui_blocks[i]; + guiblock.tree = ::std::move(blocks[i]); +#ifdef EASY_TREE_WIDGET__USE_VECTOR + ::profiler_gui::set_max(guiblock.tree_item); +#endif + } + + static_cast(m_graphicsView->widget())->view()->setTree(EASY_GLOBALS.profiler_blocks); + +#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 + static_cast(m_descTreeWidget->widget())->build(); +#endif + if (m_dialogDescTree != nullptr) + m_dialogDescTree->build(); + + m_saveAction->setEnabled(true); + m_deleteAction->setEnabled(true); + } + else + { + QMessageBox::warning(this, "Warning", QString("Cannot read profiled blocks.\n\nReason:\n%1").arg(m_reader.getError()), QMessageBox::Close); + + if (m_reader.isFile()) + { + auto index = m_lastFiles.indexOf(m_reader.filename(), 0); + if (index >= 0) + { + // Remove unexisting file from list + m_lastFiles.removeAt(index); + auto action = m_loadActionMenu->actions().at(index); + m_loadActionMenu->removeAction(action); + delete action; + } + } + } + + m_reader.interrupt(); + + m_readerTimer.stop(); + destroyProgressDialog(); + + if (EASY_GLOBALS.all_items_expanded_by_default) + { + onExpandAllClicked(true); + } + } + else if (m_progress != nullptr) + { + m_progress->setValue(m_reader.progress()); + } +} + +void EasyMainWindow::onFileReaderCancel() +{ + m_readerTimer.stop(); + m_reader.interrupt(); + destroyProgressDialog(); +} + +////////////////////////////////////////////////////////////////////////// + +EasyFileReader::EasyFileReader() +{ + +} + +EasyFileReader::~EasyFileReader() +{ + interrupt(); +} + +const bool EasyFileReader::isFile() const +{ + return m_isFile; +} + +bool EasyFileReader::done() const +{ + return m_bDone.load(::std::memory_order_acquire); +} + +int EasyFileReader::progress() const +{ + return m_progress.load(::std::memory_order_acquire); +} + +unsigned int EasyFileReader::size() const +{ + return m_size.load(::std::memory_order_acquire); +} + +const QString& EasyFileReader::filename() const +{ + return m_filename; +} + +void EasyFileReader::load(const QString& _filename) +{ + interrupt(); + + m_isFile = true; + m_filename = _filename; + m_thread = ::std::thread([this](bool _enableStatistics) { + m_size.store(fillTreesFromFile(m_progress, m_filename.toStdString().c_str(), m_serializedBlocks, m_serializedDescriptors, + m_descriptors, m_blocks, m_blocksTree, m_descriptorsNumberInFile, m_version, _enableStatistics, m_errorMessage), ::std::memory_order_release); + m_progress.store(100, ::std::memory_order_release); + m_bDone.store(true, ::std::memory_order_release); + }, EASY_GLOBALS.enable_statistics); +} + +void EasyFileReader::load(::std::stringstream& _stream) +{ + interrupt(); + + m_isFile = false; + m_filename.clear(); + +#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__llvm__) + // gcc 4 has a known bug which has been solved in gcc 5: + // std::stringstream has no swap() method :( + // have to copy all contents... Use gcc 5 or higher! +#pragma message "Warning: in gcc 4 and lower std::stringstream has no swap()! Memory consumption may increase! Better use gcc 5 or higher instead." + m_stream.str(_stream.str()); +#else + m_stream.swap(_stream); +#endif + + m_thread = ::std::thread([this](bool _enableStatistics) { + ::std::ofstream cache_file(NETWORK_CACHE_FILE, ::std::fstream::binary); + if (cache_file.is_open()) { + cache_file << m_stream.str(); + cache_file.close(); + } + m_size.store(fillTreesFromStream(m_progress, m_stream, m_serializedBlocks, m_serializedDescriptors, m_descriptors, + m_blocks, m_blocksTree, m_descriptorsNumberInFile, m_version, _enableStatistics, m_errorMessage), ::std::memory_order_release); + m_progress.store(100, ::std::memory_order_release); + m_bDone.store(true, ::std::memory_order_release); + }, EASY_GLOBALS.enable_statistics); +} + +void EasyFileReader::interrupt() +{ + m_progress.store(-100, ::std::memory_order_release); + if (m_thread.joinable()) + m_thread.join(); + + m_bDone.store(false, ::std::memory_order_release); + m_progress.store(0, ::std::memory_order_release); + m_size.store(0, ::std::memory_order_release); + m_serializedBlocks.clear(); + m_serializedDescriptors.clear(); + m_descriptors.clear(); + m_blocks.clear(); + m_blocksTree.clear(); + m_descriptorsNumberInFile = 0; + m_version = 0; + + clear_stream(m_stream); + clear_stream(m_errorMessage); +} + +void EasyFileReader::get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors, + ::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, + ::profiler::thread_blocks_tree_t& _tree, uint32_t& _descriptorsNumberInFile, uint32_t& _version, QString& _filename) +{ + if (done()) + { + m_serializedBlocks.swap(_serializedBlocks); + m_serializedDescriptors.swap(_serializedDescriptors); + ::profiler::descriptors_list_t(::std::move(m_descriptors)).swap(_descriptors); + m_blocks.swap(_blocks); + m_blocksTree.swap(_tree); + m_filename.swap(_filename); + _descriptorsNumberInFile = m_descriptorsNumberInFile; + _version = m_version; + } +} + +QString EasyFileReader::getError() +{ + return QString(m_errorMessage.str().c_str()); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onEventTracingPriorityChange(bool _checked) +{ + if (EASY_GLOBALS.connected) + m_listener.send(profiler::net::BoolMessage(profiler::net::MessageType::Change_Event_Tracing_Priority, _checked)); +} + +void EasyMainWindow::onEventTracingEnableChange(bool _checked) +{ + if (EASY_GLOBALS.connected) + m_listener.send(profiler::net::BoolMessage(profiler::net::MessageType::Change_Event_Tracing_Status, _checked)); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onFrameTimeEditFinish() +{ + auto text = m_frameTimeEdit->text(); + if (text.contains(QChar(','))) + { + text.remove(QChar('.')).replace(QChar(','), QChar('.')); + m_frameTimeEdit->setText(text); + } + + EASY_GLOBALS.frame_time = text.toFloat() * 1e3f; + + disconnect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, + this, &This::onFrameTimeChanged); + + emit EASY_GLOBALS.events.expectedFrameTimeChanged(); + + connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::expectedFrameTimeChanged, + this, &This::onFrameTimeChanged); +} + +void EasyMainWindow::onFrameTimeChanged() +{ + m_frameTimeEdit->setText(QString::number(EASY_GLOBALS.frame_time * 1e-3)); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onConnectClicked(bool) +{ + if (EASY_GLOBALS.connected) + { + // Disconnect if already connected + m_listener.disconnect(); + setDisconnected(false); + return; + } + + QString address = m_addressEdit->text(); + const decltype(m_lastPort) port = m_portEdit->text().toUShort(); + + const bool isSameAddress = (EASY_GLOBALS.connected && m_listener.port() == port && + address.toStdString() == m_listener.address()); + + profiler::net::EasyProfilerStatus reply(false, false, false); + if (!m_listener.connect(address.toStdString().c_str(), port, reply)) + { + QMessageBox::warning(this, "Warning", QString("Cannot connect to %1").arg(address), QMessageBox::Close); + if (EASY_GLOBALS.connected) + { + m_listener.closeSocket(); + setDisconnected(false); + } + + if (!isSameAddress) + { + m_lastAddress = ::std::move(address); + m_lastPort = port; + } + + return; + } + + m_lastAddress = ::std::move(address); + m_lastPort = port; + + qInfo() << "Connected successfully"; + EASY_GLOBALS.connected = true; + m_captureAction->setEnabled(true); + m_connectAction->setIcon(QIcon(imagePath("connected"))); + m_connectAction->setText(tr("Disconnect")); + + if (m_fpsViewer->isVisible()) + static_cast(m_fpsViewer->widget())->clear(); + + if (!m_fpsRequestTimer.isActive()) + m_fpsRequestTimer.start(EASY_GLOBALS.fps_timer_interval); + + disconnect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange); + disconnect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange); + + m_eventTracingEnableAction->setEnabled(true); + m_eventTracingPriorityAction->setEnabled(true); + + m_eventTracingEnableAction->setChecked(reply.isEventTracingEnabled); + m_eventTracingPriorityAction->setChecked(reply.isLowPriorityEventTracing); + + connect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange); + connect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange); + + m_addressEdit->setEnabled(false); + m_portEdit->setEnabled(false); + + emit EASY_GLOBALS.events.connectionChanged(true); + + if (reply.isProfilerEnabled) + { + // Connected application is already profiling. + // Show capture dialog immediately + onCaptureClicked(true); + } +} + +void EasyMainWindow::onCaptureClicked(bool) +{ + if (!EASY_GLOBALS.connected) + { + QMessageBox::warning(this, "Warning", "No connection with profiling app", QMessageBox::Close); + return; + } + + if (m_listener.regime() != LISTENER_IDLE) + { + if (m_listener.regime() == LISTENER_CAPTURE || m_listener.regime() == LISTENER_CAPTURE_RECEIVE) + QMessageBox::warning(this, "Warning", "Already capturing frames.\nFinish old capturing session first.", QMessageBox::Close); + else + QMessageBox::warning(this, "Warning", "Capturing blocks description.\nFinish old capturing session first.", QMessageBox::Close); + return; + } + + if (!m_listener.startCapture()) + { + // Connection lost. Try to restore connection. + + profiler::net::EasyProfilerStatus reply(false, false, false); + if (!m_listener.connect(m_lastAddress.toStdString().c_str(), m_lastPort, reply)) + { + m_listener.closeSocket(); + setDisconnected(); + return; + } + + if (!m_listener.startCapture()) + { + m_listener.closeSocket(); + setDisconnected(); + return; + } + } + + m_listenerTimer.start(250); + + m_listenerDialog = new QMessageBox(QMessageBox::Information, "Capturing frames...", "Close this dialog to stop capturing.", QMessageBox::NoButton, this); + + auto button = new QToolButton(m_listenerDialog); + button->setAutoRaise(true); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + button->setIconSize(::profiler_gui::ICONS_SIZE); + button->setIcon(QIcon(imagePath("stop"))); + button->setText("Stop"); + m_listenerDialog->addButton(button, QMessageBox::AcceptRole); + + m_listenerDialog->setAttribute(Qt::WA_DeleteOnClose, true); + connect(m_listenerDialog, &QDialog::finished, this, &This::onListenerDialogClose); + m_listenerDialog->show(); +} + +void EasyMainWindow::onGetBlockDescriptionsClicked(bool) +{ + if (!EASY_GLOBALS.connected) + { + QMessageBox::warning(this, "Warning", "No connection with profiling app", QMessageBox::Close); + return; + } + + if (m_listener.regime() != LISTENER_IDLE) + { + if (m_listener.regime() == LISTENER_DESCRIBE) + QMessageBox::warning(this, "Warning", "Already capturing blocks description.\nFinish old capturing session first.", QMessageBox::Close); + else + QMessageBox::warning(this, "Warning", "Already capturing frames.\nFinish old capturing session first.", QMessageBox::Close); + return; + } + + m_listenerDialog = new QMessageBox(QMessageBox::Information, "Waiting for blocks...", "This may take some time.", QMessageBox::NoButton, this); + m_listenerDialog->setAttribute(Qt::WA_DeleteOnClose, true); + m_listenerDialog->show(); + + m_listener.requestBlocksDescription(); + + m_listenerDialog->reject(); + m_listenerDialog = nullptr; + + if (m_listener.size() != 0) + { + // Read descriptions from stream + + decltype(EASY_GLOBALS.descriptors) descriptors; + decltype(m_serializedDescriptors) serializedDescriptors; + ::std::stringstream errorMessage; + if (readDescriptionsFromStream(m_listener.data(), serializedDescriptors, descriptors, errorMessage)) + { + // Merge old and new descriptions + + bool cancel = false; + const bool doFlush = m_descriptorsNumberInFile > descriptors.size(); + if (doFlush && !m_serializedBlocks.empty()) + { + auto button = QMessageBox::question(this, "Information", + QString("New blocks description number = %1\nis less than the old one = %2.\nTo avoid possible conflicts\nall profiled data will be deleted.\nContinue?") + .arg(descriptors.size()) + .arg(m_descriptorsNumberInFile), + QMessageBox::Yes, QMessageBox::No); + + if (button == QMessageBox::Yes) + clear(); // Clear all contents because new descriptors list conflicts with old one + else + cancel = true; + } + + if (!cancel) + { + if (!doFlush && m_descriptorsNumberInFile < EASY_GLOBALS.descriptors.size()) + { + // There are dynamically added descriptors, add them to the new list too + + auto newnumber = static_cast(descriptors.size()); + auto size = static_cast(EASY_GLOBALS.descriptors.size()); + auto diff = newnumber - size; + decltype(newnumber) failnumber = 0; + + descriptors.reserve(descriptors.size() + EASY_GLOBALS.descriptors.size() - m_descriptorsNumberInFile); + for (auto i = m_descriptorsNumberInFile; i < size; ++i) + { + auto id = EASY_GLOBALS.descriptors[i]->id(); + if (id < newnumber) + descriptors.push_back(descriptors[id]); + else + ++failnumber; + } + + if (failnumber != 0) + { + // There are some errors... + + // revert changes + descriptors.resize(newnumber); + + // clear all profiled data to avoid conflicts + auto button = QMessageBox::question(this, "Information", + "There are errors while merging block descriptions lists.\nTo avoid possible conflicts\nall profiled data will be deleted.\nContinue?", + QMessageBox::Yes, QMessageBox::No); + + if (button == QMessageBox::Yes) + clear(); // Clear all contents because new descriptors list conflicts with old one + else + cancel = true; + } + + if (!cancel && diff != 0) + { + for (auto& b : EASY_GLOBALS.gui_blocks) + { + if (b.tree.node->id() >= m_descriptorsNumberInFile) + b.tree.node->setId(b.tree.node->id() + diff); + } + + m_descriptorsNumberInFile = newnumber; + } + } + + if (!cancel) + { + EASY_GLOBALS.descriptors.swap(descriptors); + m_serializedDescriptors.swap(serializedDescriptors); + m_descriptorsNumberInFile = static_cast(EASY_GLOBALS.descriptors.size()); + + if (m_descTreeDialog != nullptr) + { +#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 + static_cast(m_descTreeWidget->widget())->build(); +#endif + m_dialogDescTree->build(); + m_descTreeDialog->raise(); + } + else + { + onEditBlocksClicked(true); + } + } + } + } + else + { + QMessageBox::warning(this, "Warning", QString("Cannot read blocks description from stream.\n\nReason:\n%1").arg(errorMessage.str().c_str()), QMessageBox::Close); + } + + m_listener.clearData(); + } + + if (!m_listener.connected()) + { + m_listener.closeSocket(); + setDisconnected(); + } +} + +////////////////////////////////////////////////////////////////////////// + +void EasyMainWindow::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status) +{ + if (EASY_GLOBALS.connected) + m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast(_status))); +} + +////////////////////////////////////////////////////////////////////////// + +EasySocketListener::EasySocketListener() : m_receivedSize(0), m_port(0), m_regime(LISTENER_IDLE) +{ + m_bInterrupt = ATOMIC_VAR_INIT(false); + m_bConnected = ATOMIC_VAR_INIT(false); + m_bStopReceive = ATOMIC_VAR_INIT(false); + m_bFrameTimeReady = ATOMIC_VAR_INIT(false); + m_bCaptureReady = ATOMIC_VAR_INIT(false); + m_frameMax = ATOMIC_VAR_INIT(0); + m_frameAvg = ATOMIC_VAR_INIT(0); +} + +EasySocketListener::~EasySocketListener() +{ + m_bInterrupt.store(true, ::std::memory_order_release); + if (m_thread.joinable()) + m_thread.join(); +} + +bool EasySocketListener::connected() const +{ + return m_bConnected.load(::std::memory_order_acquire); +} + +bool EasySocketListener::captured() const +{ + return m_bCaptureReady.load(::std::memory_order_acquire); +} + +EasyListenerRegime EasySocketListener::regime() const +{ + return m_regime; +} + +uint64_t EasySocketListener::size() const +{ + return m_receivedSize; +} + +::std::stringstream& EasySocketListener::data() +{ + return m_receivedData; +} + +const ::std::string& EasySocketListener::address() const +{ + return m_address; +} + +uint16_t EasySocketListener::port() const +{ + return m_port; +} + +void EasySocketListener::clearData() +{ + clear_stream(m_receivedData); + m_receivedSize = 0; +} + +void EasySocketListener::disconnect() +{ + if (connected()) + { + m_bInterrupt.store(true, ::std::memory_order_release); + if (m_thread.joinable()) + m_thread.join(); + + m_bConnected.store(false, ::std::memory_order_release); + m_bInterrupt.store(false, ::std::memory_order_release); + m_bCaptureReady.store(false, ::std::memory_order_release); + m_bStopReceive.store(false, ::std::memory_order_release); + } + + m_address.clear(); + m_port = 0; + + closeSocket(); +} + +void EasySocketListener::closeSocket() +{ + m_easySocket.flush(); + m_easySocket.init(); +} + +bool EasySocketListener::connect(const char* _ipaddress, uint16_t _port, profiler::net::EasyProfilerStatus& _reply, bool _disconnectFirst) +{ + if (connected()) + { + m_bInterrupt.store(true, ::std::memory_order_release); + if (m_thread.joinable()) + m_thread.join(); + + m_bConnected.store(false, ::std::memory_order_release); + m_bInterrupt.store(false, ::std::memory_order_release); + m_bCaptureReady.store(false, ::std::memory_order_release); + m_bStopReceive.store(false, ::std::memory_order_release); + } + + m_address.clear(); + m_port = 0; + + if (_disconnectFirst) + closeSocket(); + + int res = m_easySocket.setAddress(_ipaddress, _port); + res = m_easySocket.connect(); + + const bool isConnected = res == 0; + if (isConnected) + { + static const size_t buffer_size = sizeof(profiler::net::EasyProfilerStatus) << 1; + char buffer[buffer_size] = {}; + int bytes = 0; + + while (true) + { + bytes = m_easySocket.receive(buffer, buffer_size); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + return false; + bytes = 0; + continue; + } + + break; + } + + if (bytes == 0) + { + m_address = _ipaddress; + m_port = _port; + m_bConnected.store(isConnected, ::std::memory_order_release); + return isConnected; + } + + size_t seek = bytes; + while (seek < sizeof(profiler::net::EasyProfilerStatus)) + { + bytes = m_easySocket.receive(buffer + seek, buffer_size - seek); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + return false; + break; + } + + seek += bytes; + } + + auto message = reinterpret_cast(buffer); + if (message->isEasyNetMessage() && message->type == profiler::net::MessageType::Connection_Accepted) + _reply = *message; + + m_address = _ipaddress; + m_port = _port; + } + + m_bConnected.store(isConnected, ::std::memory_order_release); + return isConnected; +} + +bool EasySocketListener::reconnect(const char* _ipaddress, uint16_t _port, ::profiler::net::EasyProfilerStatus& _reply) +{ + return connect(_ipaddress, _port, _reply, true); +} + +bool EasySocketListener::startCapture() +{ + //if (m_thread.joinable()) + //{ + // m_bInterrupt.store(true, ::std::memory_order_release); + // m_thread.join(); + // m_bInterrupt.store(false, ::std::memory_order_release); + //} + + clearData(); + + profiler::net::Message request(profiler::net::MessageType::Request_Start_Capture); + m_easySocket.send(&request, sizeof(request)); + + if (m_easySocket.isDisconnected()) { + m_bConnected.store(false, ::std::memory_order_release); + return false; + } + + m_regime = LISTENER_CAPTURE; + m_bCaptureReady.store(false, ::std::memory_order_release); + //m_thread = ::std::thread(&EasySocketListener::listenCapture, this); + + return true; +} + +void EasySocketListener::stopCapture() +{ + //if (!m_thread.joinable() || m_regime != LISTENER_CAPTURE) + // return; + + if (m_regime != LISTENER_CAPTURE) + return; + + //m_bStopReceive.store(true, ::std::memory_order_release); + profiler::net::Message request(profiler::net::MessageType::Request_Stop_Capture); + m_easySocket.send(&request, sizeof(request)); + + //m_thread.join(); + + if (m_easySocket.isDisconnected()) { + m_bConnected.store(false, ::std::memory_order_release); + m_bStopReceive.store(false, ::std::memory_order_release); + m_regime = LISTENER_IDLE; + m_bCaptureReady.store(true, ::std::memory_order_release); + return; + } + + m_regime = LISTENER_CAPTURE_RECEIVE; + if (m_thread.joinable()) + { + m_bInterrupt.store(true, ::std::memory_order_release); + m_thread.join(); + m_bInterrupt.store(false, ::std::memory_order_release); + } + + m_thread = ::std::thread(&EasySocketListener::listenCapture, this); + + //m_regime = LISTENER_IDLE; + //m_bStopReceive.store(false, ::std::memory_order_release); +} + +void EasySocketListener::finalizeCapture() +{ + if (m_thread.joinable()) + { + m_bInterrupt.store(true, ::std::memory_order_release); + m_thread.join(); + m_bInterrupt.store(false, ::std::memory_order_release); + } + + m_regime = LISTENER_IDLE; + m_bCaptureReady.store(false, ::std::memory_order_release); + m_bStopReceive.store(false, ::std::memory_order_release); +} + +void EasySocketListener::requestBlocksDescription() +{ + if (m_thread.joinable()) + { + m_bInterrupt.store(true, ::std::memory_order_release); + m_thread.join(); + m_bInterrupt.store(false, ::std::memory_order_release); + } + + clearData(); + + profiler::net::Message request(profiler::net::MessageType::Request_Blocks_Description); + m_easySocket.send(&request, sizeof(request)); + + if(m_easySocket.isDisconnected() ){ + m_bConnected.store(false, ::std::memory_order_release); + } + + m_regime = LISTENER_DESCRIBE; + listenDescription(); + m_regime = LISTENER_IDLE; +} + +bool EasySocketListener::frameTime(uint32_t& _maxTime, uint32_t& _avgTime) +{ + if (m_bFrameTimeReady.exchange(false, ::std::memory_order_acquire)) + { + _maxTime = m_frameMax.load(::std::memory_order_acquire); + _avgTime = m_frameAvg.load(::std::memory_order_acquire); + return true; + } + + return false; +} + +bool EasySocketListener::requestFrameTime() +{ + if (m_regime != LISTENER_IDLE && m_regime != LISTENER_CAPTURE) + return false; + + if (m_thread.joinable()) + { + m_bInterrupt.store(true, ::std::memory_order_release); + m_thread.join(); + m_bInterrupt.store(false, ::std::memory_order_release); + } + + profiler::net::Message request(profiler::net::MessageType::Request_MainThread_FPS); + m_easySocket.send(&request, sizeof(request)); + + if (m_easySocket.isDisconnected()) + { + m_bConnected.store(false, ::std::memory_order_release); + return false; + } + + m_bFrameTimeReady.store(false, ::std::memory_order_release); + m_thread = ::std::thread(&EasySocketListener::listenFrameTime, this); + + return true; +} + +////////////////////////////////////////////////////////////////////////// + +void EasySocketListener::listenCapture() +{ + EASY_STATIC_CONSTEXPR int buffer_size = 8 * 1024 * 1024; + + char* buffer = new char[buffer_size]; + int seek = 0, bytes = 0; + auto timeBegin = ::std::chrono::system_clock::now(); + + bool isListen = true, disconnected = false; + while (isListen && !m_bInterrupt.load(::std::memory_order_acquire)) + { + if (m_bStopReceive.load(::std::memory_order_acquire)) + { + profiler::net::Message request(profiler::net::MessageType::Request_Stop_Capture); + m_easySocket.send(&request, sizeof(request)); + m_bStopReceive.store(false, ::std::memory_order_release); + } + + if ((bytes - seek) == 0) + { + bytes = m_easySocket.receive(buffer, buffer_size); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + { + m_bConnected.store(false, ::std::memory_order_release); + isListen = false; + disconnected = true; + } + + seek = 0; + bytes = 0; + + continue; + } + + seek = 0; + } + + if (bytes == 0) + { + isListen = false; + break; + } + + char* buf = buffer + seek; + + if (bytes > 0) + { + auto message = reinterpret_cast(buf); + if (!message->isEasyNetMessage()) + continue; + + switch (message->type) + { + case profiler::net::MessageType::Connection_Accepted: + { + qInfo() << "Receive MessageType::Connection_Accepted"; + //m_easySocket.send(&request, sizeof(request)); + seek += sizeof(profiler::net::Message); + break; + } + + case profiler::net::MessageType::Reply_Capturing_Started: + { + qInfo() << "Receive MessageType::Reply_Capturing_Started"; + seek += sizeof(profiler::net::Message); + break; + } + + case profiler::net::MessageType::Reply_Blocks_End: + { + qInfo() << "Receive MessageType::Reply_Blocks_End"; + seek += sizeof(profiler::net::Message); + + const auto dt = ::std::chrono::duration_cast(::std::chrono::system_clock::now() - timeBegin); + const auto bytesNumber = m_receivedData.str().size(); + qInfo() << "recieved " << bytesNumber << " bytes, " << dt.count() << " ms, average speed = " << double(bytesNumber) * 1e3 / double(dt.count()) / 1024. << " kBytes/sec"; + + seek = 0; + bytes = 0; + + isListen = false; + + break; + } + + case profiler::net::MessageType::Reply_Blocks: + { + qInfo() << "Receive MessageType::Reply_Blocks"; + + seek += sizeof(profiler::net::DataMessage); + auto dm = (profiler::net::DataMessage*)message; + timeBegin = std::chrono::system_clock::now(); + + int neededSize = dm->size; + + + buf = buffer + seek; + auto bytesNumber = ::std::min((int)dm->size, bytes - seek); + m_receivedSize += bytesNumber; + m_receivedData.write(buf, bytesNumber); + neededSize -= bytesNumber; + + if (neededSize == 0) + seek += bytesNumber; + else + { + seek = 0; + bytes = 0; + } + + + int loaded = 0; + while (neededSize > 0) + { + bytes = m_easySocket.receive(buffer, buffer_size); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + { + m_bConnected.store(false, ::std::memory_order_release); + isListen = false; + disconnected = true; + neededSize = 0; + } + + break; + } + + buf = buffer; + int toWrite = ::std::min(bytes, neededSize); + m_receivedSize += toWrite; + m_receivedData.write(buf, toWrite); + neededSize -= toWrite; + loaded += toWrite; + seek = toWrite; + } + + if (m_bStopReceive.load(::std::memory_order_acquire)) + { + profiler::net::Message request(profiler::net::MessageType::Request_Stop_Capture); + m_easySocket.send(&request, sizeof(request)); + m_bStopReceive.store(false, ::std::memory_order_release); + } + + break; + } + + default: + //qInfo() << "Receive unknown " << message->type; + break; + } + } + } + + if (disconnected) + clearData(); + + delete [] buffer; + + m_bCaptureReady.store(true, ::std::memory_order_release); +} + +void EasySocketListener::listenDescription() +{ + EASY_STATIC_CONSTEXPR int buffer_size = 8 * 1024 * 1024; + + char* buffer = new char[buffer_size]; + int seek = 0, bytes = 0; + + bool isListen = true, disconnected = false; + while (isListen && !m_bInterrupt.load(::std::memory_order_acquire)) + { + if ((bytes - seek) == 0) + { + bytes = m_easySocket.receive(buffer, buffer_size); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + { + m_bConnected.store(false, ::std::memory_order_release); + isListen = false; + disconnected = true; + } + + seek = 0; + bytes = 0; + + continue; + } + + seek = 0; + } + + if (bytes == 0) + { + isListen = false; + break; + } + + char* buf = buffer + seek; + + if (bytes > 0) + { + auto message = reinterpret_cast(buf); + if (!message->isEasyNetMessage()) + continue; + + switch (message->type) + { + case profiler::net::MessageType::Connection_Accepted: + { + qInfo() << "Receive MessageType::Connection_Accepted"; + seek += sizeof(profiler::net::Message); + break; + } + + case profiler::net::MessageType::Reply_Blocks_Description_End: + { + qInfo() << "Receive MessageType::Reply_Blocks_Description_End"; + seek += sizeof(profiler::net::Message); + + seek = 0; + bytes = 0; + + isListen = false; + + break; + } + + case profiler::net::MessageType::Reply_Blocks_Description: + { + qInfo() << "Receive MessageType::Reply_Blocks_Description"; + + seek += sizeof(profiler::net::DataMessage); + auto dm = (profiler::net::DataMessage*)message; + int neededSize = dm->size; + + buf = buffer + seek; + auto bytesNumber = ::std::min((int)dm->size, bytes - seek); + m_receivedSize += bytesNumber; + m_receivedData.write(buf, bytesNumber); + neededSize -= bytesNumber; + + if (neededSize == 0) + seek += bytesNumber; + else{ + seek = 0; + bytes = 0; + } + + int loaded = 0; + while (neededSize > 0) + { + bytes = m_easySocket.receive(buffer, buffer_size); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + { + m_bConnected.store(false, ::std::memory_order_release); + isListen = false; + disconnected = true; + neededSize = 0; + } + + break; + } + + buf = buffer; + int toWrite = ::std::min(bytes, neededSize); + m_receivedSize += toWrite; + m_receivedData.write(buf, toWrite); + neededSize -= toWrite; + loaded += toWrite; + seek = toWrite; + } + + break; + } + + default: + break; + } + } + } + + if (disconnected) + clearData(); + + delete[] buffer; +} + +void EasySocketListener::listenFrameTime() +{ + EASY_STATIC_CONSTEXPR size_t buffer_size = sizeof(::profiler::net::TimestampMessage) << 2; + + char buffer[buffer_size] = {}; + int seek = 0, bytes = 0; + + bool isListen = true; + while (isListen && !m_bInterrupt.load(::std::memory_order_acquire)) + { + if ((bytes - seek) == 0) + { + bytes = m_easySocket.receive(buffer, buffer_size); + + if (bytes == -1) + { + if (m_easySocket.isDisconnected()) + { + m_bConnected.store(false, ::std::memory_order_release); + isListen = false; + } + + seek = 0; + bytes = 0; + + continue; + } + + seek = 0; + } + + if (bytes == 0) + { + isListen = false; + break; + } + + char* buf = buffer + seek; + + if (bytes > 0) + { + auto message = reinterpret_cast(buf); + if (!message->isEasyNetMessage()) + continue; + + switch (message->type) + { + case profiler::net::MessageType::Connection_Accepted: + case profiler::net::MessageType::Reply_Capturing_Started: + { + seek += sizeof(profiler::net::Message); + break; + } + + case profiler::net::MessageType::Reply_MainThread_FPS: + { + //qInfo() << "Receive MessageType::Reply_MainThread_FPS"; + + seek += sizeof(profiler::net::TimestampMessage); + if (seek <= buffer_size) + { + auto timestampMessage = (profiler::net::TimestampMessage*)message; + m_frameMax.store(timestampMessage->maxValue, ::std::memory_order_release); + m_frameAvg.store(timestampMessage->avgValue, ::std::memory_order_release); + m_bFrameTimeReady.store(true, ::std::memory_order_release); + } + + isListen = false; + break; + } + + default: + break; + } + } + } +} + +////////////////////////////////////////////////////////////////////////// + diff --git a/3rdparty/easyprofiler/profiler_gui/main_window.h b/3rdparty/easyprofiler/profiler_gui/main_window.h new file mode 100644 index 0000000..474b972 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/main_window.h @@ -0,0 +1,335 @@ +/************************************************************************ +* file name : main_window.h +* ----------------- : +* creation time : 2016/06/26 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of MainWindow for easy_profiler GUI. +* ----------------- : +* change log : * 2016/06/26 Victor Zarubkin: initial commit. +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_PROFILER_GUI__MAIN_WINDOW__H +#define EASY_PROFILER_GUI__MAIN_WINDOW__H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +#define EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW 0 + +namespace profiler { namespace net { struct EasyProfilerStatus; } } + +////////////////////////////////////////////////////////////////////////// + +class EasyFileReader Q_DECL_FINAL +{ + ::profiler::SerializedData m_serializedBlocks; ///< + ::profiler::SerializedData m_serializedDescriptors; ///< + ::profiler::descriptors_list_t m_descriptors; ///< + ::profiler::blocks_t m_blocks; ///< + ::profiler::thread_blocks_tree_t m_blocksTree; ///< + ::std::stringstream m_stream; ///< + ::std::stringstream m_errorMessage; ///< + QString m_filename; ///< + uint32_t m_descriptorsNumberInFile = 0; ///< + uint32_t m_version = 0; ///< + ::std::thread m_thread; ///< + ::std::atomic_bool m_bDone; ///< + ::std::atomic m_progress; ///< + ::std::atomic m_size; ///< + bool m_isFile = false; ///< + +public: + + EasyFileReader(); + ~EasyFileReader(); + + const bool isFile() const; + bool done() const; + int progress() const; + unsigned int size() const; + const QString& filename() const; + + void load(const QString& _filename); + void load(::std::stringstream& _stream); + void interrupt(); + void get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors, + ::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree, + uint32_t& _descriptorsNumberInFile, uint32_t& _version, QString& _filename); + + QString getError(); + +}; // END of class EasyFileReader. + +////////////////////////////////////////////////////////////////////////// + +enum EasyListenerRegime : uint8_t +{ + LISTENER_IDLE = 0, + LISTENER_CAPTURE, + LISTENER_CAPTURE_RECEIVE, + LISTENER_DESCRIBE +}; + +class EasySocketListener Q_DECL_FINAL +{ + EasySocket m_easySocket; ///< + ::std::string m_address; ///< + ::std::stringstream m_receivedData; ///< + ::std::thread m_thread; ///< + uint64_t m_receivedSize; ///< + uint16_t m_port; ///< + ::std::atomic m_frameMax; ///< + ::std::atomic m_frameAvg; ///< + ::std::atomic_bool m_bInterrupt; ///< + ::std::atomic_bool m_bConnected; ///< + ::std::atomic_bool m_bStopReceive; ///< + ::std::atomic_bool m_bCaptureReady; ///< + ::std::atomic_bool m_bFrameTimeReady; ///< + EasyListenerRegime m_regime; ///< + +public: + + EasySocketListener(); + ~EasySocketListener(); + + bool connected() const; + bool captured() const; + EasyListenerRegime regime() const; + uint64_t size() const; + const ::std::string& address() const; + uint16_t port() const; + + ::std::stringstream& data(); + void clearData(); + + void disconnect(); + void closeSocket(); + bool connect(const char* _ipaddress, uint16_t _port, ::profiler::net::EasyProfilerStatus& _reply, bool _disconnectFirst = false); + bool reconnect(const char* _ipaddress, uint16_t _port, ::profiler::net::EasyProfilerStatus& _reply); + + bool startCapture(); + void stopCapture(); + void finalizeCapture(); + void requestBlocksDescription(); + + bool frameTime(uint32_t& _maxTime, uint32_t& _avgTime); + bool requestFrameTime(); + + template + inline void send(const T& _message) + { + m_easySocket.send(&_message, sizeof(T)); + } + +private: + + void listenCapture(); + void listenDescription(); + void listenFrameTime(); + +}; // END of class EasySocketListener. + +////////////////////////////////////////////////////////////////////////// + +class EasyDockWidget : public QDockWidget +{ + Q_OBJECT +public: + explicit EasyDockWidget(const QString& title, QWidget* parent = nullptr); + ~EasyDockWidget() override; +}; + +class EasyMainWindow : public QMainWindow +{ + Q_OBJECT + +protected: + + typedef EasyMainWindow This; + typedef QMainWindow Parent; + + QStringList m_lastFiles; + QString m_theme; + QString m_lastAddress; + QDockWidget* m_treeWidget = nullptr; + QDockWidget* m_graphicsView = nullptr; + QDockWidget* m_fpsViewer = nullptr; + +#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 + QDockWidget* m_descTreeWidget = nullptr; +#endif + + class QProgressDialog* m_progress = nullptr; + class QDialog* m_descTreeDialog = nullptr; + class EasyDescWidget* m_dialogDescTree = nullptr; + class QMessageBox* m_listenerDialog = nullptr; + QTimer m_readerTimer; + QTimer m_listenerTimer; + QTimer m_fpsRequestTimer; + ::profiler::SerializedData m_serializedBlocks; + ::profiler::SerializedData m_serializedDescriptors; + EasyFileReader m_reader; + EasySocketListener m_listener; + + class QLineEdit* m_addressEdit = nullptr; + class QLineEdit* m_portEdit = nullptr; + class QLineEdit* m_frameTimeEdit = nullptr; + + class QMenu* m_loadActionMenu = nullptr; + class QAction* m_saveAction = nullptr; + class QAction* m_deleteAction = nullptr; + + class QAction* m_captureAction = nullptr; + class QAction* m_connectAction = nullptr; + class QAction* m_eventTracingEnableAction = nullptr; + class QAction* m_eventTracingPriorityAction = nullptr; + + uint32_t m_descriptorsNumberInFile = 0; + uint16_t m_lastPort = 0; + bool m_bNetworkFileRegime = false; + bool m_bOpenedCacheFile = false; + +public: + + explicit EasyMainWindow(); + ~EasyMainWindow() override; + + // Public virtual methods + + void closeEvent(QCloseEvent* close_event) override; + void dragEnterEvent(QDragEnterEvent* drag_event) override; + void dragMoveEvent(QDragMoveEvent* drag_event) override; + void dragLeaveEvent(QDragLeaveEvent* drag_event) override; + void dropEvent(QDropEvent* drop_event) override; + +protected slots: + + void onThemeChange(bool); + void onOpenFileClicked(bool); + void onSaveFileClicked(bool); + void onDeleteClicked(bool); + void onExitClicked(bool); + void onEncodingChanged(bool); + void onChronoTextPosChanged(bool); + void onUnitsChanged(bool); + void onEnableDisableStatistics(bool); + void onCollapseItemsAfterCloseChanged(bool); + void onAllItemsExpandedByDefaultChange(bool); + void onBindExpandStatusChange(bool); + void onHierarchyFlagChange(bool); + void onExpandAllClicked(bool); + void onCollapseAllClicked(bool); + void onSpacingChange(int _value); + void onMinSizeChange(int _value); + void onNarrowSizeChange(int _value); + void onFpsIntervalChange(int _value); + void onFpsHistoryChange(int _value); + void onFpsMonitorLineWidthChange(int _value); + void onFileReaderTimeout(); + void onFrameTimeRequestTimeout(); + void onListenerTimerTimeout(); + void onFileReaderCancel(); + void onEditBlocksClicked(bool); + void onDescTreeDialogClose(int); + void onListenerDialogClose(int); + void onCaptureClicked(bool); + void onGetBlockDescriptionsClicked(bool); + void onConnectClicked(bool); + void onEventTracingPriorityChange(bool _checked); + void onEventTracingEnableChange(bool _checked); + void onFrameTimeEditFinish(); + void onFrameTimeChanged(); + + void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); + + void checkFrameTimeReady(); + +private: + + // Private non-virtual methods + + void clear(); + + void refreshDiagram(); + + void addFileToList(const QString& filename); + void loadFile(const QString& filename); + void readStream(::std::stringstream& data); + + void loadSettings(); + void loadGeometry(); + void saveSettingsAndGeometry(); + + void setDisconnected(bool _showMessage = true); + + void destroyProgressDialog(); + void createProgressDialog(const QString& text); + +}; // END of class EasyMainWindow. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_PROFILER_GUI__MAIN_WINDOW__H diff --git a/3rdparty/easyprofiler/profiler_gui/resources.qrc b/3rdparty/easyprofiler/profiler_gui/resources.qrc new file mode 100644 index 0000000..74dffc4 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/resources.qrc @@ -0,0 +1,51 @@ + + + themes/default.css + + + images/logo.svg + + + images/default/off.svg + images/default/open-folder2.svg + images/default/reload-folder2.svg + images/default/reload.svg + images/default/expand.svg + images/default/collapse.svg + images/default/save.svg + images/default/statistics.svg + images/default/statistics2.svg + images/default/lan.svg + images/default/lan_on.svg + images/default/wifi.svg + images/default/wifi_on.svg + images/default/lan.svg + images/default/lan_on.svg + images/default/play.svg + images/default/stop.svg + images/default/delete.svg + images/default/list.svg + images/default/search-next.svg + images/default/search-prev.svg + images/default/settings.svg + images/default/check.svg + images/default/check-disabled.svg + images/default/radio-indicator.svg + images/default/radio-indicator-disabled.svg + images/default/maximize-white.svg + images/default/maximize-white-hover.svg + images/default/maximize-white-pressed.svg + images/default/minimize-white.svg + images/default/minimize-white-hover.svg + images/default/minimize-white-pressed.svg + images/default/close-white.svg + images/default/close-white-hover.svg + images/default/close-white-pressed.svg + images/default/arrow-up.svg + images/default/arrow-up-hover.svg + images/default/arrow-up-disabled.svg + images/default/arrow-down.svg + images/default/arrow-down-hover.svg + images/default/arrow-down-disabled.svg + + diff --git a/3rdparty/easyprofiler/profiler_gui/resources.rc b/3rdparty/easyprofiler/profiler_gui/resources.rc new file mode 100644 index 0000000..fdc5adb --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/resources.rc @@ -0,0 +1,33 @@ +IDI_ICON1 ICON DISCARDABLE "images/logo.ico" +1 VERSIONINFO +FILEVERSION EASY_PROFILER_VERSION_MAJOR, EASY_PROFILER_VERSION_MINOR, EASY_PROFILER_VERSION_PATCH +PRODUCTVERSION EASY_PROFILER_VERSION_MAJOR, EASY_PROFILER_VERSION_MINOR, EASY_PROFILER_VERSION_PATCH + +# define EASY_STRINGIFY(a) #a +# define EASY_STRINGIFICATION(a) EASY_STRINGIFY(a) + +#define EASY_PROFILER_PRODUCT_VERSION "v" EASY_STRINGIFICATION(EASY_PROFILER_VERSION_MAJOR) "." \ + EASY_STRINGIFICATION(EASY_PROFILER_VERSION_MINOR) "." \ + EASY_STRINGIFICATION(EASY_PROFILER_VERSION_PATCH) + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "CompanyName", "EasySolutions" + VALUE "FileDescription", "EasyProfiler" + VALUE "InternalName", "profiler_gui" + VALUE "LegalCopyright", "Copyright (C) 2016-2017 Victor Zarubkin, Sergey Yagovtsev" + VALUE "LegalTrademarks1", "All Rights Reserved" + VALUE "LegalTrademarks2", "All Rights Reserved" + VALUE "OriginalFilename", "profiler_gui.exe" + VALUE "ProductName", "easy_profiler gui application" + VALUE "ProductVersion", EASY_PROFILER_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END diff --git a/3rdparty/easyprofiler/profiler_gui/themes/default.css b/3rdparty/easyprofiler/profiler_gui/themes/default.css new file mode 100644 index 0000000..4d944f7 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/themes/default.css @@ -0,0 +1,358 @@ +/********************************** +* * +* Light theme for EasyProfiler. * +* * +* Automatically generated from * +* default.scss by pysassc tool * +* * +***********************************/ +/* ****************************************************************************************************************** */ +/* Functions */ +/* ****************************************************************************************************************** */ +/* Constants */ +/* ****************************************************************************************************************** */ +/* StyleSheet */ +* { + font-family: "DejaVu Sans"; + font-size: 13px; + color: #504040; } + +*:disabled { + color: #a08888; } + +EasyMainWindow, QToolBar, QDialog { + background-color: #f8f2f2; } + +QToolTip { + background-color: #ffeccc; + border: 1px solid #cccccc; } + +QGraphicsView { + border: 1px solid #cccccc; } + +/* ****************************************************************************************************************** */ +QLineEdit, QComboBox, QSpinBox { + height: 24px; + border: 1px solid #cccccc; + background-color: white; + selection-background-color: rgba(152, 222, 152, 0.5); + selection-color: #504040; } + +QLineEdit:disabled, QComboBox:disabled, QSpinBox:disabled { + background-color: #f0f0f0; + color: #a08888; + selection-background-color: rgba(152, 222, 152, 0.5); + selection-color: #a08888; } + +QLineEdit:focus { + border: 1px solid #ffbcbc; } + +/* ****************************************************************************************************************** */ +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 24px; + border: none; + margin-left: 0; } + +QComboBox::down-arrow { + image: url(":/images/default/arrow-down"); + height: 8px; + width: 8px; } + +QComboBox::down-arrow:hover { + image: url(":/images/default/arrow-down-hover"); } + +QComboBox::down-arrow:disabled { + image: url(":/images/default/arrow-down-disabled"); } + +/* ****************************************************************************************************************** */ +QSpinBox::up-button { + subcontrol-origin: padding; + subcontrol-position: top right; + margin-left: 5px; + width: 24px; + border-left: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; } + +QSpinBox::down-button { + subcontrol-origin: padding; + subcontrol-position: bottom right; + margin-left: 5px; + width: 24px; + border-left: 1px solid #cccccc; } + +QSpinBox::up-button:pressed, QSpinBox::down-button:pressed { + background-color: #f4f4f4; } + +QSpinBox::up-arrow { + image: url(":/images/default/arrow-up"); + height: 8px; + width: 8px; } + +QSpinBox::up-arrow:hover { + image: url(":/images/default/arrow-up-hover"); } + +QSpinBox::up-arrow:disabled { + image: url(":/images/default/arrow-up-disabled"); } + +QSpinBox::down-arrow { + image: url(":/images/default/arrow-down"); + height: 8px; + width: 8px; } + +QSpinBox::down-arrow:hover { + image: url(":/images/default/arrow-down-hover"); } + +QSpinBox::down-arrow:disabled { + image: url(":/images/default/arrow-down-disabled"); } + +/* ****************************************************************************************************************** */ +QPushButton { + height: 24px; + min-width: 50px; + border: 1px solid #cccccc; + background-color: white; + padding: 0 5px 0 5px; } + +QPushButton:disabled { + background-color: #f0f0f0; + color: #a08888; } + +QPushButton:hover { + border: 1px solid #ffbcbc; + color: #922c2c; } + +QPushButton:pressed { + border: 1px solid #922c2c; + color: #370400; } + +/* ****************************************************************************************************************** */ +QListView { + background-color: white; + border: 1px solid #cccccc; } + +QListView, QTableView, QTreeView { + alternate-background-color: #e4e4ec; + selection-background-color: rgba(152, 222, 152, 0.8); + selection-color: #504040; } + +QListView::item, QTableView::item, QTreeView::item { + height: 26px; + border-bottom: 1px solid #cccccc; } + +QListView::item:selected, QTableView::item:selected, QTreeView::item:selected { + background-color: rgba(152, 222, 152, 0.8); } + +QTreeView::indicator { + width: 14px; + height: 14px; + background-color: transparent; + border: 1px solid transparent; + padding: 1px; + margin: 0; } + +QTreeView::indicator:hover, QTreeView::indicator:checked { + background-color: white; + border: 1px solid #cccccc; } + +QTreeView::indicator:checked { + image: url(":/images/default/check"); } + +QTreeView::indicator:checked:disabled { + image: url(":/images/default/check-disabled"); } + +/* ****************************************************************************************************************** */ +QMenu { + background-color: white; + border: 1px solid #cccccc; + padding-top: 4px; + padding-bottom: 4px; } + +QMenu::item { + height: 24px; + padding: 0 16px 0 25px; + border: 1px solid transparent; + /* reserve space for selection border */ } + +QMenu::item:selected { + border: 1px solid rgba(152, 222, 152, 0.5); + background-color: rgba(152, 222, 152, 0.5); } + +QMenu::icon { + width: 14px; + height: 14px; + background: none; + border: 1px inset transparent; + padding: 1px; + margin-left: 2px; } + +QMenu::icon:checked { + /* appearance of a 'checked' icon */ + background-color: #dddddd; + border: 1px inset #aaaaaa; } + +QMenu::separator { + height: 1px; + background: #cccccc; + margin-left: 5px; + margin-right: 5px; } + +QMenu::indicator { + width: 14px; + height: 14px; + background-color: white; + border: 1px solid #cccccc; + margin-left: 2px; + padding: 1px; } + +QMenu::indicator:non-exclusive:checked { + image: url(":/images/default/check"); } + +QMenu::indicator:non-exclusive:checked:disabled { + image: url(":/images/default/check-disabled"); } + +QMenu::indicator:exclusive { + border-radius: 8px; } + +QMenu::indicator:exclusive:checked { + image: url(":/images/default/radio-check"); } + +QMenu::indicator:exclusive:checked:disabled { + image: url(":/images/default/radio-check-disabled"); } + +/* ****************************************************************************************************************** */ +/*QToolButton { + border: 1px solid transparent; + background: none; + padding: 2px; +} + +QToolButton:hover { + border: 1px solid $BorderColor; +} + +QToolButton[popupMode="1"] { + padding-right: 13px; +} + +QToolButton:pressed { + background-color: #808080; +} + +QToolButton::menu-button { + border: none; + border-left: 1px solid transparent; + width: 12px; +} + +QToolButton::menu-button:hover { + border-left: 1px solid $BorderColor; + background-color: #bbbbbb; +} + +QToolButton::menu-button:pressed { + border-left: 1px solid $BorderColor; + background-color: #808080; +}*/ +/* ****************************************************************************************************************** */ +QHeaderView::section { + height: 28px; + width: 96px; + min-width: 64px; + background: #eeeeee; } + +/* ****************************************************************************************************************** */ +EasyDockWidget QWidget#EasyDockWidgetTitle { + background-color: #686464; } + EasyDockWidget QWidget#EasyDockWidgetTitle QLabel { + color: white; + margin-left: 4px; } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton { + background: none; + border: none; + max-height: 12px; + min-width: 12px; + max-width: 12px; + margin-right: 4px; + padding: 0; } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetFloatButton { + image: url(":/images/default/dock-maximize-white"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetFloatButton:hover { + image: url(":/images/default/dock-maximize-white-hover"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetFloatButton:pressed { + image: url(":/images/default/dock-maximize-white-pressed"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetFloatButton[floating=true] { + image: url(":/images/default/dock-minimize-white"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetFloatButton[floating=true]:hover { + image: url(":/images/default/dock-minimize-white-hover"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetFloatButton[floating=true]:pressed { + image: url(":/images/default/dock-minimize-white-pressed"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetCloseButton { + image: url(":/images/default/dock-close-white"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetCloseButton:hover { + image: url(":/images/default/dock-close-white-hover"); } + EasyDockWidget QWidget#EasyDockWidgetTitle QPushButton#EasyDockWidgetCloseButton:pressed { + image: url(":/images/default/dock-close-white-pressed"); } + +/* ****************************************************************************************************************** */ +QWidget#DiagramPopup, QWidget#ThreadsPopup { + background-color: white; + border: 1px solid #cccccc; } + +/* ****************************************************************************************************************** */ +QProgressBar { + height: 24px; + background-color: white; + border: 1px solid #cccccc; + color: #0B530B; + text-align: center; } + +QProgressBar::chunk { + background-color: #98DE98; + width: 2px; + margin: 0; } + +/* ****************************************************************************************************************** */ +QScrollBar { + background-color: transparent; + border: none; + padding: 0; } + +QScrollBar:hover { + background-color: rgba(0, 0, 0, 0.1); } + +QScrollBar:horizontal { + margin: 0; + height: 8px; } + +QScrollBar:vertical { + margin: 0; + width: 8px; } + +QScrollBar::handle { + background-color: rgba(0, 0, 0, 0.4); + border: none; + margin: 0; + padding: 0; } + +QScrollBar::handle:pressed { + background-color: rgba(0, 0, 0, 0.6); } + +QScrollBar::handle:vertical { + min-height: 30px; + margin-left: 4px; } + +QScrollBar::handle:vertical:hover, QScrollBar::handle:vertical:pressed { + margin-left: 0; } + +QScrollBar::handle:horizontal { + min-width: 30px; + margin-top: 4px; } + +QScrollBar::handle:horizontal:hover, QScrollBar::handle:horizontal:pressed { + margin-top: 0; } + +QScrollBar::add-line, QScrollBar::sub-line { + background: none; + border: none; } diff --git a/3rdparty/easyprofiler/profiler_gui/themes/default.scss b/3rdparty/easyprofiler/profiler_gui/themes/default.scss new file mode 100644 index 0000000..2bd248c --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/themes/default.scss @@ -0,0 +1,391 @@ +/********************************** +* * +* Light theme for EasyProfiler. * +* * +* Automatically generated from * +* default.scss by pysassc tool * +* * +***********************************/ + +/* ****************************************************************************************************************** */ +/* Functions */ +@function rgb_a($color, $opacity) { + @return fade_out($color, 1.0 - $opacity); +} + +/* ****************************************************************************************************************** */ +/* Constants */ +$TextColor: #504040; +$DisabledTextColor: #a08888; +$BorderColor: #cccccc; +$MainColor: #f44336; +$HoveredMenuRowColor: rgb_a(#98DE98, 0.5); +$BackgroundColor: white; +$DisabledBackgroundColor: #f0f0f0; +$ButtonHoverColor: #922c2c;//#d77d7d; +$ButtonPressedColor: #370400;//#922c2c; +$FocusBorderColor: #ffbcbc; +$DefaultHeight: 24px; +$ComboBoxArrowSize: 8px; +$SpinBoxArrowSize: 8px; + +/* ****************************************************************************************************************** */ +/* StyleSheet */ + +* { + font-family: "DejaVu Sans"; + font-size: 13px; + color: $TextColor; +} + +*:disabled { + color: $DisabledTextColor; +} + +EasyMainWindow, QToolBar, QDialog { + background-color: #f8f2f2; +} + +QToolTip { + background-color: #ffeccc; + border: 1px solid $BorderColor; +} + +QGraphicsView { + border: 1px solid $BorderColor; +} + +/* ****************************************************************************************************************** */ +QLineEdit, QComboBox, QSpinBox { + height: $DefaultHeight; + border: 1px solid $BorderColor; + background-color: $BackgroundColor; + selection-background-color: $HoveredMenuRowColor; + selection-color: $TextColor; +} + +QLineEdit:disabled, QComboBox:disabled, QSpinBox:disabled { + background-color: $DisabledBackgroundColor; + color: $DisabledTextColor; + selection-background-color: $HoveredMenuRowColor; + selection-color: $DisabledTextColor; +} + +QLineEdit:focus { border: 1px solid $FocusBorderColor; } + +/* ****************************************************************************************************************** */ +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: $DefaultHeight; + border: none; + margin-left: 0; +} + +QComboBox::down-arrow { image: url(":/images/default/arrow-down"); height: $ComboBoxArrowSize; width: $ComboBoxArrowSize; } +QComboBox::down-arrow:hover { image: url(":/images/default/arrow-down-hover"); } +QComboBox::down-arrow:disabled { image: url(":/images/default/arrow-down-disabled"); } + +/* ****************************************************************************************************************** */ +QSpinBox::up-button { + subcontrol-origin: padding; + subcontrol-position: top right; + margin-left: 5px; + width: $DefaultHeight; + border-left: 1px solid $BorderColor; + border-bottom: 1px solid $BorderColor; +} + +QSpinBox::down-button { + subcontrol-origin: padding; + subcontrol-position: bottom right; + margin-left: 5px; + width: $DefaultHeight; + border-left: 1px solid $BorderColor; +} + +QSpinBox::up-button:pressed, QSpinBox::down-button:pressed { + background-color: #f4f4f4; +} + +QSpinBox::up-arrow { image: url(":/images/default/arrow-up"); height: $SpinBoxArrowSize; width: $SpinBoxArrowSize; } +QSpinBox::up-arrow:hover { image: url(":/images/default/arrow-up-hover"); } +QSpinBox::up-arrow:disabled { image: url(":/images/default/arrow-up-disabled"); } + +QSpinBox::down-arrow { image: url(":/images/default/arrow-down"); height: $SpinBoxArrowSize; width: $SpinBoxArrowSize; } +QSpinBox::down-arrow:hover { image: url(":/images/default/arrow-down-hover"); } +QSpinBox::down-arrow:disabled { image: url(":/images/default/arrow-down-disabled"); } + +/* ****************************************************************************************************************** */ +QPushButton { + height: $DefaultHeight; + min-width: 50px; + border: 1px solid $BorderColor; + background-color: $BackgroundColor; + padding: 0 5px 0 5px; +} + +QPushButton:disabled { + background-color: $DisabledBackgroundColor; + color: $DisabledTextColor; +} + +QPushButton:hover { + border: 1px solid $FocusBorderColor; + color: $ButtonHoverColor; +} + +QPushButton:pressed { + border: 1px solid $ButtonHoverColor; + color: $ButtonPressedColor; +} + +/* ****************************************************************************************************************** */ +QListView { + background-color: $BackgroundColor; + border: 1px solid $BorderColor; +} + +QListView, QTableView, QTreeView { + alternate-background-color: #e4e4ec; + selection-background-color: rgb_a(#98DE98, 0.8); + selection-color: $TextColor; +} + +QListView::item, QTableView::item, QTreeView::item { + height: $DefaultHeight + 2px; + border-bottom: 1px solid $BorderColor; +} + +QListView::item:selected, QTableView::item:selected, QTreeView::item:selected { + background-color: rgb_a(#98DE98, 0.8); +} + + +QTreeView::indicator { + width: 14px; + height: 14px; + background-color: transparent; + border: 1px solid transparent; + padding: 1px; + margin: 0; +} + +QTreeView::indicator:hover, QTreeView::indicator:checked { + background-color: $BackgroundColor; + border: 1px solid $BorderColor; +} + +QTreeView::indicator:checked { image: url(":/images/default/check"); } +QTreeView::indicator:checked:disabled { image: url(":/images/default/check-disabled"); } + +/* ****************************************************************************************************************** */ +QMenu { + background-color: $BackgroundColor; + border: 1px solid $BorderColor; + padding-top: 4px; + padding-bottom: 4px; +} + +QMenu::item { + height: $DefaultHeight; + padding: 0 16px 0 25px; + border: 1px solid transparent; /* reserve space for selection border */ +} + +QMenu::item:selected { + border: 1px solid $HoveredMenuRowColor; + background-color: $HoveredMenuRowColor; +} + +QMenu::icon { + width: 14px; + height: 14px; + background: none; + border: 1px inset transparent; + padding: 1px; + margin-left: 2px; +} + +QMenu::icon:checked { /* appearance of a 'checked' icon */ + background-color: #dddddd; + border: 1px inset #aaaaaa; +} + +QMenu::separator { + height: 1px; + background: $BorderColor; + margin-left: 5px; + margin-right: 5px; +} + +QMenu::indicator { + width: 14px; + height: 14px; + background-color: $BackgroundColor; + border: 1px solid $BorderColor; + margin-left: 2px; + padding: 1px; +} + +QMenu::indicator:non-exclusive:checked { image: url(":/images/default/check"); } +QMenu::indicator:non-exclusive:checked:disabled { image: url(":/images/default/check-disabled"); } + +QMenu::indicator:exclusive { border-radius: 8px; } +QMenu::indicator:exclusive:checked { image: url(":/images/default/radio-check"); } +QMenu::indicator:exclusive:checked:disabled { image: url(":/images/default/radio-check-disabled"); } + + + + +/* ****************************************************************************************************************** */ +/*QToolButton { + border: 1px solid transparent; + background: none; + padding: 2px; +} + +QToolButton:hover { + border: 1px solid $BorderColor; +} + +QToolButton[popupMode="1"] { + padding-right: 13px; +} + +QToolButton:pressed { + background-color: #808080; +} + +QToolButton::menu-button { + border: none; + border-left: 1px solid transparent; + width: 12px; +} + +QToolButton::menu-button:hover { + border-left: 1px solid $BorderColor; + background-color: #bbbbbb; +} + +QToolButton::menu-button:pressed { + border-left: 1px solid $BorderColor; + background-color: #808080; +}*/ + + + + + + +/* ****************************************************************************************************************** */ +QHeaderView::section { + height: 28px; + width: 96px; + min-width: 64px; + background: #eeeeee; +} + + + + + +/* ****************************************************************************************************************** */ +EasyDockWidget +{ + QWidget#EasyDockWidgetTitle + { + background-color: #686464; + + QLabel { + color: white; + margin-left: 4px; + } + + QPushButton { + background: none; + border: none; + max-height: 12px; + min-width: 12px; + max-width: 12px; + margin-right: 4px; + padding: 0; + } + + QPushButton#EasyDockWidgetFloatButton { image: url(":/images/default/dock-maximize-white"); } + QPushButton#EasyDockWidgetFloatButton:hover { image: url(":/images/default/dock-maximize-white-hover"); } + QPushButton#EasyDockWidgetFloatButton:pressed { image: url(":/images/default/dock-maximize-white-pressed"); } + + QPushButton#EasyDockWidgetFloatButton[floating=true] { image: url(":/images/default/dock-minimize-white"); } + QPushButton#EasyDockWidgetFloatButton[floating=true]:hover { image: url(":/images/default/dock-minimize-white-hover"); } + QPushButton#EasyDockWidgetFloatButton[floating=true]:pressed { image: url(":/images/default/dock-minimize-white-pressed"); } + + QPushButton#EasyDockWidgetCloseButton { image: url(":/images/default/dock-close-white"); } + QPushButton#EasyDockWidgetCloseButton:hover { image: url(":/images/default/dock-close-white-hover"); } + QPushButton#EasyDockWidgetCloseButton:pressed { image: url(":/images/default/dock-close-white-pressed"); } + } +} + +/* ****************************************************************************************************************** */ +QWidget#DiagramPopup, QWidget#ThreadsPopup { + background-color: $BackgroundColor; + border: 1px solid $BorderColor; +} + +/* ****************************************************************************************************************** */ +QProgressBar { + height: $DefaultHeight; + background-color: $BackgroundColor; + border: 1px solid $BorderColor;//#64BC64; + color: #0B530B; + text-align: center; +} + +QProgressBar::chunk { + background-color: #98DE98; + width: 2px; + margin: 0; +} + +/* ****************************************************************************************************************** */ +QScrollBar { + background-color: transparent; + border: none; + padding: 0; +} + +QScrollBar:hover { + background-color: rgb_a(#000000, 0.1); +} + +QScrollBar:horizontal { + margin: 0; + height: 8px; +} + +QScrollBar:vertical { + margin: 0; + width: 8px; +} + +QScrollBar::handle { + background-color: rgb_a(#000000, 0.4); + border: none; + margin: 0; + padding: 0; +} + +QScrollBar::handle:pressed { + background-color: rgb_a(#000000, 0.6); +} + +QScrollBar::handle:vertical { min-height: 30px; margin-left: 4px; } +QScrollBar::handle:vertical:hover, QScrollBar::handle:vertical:pressed { margin-left: 0; } + +QScrollBar::handle:horizontal { min-width: 30px; margin-top: 4px; } +QScrollBar::handle:horizontal:hover, QScrollBar::handle:horizontal:pressed { margin-top: 0; } + +QScrollBar::add-line, QScrollBar::sub-line { + background: none; + border: none; +} diff --git a/3rdparty/easyprofiler/profiler_gui/tree_widget_item.cpp b/3rdparty/easyprofiler/profiler_gui/tree_widget_item.cpp new file mode 100644 index 0000000..4fd2459 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/tree_widget_item.cpp @@ -0,0 +1,431 @@ +/************************************************************************ +* file name : tree_widget_item.cpp +* ----------------- : +* creation time : 2016/08/18 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyTreeWidgetItem. +* ----------------- : +* change log : * 2016/08/18 Victor Zarubkin: Moved sources from blocks_tree_widget.cpp +* : and renamed classes from Prof* to Easy*. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include "tree_widget_item.h" +#include "globals.h" +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////// + +EASY_CONSTEXPR int BlockColorRole = Qt::UserRole + 1; + +////////////////////////////////////////////////////////////////////////// + +EASY_CONSTEXPR int ColumnBit[COL_COLUMNS_NUMBER] = { + -1 // COL_NAME = 0, + + , 0 // COL_BEGIN, + + , 1 // COL_DURATION, + , 2 // COL_SELF_DURATION, + , 3 // COL_DURATION_SUM_PER_PARENT, + , 4 // COL_DURATION_SUM_PER_FRAME, + , 5 // COL_DURATION_SUM_PER_THREAD, + + , -1 // COL_SELF_DURATION_PERCENT, + , -1 // COL_PERCENT_PER_PARENT, + , -1 // COL_PERCENT_PER_FRAME, + , -1 // COL_PERCENT_SUM_PER_PARENT, + , -1 // COL_PERCENT_SUM_PER_FRAME, + , -1 // COL_PERCENT_SUM_PER_THREAD, + + , 6 // COL_END, + + , 7 // COL_MIN_PER_FRAME, + , 8 // COL_MAX_PER_FRAME, + , 9 // COL_AVERAGE_PER_FRAME, + , -1 // COL_NCALLS_PER_FRAME, + + , 10 // COL_MIN_PER_THREAD, + , 11 // COL_MAX_PER_THREAD, + , 12 // COL_AVERAGE_PER_THREAD, + , -1 // COL_NCALLS_PER_THREAD, + + , 13 // COL_MIN_PER_PARENT, + , 14 // COL_MAX_PER_PARENT, + , 15 // COL_AVERAGE_PER_PARENT, + , -1 // COL_NCALLS_PER_PARENT, + + , 16 // COL_ACTIVE_TIME, + , -1 // COL_ACTIVE_PERCENT, +}; + +////////////////////////////////////////////////////////////////////////// + +EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock, Parent* _parent) + : Parent(_parent, QTreeWidgetItem::UserType) + , m_block(_treeBlock) + , m_customBGColor(0) + , m_bMain(false) +{ + +} + +EasyTreeWidgetItem::~EasyTreeWidgetItem() +{ +} + +bool EasyTreeWidgetItem::operator < (const Parent& _other) const +{ + const auto col = treeWidget()->sortColumn(); + + switch (col) + { + //case COL_UNKNOWN: + case COL_NAME: + { + if (parent() == nullptr) + return false; // Do not sort topLevelItems by name + return Parent::operator < (_other); + } + + case COL_NCALLS_PER_THREAD: + case COL_NCALLS_PER_PARENT: + case COL_NCALLS_PER_FRAME: + { + return data(col, Qt::UserRole).toUInt() < _other.data(col, Qt::UserRole).toUInt(); + } + + case COL_SELF_DURATION_PERCENT: + case COL_PERCENT_PER_PARENT: + case COL_PERCENT_PER_FRAME: + case COL_PERCENT_SUM_PER_PARENT: + case COL_PERCENT_SUM_PER_FRAME: + case COL_PERCENT_SUM_PER_THREAD: + { + return data(col, Qt::UserRole).toInt() < _other.data(col, Qt::UserRole).toInt(); + } + + case COL_ACTIVE_PERCENT: + { + return data(col, Qt::UserRole).toDouble() < _other.data(col, Qt::UserRole).toDouble(); + } + + default: + { + // durations min, max, average + return data(col, Qt::UserRole).toULongLong() < _other.data(col, Qt::UserRole).toULongLong(); + } + } + + return false; +} + +bool EasyTreeWidgetItem::hasToolTip(int _column) const +{ + const int bit = ColumnBit[_column]; + return bit < 0 ? false : m_bHasToolTip.test(static_cast(bit)); +} + +void EasyTreeWidgetItem::setHasToolTip(int _column) +{ + const int bit = ColumnBit[_column]; + if (bit >= 0) + m_bHasToolTip.set(static_cast(bit), true); +} + +QVariant EasyTreeWidgetItem::data(int _column, int _role) const +{ + if (_column == COL_NAME) + { + if (_role == Qt::SizeHintRole) + { +#ifdef _WIN32 + const float k = m_font.bold() ? 1.2f : 1.f; +#else + const float k = m_font.bold() ? 1.15f : 1.f; +#endif + return QSize(static_cast(QFontMetrics(m_font).width(text(COL_NAME)) * k) + 20, 26); + } + + if (_role == BlockColorRole) + { + if (parent() != nullptr || m_bMain) + return QBrush(QColor::fromRgba(m_customBGColor)); + return QVariant(); + } + } + + switch (_role) + { + case Qt::FontRole: + return m_font; + + case Qt::ForegroundRole: + return m_bMain ? QVariant::fromValue(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_FOREGROUND)) : QVariant(); + + case Qt::ToolTipRole: + return hasToolTip(_column) ? + QVariant::fromValue(QString("%1 ns").arg(QTreeWidgetItem::data(_column, Qt::UserRole).toULongLong())) : + QVariant(); + + default: + return QTreeWidgetItem::data(_column, _role); + } +} + +::profiler::block_index_t EasyTreeWidgetItem::block_index() const +{ + return m_block; +} + +::profiler_gui::EasyBlock& EasyTreeWidgetItem::guiBlock() +{ + return easyBlock(m_block); +} + +const ::profiler::BlocksTree& EasyTreeWidgetItem::block() const +{ + return easyBlocksTree(m_block); +} + +::profiler::timestamp_t EasyTreeWidgetItem::duration() const +{ + if (parent() != nullptr) + return block().node->duration(); + return data(COL_DURATION, Qt::UserRole).toULongLong(); +} + +::profiler::timestamp_t EasyTreeWidgetItem::selfDuration() const +{ + return data(COL_SELF_DURATION, Qt::UserRole).toULongLong(); +} + +void EasyTreeWidgetItem::setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time, const QString& _prefix) +{ + const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time); + + setData(_column, Qt::UserRole, (quint64)nanosecondsTime); + setHasToolTip(_column); + setText(_column, QString("%1%2").arg(_prefix).arg(::profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3))); + +// if (_time < 1e3) +// { +// setText(_column, QString("%1%2 ns").arg(_prefix).arg(nanosecondsTime)); +// } +// else if (_time < 1e6) +// { +// setText(_column, QString("%1%2 us").arg(_prefix).arg(double(nanosecondsTime) * 1e-3, 0, 'f', 3)); +// } +// else if (_time < 1e9) +// { +// setText(_column, QString("%1%2 ms").arg(_prefix).arg(double(nanosecondsTime) * 1e-6, 0, 'f', 3)); +// } +// else +// { +// setText(_column, QString("%1%2 s").arg(_prefix).arg(double(nanosecondsTime) * 1e-9, 0, 'f', 3)); +// } +} + +void EasyTreeWidgetItem::setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time) +{ + const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time); + + setData(_column, Qt::UserRole, (quint64)nanosecondsTime); + setHasToolTip(_column); + setText(_column, ::profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3)); +} + +void EasyTreeWidgetItem::setTimeMs(int _column, const ::profiler::timestamp_t& _time) +{ + const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time); + setData(_column, Qt::UserRole, (quint64)nanosecondsTime); + setHasToolTip(_column); + setText(_column, QString::number(double(nanosecondsTime) * 1e-6, 'g', 9)); +} + +void EasyTreeWidgetItem::setTimeMs(int _column, const ::profiler::timestamp_t& _time, const QString& _prefix) +{ + const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time); + setData(_column, Qt::UserRole, (quint64)nanosecondsTime); + setHasToolTip(_column); + setText(_column, QString("%1%2").arg(_prefix).arg(double(nanosecondsTime) * 1e-6, 0, 'g', 9)); +} + +void EasyTreeWidgetItem::setBackgroundColor(QRgb _color) +{ + m_customBGColor = _color; +} + +void EasyTreeWidgetItem::setMain(bool _main) +{ + m_bMain = _main; +} + +void EasyTreeWidgetItem::collapseAll() +{ + for (int i = 0, childrenNumber = childCount(); i < childrenNumber; ++i) + { + static_cast(child(i))->collapseAll(); + } + + setExpanded(false); + if (parent() != nullptr) + guiBlock().expanded = false; +} + +void EasyTreeWidgetItem::expandAll() +{ + for (int i = 0, childrenNumber = childCount(); i < childrenNumber; ++i) + { + static_cast(child(i))->expandAll(); + } + + setExpanded(true); + if (parent() != nullptr) + guiBlock().expanded = true; +} + +void EasyTreeWidgetItem::setBold(bool _bold) +{ + m_font.setBold(_bold); +} + +////////////////////////////////////////////////////////////////////////// + +EasyItemDelegate::EasyItemDelegate(QTreeWidget* parent) : QStyledItemDelegate(parent), m_treeWidget(parent) +{ + +} + +EasyItemDelegate::~EasyItemDelegate() +{ + +} + +void EasyItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + auto brushData = m_treeWidget->model()->data(index, BlockColorRole); + if (brushData.isNull()) + { +#ifdef _WIN32 + const auto currentTreeIndex = m_treeWidget->currentIndex(); + if (index.parent() == currentTreeIndex.parent() && index.row() == currentTreeIndex.row()) + { + // Draw selection background for selected row + painter->save(); + painter->setBrush(QColor::fromRgba(0xCC98DE98)); + painter->setPen(Qt::NoPen); + painter->drawRect(QRect(0, option.rect.top(), option.rect.left() + 16, option.rect.height())); + painter->restore(); + } +#endif + + // Draw item as usual + QStyledItemDelegate::paint(painter, option, index); + + // Draw line under tree indicator + const auto bottomLeft = option.rect.bottomLeft(); + if (bottomLeft.x() > 0) + { + painter->save(); + painter->setBrush(Qt::NoBrush); + painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + painter->drawLine(QPoint(0, bottomLeft.y()), bottomLeft); + painter->restore(); + } + + return; + } + + const auto currentTreeIndex = m_treeWidget->currentIndex(); + if (index.parent() == currentTreeIndex.parent() && index.row() == currentTreeIndex.row()) + { + // Draw selection background for selected row + + painter->save(); + + painter->setBrush(QColor::fromRgba(0xCC98DE98)); + painter->setPen(Qt::NoPen); + +#ifdef _WIN32 + painter->drawRect(QRect(0, option.rect.top(), option.rect.left() + 16, option.rect.height())); +#else + painter->drawRect(QRect(option.rect.left(), option.rect.top(), 16, option.rect.height())); +#endif + + painter->restore(); + } + + // Adjust rect size for drawing color marker + QStyleOptionViewItem opt = option; + opt.rect.adjust(16, 0, 0, 0); + + // Draw item as usual + QStyledItemDelegate::paint(painter, opt, index); + + painter->save(); + + // Draw color marker with block color + const auto brush = m_treeWidget->model()->data(index, Qt::UserRole + 1).value(); + painter->setBrush(brush); + painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + painter->drawRect(QRect(option.rect.left(), option.rect.top() + 5, 16, option.rect.height() - 10)); + + // Draw line under tree indicator + const auto bottomLeft = opt.rect.bottomLeft(); + if (bottomLeft.x() > 0) + { + painter->setBrush(Qt::NoBrush); + painter->drawLine(QPoint(0, bottomLeft.y()), bottomLeft); + } + + painter->restore(); +} diff --git a/3rdparty/easyprofiler/profiler_gui/tree_widget_item.h b/3rdparty/easyprofiler/profiler_gui/tree_widget_item.h new file mode 100644 index 0000000..b164907 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/tree_widget_item.h @@ -0,0 +1,184 @@ +/************************************************************************ +* file name : tree_widget_item.h +* ----------------- : +* creation time : 2016/08/18 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyTreeWidgetItem +* : for displyaing EasyProfiler blocks tree. +* ----------------- : +* change log : * 2016/08/18 Victor Zarubkin: moved sources from blocks_tree_widget.h +* : and renamed classes from Prof* to Easy*. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_TREE_WIDGET_ITEM_H +#define EASY_TREE_WIDGET_ITEM_H + +#include +#include +#include +#include +#include + +#include "common_functions.h" + +////////////////////////////////////////////////////////////////////////// + +enum EasyColumnsIndexes +{ + COL_UNKNOWN = -1, + + COL_NAME = 0, + + COL_BEGIN, + + COL_DURATION, + COL_SELF_DURATION, + COL_DURATION_SUM_PER_PARENT, + COL_DURATION_SUM_PER_FRAME, + COL_DURATION_SUM_PER_THREAD, + + COL_SELF_DURATION_PERCENT, + COL_PERCENT_PER_PARENT, + COL_PERCENT_PER_FRAME, + COL_PERCENT_SUM_PER_PARENT, + COL_PERCENT_SUM_PER_FRAME, + COL_PERCENT_SUM_PER_THREAD, + + COL_END, + + COL_MIN_PER_FRAME, + COL_MAX_PER_FRAME, + COL_AVERAGE_PER_FRAME, + COL_NCALLS_PER_FRAME, + + COL_MIN_PER_THREAD, + COL_MAX_PER_THREAD, + COL_AVERAGE_PER_THREAD, + COL_NCALLS_PER_THREAD, + + COL_MIN_PER_PARENT, + COL_MAX_PER_PARENT, + COL_AVERAGE_PER_PARENT, + COL_NCALLS_PER_PARENT, + + COL_ACTIVE_TIME, + COL_ACTIVE_PERCENT, + + COL_COLUMNS_NUMBER +}; + +////////////////////////////////////////////////////////////////////////// + +class EasyTreeWidgetItem : public QTreeWidgetItem +{ + using Parent = QTreeWidgetItem; + using This = EasyTreeWidgetItem; + + QFont m_font; + const ::profiler::block_index_t m_block; + QRgb m_customBGColor; + std::bitset<17> m_bHasToolTip; + bool m_bMain; + +public: + + explicit EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock = ::profiler_gui::numeric_max(), Parent* _parent = nullptr); + virtual ~EasyTreeWidgetItem(); + + bool operator < (const Parent& _other) const override; + QVariant data(int _column, int _role) const override; + +public: + + ::profiler::block_index_t block_index() const; + ::profiler_gui::EasyBlock& guiBlock(); + const ::profiler::BlocksTree& block() const; + + ::profiler::timestamp_t duration() const; + ::profiler::timestamp_t selfDuration() const; + + void setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time, const QString& _prefix); + void setTimeSmart(int _column, ::profiler_gui::TimeUnits _units, const ::profiler::timestamp_t& _time); + + void setTimeMs(int _column, const ::profiler::timestamp_t& _time); + void setTimeMs(int _column, const ::profiler::timestamp_t& _time, const QString& _prefix); + + void setBackgroundColor(QRgb _color); + + void setMain(bool _main); + + void collapseAll(); + + void expandAll(); + + void setBold(bool _bold); + +private: + + bool hasToolTip(int _column) const; + void setHasToolTip(int _column); + +}; // END of class EasyTreeWidgetItem. + +////////////////////////////////////////////////////////////////////////// + +class EasyItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + QTreeWidget* m_treeWidget; + +public: + + explicit EasyItemDelegate(QTreeWidget* parent = nullptr); + ~EasyItemDelegate() override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + +}; // END of class EasyItemDelegate. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_TREE_WIDGET_ITEM_H diff --git a/3rdparty/easyprofiler/profiler_gui/tree_widget_loader.cpp b/3rdparty/easyprofiler/profiler_gui/tree_widget_loader.cpp new file mode 100644 index 0000000..c6ae0b8 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/tree_widget_loader.cpp @@ -0,0 +1,1031 @@ +/************************************************************************ +* file name : tree_widget_loader.h +* ----------------- : +* creation time : 2016/08/18 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains implementation of EasyTreeWidgetLoader which aim is +* : to load EasyProfiler blocks hierarchy in separate thread. +* ----------------- : +* change log : * 2016/08/18 Victor Zarubkin: moved sources from blocks_tree_widget.h/.cpp +* : and renamed Prof* to Easy*. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#include "tree_widget_loader.h" +#include "tree_widget_item.h" +#include "globals.h" + +#ifdef _WIN32 +#include + +#ifdef __MINGW32__ +#include +#endif + +#endif + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +////////////////////////////////////////////////////////////////////////// + +EasyTreeWidgetLoader::EasyTreeWidgetLoader() + : m_bDone(ATOMIC_VAR_INIT(false)) + , m_bInterrupt(ATOMIC_VAR_INIT(false)) + , m_progress(ATOMIC_VAR_INIT(0)) + , m_mode(EasyTreeMode_Full) +{ +} + +EasyTreeWidgetLoader::~EasyTreeWidgetLoader() +{ + interrupt(true); +} + +bool EasyTreeWidgetLoader::done() const +{ + return m_bDone.load(); +} + +void EasyTreeWidgetLoader::setDone() +{ + m_bDone.store(true); + //m_progress.store(100); +} + +void EasyTreeWidgetLoader::setProgress(int _progress) +{ + m_progress.store(_progress); +} + +bool EasyTreeWidgetLoader::interrupted() const +{ + return m_bInterrupt.load(); +} + +int EasyTreeWidgetLoader::progress() const +{ + return m_progress.load(); +} + +void EasyTreeWidgetLoader::takeTopLevelItems(ThreadedItems& _output) +{ + if (done()) + { + _output = ::std::move(m_topLevelItems); + m_topLevelItems.clear(); + } +} + +void EasyTreeWidgetLoader::takeItems(Items& _output) +{ + if (done()) + { + _output = ::std::move(m_items); + m_items.clear(); + } +} + +void EasyTreeWidgetLoader::interrupt(bool _wait) +{ + m_bInterrupt.store(true); + if (m_thread.joinable()) + m_thread.join(); + + m_bInterrupt.store(false); + m_bDone.store(false); + m_progress.store(0); + + if (!_wait) + { + auto deleter_thread = ::std::thread([](decltype(m_topLevelItems) _items) + { +#ifdef _WIN32 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); +#endif + + for (auto item : _items) + delete item.second; + + }, ::std::move(m_topLevelItems)); + + deleter_thread.detach(); + } + else + { + for (auto item : m_topLevelItems) + delete item.second; + } + + m_items.clear(); + m_topLevelItems.clear(); + m_iditems.clear(); +} + +void EasyTreeWidgetLoader::fillTree(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, EasyTreeMode _mode) +{ + interrupt(); + m_mode = _mode; + m_thread = ::std::thread(&EasyTreeWidgetLoader::setTreeInternal1, this, + ::std::ref(_beginTime), _blocksNumber, ::std::ref(_blocksTree), EASY_GLOBALS.add_zero_blocks_to_hierarchy, + EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.hex_thread_id, EASY_GLOBALS.time_units); +} + +void EasyTreeWidgetLoader::fillTreeBlocks(const::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _beginTime, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, EasyTreeMode _mode) +{ + interrupt(); + m_mode = _mode; + m_thread = ::std::thread(&EasyTreeWidgetLoader::setTreeInternal2, this, + _beginTime, ::std::ref(_blocks), _left, _right, _strict, EASY_GLOBALS.add_zero_blocks_to_hierarchy, + EASY_GLOBALS.use_decorated_thread_name, EASY_GLOBALS.hex_thread_id, EASY_GLOBALS.time_units); +} + +////////////////////////////////////////////////////////////////////////// + +void EasyTreeWidgetLoader::setTreeInternal1(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units) +{ + m_items.reserve(_blocksNumber + _blocksTree.size()); // _blocksNumber does not include Thread root blocks + + ::profiler::timestamp_t finishtime = 0; + for (const auto& threadTree : _blocksTree) + { + const auto node_block = easyBlocksTree(threadTree.second.children.front()).node; + const auto startTime = node_block->begin(); + const auto endTime = node_block->end(); + + if (_beginTime > startTime) + _beginTime = startTime; + + if (finishtime < endTime) + finishtime = endTime; + } + + //const QSignalBlocker b(this); + const auto u_thread = ::profiler_gui::toUnicode("thread"); + int i = 0; + const int total = static_cast(_blocksTree.size()); + for (const auto& threadTree : _blocksTree) + { + if (interrupted()) + break; + + const auto& root = threadTree.second; + auto item = new EasyTreeWidgetItem(); + item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(_decoratedThreadNames, root, u_thread, _hexThreadId)); + + ::profiler::timestamp_t duration = 0; + if (!root.children.empty()) + duration = easyBlocksTree(root.children.back()).node->end() - easyBlocksTree(root.children.front()).node->begin(); + + item->setTimeSmart(COL_DURATION, _units, duration); + item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND); + + //_items.push_back(item); + + item->setTimeSmart(COL_SELF_DURATION, _units, root.profiled_time); + + ::profiler::timestamp_t children_duration = 0; + const auto children_items_number = setTreeInternal(root, 0, _beginTime, root.children, item, nullptr, + _beginTime, finishtime + 1000000000ULL, false, + children_duration, _addZeroBlocks, _units); + + if (children_items_number > 0) + { + //total_items += children_items_number + 1; + //addTopLevelItem(item); + //m_roots[threadTree.first] = item; + m_topLevelItems.emplace_back(root.thread_id, item); + } + else + { + //_items.pop_back(); + delete item; + } + + setProgress((100 * ++i) / total); + } + + setDone(); + //return total_items; +} + +////////////////////////////////////////////////////////////////////////// + +// auto calculateTotalChildrenNumber(const ::profiler::BlocksTree& _tree) -> decltype(_tree.children.size()) +// { +// auto children_number = _tree.children.size(); +// for (auto i : _tree.children) +// children_number += calculateTotalChildrenNumber(easyBlocksTree(i)); +// return children_number; +// } + +using BeginEndIndicesMap = ::std::unordered_map<::profiler::thread_id_t, ::profiler::block_index_t, + ::estd::hash<::profiler::thread_id_t> >; + +void EasyTreeWidgetLoader::setTreeInternal2(const ::profiler::timestamp_t& _beginTime, + const ::profiler_gui::TreeBlocks& _blocks, + ::profiler::timestamp_t _left, + ::profiler::timestamp_t _right, + bool _strict, + bool _addZeroBlocks, + bool _decoratedThreadNames, + bool _hexThreadId, + ::profiler_gui::TimeUnits _units) +{ + //size_t blocksNumber = 0; + //for (const auto& block : _blocks) + // blocksNumber += calculateTotalChildrenNumber(*block.tree); + // //blocksNumber += block.tree->total_children_number; + //m_items.reserve(blocksNumber + _blocks.size()); // blocksNumber does not include root blocks + + BeginEndIndicesMap beginEndMap; + RootsMap threadsMap; + + auto const setTree = (m_mode == EasyTreeMode_Full) ? &EasyTreeWidgetLoader::setTreeInternal : &EasyTreeWidgetLoader::setTreeInternalPlain; + + const auto u_thread = ::profiler_gui::toUnicode("thread"); + int i = 0, total = static_cast(_blocks.size()); + //const QSignalBlocker b(this); + for (const auto& block : _blocks) + { + if (interrupted()) + break; + + auto& gui_block = easyBlock(block.tree); + const auto startTime = gui_block.tree.node->begin(); + const auto endTime = gui_block.tree.node->end(); + if (startTime > _right || endTime < _left) + { + setProgress((90 * ++i) / total); + continue; + } + + ::profiler::timestamp_t duration = 0; + EasyTreeWidgetItem* thread_item = nullptr; + ::profiler::block_index_t& firstCswitch = beginEndMap[block.root->thread_id]; + auto thread_item_it = threadsMap.find(block.root->thread_id); + if (thread_item_it != threadsMap.end()) + { + thread_item = thread_item_it->second; + } + else + { + thread_item = new EasyTreeWidgetItem(); + thread_item->setText(COL_NAME, ::profiler_gui::decoratedThreadName(_decoratedThreadNames, *block.root, u_thread, _hexThreadId)); + + if (!block.root->children.empty()) + duration = easyBlocksTree(block.root->children.back()).node->end() - easyBlocksTree(block.root->children.front()).node->begin(); + + thread_item->setTimeSmart(COL_DURATION, _units, duration); + thread_item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND); + + // Sum of all children durations: + thread_item->setTimeSmart(COL_SELF_DURATION, _units, block.root->profiled_time); + + threadsMap.insert(::std::make_pair(block.root->thread_id, thread_item)); + + firstCswitch = 0; + auto it = ::std::lower_bound(block.root->sync.begin(), block.root->sync.end(), _left, [](::profiler::block_index_t ind, decltype(_left) _val) + { + return EASY_GLOBALS.gui_blocks[ind].tree.node->begin() < _val; + }); + + if (it != block.root->sync.end()) + { + firstCswitch = it - block.root->sync.begin(); + if (firstCswitch > 0) + --firstCswitch; + } + else + { + firstCswitch = static_cast<::profiler::block_index_t>(block.root->sync.size()); + } + } + + bool hasContextSwitch = false; + ::profiler::timestamp_t idleTime = 0; + for (::profiler::block_index_t ind = firstCswitch, ncs = static_cast<::profiler::block_index_t>(block.root->sync.size()); ind < ncs; ++ind) + { + auto cs_index = block.root->sync[ind]; + const auto cs = EASY_GLOBALS.gui_blocks[cs_index].tree.node; + + if (cs->begin() > endTime) + { + if (!hasContextSwitch) + firstCswitch = ind; + break; + } + + if (startTime <= cs->begin() && cs->end() <= endTime) + { + if (!hasContextSwitch) + { + firstCswitch = ind; + hasContextSwitch = true; + } + + idleTime += cs->duration(); + } + } + + auto item = new EasyTreeWidgetItem(block.tree, thread_item); + duration = endTime - startTime; + + auto name = *gui_block.tree.node->name() != 0 ? gui_block.tree.node->name() : easyDescriptor(gui_block.tree.node->id()).name(); + item->setText(COL_NAME, ::profiler_gui::toUnicode(name)); + item->setTimeSmart(COL_DURATION, _units, duration); + + auto active_time = duration - idleTime; + auto active_percent = duration == 0 ? 100. : ::profiler_gui::percentReal(active_time, duration); + item->setTimeSmart(COL_ACTIVE_TIME, _units, active_time); + item->setText(COL_ACTIVE_PERCENT, QString::number(active_percent, 'g', 3)); + item->setData(COL_ACTIVE_PERCENT, Qt::UserRole, active_percent); + + item->setTimeMs(COL_BEGIN, startTime - _beginTime); + item->setTimeMs(COL_END, endTime - _beginTime); + + item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0); + + auto percentage_per_thread = ::profiler_gui::percent(duration, block.root->profiled_time); + item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread); + item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread)); + + if (gui_block.tree.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also + { + const ::profiler::BlockStatistics* per_thread_stats = gui_block.tree.per_thread_stats; + const ::profiler::BlockStatistics* per_parent_stats = gui_block.tree.per_parent_stats; + const ::profiler::BlockStatistics* per_frame_stats = gui_block.tree.per_frame_stats; + + + if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_THREAD, _units, easyBlock(per_thread_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_THREAD, _units, easyBlock(per_thread_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_THREAD, _units, per_thread_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, _units, per_thread_stats->total_duration); + } + + item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number); + item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number)); + + percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, block.root->profiled_time); + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread); + item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread)); + + + if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_PARENT, _units, easyBlock(per_parent_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_PARENT, _units, easyBlock(per_parent_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_PARENT, _units, per_parent_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, _units, per_parent_stats->total_duration); + } + + item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, per_parent_stats->calls_number); + item->setText(COL_NCALLS_PER_PARENT, QString::number(per_parent_stats->calls_number)); + + + if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_FRAME, _units, easyBlock(per_frame_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_FRAME, _units, easyBlock(per_frame_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_FRAME, _units, per_frame_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, _units, per_frame_stats->total_duration); + } + + item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number); + item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number)); + } + else + { + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0); + item->setText(COL_PERCENT_SUM_PER_THREAD, ""); + } + + const auto color = easyDescriptor(gui_block.tree.node->id()).color(); + item->setBackgroundColor(color); + +#ifdef EASY_TREE_WIDGET__USE_VECTOR + auto item_index = static_cast(m_items.size()); + m_items.push_back(item); +#endif + + size_t children_items_number = 0; + ::profiler::timestamp_t children_duration = 0; + if (!gui_block.tree.children.empty()) + { + m_iditems.clear(); + + children_items_number = (this->*setTree)(*block.root, firstCswitch, _beginTime, gui_block.tree.children, + item, item, _left, _right, _strict, children_duration, + _addZeroBlocks, _units); + + if (interrupted()) + break; + } + + int percentage = 100; + auto self_duration = duration - children_duration; + if (children_duration > 0 && duration > 0) + { + percentage = static_cast(0.5 + 100. * static_cast(self_duration) / static_cast(duration)); + } + + item->setTimeSmart(COL_SELF_DURATION, _units, self_duration); + item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage); + item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage)); + + if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right)) + { + //total_items += children_items_number + 1; +#ifdef EASY_TREE_WIDGET__USE_VECTOR + gui_block.tree_item = item_index; +#endif + + if (gui_block.expanded) + item->setExpanded(true); + +#ifndef EASY_TREE_WIDGET__USE_VECTOR + m_items.insert(::std::make_pair(block.tree, item)); +#endif + } + else + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + m_items.pop_back(); +#endif + delete item; + } + + setProgress((90 * ++i) / total); + } + + i = 0; + total = static_cast(threadsMap.size()); + for (auto& it : threadsMap) + { + auto item = it.second; + + if (item->childCount() > 0) + { + //addTopLevelItem(item); + //m_roots[it.first] = item; + + //_items.push_back(item); + m_topLevelItems.emplace_back(it.first, item); + + //++total_items; + } + else + { + delete item; + } + + setProgress(90 + (10 * ++i) / total); + } + + setDone(); + //return total_items; +} + +////////////////////////////////////////////////////////////////////////// + +size_t EasyTreeWidgetLoader::setTreeInternal(const ::profiler::BlocksTreeRoot& _threadRoot, + ::profiler::block_index_t _firstCswitch, + const ::profiler::timestamp_t& _beginTime, + const ::profiler::BlocksTree::children_t& _children, + EasyTreeWidgetItem* _parent, + EasyTreeWidgetItem* _frame, + ::profiler::timestamp_t _left, + ::profiler::timestamp_t _right, + bool _strict, + ::profiler::timestamp_t& _duration, + bool _addZeroBlocks, + ::profiler_gui::TimeUnits _units) +{ + auto const setTree = m_mode == EasyTreeMode_Full ? &EasyTreeWidgetLoader::setTreeInternal : &EasyTreeWidgetLoader::setTreeInternalPlain; + + size_t total_items = 0; + for (auto child_index : _children) + { + if (interrupted()) + break; + + auto& gui_block = easyBlock(child_index); + const auto& child = gui_block.tree; + const auto startTime = child.node->begin(); + const auto endTime = child.node->end(); + const auto duration = endTime - startTime; + + if (duration == 0 && !_addZeroBlocks) + continue; + + _duration += duration; + + if (startTime > _right || endTime < _left) + continue; + + bool hasContextSwitch = false; + ::profiler::timestamp_t idleTime = 0; + for (::profiler::block_index_t ind = _firstCswitch, ncs = static_cast<::profiler::block_index_t>(_threadRoot.sync.size()); ind < ncs; ++ind) + { + auto cs_index = _threadRoot.sync[ind]; + const auto cs = EASY_GLOBALS.gui_blocks[cs_index].tree.node; + + if (cs->begin() > endTime) + { + if (!hasContextSwitch) + _firstCswitch = ind; + break; + } + + if (startTime <= cs->begin() && cs->end() <= endTime) + { + if (!hasContextSwitch) + { + _firstCswitch = ind; + hasContextSwitch = true; + } + + idleTime += cs->duration(); + } + } + + auto item = new EasyTreeWidgetItem(child_index, _parent); + + auto name = *child.node->name() != 0 ? child.node->name() : easyDescriptor(child.node->id()).name(); + item->setText(COL_NAME, ::profiler_gui::toUnicode(name)); + item->setTimeSmart(COL_DURATION, _units, duration); + + auto active_time = duration - idleTime; + auto active_percent = duration == 0 ? 100. : ::profiler_gui::percentReal(active_time, duration); + item->setTimeSmart(COL_ACTIVE_TIME, _units, active_time); + item->setText(COL_ACTIVE_PERCENT, QString::number(active_percent, 'g', 3)); + item->setData(COL_ACTIVE_PERCENT, Qt::UserRole, active_percent); + + item->setTimeMs(COL_BEGIN, startTime - _beginTime); + item->setTimeMs(COL_END, endTime - _beginTime); + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0); + + if (child.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also + { + const ::profiler::BlockStatistics* per_thread_stats = child.per_thread_stats; + const ::profiler::BlockStatistics* per_parent_stats = child.per_parent_stats; + const ::profiler::BlockStatistics* per_frame_stats = child.per_frame_stats; + + auto parent_duration = _parent->duration(); + auto percentage = duration == 0 ? 0 : ::profiler_gui::percent(duration, parent_duration); + auto percentage_sum = ::profiler_gui::percent(per_parent_stats->total_duration, parent_duration); + item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage); + item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage)); + item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, percentage_sum); + item->setText(COL_PERCENT_SUM_PER_PARENT, QString::number(percentage_sum)); + + if (_frame != nullptr) + { + if (_parent != _frame) + { + parent_duration = _frame->duration(); + percentage = duration == 0 ? 0 : ::profiler_gui::percent(duration, parent_duration); + percentage_sum = ::profiler_gui::percent(per_frame_stats->total_duration, parent_duration); + } + + item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, percentage); + item->setText(COL_PERCENT_PER_FRAME, QString::number(percentage)); + item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, percentage_sum); + item->setText(COL_PERCENT_SUM_PER_FRAME, QString::number(percentage_sum)); + } + else + { + item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0); + item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, 0); + + auto percentage_per_thread = ::profiler_gui::percent(duration, _threadRoot.profiled_time); + item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread); + item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread)); + } + + + if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_THREAD, _units, easyBlock(per_thread_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_THREAD, _units, easyBlock(per_thread_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_THREAD, _units, per_thread_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, _units, per_thread_stats->total_duration); + } + + item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number); + item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number)); + + auto percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, _threadRoot.profiled_time); + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread); + item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread)); + + + if (per_parent_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_PARENT, _units, easyBlock(per_parent_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_PARENT, _units, easyBlock(per_parent_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_PARENT, _units, per_parent_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_PARENT, _units, per_parent_stats->total_duration); + } + + item->setData(COL_NCALLS_PER_PARENT, Qt::UserRole, per_parent_stats->calls_number); + item->setText(COL_NCALLS_PER_PARENT, QString::number(per_parent_stats->calls_number)); + + + if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_FRAME, _units, easyBlock(per_frame_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_FRAME, _units, easyBlock(per_frame_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_FRAME, _units, per_frame_stats->average_duration()); + item->setTimeSmart(COL_DURATION_SUM_PER_FRAME, _units, per_frame_stats->total_duration); + } + + item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number); + item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number)); + } + else + { + if (_frame == nullptr) + { + auto percentage_per_thread = ::profiler_gui::percent(duration, _threadRoot.profiled_time); + item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread); + item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread)); + } + else + { + item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0); + } + + item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, 0); + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0); + } + + const auto color = easyDescriptor(child.node->id()).color(); + item->setBackgroundColor(color); + +#ifdef EASY_TREE_WIDGET__USE_VECTOR + auto item_index = static_cast(m_items.size()); + m_items.push_back(item); +#endif + + size_t children_items_number = 0; + ::profiler::timestamp_t children_duration = 0; + if (!child.children.empty()) + { + m_iditems.clear(); + + children_items_number = (this->*setTree)(_threadRoot, _firstCswitch, _beginTime, child.children, item, + _frame ? _frame : item, _left, _right, _strict, children_duration, + _addZeroBlocks, _units); + + if (interrupted()) + break; + } + + int percentage = 100; + auto self_duration = duration - children_duration; + if (children_duration > 0 && duration > 0) + { + percentage = ::profiler_gui::percent(self_duration, duration); + } + + item->setTimeSmart(COL_SELF_DURATION, _units, self_duration); + item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage); + item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage)); + + if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right)) + { + total_items += children_items_number + 1; +#ifdef EASY_TREE_WIDGET__USE_VECTOR + gui_block.tree_item = item_index; +#endif + + if (gui_block.expanded) + item->setExpanded(true); + +#ifndef EASY_TREE_WIDGET__USE_VECTOR + m_items.insert(::std::make_pair(child_index, item)); +#endif + } + else + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + m_items.pop_back(); +#endif + delete item; + } + } + + return total_items; +} + +////////////////////////////////////////////////////////////////////////// + +::profiler::timestamp_t EasyTreeWidgetLoader::calculateChildrenDurationRecursive(const ::profiler::BlocksTree::children_t& _children, ::profiler::block_id_t _id) +{ + ::profiler::timestamp_t total_duration = 0; + + for (auto child_index : _children) + { + if (interrupted()) + break; + + const auto& gui_block = easyBlock(child_index); + total_duration += gui_block.tree.node->duration(); + if (gui_block.tree.node->id() == _id) + total_duration += calculateChildrenDurationRecursive(gui_block.tree.children, _id); + } + + return total_duration; +} + +size_t EasyTreeWidgetLoader::setTreeInternalPlain(const ::profiler::BlocksTreeRoot& _threadRoot, + ::profiler::block_index_t _firstCswitch, + const ::profiler::timestamp_t& _beginTime, + const ::profiler::BlocksTree::children_t& _children, + EasyTreeWidgetItem*, + EasyTreeWidgetItem* _frame, + ::profiler::timestamp_t _left, + ::profiler::timestamp_t _right, + bool _strict, + ::profiler::timestamp_t& _duration, + bool _addZeroBlocks, + ::profiler_gui::TimeUnits _units) +{ + size_t total_items = 0; + + for (auto child_index : _children) + { + if (interrupted()) + break; + + const auto& gui_block = easyBlock(child_index); + const auto& child = gui_block.tree; + const auto startTime = child.node->begin(); + const auto endTime = child.node->end(); + const auto duration = endTime - startTime; + + _duration += duration; + + auto it = m_iditems.find(child.node->id()); + if (it != m_iditems.end()) + { + ++total_items; + + ::profiler::timestamp_t children_duration = 0; + if (!child.children.empty()) + { + setTreeInternalPlain(_threadRoot, _firstCswitch, _beginTime, child.children, _frame, _frame, _left, + _right, _strict, children_duration, _addZeroBlocks, _units); + + if (interrupted()) + break; + } + + if (it->second != nullptr && child.per_frame_stats != nullptr) + { + auto item = it->second; + + //auto children_duration = calculateChildrenDurationRecursive(child.children, it->first); + if (children_duration != 0) + { + auto self_duration = item->data(COL_SELF_DURATION, Qt::UserRole).toULongLong() - children_duration; + + int percentage = 100; + if (child.per_frame_stats->total_duration > 0) + percentage = ::profiler_gui::percent(self_duration, child.per_frame_stats->total_duration); + + item->setTimeSmart(COL_SELF_DURATION, _units, self_duration); + item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage); + item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage)); + } + + bool hasContextSwitch = false; + ::profiler::timestamp_t idleTime = 0; + for (::profiler::block_index_t ind = _firstCswitch, ncs = static_cast<::profiler::block_index_t>(_threadRoot.sync.size()); ind < ncs; ++ind) + { + auto cs_index = _threadRoot.sync[ind]; + const auto cs = EASY_GLOBALS.gui_blocks[cs_index].tree.node; + + if (cs->begin() > endTime) + { + if (!hasContextSwitch) + _firstCswitch = ind; + break; + } + + if (startTime <= cs->begin() && cs->end() <= endTime) + { + if (!hasContextSwitch) + { + _firstCswitch = ind; + hasContextSwitch = true; + } + + idleTime += cs->duration(); + } + } + + auto active_time = item->data(COL_ACTIVE_TIME, Qt::UserRole).toULongLong() - idleTime; + auto active_percent = child.per_frame_stats->total_duration == 0 ? 100. : ::profiler_gui::percentReal(active_time, child.per_frame_stats->total_duration); + item->setTimeSmart(COL_ACTIVE_TIME, _units, active_time); + item->setText(COL_ACTIVE_PERCENT, QString::number(active_percent, 'g', 3)); + item->setData(COL_ACTIVE_PERCENT, Qt::UserRole, active_percent); + } + + continue; + } + + if (startTime > _right || endTime < _left) + continue; + + bool hasContextSwitch = false; + ::profiler::timestamp_t idleTime = 0; + for (::profiler::block_index_t ind = _firstCswitch, ncs = static_cast<::profiler::block_index_t>(_threadRoot.sync.size()); ind < ncs; ++ind) + { + auto cs_index = _threadRoot.sync[ind]; + const auto cs = EASY_GLOBALS.gui_blocks[cs_index].tree.node; + + if (cs->begin() > endTime) + { + if (!hasContextSwitch) + _firstCswitch = ind; + break; + } + + if (startTime <= cs->begin() && cs->end() <= endTime) + { + if (!hasContextSwitch) + { + _firstCswitch = ind; + hasContextSwitch = true; + } + + idleTime += cs->duration(); + } + } + + auto item = new EasyTreeWidgetItem(child_index, _frame); + + auto name = *child.node->name() != 0 ? child.node->name() : easyDescriptor(child.node->id()).name(); + item->setText(COL_NAME, ::profiler_gui::toUnicode(name)); + + if (child.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also + { + const ::profiler::BlockStatistics* per_thread_stats = child.per_thread_stats; + if (per_thread_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_THREAD, _units, easyBlock(per_thread_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_THREAD, _units, easyBlock(per_thread_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_THREAD, _units, per_thread_stats->average_duration()); + } + + item->setTimeSmart(COL_DURATION_SUM_PER_THREAD, _units, per_thread_stats->total_duration); + item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number); + item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number)); + + auto percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, _threadRoot.profiled_time); + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread); + item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread)); + + const ::profiler::BlockStatistics* per_frame_stats = child.per_frame_stats; + const auto percentage_sum = ::profiler_gui::percent(per_frame_stats->total_duration, _frame->duration()); + item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, percentage_sum); + item->setText(COL_PERCENT_PER_FRAME, QString::number(percentage_sum)); + + if (per_frame_stats->calls_number > 1 || !EASY_GLOBALS.display_only_relevant_stats) + { + item->setTimeSmart(COL_MIN_PER_FRAME, _units, easyBlock(per_frame_stats->min_duration_block).tree.node->duration()); + item->setTimeSmart(COL_MAX_PER_FRAME, _units, easyBlock(per_frame_stats->max_duration_block).tree.node->duration()); + item->setTimeSmart(COL_AVERAGE_PER_FRAME, _units, per_frame_stats->average_duration()); + } + + item->setTimeSmart(COL_DURATION, _units, per_frame_stats->total_duration); + item->setData(COL_NCALLS_PER_FRAME, Qt::UserRole, per_frame_stats->calls_number); + item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number)); + } + else + { + item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0); + item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0); + } + + const auto color = easyDescriptor(child.node->id()).color(); + item->setBackgroundColor(color); + +#ifdef EASY_TREE_WIDGET__USE_VECTOR + auto item_index = static_cast(m_items.size()); + m_items.push_back(item); +#endif + m_iditems[child.node->id()] = nullptr; + + size_t children_items_number = 0; + ::profiler::timestamp_t children_duration = 0; + if (!child.children.empty()) + { + children_items_number = setTreeInternalPlain(_threadRoot, _firstCswitch, _beginTime, child.children, _frame, + _frame, _left, _right, _strict, children_duration, + _addZeroBlocks, _units); + + if (interrupted()) + break; + } + + m_iditems[child.node->id()] = item; + + if (child.per_frame_stats != nullptr) + { + int percentage = 100; + auto self_duration = child.per_frame_stats->total_duration - children_duration; + if (child.per_frame_stats->total_duration > 0) + percentage = ::profiler_gui::percent(self_duration, child.per_frame_stats->total_duration); + + item->setTimeSmart(COL_SELF_DURATION, _units, self_duration); + item->setData(COL_SELF_DURATION_PERCENT, Qt::UserRole, percentage); + item->setText(COL_SELF_DURATION_PERCENT, QString::number(percentage)); + + auto active_time = child.per_frame_stats->total_duration - idleTime; + auto active_percent = child.per_frame_stats->total_duration == 0 ? 100. : ::profiler_gui::percentReal(active_time, child.per_frame_stats->total_duration); + item->setTimeSmart(COL_ACTIVE_TIME, _units, active_time); + item->setText(COL_ACTIVE_PERCENT, QString::number(active_percent, 'g', 3)); + item->setData(COL_ACTIVE_PERCENT, Qt::UserRole, active_percent); + } + + if (children_items_number > 0 || !_strict || (startTime >= _left && endTime <= _right)) + { + total_items += children_items_number + 1; +#ifdef EASY_TREE_WIDGET__USE_VECTOR + gui_block.tree_item = item_index; +#endif + + if (gui_block.expanded) + item->setExpanded(true); + +#ifndef EASY_TREE_WIDGET__USE_VECTOR + m_items.insert(::std::make_pair(child_index, item)); +#endif + } + else + { +#ifdef EASY_TREE_WIDGET__USE_VECTOR + m_items.pop_back(); +#endif + delete item; + m_iditems.erase(gui_block.tree.node->id()); + } + } + + return total_items; +} + +////////////////////////////////////////////////////////////////////////// diff --git a/3rdparty/easyprofiler/profiler_gui/tree_widget_loader.h b/3rdparty/easyprofiler/profiler_gui/tree_widget_loader.h new file mode 100644 index 0000000..5e0dc09 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/tree_widget_loader.h @@ -0,0 +1,134 @@ +/************************************************************************ +* file name : tree_widget_loader.h +* ----------------- : +* creation time : 2016/08/18 +* author : Victor Zarubkin +* email : v.s.zarubkin@gmail.com +* ----------------- : +* description : The file contains declaration of EasyTreeWidgetLoader which aim is +* : to load EasyProfiler blocks hierarchy in separate thread. +* ----------------- : +* change log : * 2016/08/18 Victor Zarubkin: moved sources from blocks_tree_widget.h/.cpp +* : and renamed Prof* to Easy*. +* : +* : * +* ----------------- : +* license : Lightweight profiler library for c++ +* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin +* : +* : Licensed under either of +* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) +* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +* : at your option. +* : +* : The MIT License +* : +* : Permission is hereby granted, free of charge, to any person obtaining a copy +* : of this software and associated documentation files (the "Software"), to deal +* : in the Software without restriction, including without limitation the rights +* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* : of the Software, and to permit persons to whom the Software is furnished +* : to do so, subject to the following conditions: +* : +* : The above copyright notice and this permission notice shall be included in all +* : copies or substantial portions of the Software. +* : +* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +* : USE OR OTHER DEALINGS IN THE SOFTWARE. +* : +* : The Apache License, Version 2.0 (the "License") +* : +* : You may not use this file except in compliance with the License. +* : You may obtain a copy of the License at +* : +* : http://www.apache.org/licenses/LICENSE-2.0 +* : +* : Unless required by applicable law or agreed to in writing, software +* : distributed under the License is distributed on an "AS IS" BASIS, +* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* : See the License for the specific language governing permissions and +* : limitations under the License. +************************************************************************/ + +#ifndef EASY_TREE_WIDGET_LOADER_H +#define EASY_TREE_WIDGET_LOADER_H + +#include +#include +#include +#include +#include +#include "common_types.h" + +////////////////////////////////////////////////////////////////////////// + +class EasyTreeWidgetItem; + +#ifndef EASY_TREE_WIDGET__USE_VECTOR +using Items = ::std::unordered_map<::profiler::block_index_t, EasyTreeWidgetItem*, ::estd::hash<::profiler::block_index_t> >; +#else +using Items = ::std::vector; +#endif + +using ThreadedItems = ::std::vector<::std::pair<::profiler::thread_id_t, EasyTreeWidgetItem*> >; +using RootsMap = ::std::unordered_map<::profiler::thread_id_t, EasyTreeWidgetItem*, ::estd::hash<::profiler::thread_id_t> >; +using IdItems = ::std::unordered_map<::profiler::block_id_t, EasyTreeWidgetItem*, ::estd::hash<::profiler::block_index_t> >; + +////////////////////////////////////////////////////////////////////////// + +enum EasyTreeMode : uint8_t +{ + EasyTreeMode_Full, + EasyTreeMode_Plain +}; + +////////////////////////////////////////////////////////////////////////// + +class EasyTreeWidgetLoader Q_DECL_FINAL +{ + ThreadedItems m_topLevelItems; ///< + Items m_items; ///< + IdItems m_iditems; ///< + ::std::thread m_thread; ///< + ::std::atomic_bool m_bDone; ///< + ::std::atomic_bool m_bInterrupt; ///< + ::std::atomic m_progress; ///< + EasyTreeMode m_mode; ///< + +public: + + EasyTreeWidgetLoader(); + ~EasyTreeWidgetLoader(); + + int progress() const; + bool done() const; + + void takeTopLevelItems(ThreadedItems& _output); + void takeItems(Items& _output); + + void interrupt(bool _wait = false); + void fillTree(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, EasyTreeMode _mode); + void fillTreeBlocks(const::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _beginTime, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, EasyTreeMode _mode); + +private: + + bool interrupted() const; + void setDone(); + void setProgress(int _progress); + + void setTreeInternal1(::profiler::timestamp_t& _beginTime, const unsigned int _blocksNumber, const ::profiler::thread_blocks_tree_t& _blocksTree, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units); + void setTreeInternal2(const ::profiler::timestamp_t& _beginTime, const ::profiler_gui::TreeBlocks& _blocks, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, bool _addZeroBlocks, bool _decoratedThreadNames, bool _hexThreadId, ::profiler_gui::TimeUnits _units); + size_t setTreeInternal(const ::profiler::BlocksTreeRoot& _threadRoot, ::profiler::block_index_t _firstCswitch, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units); + size_t setTreeInternalPlain(const ::profiler::BlocksTreeRoot& _threadRoot, ::profiler::block_index_t _firstCswitch, const ::profiler::timestamp_t& _beginTime, const ::profiler::BlocksTree::children_t& _children, EasyTreeWidgetItem* _parent, EasyTreeWidgetItem* _frame, ::profiler::timestamp_t _left, ::profiler::timestamp_t _right, bool _strict, ::profiler::timestamp_t& _duration, bool _addZeroBlocks, ::profiler_gui::TimeUnits _units); + + ::profiler::timestamp_t calculateChildrenDurationRecursive(const ::profiler::BlocksTree::children_t& _children, ::profiler::block_id_t _id); + +}; // END of class EasyTreeWidgetLoader. + +////////////////////////////////////////////////////////////////////////// + +#endif // EASY_TREE_WIDGET_LOADER_H diff --git a/3rdparty/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp b/3rdparty/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp new file mode 100644 index 0000000..bc61555 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/treeview_first_column_delegate.cpp @@ -0,0 +1,33 @@ + + +#include +#include +#include "treeview_first_column_delegate.h" +#include "globals.h" + +EasyTreeViewFirstColumnItemDelegate::EasyTreeViewFirstColumnItemDelegate(QObject* parent) : QStyledItemDelegate(parent) +{ + +} + +EasyTreeViewFirstColumnItemDelegate::~EasyTreeViewFirstColumnItemDelegate() +{ + +} + +void EasyTreeViewFirstColumnItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + // Draw item as usual + QStyledItemDelegate::paint(painter, option, index); + + // Draw line under tree indicator + const auto bottomLeft = option.rect.bottomLeft(); + if (bottomLeft.x() > 0) + { + painter->save(); + painter->setBrush(Qt::NoBrush); + painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR); + painter->drawLine(QPoint(0, bottomLeft.y()), bottomLeft); + painter->restore(); + } +} \ No newline at end of file diff --git a/3rdparty/easyprofiler/profiler_gui/treeview_first_column_delegate.h b/3rdparty/easyprofiler/profiler_gui/treeview_first_column_delegate.h new file mode 100644 index 0000000..d55c056 --- /dev/null +++ b/3rdparty/easyprofiler/profiler_gui/treeview_first_column_delegate.h @@ -0,0 +1,23 @@ + + + + + +#ifndef EASY_PROFILER_GUI_TREEVIEW_FIRST_COLUMN_DELEGATE_H +#define EASY_PROFILER_GUI_TREEVIEW_FIRST_COLUMN_DELEGATE_H + +#include + +class EasyTreeViewFirstColumnItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + + explicit EasyTreeViewFirstColumnItemDelegate(QObject* parent = nullptr); + ~EasyTreeViewFirstColumnItemDelegate() override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + +}; // END of class EasyTreeViewFirstColumnItemDelegate. + +#endif // EASY_PROFILER_GUI_TREEVIEW_FIRST_COLUMN_DELEGATE_H diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/CMakeDirectoryInformation.cmake b/3rdparty/easyprofiler/reader/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..9ecfcf5 --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/alex/Work/C++Projects/easyprofiler") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/alex/Work/C++Projects/easyprofiler") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/DependInfo.cmake b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/DependInfo.cmake new file mode 100644 index 0000000..235700c --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/DependInfo.cmake @@ -0,0 +1,31 @@ +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +set(CMAKE_DEPENDS_CHECK_CXX + "/home/alex/Work/C++Projects/easyprofiler/reader/main.cpp" "/home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/profiler_reader.dir/main.cpp.o" + ) +set(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +set(CMAKE_TARGET_DEFINITIONS_CXX + "BUILD_WITH_EASY_PROFILER=1" + "EASY_DEFAULT_PORT=28077" + "EASY_PROFILER_VERSION_MAJOR=1" + "EASY_PROFILER_VERSION_MINOR=3" + "EASY_PROFILER_VERSION_PATCH=0" + ) + +# The include file search paths: +set(CMAKE_CXX_TARGET_INCLUDE_PATH + "easy_profiler_core/include" + ) + +# Targets to which this target links. +set(CMAKE_TARGET_LINKED_INFO_FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake" + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/build.make b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/build.make new file mode 100644 index 0000000..604c854 --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/build.make @@ -0,0 +1,114 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/alex/Work/C++Projects/easyprofiler + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/alex/Work/C++Projects/easyprofiler + +# Include any dependencies generated for this target. +include reader/CMakeFiles/profiler_reader.dir/depend.make + +# Include the progress variables for this target. +include reader/CMakeFiles/profiler_reader.dir/progress.make + +# Include the compile flags for this target's objects. +include reader/CMakeFiles/profiler_reader.dir/flags.make + +reader/CMakeFiles/profiler_reader.dir/main.cpp.o: reader/CMakeFiles/profiler_reader.dir/flags.make +reader/CMakeFiles/profiler_reader.dir/main.cpp.o: reader/main.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object reader/CMakeFiles/profiler_reader.dir/main.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/reader && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_reader.dir/main.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/reader/main.cpp + +reader/CMakeFiles/profiler_reader.dir/main.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_reader.dir/main.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/reader && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/reader/main.cpp > CMakeFiles/profiler_reader.dir/main.cpp.i + +reader/CMakeFiles/profiler_reader.dir/main.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_reader.dir/main.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/reader && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/reader/main.cpp -o CMakeFiles/profiler_reader.dir/main.cpp.s + +reader/CMakeFiles/profiler_reader.dir/main.cpp.o.requires: + +.PHONY : reader/CMakeFiles/profiler_reader.dir/main.cpp.o.requires + +reader/CMakeFiles/profiler_reader.dir/main.cpp.o.provides: reader/CMakeFiles/profiler_reader.dir/main.cpp.o.requires + $(MAKE) -f reader/CMakeFiles/profiler_reader.dir/build.make reader/CMakeFiles/profiler_reader.dir/main.cpp.o.provides.build +.PHONY : reader/CMakeFiles/profiler_reader.dir/main.cpp.o.provides + +reader/CMakeFiles/profiler_reader.dir/main.cpp.o.provides.build: reader/CMakeFiles/profiler_reader.dir/main.cpp.o + + +# Object files for target profiler_reader +profiler_reader_OBJECTS = \ +"CMakeFiles/profiler_reader.dir/main.cpp.o" + +# External object files for target profiler_reader +profiler_reader_EXTERNAL_OBJECTS = + +bin/profiler_reader: reader/CMakeFiles/profiler_reader.dir/main.cpp.o +bin/profiler_reader: reader/CMakeFiles/profiler_reader.dir/build.make +bin/profiler_reader: bin/libeasy_profiler.so +bin/profiler_reader: reader/CMakeFiles/profiler_reader.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable ../bin/profiler_reader" + cd /home/alex/Work/C++Projects/easyprofiler/reader && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profiler_reader.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +reader/CMakeFiles/profiler_reader.dir/build: bin/profiler_reader + +.PHONY : reader/CMakeFiles/profiler_reader.dir/build + +reader/CMakeFiles/profiler_reader.dir/requires: reader/CMakeFiles/profiler_reader.dir/main.cpp.o.requires + +.PHONY : reader/CMakeFiles/profiler_reader.dir/requires + +reader/CMakeFiles/profiler_reader.dir/clean: + cd /home/alex/Work/C++Projects/easyprofiler/reader && $(CMAKE_COMMAND) -P CMakeFiles/profiler_reader.dir/cmake_clean.cmake +.PHONY : reader/CMakeFiles/profiler_reader.dir/clean + +reader/CMakeFiles/profiler_reader.dir/depend: + cd /home/alex/Work/C++Projects/easyprofiler && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/reader /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/reader /home/alex/Work/C++Projects/easyprofiler/reader/CMakeFiles/profiler_reader.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : reader/CMakeFiles/profiler_reader.dir/depend + diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/cmake_clean.cmake b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/cmake_clean.cmake new file mode 100644 index 0000000..93ff1ac --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +file(REMOVE_RECURSE + "CMakeFiles/profiler_reader.dir/main.cpp.o" + "../bin/profiler_reader.pdb" + "../bin/profiler_reader" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profiler_reader.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/depend.make b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/depend.make new file mode 100644 index 0000000..e5f4bcd --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profiler_reader. +# This may be replaced when dependencies are built. diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/flags.make b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/flags.make new file mode 100644 index 0000000..a02c938 --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -O3 -DNDEBUG -DEASY_CHRONO_STEADY_CLOCK=0 -DEASY_CHRONO_HIGHRES_CLOCK=0 -DEASY_OPTION_START_LISTEN_ON_STARTUP=0 -DEASY_OPTION_MEASURE_STORAGE_EXPAND=0 -DEASY_OPTION_STORAGE_EXPAND_BLOCKS_ON=0 -DEASY_OPTION_IMPLICIT_THREAD_REGISTRATION=1 -DEASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS=0 -DEASY_OPTION_LOG_ENABLED=0 -DEASY_OPTION_PRETTY_PRINT_FUNCTIONS=0 -DEASY_OPTION_BUILTIN_COLORS=1 -std=gnu++11 + +CXX_DEFINES = -DBUILD_WITH_EASY_PROFILER=1 -DEASY_DEFAULT_PORT=28077 -DEASY_PROFILER_VERSION_MAJOR=1 -DEASY_PROFILER_VERSION_MINOR=3 -DEASY_PROFILER_VERSION_PATCH=0 + +CXX_INCLUDES = -I/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include + diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/link.txt b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/link.txt new file mode 100644 index 0000000..73eee0f --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/profiler_reader.dir/main.cpp.o -o ../bin/profiler_reader -rdynamic ../bin/libeasy_profiler.so -lpthread -Wl,-rpath,/home/alex/Work/C++Projects/easyprofiler/bin diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/progress.make b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/progress.make new file mode 100644 index 0000000..335ef43 --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/profiler_reader.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 30 +CMAKE_PROGRESS_2 = 31 + diff --git a/3rdparty/easyprofiler/reader/CMakeFiles/progress.marks b/3rdparty/easyprofiler/reader/CMakeFiles/progress.marks new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeFiles/progress.marks @@ -0,0 +1 @@ +10 diff --git a/3rdparty/easyprofiler/reader/CMakeLists.txt b/3rdparty/easyprofiler/reader/CMakeLists.txt new file mode 100644 index 0000000..903c910 --- /dev/null +++ b/3rdparty/easyprofiler/reader/CMakeLists.txt @@ -0,0 +1,3 @@ + +add_executable(profiler_reader main.cpp) +target_link_libraries(profiler_reader easy_profiler) diff --git a/3rdparty/easyprofiler/reader/cmake_install.cmake b/3rdparty/easyprofiler/reader/cmake_install.cmake new file mode 100644 index 0000000..bf2dcfa --- /dev/null +++ b/3rdparty/easyprofiler/reader/cmake_install.cmake @@ -0,0 +1,34 @@ +# Install script for directory: /home/alex/Work/C++Projects/easyprofiler/reader + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + diff --git a/3rdparty/easyprofiler/reader/main.cpp b/3rdparty/easyprofiler/reader/main.cpp new file mode 100644 index 0000000..34a9360 --- /dev/null +++ b/3rdparty/easyprofiler/reader/main.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TreePrinter +{ + struct Info{ + std::string name; + std::string info; + }; + std::vector m_rows; + +public: + TreePrinter(){ + + } + void addNewRow(int level) + { + + } + + void printTree() + { + for (auto& row : m_rows){ + std::cout << row.name << " " << row.info << std::endl; + } + } +}; + + +void printTree(TreePrinter& printer, const ::profiler::BlocksTree& tree, int level = 0, profiler::timestamp_t parent_dur = 0, profiler::timestamp_t root_dur = 0) +{ + // + //if (tree.node){ + // auto duration = tree.node->block()->duration(); + // float duration_ms = duration / 1e6f; + // float percent = parent_dur ? float(duration) / float(parent_dur)*100.0f : 100.0f; + // float rpercent = root_dur ? float(duration) / float(root_dur)*100.0f : 100.0f; + // std::cout << std::string(level, '\t') << tree.node->getName() + // << std::string(5 - level, '\t') + // /*<< std::string(level, ' ')*/ << percent << "%| " + // << rpercent << "%| " + // << duration_ms << " ms" + // << std::endl; + // if (root_dur == 0){ + // root_dur = tree.node->block()->duration(); + // } + //} + //else{ + // root_dur = 0; + //} + // + + //for (const auto& i : tree.children){ + + // printTree(printer, i, level + 1, tree.node ? tree.node->block()->duration() : 0, root_dur); + //} +} + +int main(int argc, char* argv[]) +{ + + ::profiler::thread_blocks_tree_t threaded_trees; + + ::std::string filename;// = "test.prof"; + if (argc > 1 && argv[1]) + { + filename = argv[1]; + } + else + { + std::cout << "Specify prof file: "; + std::getline(std::cin, filename); + //return 255; + } + + ::std::string dump_filename; + if (argc > 2 && argv[2]) + { + dump_filename = argv[2]; + } + else + { + std::cout << "Specify output prof file: "; + std::getline(std::cin, dump_filename); + } + + if (dump_filename.size() > 2) + { + EASY_PROFILER_ENABLE; + std::cout << "Will dump reader prof file to " << dump_filename << std::endl; + } + else + { + dump_filename.clear(); + } + + + auto start = std::chrono::system_clock::now(); + + ::profiler::SerializedData serialized_blocks, serialized_descriptors; + ::profiler::descriptors_list_t descriptors; + ::profiler::blocks_t blocks; + ::std::stringstream errorMessage; + uint32_t descriptorsNumberInFile = 0; + uint32_t version = 0; + auto blocks_counter = fillTreesFromFile(filename.c_str(), serialized_blocks, serialized_descriptors, descriptors, blocks, + threaded_trees, descriptorsNumberInFile, version, true, errorMessage); + if (blocks_counter == 0) + std::cout << "Can not read blocks from file " << filename.c_str() << "\nReason: " << errorMessage.str(); + + auto end = std::chrono::system_clock::now(); + + std::cout << "Blocks count: " << blocks_counter << std::endl; + std::cout << "dT = " << std::chrono::duration_cast(end - start).count() << " usec" << std::endl; + //for (const auto & i : threaded_trees){ + // TreePrinter p; + // std::cout << std::string(20, '=') << " thread "<< i.first << " "<< std::string(20, '=') << std::endl; + // printTree(p, i.second.tree,-1); + //} + + if (!dump_filename.empty()) + { + auto bcount = profiler::dumpBlocksToFile(dump_filename.c_str()); + + std::cout << "Blocks count for reader: " << bcount << std::endl; + } + + //char c; + //::std::cin >> c; + + + return 0; +} diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/CMakeDirectoryInformation.cmake b/3rdparty/easyprofiler/sample/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..9ecfcf5 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/alex/Work/C++Projects/easyprofiler") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/alex/Work/C++Projects/easyprofiler") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/DependInfo.cmake b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/DependInfo.cmake new file mode 100644 index 0000000..60f0791 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/DependInfo.cmake @@ -0,0 +1,31 @@ +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +set(CMAKE_DEPENDS_CHECK_CXX + "/home/alex/Work/C++Projects/easyprofiler/sample/main.cpp" "/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/profiler_sample.dir/main.cpp.o" + ) +set(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +set(CMAKE_TARGET_DEFINITIONS_CXX + "BUILD_WITH_EASY_PROFILER=1" + "EASY_DEFAULT_PORT=28077" + "EASY_PROFILER_VERSION_MAJOR=1" + "EASY_PROFILER_VERSION_MINOR=3" + "EASY_PROFILER_VERSION_PATCH=0" + ) + +# The include file search paths: +set(CMAKE_CXX_TARGET_INCLUDE_PATH + "easy_profiler_core/include" + ) + +# Targets to which this target links. +set(CMAKE_TARGET_LINKED_INFO_FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake" + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/build.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/build.make new file mode 100644 index 0000000..3e96c75 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/build.make @@ -0,0 +1,114 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/alex/Work/C++Projects/easyprofiler + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/alex/Work/C++Projects/easyprofiler + +# Include any dependencies generated for this target. +include sample/CMakeFiles/profiler_sample.dir/depend.make + +# Include the progress variables for this target. +include sample/CMakeFiles/profiler_sample.dir/progress.make + +# Include the compile flags for this target's objects. +include sample/CMakeFiles/profiler_sample.dir/flags.make + +sample/CMakeFiles/profiler_sample.dir/main.cpp.o: sample/CMakeFiles/profiler_sample.dir/flags.make +sample/CMakeFiles/profiler_sample.dir/main.cpp.o: sample/main.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object sample/CMakeFiles/profiler_sample.dir/main.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/sample && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_sample.dir/main.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/sample/main.cpp + +sample/CMakeFiles/profiler_sample.dir/main.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_sample.dir/main.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/sample && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/sample/main.cpp > CMakeFiles/profiler_sample.dir/main.cpp.i + +sample/CMakeFiles/profiler_sample.dir/main.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_sample.dir/main.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/sample && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/sample/main.cpp -o CMakeFiles/profiler_sample.dir/main.cpp.s + +sample/CMakeFiles/profiler_sample.dir/main.cpp.o.requires: + +.PHONY : sample/CMakeFiles/profiler_sample.dir/main.cpp.o.requires + +sample/CMakeFiles/profiler_sample.dir/main.cpp.o.provides: sample/CMakeFiles/profiler_sample.dir/main.cpp.o.requires + $(MAKE) -f sample/CMakeFiles/profiler_sample.dir/build.make sample/CMakeFiles/profiler_sample.dir/main.cpp.o.provides.build +.PHONY : sample/CMakeFiles/profiler_sample.dir/main.cpp.o.provides + +sample/CMakeFiles/profiler_sample.dir/main.cpp.o.provides.build: sample/CMakeFiles/profiler_sample.dir/main.cpp.o + + +# Object files for target profiler_sample +profiler_sample_OBJECTS = \ +"CMakeFiles/profiler_sample.dir/main.cpp.o" + +# External object files for target profiler_sample +profiler_sample_EXTERNAL_OBJECTS = + +bin/profiler_sample: sample/CMakeFiles/profiler_sample.dir/main.cpp.o +bin/profiler_sample: sample/CMakeFiles/profiler_sample.dir/build.make +bin/profiler_sample: bin/libeasy_profiler.so +bin/profiler_sample: sample/CMakeFiles/profiler_sample.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable ../bin/profiler_sample" + cd /home/alex/Work/C++Projects/easyprofiler/sample && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profiler_sample.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +sample/CMakeFiles/profiler_sample.dir/build: bin/profiler_sample + +.PHONY : sample/CMakeFiles/profiler_sample.dir/build + +sample/CMakeFiles/profiler_sample.dir/requires: sample/CMakeFiles/profiler_sample.dir/main.cpp.o.requires + +.PHONY : sample/CMakeFiles/profiler_sample.dir/requires + +sample/CMakeFiles/profiler_sample.dir/clean: + cd /home/alex/Work/C++Projects/easyprofiler/sample && $(CMAKE_COMMAND) -P CMakeFiles/profiler_sample.dir/cmake_clean.cmake +.PHONY : sample/CMakeFiles/profiler_sample.dir/clean + +sample/CMakeFiles/profiler_sample.dir/depend: + cd /home/alex/Work/C++Projects/easyprofiler && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/sample /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/sample /home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/profiler_sample.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : sample/CMakeFiles/profiler_sample.dir/depend + diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/cmake_clean.cmake b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/cmake_clean.cmake new file mode 100644 index 0000000..4b8b8c5 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +file(REMOVE_RECURSE + "CMakeFiles/profiler_sample.dir/main.cpp.o" + "../bin/profiler_sample.pdb" + "../bin/profiler_sample" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profiler_sample.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/depend.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/depend.make new file mode 100644 index 0000000..6b5fc0b --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profiler_sample. +# This may be replaced when dependencies are built. diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/flags.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/flags.make new file mode 100644 index 0000000..a02c938 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -O3 -DNDEBUG -DEASY_CHRONO_STEADY_CLOCK=0 -DEASY_CHRONO_HIGHRES_CLOCK=0 -DEASY_OPTION_START_LISTEN_ON_STARTUP=0 -DEASY_OPTION_MEASURE_STORAGE_EXPAND=0 -DEASY_OPTION_STORAGE_EXPAND_BLOCKS_ON=0 -DEASY_OPTION_IMPLICIT_THREAD_REGISTRATION=1 -DEASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS=0 -DEASY_OPTION_LOG_ENABLED=0 -DEASY_OPTION_PRETTY_PRINT_FUNCTIONS=0 -DEASY_OPTION_BUILTIN_COLORS=1 -std=gnu++11 + +CXX_DEFINES = -DBUILD_WITH_EASY_PROFILER=1 -DEASY_DEFAULT_PORT=28077 -DEASY_PROFILER_VERSION_MAJOR=1 -DEASY_PROFILER_VERSION_MINOR=3 -DEASY_PROFILER_VERSION_PATCH=0 + +CXX_INCLUDES = -I/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include + diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/link.txt b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/link.txt new file mode 100644 index 0000000..d0949c3 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/profiler_sample.dir/main.cpp.o -o ../bin/profiler_sample -L/home/alex/Work/C++Projects/easyprofiler/../bin -rdynamic ../bin/libeasy_profiler.so -lpthread -Wl,-rpath,/home/alex/Work/C++Projects/easyprofiler/../bin:/home/alex/Work/C++Projects/easyprofiler/bin diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/progress.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/progress.make new file mode 100644 index 0000000..e1615c1 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 32 +CMAKE_PROGRESS_2 = 33 + diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/DependInfo.cmake b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/DependInfo.cmake new file mode 100644 index 0000000..228a991 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/DependInfo.cmake @@ -0,0 +1,32 @@ +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + "CXX" + ) +# The set of files for implicit dependencies of each language: +set(CMAKE_DEPENDS_CHECK_CXX + "/home/alex/Work/C++Projects/easyprofiler/sample/main.cpp" "/home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o" + ) +set(CMAKE_CXX_COMPILER_ID "GNU") + +# Preprocessor definitions for this target. +set(CMAKE_TARGET_DEFINITIONS_CXX + "BUILD_WITH_EASY_PROFILER=1" + "DISABLE_EASY_PROFILER" + "EASY_DEFAULT_PORT=28077" + "EASY_PROFILER_VERSION_MAJOR=1" + "EASY_PROFILER_VERSION_MINOR=3" + "EASY_PROFILER_VERSION_PATCH=0" + ) + +# The include file search paths: +set(CMAKE_CXX_TARGET_INCLUDE_PATH + "easy_profiler_core/include" + ) + +# Targets to which this target links. +set(CMAKE_TARGET_LINKED_INFO_FILES + "/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/CMakeFiles/easy_profiler.dir/DependInfo.cmake" + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build.make new file mode 100644 index 0000000..17502cf --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build.make @@ -0,0 +1,114 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/alex/Work/C++Projects/easyprofiler + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/alex/Work/C++Projects/easyprofiler + +# Include any dependencies generated for this target. +include sample/CMakeFiles/profiler_sample_disabled_profiler.dir/depend.make + +# Include the progress variables for this target. +include sample/CMakeFiles/profiler_sample_disabled_profiler.dir/progress.make + +# Include the compile flags for this target's objects. +include sample/CMakeFiles/profiler_sample_disabled_profiler.dir/flags.make + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/flags.make +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o: sample/main.cpp + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o" + cd /home/alex/Work/C++Projects/easyprofiler/sample && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o -c /home/alex/Work/C++Projects/easyprofiler/sample/main.cpp + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.i" + cd /home/alex/Work/C++Projects/easyprofiler/sample && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/alex/Work/C++Projects/easyprofiler/sample/main.cpp > CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.i + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.s" + cd /home/alex/Work/C++Projects/easyprofiler/sample && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/alex/Work/C++Projects/easyprofiler/sample/main.cpp -o CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.s + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.requires: + +.PHONY : sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.requires + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.provides: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.requires + $(MAKE) -f sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build.make sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.provides.build +.PHONY : sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.provides + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.provides.build: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o + + +# Object files for target profiler_sample_disabled_profiler +profiler_sample_disabled_profiler_OBJECTS = \ +"CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o" + +# External object files for target profiler_sample_disabled_profiler +profiler_sample_disabled_profiler_EXTERNAL_OBJECTS = + +bin/profiler_sample_disabled_profiler: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o +bin/profiler_sample_disabled_profiler: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build.make +bin/profiler_sample_disabled_profiler: bin/libeasy_profiler.so +bin/profiler_sample_disabled_profiler: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/alex/Work/C++Projects/easyprofiler/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable ../bin/profiler_sample_disabled_profiler" + cd /home/alex/Work/C++Projects/easyprofiler/sample && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profiler_sample_disabled_profiler.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build: bin/profiler_sample_disabled_profiler + +.PHONY : sample/CMakeFiles/profiler_sample_disabled_profiler.dir/build + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/requires: sample/CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o.requires + +.PHONY : sample/CMakeFiles/profiler_sample_disabled_profiler.dir/requires + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/clean: + cd /home/alex/Work/C++Projects/easyprofiler/sample && $(CMAKE_COMMAND) -P CMakeFiles/profiler_sample_disabled_profiler.dir/cmake_clean.cmake +.PHONY : sample/CMakeFiles/profiler_sample_disabled_profiler.dir/clean + +sample/CMakeFiles/profiler_sample_disabled_profiler.dir/depend: + cd /home/alex/Work/C++Projects/easyprofiler && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/sample /home/alex/Work/C++Projects/easyprofiler /home/alex/Work/C++Projects/easyprofiler/sample /home/alex/Work/C++Projects/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/DependInfo.cmake --color=$(COLOR) +.PHONY : sample/CMakeFiles/profiler_sample_disabled_profiler.dir/depend + diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/cmake_clean.cmake b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/cmake_clean.cmake new file mode 100644 index 0000000..38c16f6 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/cmake_clean.cmake @@ -0,0 +1,10 @@ +file(REMOVE_RECURSE + "CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o" + "../bin/profiler_sample_disabled_profiler.pdb" + "../bin/profiler_sample_disabled_profiler" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profiler_sample_disabled_profiler.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/depend.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/depend.make new file mode 100644 index 0000000..6291d48 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profiler_sample_disabled_profiler. +# This may be replaced when dependencies are built. diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/flags.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/flags.make new file mode 100644 index 0000000..084b973 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.5 + +# compile CXX with /usr/bin/c++ +CXX_FLAGS = -O3 -DNDEBUG -DEASY_CHRONO_STEADY_CLOCK=0 -DEASY_CHRONO_HIGHRES_CLOCK=0 -DEASY_OPTION_START_LISTEN_ON_STARTUP=0 -DEASY_OPTION_MEASURE_STORAGE_EXPAND=0 -DEASY_OPTION_STORAGE_EXPAND_BLOCKS_ON=0 -DEASY_OPTION_IMPLICIT_THREAD_REGISTRATION=1 -DEASY_OPTION_REMOVE_EMPTY_UNGUARDED_THREADS=0 -DEASY_OPTION_LOG_ENABLED=0 -DEASY_OPTION_PRETTY_PRINT_FUNCTIONS=0 -DEASY_OPTION_BUILTIN_COLORS=1 -std=gnu++11 + +CXX_DEFINES = -DBUILD_WITH_EASY_PROFILER=1 -DDISABLE_EASY_PROFILER -DEASY_DEFAULT_PORT=28077 -DEASY_PROFILER_VERSION_MAJOR=1 -DEASY_PROFILER_VERSION_MINOR=3 -DEASY_PROFILER_VERSION_PATCH=0 + +CXX_INCLUDES = -I/home/alex/Work/C++Projects/easyprofiler/easy_profiler_core/include + diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/link.txt b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/link.txt new file mode 100644 index 0000000..caada90 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/profiler_sample_disabled_profiler.dir/main.cpp.o -o ../bin/profiler_sample_disabled_profiler -L/home/alex/Work/C++Projects/easyprofiler/../bin -rdynamic ../bin/libeasy_profiler.so -lpthread -Wl,-rpath,/home/alex/Work/C++Projects/easyprofiler/../bin:/home/alex/Work/C++Projects/easyprofiler/bin diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/progress.make b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/progress.make new file mode 100644 index 0000000..30c3091 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/profiler_sample_disabled_profiler.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 34 +CMAKE_PROGRESS_2 = 35 + diff --git a/3rdparty/easyprofiler/sample/CMakeFiles/progress.marks b/3rdparty/easyprofiler/sample/CMakeFiles/progress.marks new file mode 100644 index 0000000..48082f7 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeFiles/progress.marks @@ -0,0 +1 @@ +12 diff --git a/3rdparty/easyprofiler/sample/CMakeLists.txt b/3rdparty/easyprofiler/sample/CMakeLists.txt new file mode 100644 index 0000000..dbc31a3 --- /dev/null +++ b/3rdparty/easyprofiler/sample/CMakeLists.txt @@ -0,0 +1,16 @@ +set(CPP_FILES + main.cpp +) + +set(SOURCES + ${CPP_FILES} +) + +link_directories(${CMAKE_SOURCE_DIR}/../bin) + +add_executable(profiler_sample ${SOURCES}) +target_link_libraries(profiler_sample easy_profiler) + +add_executable(profiler_sample_disabled_profiler ${SOURCES}) +target_link_libraries(profiler_sample_disabled_profiler easy_profiler) +target_compile_definitions(profiler_sample_disabled_profiler PRIVATE DISABLE_EASY_PROFILER) diff --git a/3rdparty/easyprofiler/sample/build_express_test.sh b/3rdparty/easyprofiler/sample/build_express_test.sh new file mode 100755 index 0000000..638ee2a --- /dev/null +++ b/3rdparty/easyprofiler/sample/build_express_test.sh @@ -0,0 +1,21 @@ +#!/bin/bash +TEMP_FILE_ENABLE="enable.info" +TEMP_FILE_DISABLE="disable.info" +OBJECTS="1000" + +$CXX_COMPILER -O3 -std=c++11 -I../easy_profiler_core/include/ -L../bin/ -leasy_profiler express_sample.cpp -o express_test_disabled +$CXX_COMPILER -O3 -std=c++11 -I../easy_profiler_core/include/ -L../bin/ -leasy_profiler -DBUILD_WITH_EASY_PROFILER express_sample.cpp -o express_test_enabled + +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../bin + +./express_test_disabled $OBJECTS > $TEMP_FILE_DISABLE +./express_test_enabled $OBJECTS > $TEMP_FILE_ENABLE + +DT_ENA=`cat $TEMP_FILE_ENABLE | grep Elapsed| awk '{print $3}'` +N_ENA=`cat $TEMP_FILE_ENABLE | grep Blocks| awk '{print $3}'` +DT_DIS=`cat $TEMP_FILE_DISABLE | grep Elapsed| awk '{print $3}'` + +DELTA=$(($DT_ENA-$DT_DIS)) +USEC_BLOCK=`awk "BEGIN{print $DELTA/$N_ENA}"` + +echo "~" $USEC_BLOCK "usec/block" diff --git a/3rdparty/easyprofiler/sample/cmake_install.cmake b/3rdparty/easyprofiler/sample/cmake_install.cmake new file mode 100644 index 0000000..a3eabe7 --- /dev/null +++ b/3rdparty/easyprofiler/sample/cmake_install.cmake @@ -0,0 +1,34 @@ +# Install script for directory: /home/alex/Work/C++Projects/easyprofiler/sample + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + diff --git a/3rdparty/easyprofiler/sample/express_sample.cpp b/3rdparty/easyprofiler/sample/express_sample.cpp new file mode 100644 index 0000000..4212c48 --- /dev/null +++ b/3rdparty/easyprofiler/sample/express_sample.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int OBJECTS = 500; + +void modellingThread(){ + EASY_THREAD("Modelling"); + + static const int N = OBJECTS; + + volatile double *pos[N]; + for (int i = 0; i < N; ++i) + { + pos[i] = new volatile double[3]; + } + + { + EASY_BLOCK("Collisions"); + volatile int i, j; + volatile double dist; + for (i = 0; i < N; ++i) + { + for (j = i + 1; j < N; ++j) + { + EASY_BLOCK("Check"); + volatile double v[3]; + v[0] = pos[i][0] - pos[j][0]; + v[1] = pos[i][1] - pos[j][1]; + v[2] = pos[i][2] - pos[j][2]; + dist = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + if (dist < 10000) + { + dist *= dist; + } + } + } + } + + for (int i = 0; i < N; ++i) + { + delete [] pos[i]; + } +} + +////////////////////////////////////////////////////////////////////////// + +int main(int argc, char* argv[]) +{ + if (argc > 1 && argv[1]){ + OBJECTS = std::atoi(argv[1]); + } + + std::cout << "Objects count: " << OBJECTS << std::endl; + + auto start = std::chrono::system_clock::now(); + + + EASY_PROFILER_ENABLE; + EASY_MAIN_THREAD; + + + modellingThread(); + + auto end = std::chrono::system_clock::now(); + auto elapsed = + std::chrono::duration_cast(end - start); + + std::cout << "Elapsed time: " << elapsed.count() << " usec" << std::endl; + + auto blocks_count = profiler::dumpBlocksToFile("test.prof"); + + std::cout << "Blocks count: " << blocks_count << std::endl; + + return 0; +} diff --git a/3rdparty/easyprofiler/sample/main.cpp b/3rdparty/easyprofiler/sample/main.cpp new file mode 100644 index 0000000..b2e694f --- /dev/null +++ b/3rdparty/easyprofiler/sample/main.cpp @@ -0,0 +1,289 @@ +//#define FULL_DISABLE_PROFILER +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +std::condition_variable cv; +std::mutex cv_m; +int g_i = 0; + +int OBJECTS = 500; +int MODELLING_STEPS = 1500; +int RENDER_STEPS = 1500; +int RESOURCE_LOADING_COUNT = 50; + +#define SAMPLE_NETWORK_TEST + +void localSleep(int magic=200000) +{ + //PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + volatile int i = 0; + for (; i < magic; ++i); +} + +void loadingResources(){ + EASY_FUNCTION(profiler::colors::DarkCyan); + localSleep(); +// std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} + +void prepareMath(){ + EASY_FUNCTION(profiler::colors::Green); + uint64_t sum = 0; + int* intarray = new int[OBJECTS]; + for (int i = 0; i < OBJECTS; ++i) + { + intarray[i] = i * i; + sum += i * i; + } + delete[] intarray; + //std::this_thread::sleep_for(std::chrono::milliseconds(3)); + + EASY_VALUE("sum", sum, profiler::colors::Blue); +} + +void calcIntersect(){ + EASY_FUNCTION(profiler::colors::Gold); + //int* intarray = new int[OBJECTS * OBJECTS]; + int* intarray = new int[OBJECTS]; + for (int i = 0; i < OBJECTS; ++i) + { + for (int j = i; j < OBJECTS; ++j) + //intarray[i * OBJECTS + j] = i * j - i / 2 + (OBJECTS - j) * 5; + intarray[j] = i * j - i / 2 + (OBJECTS - j) * 5; + } + delete[] intarray; + //std::this_thread::sleep_for(std::chrono::milliseconds(4)); +} + +double multModel(double i) +{ + EASY_FUNCTION(profiler::colors::PaleGold); + return i * sin(i) * cos(i); +} + +void calcPhys(){ + EASY_FUNCTION(profiler::colors::Amber); + double* intarray = new double[OBJECTS]; + for (int i = 0; i < OBJECTS; ++i) + intarray[i] = multModel(double(i)) + double(i / 3) - double((OBJECTS - i) / 2); + calcIntersect(); + delete[] intarray; +} + +double calcSubbrain(int i) +{ + EASY_FUNCTION(profiler::colors::Navy); + auto val = i * i * i - i / 10 + (OBJECTS - i) * 7 ; + EASY_VALUE("subbrainResult", val, profiler::colors::DarkRed); + return val; +} + +void calcBrain(){ + EASY_FUNCTION(profiler::colors::LightBlue); + double* intarray = new double[OBJECTS]; + for (int i = 0; i < OBJECTS; ++i) + intarray[i] = calcSubbrain(i) + double(i * 180 / 3); + delete[] intarray; + //std::this_thread::sleep_for(std::chrono::milliseconds(3)); +} + +void calculateBehavior(){ + EASY_FUNCTION(profiler::colors::Blue); + calcPhys(); + calcBrain(); +} + +void modellingStep(){ + EASY_FUNCTION(); + prepareMath(); + calculateBehavior(); +} + +void prepareRender(){ + EASY_FUNCTION(profiler::colors::Brick); + localSleep(); + //std::this_thread::sleep_for(std::chrono::milliseconds(8)); + +} + +int multPhys(int i) +{ + EASY_FUNCTION(profiler::colors::Red700, profiler::ON); + return i * i * i * i / 100; +} + +int calcPhysicForObject(int i) +{ + EASY_FUNCTION(profiler::colors::Red); + return multPhys(i) + i / 3 - (OBJECTS - i) * 15; +} + +void calculatePhysics(){ + EASY_FUNCTION(profiler::colors::Red); + unsigned int* intarray = new unsigned int[OBJECTS]; + for (int i = 0; i < OBJECTS; ++i) + intarray[i] = calcPhysicForObject(i); + delete[] intarray; + //std::this_thread::sleep_for(std::chrono::milliseconds(8)); +} + +void frame(){ + EASY_FUNCTION(profiler::colors::Magenta); + prepareRender(); + calculatePhysics(); +} + +void loadingResourcesThread(){ + //std::unique_lock lk(cv_m); + //cv.wait(lk, []{return g_i == 1; }); + EASY_THREAD("Resource loading"); +#ifdef SAMPLE_NETWORK_TEST + while (true) { +#else + for(int i = 0; i < RESOURCE_LOADING_COUNT; i++){ +#endif + loadingResources(); + EASY_EVENT("Resources Loading!", profiler::colors::Cyan); + localSleep(1200000); + //std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } +} + +void modellingThread(){ + //std::unique_lock lk(cv_m); + //cv.wait(lk, []{return g_i == 1; }); + EASY_THREAD("Modelling"); + uint64_t step = 0; +#ifdef SAMPLE_NETWORK_TEST + while (true) { +#else + for (int i = 0; i < MODELLING_STEPS; i++){ +#endif + EASY_END_BLOCK; + EASY_NONSCOPED_BLOCK("Frame", true, 15., profiler::ON, -5.f, profiler::colors::Red); + modellingStep(); + + localSleep(1200000); + + ++step; + EASY_VALUE("step", step, profiler::colors::Gold); + if (step > 10000000) + step = 0; + + EASY_TEXT("Test String", "Some short text. Hey!", profiler::colors::Red); + //std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } + EASY_END_BLOCK; +} + +void renderThread(){ + //std::unique_lock lk(cv_m); + //cv.wait(lk, []{return g_i == 1; }); + EASY_THREAD("Render"); +#ifdef SAMPLE_NETWORK_TEST + while (true) { +#else + for (int i = 0; i < RENDER_STEPS; i++){ +#endif + frame(); + localSleep(1200000); + //std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } +} + +////////////////////////////////////////////////////////////////////////// + +int main(int argc, char* argv[]) +{ + if (argc > 1 && argv[1]){ + OBJECTS = std::atoi(argv[1]); + } + if (argc > 2 && argv[2]){ + MODELLING_STEPS = std::atoi(argv[2]); + } + if (argc > 3 && argv[3]){ + RENDER_STEPS = std::atoi(argv[3]); + } + if (argc > 4 && argv[4]){ + RESOURCE_LOADING_COUNT = std::atoi(argv[4]); + } + + std::cout << "Objects count: " << OBJECTS << std::endl; + std::cout << "Render steps: " << MODELLING_STEPS << std::endl; + std::cout << "Modelling steps: " << RENDER_STEPS << std::endl; + std::cout << "Resource loading count: " << RESOURCE_LOADING_COUNT << std::endl; + + auto start = std::chrono::system_clock::now(); + +#ifndef SAMPLE_NETWORK_TEST + EASY_PROFILER_ENABLE; +#endif + + EASY_MAIN_THREAD; + profiler::startListen(); + +#ifdef EASY_CONSTEXPR_AVAILABLE + constexpr int grrr[] {2, -3, 4}; + auto pppp = &grrr; + EASY_ARRAY("threads count", grrr, 3, false, true, "blabla", profiler::colors::Blue/*, EASY_VIN("threads count")*/, profiler::OFF); +#endif + + int* intPtr = new int(2); + EASY_VALUE("count", *intPtr); + + std::vector threads; + //for (int i=0; i < 3; i++) + { + threads.emplace_back(loadingResourcesThread); + threads.emplace_back(renderThread); + threads.emplace_back(modellingThread); + } + + cv_m.lock(); + g_i = 1; + cv_m.unlock(); + cv.notify_all(); + +#ifndef SAMPLE_NETWORK_TEST + std::atomic_bool stop = ATOMIC_VAR_INIT(false); + auto frame_time_printer_thread = std::thread([&stop]() + { + while (!stop.load(std::memory_order_acquire)) + { + std::cout << "Frame time: max " << profiler::main_thread::frameTimeLocalMax() << " us // avg " << profiler::main_thread::frameTimeLocalAvg() << " us\n"; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + }); +#endif + + modellingThread(); + +#ifndef SAMPLE_NETWORK_TEST + stop.store(true, std::memory_order_release); + frame_time_printer_thread.join(); +#endif + + for(auto& t : threads) + t.join(); + + auto end = std::chrono::system_clock::now(); + auto elapsed = + std::chrono::duration_cast(end - start); + + std::cout << "Elapsed time: " << elapsed.count() << " usec" << std::endl; + + auto blocks_count = profiler::dumpBlocksToFile("test.prof"); + + std::cout << "Blocks count: " << blocks_count << std::endl; + + return 0; +} diff --git a/3rdparty/easyprofiler/sample/main_clock.cpp b/3rdparty/easyprofiler/sample/main_clock.cpp new file mode 100644 index 0000000..95fa008 --- /dev/null +++ b/3rdparty/easyprofiler/sample/main_clock.cpp @@ -0,0 +1,249 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +static inline uint64_t getCurrentTime() +{ +#if defined(__i386__) + int64_t ret; + __asm__ volatile("rdtsc" : "=A"(ret)); + return ret; +#elif defined(__x86_64__) || defined(__amd64__) + uint64_t low, high; + __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); + return (high << 32) | low; +#endif +} + +int OBJECTS = 500; +#define STR(x) #x + +int64_t calculate_cpu_frequency()//per sec +{ + double g_TicksPerNanoSec; + struct timespec begints, endts; + uint64_t begin = 0, end = 0; + clock_gettime(CLOCK_MONOTONIC, &begints); + begin = getCurrentTime(); + volatile uint64_t i; + for (i = 0; i < 100000000; i++); /* must be CPU intensive */ + end = getCurrentTime(); + clock_gettime(CLOCK_MONOTONIC, &endts); + struct timespec tmpts; + const int NANO_SECONDS_IN_SEC = 1000000000; + tmpts.tv_sec = endts.tv_sec - begints.tv_sec; + tmpts.tv_nsec = endts.tv_nsec - begints.tv_nsec; + if (tmpts.tv_nsec < 0) + { + tmpts.tv_sec--; + tmpts.tv_nsec += NANO_SECONDS_IN_SEC; + } + + uint64_t nsecElapsed = tmpts.tv_sec * 1000000000LL + tmpts.tv_nsec; + g_TicksPerNanoSec = (double)(end - begin) / (double)nsecElapsed; + + int64_t cpu_frequency = int(g_TicksPerNanoSec * 1000); + + return cpu_frequency; +} + +const auto CPU_FREQUENCY = calculate_cpu_frequency(); + +# define TICKS_TO_US(ticks) ticks / CPU_FREQUENCY + +void localSleep(int magic=200000) +{ + volatile int i = 0; + for (; i < magic; ++i); +} + +template +auto calcDelta(int magic=200000) -> decltype(Clock::now().time_since_epoch().count()) +{ + auto start = Clock::now().time_since_epoch().count(); + localSleep(magic); + auto end = Clock::now().time_since_epoch().count(); + return end - start; +} + +template +double calcDuration(int objects) +{ + const auto frequency = Clock::period::den / Clock::period::num; + + auto start = Clock::now(); + + decltype(Clock::now().time_since_epoch().count()) summ = 0; + + for (int i=0; i < objects; i++) + { + summ += calcDelta(); + } + + summ = summ * 1000000LL / frequency; + + auto end = Clock::now(); + auto elapsed = + std::chrono::duration_cast(end - start); + + + return (elapsed.count()-summ)/double(objects)/2.0; +} + +uint64_t calcDeltaRdtsc(int magic=200000) +{ + auto start = getCurrentTime(); + localSleep(magic); + auto end = getCurrentTime(); + return end - start; +} + +double calcDurationByRdtsc(int objects) +{ + auto start = getCurrentTime(); + + uint64_t summ = 0; + + for (int i=0; i < objects; i++) + { + summ += calcDeltaRdtsc(); + } + + auto end = getCurrentTime(); + return TICKS_TO_US((end - start - summ))/double(objects)/2.0; +} + +uint64_t calcDeltaSysCall(int magic, int type) +{ + timespec tp0,tp1; + syscall(SYS_clock_gettime, type, &tp0); + auto start = tp0.tv_sec*1000000000+tp0.tv_nsec; + localSleep(magic); + syscall(SYS_clock_gettime, type, &tp1); + auto end = tp1.tv_sec*1000000000+tp1.tv_nsec; + return end - start; +} + +double calcDurationBySyscall(int objects, int type) +{ + timespec tp0,tp1; + syscall(SYS_clock_gettime, type, &tp0); + auto start = tp0.tv_sec*1000000000+tp0.tv_nsec; + + uint64_t summ = 0; + + for (int i=0; i < objects; i++) + { + summ += calcDeltaSysCall(200000,type); + } + + syscall(SYS_clock_gettime, type, &tp1); + auto end = tp1.tv_sec*1000000000+tp1.tv_nsec; + return (end - start - summ)/double(objects)/2.0/1000.0; +} + +uint64_t calcDeltaSysGetTime(int magic, int type) +{ + timespec tp0,tp1; + clock_gettime(type, &tp0); + auto start = tp0.tv_sec*1000000000+tp0.tv_nsec; + localSleep(magic); + clock_gettime(type, &tp1); + auto end = tp1.tv_sec*1000000000+tp1.tv_nsec; + return end - start; +} + +double calcDurationByGetTime(int objects, int type) +{ + timespec tp0,tp1; + clock_gettime(type, &tp0); + auto start = tp0.tv_sec*1000000000+tp0.tv_nsec; + + uint64_t summ = 0; + + for (int i=0; i < objects; i++) + { + summ += calcDeltaSysGetTime(200000,type); + } + + clock_gettime(type, &tp1); + auto end = tp1.tv_sec*1000000000+tp1.tv_nsec; + return (end - start - summ)/double(objects)/2.0/1000.0; +} + +uint64_t calcDeltaSysGetTimeOfDay(int magic=200000) +{ + timeval tv0,tv1; + gettimeofday(&tv0,0); + auto start = tv0.tv_sec*1000000+tv0.tv_usec; + localSleep(magic); + gettimeofday(&tv1, 0); + auto end = tv1.tv_sec*1000000+tv1.tv_usec; + return end - start; +} + +double calcDurationByGetTimeOfDay(int objects) +{ + timeval tv0,tv1; + gettimeofday(&tv0,0); + auto start = tv0.tv_sec*1000000+tv0.tv_usec; + + uint64_t summ = 0; + + for (int i=0; i < objects; i++) + { + summ += calcDeltaSysGetTimeOfDay(); + } + + gettimeofday(&tv1, 0); + auto end = tv1.tv_sec*1000000+tv1.tv_usec; + return (end - start - summ)/double(objects)/2.0; +} + +int main(int argc, char* argv[]) +{ + if (argc > 1 && argv[1]){ + OBJECTS = std::atoi(argv[1]); + } + + + std::cout << STR(std::chrono::steady_clock) << ": "<(OBJECTS) << " usec\n"; + std::cout << STR(std::chrono::high_resolution_clock)<< ": " << calcDuration(OBJECTS) << " usec\n"; + std::cout << STR(std::chrono::system_clock)<< ": " << calcDuration(OBJECTS) << " usec\n"; + + std::cout << "\n"; + + std::cout << "rdtsc: " << calcDurationByRdtsc(OBJECTS) << " usec\n"; + + std::cout << "\n"; + + std::cout << "syscall(SYS_clock_gettime, CLOCK_MONOTONIC): " << calcDurationBySyscall(OBJECTS,CLOCK_MONOTONIC) << " usec\n"; + std::cout << "syscall(SYS_clock_gettime, CLOCK_REALTIME): " << calcDurationBySyscall(OBJECTS,CLOCK_REALTIME) << " usec\n"; + std::cout << "syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW): " << calcDurationBySyscall(OBJECTS,CLOCK_MONOTONIC_RAW) << " usec\n"; + std::cout << "syscall(SYS_clock_gettime, CLOCK_MONOTONIC_COARSE): " << calcDurationBySyscall(OBJECTS,CLOCK_MONOTONIC_COARSE) << " usec\n"; + std::cout << "syscall(SYS_clock_gettime, CLOCK_REALTIME_COARSE): " << calcDurationBySyscall(OBJECTS,CLOCK_REALTIME_COARSE) << " usec\n"; + + std::cout << "\n"; + + std::cout << "clock_gettime(CLOCK_MONOTONIC): " << calcDurationByGetTime(OBJECTS,CLOCK_MONOTONIC) << " usec\n"; + std::cout << "clock_gettime(CLOCK_REALTIME): " << calcDurationByGetTime(OBJECTS,CLOCK_REALTIME) << " usec\n"; + std::cout << "clock_gettime(CLOCK_MONOTONIC_RAW): " << calcDurationByGetTime(OBJECTS,CLOCK_MONOTONIC_RAW) << " usec\n"; + std::cout << "clock_gettime(CLOCK_MONOTONIC_COARSE): " << calcDurationByGetTime(OBJECTS,CLOCK_MONOTONIC_COARSE) << " usec\n"; + std::cout << "clock_gettime(CLOCK_REALTIME_COARSE): " << calcDurationByGetTime(OBJECTS,CLOCK_REALTIME_COARSE) << " usec\n"; + + std::cout << "\n"; + + std::cout << "gettimeofday(): " << calcDurationByGetTimeOfDay(OBJECTS) << " usec\n"; + + return 0; +} diff --git a/3rdparty/easyprofiler/scripts/context_switch_logger.stp b/3rdparty/easyprofiler/scripts/context_switch_logger.stp new file mode 100644 index 0000000..fd10537 --- /dev/null +++ b/3rdparty/easyprofiler/scripts/context_switch_logger.stp @@ -0,0 +1,37 @@ +global target_pid +global target_name + +probe scheduler.ctxswitch { + + if (target_pid != 0 + && next_pid != target_pid + && prev_pid != target_pid) + next + + if (target_name != "" + && prev_task_name != target_name + && next_task_name != target_name) + next + + //printf("Switch from %d(%s) to %d(%s) at %d\n",prev_tid, prev_task_name,next_tid,next_task_name, gettimeofday_ns()) + printf("%d %d %d %s %d\n",gettimeofday_ns(),prev_tid, next_tid, next_task_name,next_pid ) + //printf("%d %d %d\n",gettimeofday_ns(),prev_tid, next_tid ) +} + +probe begin +{ + target_pid = 0 + target_name = "" + + %( $# == 1 || $# > 2 %? + log("Wrong number of arguments, use none, 'pid nr' or 'name proc'") + exit() + %) + + %( $# == 2 %? + if(@1 == "pid") + target_pid = strtol(@2, 10) + if(@1 == "name") + target_name = @2 + %) +} diff --git a/3rdparty/easyprofiler/scripts/make_style.sh b/3rdparty/easyprofiler/scripts/make_style.sh new file mode 100755 index 0000000..6646ccd --- /dev/null +++ b/3rdparty/easyprofiler/scripts/make_style.sh @@ -0,0 +1,19 @@ +if [ "$#" -ne 1 ]; then + echo -e "Usage: \n$0 DIRECTORY\n\twhere DIRECTORY is a derectory with sources for styling" + exit 1 +fi + +if ! [ -x "$(command -v clang-format)" ]; then + echo 'Error: clang-format is not installed. Please install clang-format with minimal version 3.8' >&2 + exit 1 +fi + +DIR=$1 + +FILES=`find $DIR -name "*.h" -or -name "*.cpp"` + +for FILE in $FILES +do + echo "Set style for $FILE" + clang-format -i $FILE +done diff --git a/3rdparty/easyprofiler/scripts/test.sh b/3rdparty/easyprofiler/scripts/test.sh new file mode 100755 index 0000000..4072207 --- /dev/null +++ b/3rdparty/easyprofiler/scripts/test.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +unamestr=`uname` +SUBDIR="./bin" +if [[ ! "$unamestr" == 'Linux' ]]; then + SUBDIR="./bin/Release/" +fi + +DISABLED_PROF=$SUBDIR/profiler_sample_disabled_profiler +ENABLED_PROF=$SUBDIR/profiler_sample + +TEMP_FILE_ENABLE="enable.info" +TEMP_FILE_DISABLE="disable.info" +RESULT_FILE="result.csv" +RESULT_FILE_TMP="result.csv.tmp" + +HEADER="Blocks count, dT prof enabled usec, dT prof disabled usec,delta, usec/block" + +#echo "Blocks count, dT prof enabled usec, dT prof disabled usec,delta, usec/block" > $RESULT_FILE + +rm -rf $RESULT_FILE + +for i in {1..9} +do + OBJECTS_COUNT=$(($i*100)) + for j in {10..15} + do + RENDER_COUNT=$(($j*100)) + for k in {10..15} + do + MODELLING_COUNT=$(($k*100)) + $ENABLED_PROF $OBJECTS_COUNT $RENDER_COUNT $MODELLING_COUNT > $TEMP_FILE_ENABLE + $DISABLED_PROF $OBJECTS_COUNT $RENDER_COUNT $MODELLING_COUNT > $TEMP_FILE_DISABLE + DT_ENA=`cat $TEMP_FILE_ENABLE | grep Elapsed| awk '{print $3}'` + N_ENA=`cat $TEMP_FILE_ENABLE | grep Blocks| awk '{print $3}'` + N_DIS=`cat $TEMP_FILE_DISABLE | grep Elapsed| awk '{print $3}'` + + DELTA=$(($DT_ENA-$N_DIS)) + USEC_BLOCK=`awk "BEGIN{print $DELTA/$N_ENA}"` + + echo $N_ENA,$DT_ENA,$N_DIS,$DELTA,$USEC_BLOCK >> $RESULT_FILE + done + done + echo $i + +done + +cat $RESULT_FILE | sort > $RESULT_FILE_TMP + +echo $HEADER > $RESULT_FILE +cat $RESULT_FILE_TMP >> $RESULT_FILE + +rm -rf $TEMP_FILE_ENABLE +rm -rf $TEMP_FILE_DISABLE +rm -rf $RESULT_FILE_TMP + +echo "See result in $RESULT_FILE" diff --git a/3rdparty/light_style_sheet/COPYING b/3rdparty/light_style_sheet/COPYING new file mode 100644 index 0000000..49f878c --- /dev/null +++ b/3rdparty/light_style_sheet/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) <2013-2017> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/3rdparty/light_style_sheet/qlightstyle/lightstyle.qrc b/3rdparty/light_style_sheet/qlightstyle/lightstyle.qrc new file mode 100644 index 0000000..dcc7c27 --- /dev/null +++ b/3rdparty/light_style_sheet/qlightstyle/lightstyle.qrc @@ -0,0 +1,48 @@ + + + rc/up_arrow_disabled.png + rc/Hmovetoolbar.png + rc/stylesheet-branch-end.png + rc/branch_closed-on.png + rc/stylesheet-vline.png + rc/branch_closed.png + rc/branch_open-on.png + rc/transparent.png + rc/right_arrow_disabled.png + rc/sizegrip.png + rc/close.png + rc/close-hover.png + rc/close-pressed.png + rc/down_arrow.png + rc/Vmovetoolbar.png + rc/left_arrow.png + rc/stylesheet-branch-more.png + rc/up_arrow.png + rc/right_arrow.png + rc/left_arrow_disabled.png + rc/Hsepartoolbar.png + rc/branch_open.png + rc/Vsepartoolbar.png + rc/down_arrow_disabled.png + rc/undock.png + rc/undock-hover.png + rc/checkbox_checked_disabled.png + rc/checkbox_checked_focus.png + rc/checkbox_checked.png + rc/checkbox_indeterminate.png + rc/checkbox_indeterminate_focus.png + rc/checkbox_unchecked_disabled.png + rc/checkbox_unchecked_focus.png + rc/checkbox_unchecked.png + rc/radio_checked_disabled.png + rc/radio_checked_focus.png + rc/radio_checked.png + rc/radio_unchecked_disabled.png + rc/radio_unchecked_focus.png + rc/radio_unchecked.png + rc/extend.png + + + lightstyle.qss + + diff --git a/3rdparty/light_style_sheet/qlightstyle/lightstyle.qss b/3rdparty/light_style_sheet/qlightstyle/lightstyle.qss new file mode 100644 index 0000000..1c768a4 --- /dev/null +++ b/3rdparty/light_style_sheet/qlightstyle/lightstyle.qss @@ -0,0 +1,1453 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) <2013-2014> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +QToolTip +{ + border: 1px solid #b6b6b6; + background-color: #f0f0f0; + color: #000; +\\ padding: 5px; + +} + +QWidget +{ + color: #000; + background-color: #f0f0f0; + selection-background-color:#b5da91; + selection-color: #000; + background-clip: border; + border-image: none; + border: 0px transparent black; + outline: 0; +} + +QWidget:item:hover +{ + background-color: #b5da91; + color: #000; +} + +QWidget:item:selected +{ + background-color: #b5da91; +} + +QCheckBox +{ + spacing: 5px; + outline: none; + color: #000; + margin-right: 2px; + +} + +QCheckBox::item{ + background-color: #ffffff; +} + +QCheckBox:disabled +{ + color: #494949; +} + +QCheckBox::indicator{ + width: 16px; + height: 16px; + color: #222222; +} + + +QCheckBox::indicator:unchecked +{ + image: url(:/qss_qlight_icons/rc/checkbox_unchecked.png); +} + +QCheckBox::indicator:unchecked:hover, +QCheckBox::indicator:unchecked:focus, +QCheckBox::indicator:unchecked:pressed, +QGroupBox::indicator:unchecked:hover, +QGroupBox::indicator:unchecked:focus, +QGroupBox::indicator:unchecked:pressed +{ + border: none; + image: url(:/qss_qlight_icons/rc/checkbox_unchecked_focus.png); +} + +QCheckBox::indicator:checked +{ + image: url(:/qss_qlight_icons/rc/checkbox_checked.png); +} + +QCheckBox::indicator:checked:hover, +QCheckBox::indicator:checked:focus, +QCheckBox::indicator:checked:pressed, +QGroupBox::indicator:checked:hover, +QGroupBox::indicator:checked:focus, +QGroupBox::indicator:checked:pressed +{ + border: none; + image: url(:/qss_qlight_icons/rc/checkbox_checked_focus.png); +} + + +QCheckBox::indicator:indeterminate +{ + image: url(:/qss_qlight_icons/rc/checkbox_indeterminate.png); +} + +QCheckBox::indicator:indeterminate:focus, +QCheckBox::indicator:indeterminate:hover, +QCheckBox::indicator:indeterminate:pressed +{ + image: url(:/qss_qlight_icons/rc/checkbox_indeterminate_focus.png); +} + +QCheckBox::indicator:checked:disabled, +QGroupBox::indicator:checked:disabled +{ + image: url(:/qss_qlight_icons/rc/checkbox_checked_disabled.png); +} + +QCheckBox::indicator:unchecked:disabled, +QGroupBox::indicator:unchecked:disabled +{ + image: url(:/qss_qlight_icons/rc/checkbox_unchecked_disabled.png); +} + +QGroupBox::indicator +{ + width: 18px; + height: 18px; +} +QGroupBox::indicator +{ + margin-left: 2px; +} + +QRadioButton +{ + spacing: 5px; + outline: none; + color: #000; + margin-bottom: 2px; +} + +QRadioButton:disabled +{ + color: #b6b6b6; +} + +QRadioButton::indicator +{ + width: 16px; + height: 16px; +} + +QRadioButton::indicator:unchecked +{ + image: url(:/qss_qlight_icons/rc/radio_unchecked.png); +} + +QRadioButton::indicator:unchecked:hover, +QRadioButton::indicator:unchecked:focus, +QRadioButton::indicator:unchecked:pressed +{ + border: none; + outline: none; + image: url(:/qss_qlight_icons/rc/radio_unchecked_focus.png); +} + +QRadioButton::indicator:checked +{ + border: none; + outline: none; + image: url(:/qss_qlight_icons/rc/radio_checked.png); +} + +QRadioButton::indicator:checked:hover, +QRadioButton::indicator:checked:focus, +QRadioButton::indicator:checked:pressed +{ + border: none; + outline: none; + image: url(:/qss_qlight_icons/rc/radio_checked_focus.png); +} + +QRadioButton::indicator:checked:disabled +{ + outline: none; + image: url(:/qss_qlight_icons/rc/radio_checked_disabled.png); +} + +QRadioButton::indicator:unchecked:disabled +{ + image: url(:/qss_qlight_icons/rc/radio_unchecked_disabled.png); +} + +QMenuBar +{ + background-color: #f9f9f9; + color: #000; + border-bottom: 1px solid #b6b6b6; +} + +QMenuBar::item +{ + background: transparent; +} + +QMenuBar::item:selected +{ + background: transparent; + background-color: #75bf3f; + border: 1px solid #b6b6b6; +} + +QMenuBar::item:pressed +{ + border: 1px solid #b6b6b6; +\\ background-color: #f9f9f9; + background-color: #75bf3f; + color: #000; + margin-bottom:-1px; + padding-bottom:1px; +} + +QMenu +{ + border: 1px solid #b6b6b6; + color: #000; +\\ margin: 2px; +} + +QMenu::icon +{ + margin: 5px; +} + +QMenu::item +{ + padding: 5px 30px 5px 30px; + border: 1px solid transparent; /* reserve space for selection border */ +} + +QMenu::item:selected +{ + color: #000; +} + +QMenu::separator { + height: 2px; + background: lightblue; + margin-left: 10px; + margin-right: 5px; +} + +QMenu::indicator { + width: 18px; + height: 18px; + padding-left: 4px; +} + +/* non-exclusive indicator = check box style indicator + (see QActionGroup::setExclusive) */ +QMenu::indicator:non-exclusive:unchecked { + image: url(:/qss_qlight_icons/rc/checkbox_unchecked.png); +} + +QMenu::indicator:non-exclusive:unchecked:selected { + image: url(:/qss_qlight_icons/rc/checkbox_unchecked_disabled.png); +} + +QMenu::indicator:non-exclusive:checked { + image: url(:/qss_qlight_icons/rc/checkbox_checked.png); +} + +QMenu::indicator:non-exclusive:checked:selected { + image: url(:/qss_qlight_icons/rc/checkbox_checked_disabled.png); +} + +/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +QMenu::indicator:exclusive:unchecked { + image: url(:/qss_qlight_icons/rc/radio_unchecked.png); +} + +QMenu::indicator:exclusive:unchecked:selected { + image: url(:/qss_qlight_icons/rc/radio_unchecked_disabled.png); +} + +QMenu::indicator:exclusive:checked { + image: url(:/qss_qlight_icons/rc/radio_checked.png); +} + +QMenu::indicator:exclusive:checked:selected { + image: url(:/qss_qlight_icons/rc/radio_checked_disabled.png); +} + +QMenu::right-arrow { + margin: 5px; + image: url(:/qss_qlight_icons/rc/right_arrow.png) +} + + +QWidget:disabled +{ + color: #7a7a7a; + background-color: #ffffff; +} + +QAbstractItemView +{ + alternate-background-color: #f0f0f0; + color: #000; + border: 1px solid 3A3939; +\\ border-radius: 2px; +} + +QWidget:focus, QMenuBar:focus +{ + border: 1px solid #4b6807; +} + +QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus +{ + border: none; +} + +QLineEdit +{ + background-color: #ffffff; + padding-right: 5px; + padding-left: 5px; + padding-top: 1px; + padding-bottom: 1px; + margin: 1px; + border-style: solid; + border: 1px solid #b6b6b6; +\\ border-radius: 2px; + color: #000; +} + +QLineEdit[text=""] +{ + color:#000; +} + +QLineEdit:disabled{ + color: #858585; +} + +QAbstractItemView QLineEdit +{ + padding: 0; +} + +QGroupBox { + margin-top: 1.5em; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + padding-left: 0px; + padding-right: 0px; + margin-top: 2px; + margin-bottom: 2px; +} + +QAbstractScrollArea +{ +\\ border-radius: 2px; + border: 1px solid #b6b6b6; + background-color: transparent; +} + +QScrollBar:horizontal +{ + height: 15px; + margin: 3px 15px 3px 15px; + border: 1px transparent #efefef; + border-radius: 4px; + background-color: #efefef; +} + +QScrollBar::handle:horizontal +{ + background-color: #8f8f8f; + min-width: 5px; + border-radius: 4px; +} + +QScrollBar::add-line:horizontal +{ + margin: 0px 3px 0px 3px; + border-image: url(:/qss_qlight_icons/rc/right_arrow_disabled.png); + width: 10px; + height: 10px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal +{ + margin: 0px 3px 0px 3px; + border-image: url(:/qss_qlight_icons/rc/left_arrow_disabled.png); + height: 10px; + width: 10px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on +{ + border-image: url(:/qss_qlight_icons/rc/right_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: right; + subcontrol-origin: margin; +} + + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on +{ + border-image: url(:/qss_qlight_icons/rc/left_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal +{ + background: none; +} + + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal +{ + background: none; +} + +QScrollBar:vertical +{ + background-color: #efefef; + width: 15px; + margin: 15px 3px 15px 3px; + border: 1px transparent #efefef; + border-radius: 4px; +} + +QScrollBar::handle:vertical +{ + background-color: #8f8f8f; + min-height: 5px; + border-radius: 4px; +} + +QScrollBar::sub-line:vertical +{ + margin: 3px 0px 3px 0px; + border-image: url(:/qss_qlight_icons/rc/up_arrow_disabled.png); + height: 10px; + width: 10px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical +{ + margin: 3px 0px 3px 0px; + border-image: url(:/qss_qlight_icons/rc/down_arrow_disabled.png); + height: 10px; + width: 10px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on +{ + + border-image: url(:/qss_qlight_icons/rc/up_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: top; + subcontrol-origin: margin; +} + + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on +{ + border-image: url(:/qss_qlight_icons/rc/down_arrow.png); + height: 10px; + width: 10px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical +{ + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; +} + +QTextEdit +{ + background-color: #ffffff; + color: #000; + border: 1px solid #b6b6b6; +} + +QPlainTextEdit +{ + background-color: #ffffff;; + color: #000; +\\ border-radius: 2px; + border: 1px solid #b6b6b6; +} + +QHeaderView::section +{ + background-color: #b6b6b6; + color: #000; + padding: 5px; + border: 1px solid #b6b6b6; +} + +QSizeGrip { + image: url(:/qss_qlight_icons/rc/sizegrip.png); + width: 12px; + height: 12px; +} + + +QMainWindow::separator +{ + background-color: #f0f0f0; + color: white; + padding-left: 4px; + spacing: 2px; + border: 1px dashed #b6b6b6; +} + +QMainWindow::separator:hover +{ + + background-color: #787876; + color: white; + padding-left: 4px; + border: 1px solid #b6b6b6; + spacing: 2px; +} + + +QMenu::separator +{ + height: 1px; + background-color: #b6b6b6; + color: white; + padding-left: 4px; + margin-left: 10px; + margin-right: 5px; +} + + +QFrame +{ + border-radius: 0px; +\\ border-top: 1px solid #494949; +\\ border-left: 1px solid #494949; + border-top: 1px solid #b6b6b6; + border-left: 1px solid #b6b6b6; + border-bottom: 1px solid #b6b6b6; + border-right: 1px solid #b6b6b6; +} + +QFrame[frameShape="0"] +{ +\\ border-radius: 2px; + border: 1px transparent #b6b6b6; +} + +QStackedWidget +{ + border: 1px transparent black; +} + +QToolBar { +\\ border: 1px solid #b6b6b6; +\\ background: #f0f0f0; + font-weight: bold; + border-bottom: 1px solid #b6b6b6; +} + +QToolBar:top{ + border-bottom: 1px solid #b6b6b6; +} + +QToolBar:left{ + border-right: 1px solid #b6b6b6; +} + +QToolBar:right{ + border-left: 1px solid #b6b6b6; +} + +QToolBar:bottom{ + border-top: 1px solid #b6b6b6; +} + +QToolBar::handle:horizontal { + image: url(:/qss_qlight_icons/rc/Hmovetoolbar.png); +} +QToolBar::handle:vertical { + image: url(:/qss_qlight_icons/rc/Vmovetoolbar.png); +} +QToolBar::separator:horizontal { + image: url(:/qss_qlight_icons/rc/Hsepartoolbar.png); +} +QToolBar::separator:vertical { + image: url(:/qss_qlight_icons/rc/Vsepartoolbar.png); +} + +QToolButton#qt_toolbar_ext_button { + background: transparent; + min-width: 8px; + width: 8px; + padding: 1px; + qproperty-icon: url(:/qss_qlight_icons/rc/extend.png); +} + +QPushButton +{ + color: #000; + background-color: #ffffff; + border-width: 1px; + border-color: #b6b6b6; + border-style: solid; + padding: 5px; +\\ border-radius: 2px; + outline: none; +} + +QPushButton:disabled +{ + background-color: #f0f0f0; + border-width: 1px; + border-color: #454545; + border-style: solid; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 10px; + padding-right: 10px; +\\ border-radius: 2px; + color: #454545; +} + +QPushButton:focus { + background-color: #b5da91; + color: #000; +} + +QPushButton:pressed +{ + background-color: #f9f9f9; + padding-top: -15px; + padding-bottom: -17px; +} + +QComboBox +{ + background-color: #fff; + selection-background-color: #f9f9f9; + border-style: solid; + border: 1px solid #b6b6b6; +\\ border-radius: 2px; + padding-right: 5px; + padding-left: 5px; + padding-top: 1px; + padding-bottom: 1px; + margin: 1px; + min-width: 75px; +} + +QPushButton:checked{ + background-color: #b6b6b6; + border-color: #6A6969; +} + +QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover, +QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover, +QTableView:hover, QTableWidget::hover, QListWidget::hover +{ + border: 1px solid #75bf3f; + color: #000; +} + +QPushButton:hover +{ + background-color: #c3e9a7; +} + +QComboBox:on +{ + padding-top: 3px; + padding-left: 4px; + selection-background-color: #4a4a4a; +} + +QAbstractItemView +{ + background-color: #ffffff; +\\ border-radius: 2px; + border: 1px solid #b6b6b6; + selection-color: #000; + selection-background-color: #b5da91; +} + +QComboBox QAbstractItemView +{ + background-color: #ffffff; +\\ border-radius: 2px; + border: 1px solid #b6b6b6; + selection-color: #000; + selection-background-color: #b5da91; +} + +QComboBox::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + + border-left-width: 0px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +QComboBox::down-arrow +{ + image: url(:/qss_qlight_icons/rc/down_arrow_disabled.png); +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, +QComboBox::down-arrow:focus +{ +\\ image: url(:/qss_qlight_icons/rc/down_arrow.png); +} + +QAbstractSpinBox { + padding-right: 5px; + padding-left: 5px; + padding-top: 1px; + padding-bottom: 1px; + margin: 1px; + border: 1px solid #b6b6b6; + background-color: #ffffff; + color: #000; +\\ border-radius: 2px; +} + +QAbstractSpinBox:up-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: top right; +} + +QAbstractSpinBox:down-button +{ + background-color: transparent; + subcontrol-origin: border; + subcontrol-position: bottom right; +} + +QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { + image: url(:/qss_qlight_icons/rc/up_arrow_disabled.png); + width: 10px; + height: 10px; +} +QAbstractSpinBox::up-arrow:hover +{ + image: url(:/qss_qlight_icons/rc/up_arrow.png); +} + + +QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off +{ + image: url(:/qss_qlight_icons/rc/down_arrow_disabled.png); + width: 10px; + height: 10px; +} +QAbstractSpinBox::down-arrow:hover +{ + image: url(:/qss_qlight_icons/rc/down_arrow.png); +} + + +QLabel +{ + border: 0px solid black; +} + +QTabWidget{ + border: 0px transparent black; +} + +QTabWidget::pane { + border: 1px solid #b6b6b6; + background-color: #ffffff; + padding: 5px; +} + +QTabWidget QWidget{ + background-color: #ffffff; +} + +QTabWidget::tab-bar { + left: 5px; /* move to the right by 5px */ +} + +QTabBar +{ + qproperty-drawBase: 0; + border-radius: 3px; +} + +QTabBar:focus +{ + border: 0px transparent black; +} + +QTabBar::close-button { + image: url(:/qss_qlight_icons/rc/close.png); + background: transparent; +} + +QTabBar::close-button:hover +{ + image: url(:/qss_qlight_icons/rc/close-hover.png); + background: transparent; +} + +QTabBar::close-button:pressed { + image: url(:/qss_qlight_icons/rc/close-pressed.png); + background: transparent; +} + +/* TOP TABS */ +QTabBar::tab:top { + color: #000; + border: 1px solid #b6b6b6; + border-bottom: 1px solid transparent; + background-color: #ffffff; + padding: 5px; + min-width: 10px; + margin-bottom: -1; +} + +QTabBar::tab:top:!selected +{ + color: #000; + background-color: #f8f8f8; + border: 1px solid transparent; +} + +QTabBar::tab:top:selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab:top:!selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab::top:selected +{ + border-top: 2px solid #75bf3f; + background-color: #fff; + +} + +/* BOTTOM TABS */ +QTabBar::tab:bottom { + color: #000; + border: 1px solid #b6b6b6; + border-top: 1px solid #ffffff; + background-color: #ffffff; + padding: 5px; + min-width: 10px; + margin-top: -1; +} + +QTabBar::tab:bottom:!selected +{ + color: #000; + background-color: #f3f3f3; + border: 1px solid transparent; +} + +QTabBar::tab:bottom:selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab:bottom:!selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab::bottom:selected +{ + border-bottom: 2px solid #75bf3f; + background-color: #fff; +} + +/* LEFT TABS */ +QTabBar::tab:left { + color: #000; + border: 1px solid #b6b6b6; + border-left: 1px solid #ffffff; + background-color: #ffffff; + padding: 5px; + min-height: 10px; +} + +QTabBar::tab:left:!selected +{ + color: #000; + background-color: #f8f8f8; + border: 1px solid transparent; +} + +QTabBar::tab:left:selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab:left:!selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab::left:selected +{ + border-left: 2px solid #75bf3f; + background-color: #fff; +} + +/* RIGHT TABS */ +QTabBar::tab:right { + color: #000; + border: 1px solid #b6b6b6; + border-right: 1px solid #ffffff; + background-color: #ffffff; + padding: 5px; + min-height: 10px; +} + +QTabBar::tab:right:!selected +{ + color: #000; + background-color: #f8f8f8; + border: 1px solid transparent; +} + +QTabBar::tab:right:!selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab:right:!selected:hover { + background-color: #c3e9a7; +} + +QTabBar::tab::right:selected +{ + border-bottom: 2px solid #75bf3f; + background-color: #fff; +} + +QTabBar QToolButton::right-arrow:enabled { + image: url(:/qss_qlight_icons/rc/right_arrow.png); +} + + QTabBar QToolButton::left-arrow:enabled { + image: url(:/qss_qlight_icons/rc/left_arrow.png); +} + +QTabBar QToolButton::right-arrow:disabled { + image: url(:/qss_qlight_icons/rc/right_arrow_disabled.png); +} + + QTabBar QToolButton::left-arrow:disabled { + image: url(:/qss_qlight_icons/rc/left_arrow_disabled.png); +} + + +QDockWidget { + background: #f0f0f0; + border: 1px solid #403F3F; + titlebar-close-icon: url(:/qss_qlight_icons/rc/transparent.png); + titlebar-normal-icon: url(:/qss_qlight_icons/rc/transparent.png); +} + +\\QDockWidget::title{ +\\ background: #f0f0f0; +\\ background-color: #d2d2d2; +\\ padding-left: 5px; +\\ padding-top: 4px; +\\ margin-top: 4px; +\\} + +QDockWidget::title{ + background: #f0f0f0; + padding-left: 5px; + padding-top: 4px; + margin-top: 4px; + icon-size: 16px; +} + +QDockWidget::close-button, QDockWidget::float-button { + border: 1px solid transparent; + border-radius: 2px; + background: transparent; +} + +QDockWidget::close-button { + subcontrol-position: top right; + subcontrol-origin: margin; + position: absolute; + top: 4px; left: 0px; bottom: 0px; right: 2px; + width: 16px; +} + +QDockWidget::float-button { + subcontrol-position: top right; + subcontrol-origin: margin; + position: absolute; + top: 4px; left: 0px; bottom: 0px; right: 18px; + width: 16px; +} + +QDockWidget::close-button:hover, QDockWidget::float-button:hover { +\\ background: rgba(255, 255, 255, 10); +\\ background-color: #fff; +} + +QDockWidget::close-button { + image: url(:/qss_qlight_icons/rc/close.png); +} + +QDockWidget::close-button:hover { + image: url(:/qss_qlight_icons/rc/close-hover.png); +} + +QDockWidget::float-button { + image: url(:/qss_qlight_icons/rc/undock.png); +} + +QDockWidget::float-button:hover { + image: url(:/qss_qlight_icons/rc/undock-hover.png); +} + +QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { + padding: 1px -1px -1px 1px; + background: rgba(255, 255, 255, 10); +} + +QLabel#limeReportLabel{ + color: #75bf3f; +} + +QTreeView, QListView +{ + border-top: 1px solid #b6b6b6; + border-left: 1px solid #b6b6b6; + border-bottom: 1px solid #b6b6b6; + border-right: 1px solid #b6b6b6; + background-color: #ffffff; +} + +QTreeView::item, QListView::item{ + height: 25px; +} + +QTreeView::branch:selected{ + background-color: #b5da91; +} + +QTreeView::branch:!selected:hover, QTreeView::item:!selected:hover{ +\\ background-color: #287399; + background-color: #b5da91; +} + +QTreeView::branch:has-siblings:!adjoins-item { + border-image: url(:/qss_qlight_icons/rc/transparent.png); +} + +QTreeView::branch:has-siblings:adjoins-item { + border-image: url(:/qss_qlight_icons/rc/transparent.png); +} + +QTreeView::branch:!has-children:!has-siblings:adjoins-item { + border-image: url(:/qss_qlight_icons/rc/transparent.png); +} + +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings { + image: url(:/qss_qlight_icons/rc/branch_closed.png); +} + +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings { + image: url(:/qss_qlight_icons/rc/branch_open.png); +} + +QTreeView::branch:has-children:!has-siblings:closed:hover, +QTreeView::branch:closed:has-children:has-siblings:hover { + image: url(:/qss_qlight_icons/rc/branch_closed-on.png); +} + +QTreeView::branch:open:has-children:!has-siblings:hover, +QTreeView::branch:open:has-children:has-siblings:hover { + image: url(:/qss_qlight_icons/rc/branch_open-on.png); +} + +QSlider::groove:horizontal { + border: 1px solid #565a5e; + height: 4px; + background: #565a5e; + margin: 0px; + border-radius: 2px; +} + +QSlider::handle:horizontal { + background: #ffffff; + border: 1px solid #565a5e; + width: 16px; + height: 16px; + margin: -8px 0; + border-radius: 9px; +} + +QSlider::groove:vertical { + border: 1px solid #565a5e; + width: 4px; + background: #565a5e; + margin: 0px; + border-radius: 3px; +} + +QSlider::handle:vertical { + background: #ffffff; + border: 1px solid #565a5e; + width: 16px; + height: 16px; + margin: 0 -8px; + border-radius: 9px; +} + +QToolButton { + color : #000; + border: 1px solid transparent; + margin: 2px; + padding: 2px; +} + +QToolButton:hover, QToolButton::menu-button:hover { + background-color: #c3e9a7;; + border: 1px solid #75bf3f; +} + +QToolButton:checked, QToolButton:pressed, + QToolButton::menu-button:pressed { + background-color: #fff; + border: 1px solid #75bf3f; +} + +QToolButton:hover:checked +{ + background-color: #c3e9a7;; +} + +QToolButton:text{ + color: #000; +} + +QToolButton:disabled{ + background-color: transparent; + border: 1px transparent #b6b6b6; +} + +\\ +\\QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ +\\ padding-right: 20px; /* make way for the popup button */ +\\ border: 1px #b6b6b6; +\\ border-radius: 5px; +\\} +\\ +\\QToolButton[popupMode="2"] { /* only for InstantPopup */ +\\ padding-right: 10px; /* make way for the popup button */ +\\ border: 1px #b6b6b6; +\\} +\\ +\\/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +\\QToolButton::menu-indicator { +\\ image: url(:/qss_qlight_icons/rc/down_arrow.png); +\\ top: -7px; left: -2px; /* shift it a bit */ +\\} +\\ +\\/* the subcontrols below are used only in the MenuButtonPopup mode */ +\\QToolButton::menu-button { +\\ border: 1px transparent #b6b6b6; +\\ border-top-right-radius: 6px; +\\ border-bottom-right-radius: 6px; +\\ /* 16px width + 4px for border = 20px allocated above */ +\\ width: 16px; +\\ outline: none; +\\} +\\ +\\QToolButton::menu-arrow { +\\ image: url(:/qss_qlight_icons/rc/down_arrow.png); +\\} +\\ +\\QToolButton::menu-arrow:open { +\\ border: 1px solid #b6b6b6; +\\} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + left: 8px; +} + +QTableView +{ + border: 1px solid #b6b6b6; + gridline-color: #f0f0f0; + background-color: #ffffff; +} + + +QTableView, QHeaderView +{ + border-radius: 0px; +} + +QTableView::item:pressed, QListView::item:pressed { + background: #b5da91; + color: #000; +} + +QTableView::item:selected:active, QListView::item:selected:active { + background: #b5da91; + color: #000; +} + +QTableView::focus{ + border: 1px solid #4b6807 +} + +QHeaderView +{ + background-color: #f0f0f0; + border: 1px transparent; + border-radius: 0px; + margin: 0px; + padding: 0px; + +} + +QHeaderView::section { + background-color: #f0f0f0; +\\ background-color: #000; + color: #000; + padding: 5px; + border-top: 1px transparent #b6b6b6; + border-left: 1px solid #b6b6b6; + border-right: 1px solid #b6b6b6; + border-bottom: 1px solid #b6b6b6; + border-radius: 0px; + text-align: center; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one +{ + border-top: 1px transparent #b6b6b6; +} + +QHeaderView::section::vertical +{ + border-top: transparent; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one +{ + border-left: 1px transparent #b6b6b6; +} + +QHeaderView::section::horizontal +{ + border-left: transparent; +} + + +QHeaderView::section:checked + { + color: white; + background-color: #334e5e; + } + + /* style the sort indicator */ +QHeaderView::down-arrow { + image: url(:/qss_qlight_icons/rc/down_arrow.png); +} + +QHeaderView::up-arrow { + image: url(:/qss_qlight_icons/rc/up_arrow.png); +} + + +QTableCornerButton::section { + background-color: #f0f0f0; + border: 1px transparent #b6b6b6; + border-radius: 0px; +} + +QToolBox { + padding: 5px; + border: 1px transparent black; +} + +QToolBox::tab { + color: #000; + font-weight: bold; + background-color: #f0f0f0; +\\ background-color: #b6b6b6; + border: 2px solid #d0d0d0; + border-top: 1px transparent #f0f0f0; + border-left: 1px transparent #f0f0f0; + border-right: 1px transparent #f0f0f0; +\\ border-bottom: 1px transparent #f0f0f0; +\\ border-top-left-radius: 5px; +\\ border-top-right-radius: 5px; +} + +QToolBox::tab:hover{ + background-color: #c3e9a7; + border-color: #75bf3f; +} + +QToolBox::tab:selected { /* italicize selected tabs */ +\\ font: italic; + font-weight: bold; +\\ background-color: #f0f0f0; + background-color: #fff; + border-color: #75bf3f; + } + +QStatusBar::item { + border: 0px transparent dark; + } + + +QFrame[height="3"], QFrame[width="3"] { + background-color: #b6b6b6; +} + + +QSplitter::handle { + border: 1px dashed #b6b6b6; +} + +QSplitter::handle:hover { + background-color: #787876; + border: 1px solid #b6b6b6; +} + +QSplitter::handle:horizontal { + width: 1px; +} + +QSplitter::handle:vertical { + height: 1px; +} + +QProgressBar { + border: 1px solid #b6b6b6; + border-radius: 5px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #05B8CC; +} + +QDateEdit +{ + selection-background-color: #f9f9f9; + border-style: solid; + border: 1px solid #3375A3; + border-radius: 2px; + padding: 1px; + min-width: 75px; +} + +QDateEdit:on +{ + padding-top: 3px; + padding-left: 4px; + selection-background-color: #4a4a4a; +} + +QDateEdit QAbstractItemView +{ + background-color: #ffffff; + border-radius: 2px; + border: 1px solid #3375A3; + selection-background-color: #f9f9f9; +} + +QDateEdit::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + border-left-width: 0px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +QDateEdit::down-arrow +{ + image: url(:/qss_qlight_icons/rc/down_arrow_disabled.png); +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, +QDateEdit::down-arrow:focus +{ + image: url(:/qss_qlight_icons/rc/down_arrow.png); +} diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/Hmovetoolbar.png b/3rdparty/light_style_sheet/qlightstyle/rc/Hmovetoolbar.png new file mode 100644 index 0000000..231aba1 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/Hmovetoolbar.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/Hsepartoolbar.png b/3rdparty/light_style_sheet/qlightstyle/rc/Hsepartoolbar.png new file mode 100644 index 0000000..a503e79 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/Hsepartoolbar.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/Vmovetoolbar.png b/3rdparty/light_style_sheet/qlightstyle/rc/Vmovetoolbar.png new file mode 100644 index 0000000..bbfbf20 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/Vmovetoolbar.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/Vsepartoolbar.png b/3rdparty/light_style_sheet/qlightstyle/rc/Vsepartoolbar.png new file mode 100644 index 0000000..5e8c387 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/Vsepartoolbar.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/branch_closed-on.png b/3rdparty/light_style_sheet/qlightstyle/rc/branch_closed-on.png new file mode 100644 index 0000000..df2c8a4 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/branch_closed-on.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/branch_closed.png b/3rdparty/light_style_sheet/qlightstyle/rc/branch_closed.png new file mode 100644 index 0000000..bec595a Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/branch_closed.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/branch_open-on.png b/3rdparty/light_style_sheet/qlightstyle/rc/branch_open-on.png new file mode 100644 index 0000000..843c8e4 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/branch_open-on.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/branch_open.png b/3rdparty/light_style_sheet/qlightstyle/rc/branch_open.png new file mode 100644 index 0000000..e76b557 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/branch_open.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked.png new file mode 100644 index 0000000..878eaaf Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked_disabled.png new file mode 100644 index 0000000..a4eef25 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked_focus.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked_focus.png new file mode 100644 index 0000000..38eee8b Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_checked_focus.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate.png new file mode 100644 index 0000000..62ab302 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate_disabled.png new file mode 100644 index 0000000..6f3e276 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate_focus.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate_focus.png new file mode 100644 index 0000000..4f563e7 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_indeterminate_focus.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked.png new file mode 100644 index 0000000..151dc32 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked_disabled.png new file mode 100644 index 0000000..2c1c912 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked_focus.png b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked_focus.png new file mode 100644 index 0000000..e698c33 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/checkbox_unchecked_focus.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/cloce.png b/3rdparty/light_style_sheet/qlightstyle/rc/cloce.png new file mode 100644 index 0000000..3ad4679 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/cloce.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/close-hover.png b/3rdparty/light_style_sheet/qlightstyle/rc/close-hover.png new file mode 100644 index 0000000..49fc01b Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/close-hover.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/close-pressed.png b/3rdparty/light_style_sheet/qlightstyle/rc/close-pressed.png new file mode 100644 index 0000000..82927ff Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/close-pressed.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/close.png b/3rdparty/light_style_sheet/qlightstyle/rc/close.png new file mode 100644 index 0000000..2fbe770 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/close.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/down_arrow.png b/3rdparty/light_style_sheet/qlightstyle/rc/down_arrow.png new file mode 100644 index 0000000..ee60137 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/down_arrow.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/down_arrow_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/down_arrow_disabled.png new file mode 100644 index 0000000..e76b557 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/down_arrow_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/extend.png b/3rdparty/light_style_sheet/qlightstyle/rc/extend.png new file mode 100644 index 0000000..88472c2 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/extend.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/left_arrow.png b/3rdparty/light_style_sheet/qlightstyle/rc/left_arrow.png new file mode 100644 index 0000000..c443da7 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/left_arrow.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/left_arrow_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/left_arrow_disabled.png new file mode 100644 index 0000000..085a994 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/left_arrow_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked.png b/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked.png new file mode 100644 index 0000000..bb5d220 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked_disabled.png new file mode 100644 index 0000000..863b6dc Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked_focus.png b/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked_focus.png new file mode 100644 index 0000000..b70a3a1 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/radio_checked_focus.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked.png b/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked.png new file mode 100644 index 0000000..3018453 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked_disabled.png new file mode 100644 index 0000000..30a6368 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked_focus.png b/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked_focus.png new file mode 100644 index 0000000..5d07abd Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/radio_unchecked_focus.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/right_arrow.png b/3rdparty/light_style_sheet/qlightstyle/rc/right_arrow.png new file mode 100644 index 0000000..02d0771 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/right_arrow.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/right_arrow_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/right_arrow_disabled.png new file mode 100644 index 0000000..bec595a Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/right_arrow_disabled.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/sizegrip.png b/3rdparty/light_style_sheet/qlightstyle/rc/sizegrip.png new file mode 100644 index 0000000..92a83f5 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/sizegrip.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-branch-end.png b/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-branch-end.png new file mode 100644 index 0000000..45c3691 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-branch-end.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-branch-more.png b/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-branch-more.png new file mode 100644 index 0000000..ad1504a Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-branch-more.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-vline.png b/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-vline.png new file mode 100644 index 0000000..61fd69f Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/stylesheet-vline.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/transparent.png b/3rdparty/light_style_sheet/qlightstyle/rc/transparent.png new file mode 100644 index 0000000..fdfb807 Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/transparent.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/undock-hover.png b/3rdparty/light_style_sheet/qlightstyle/rc/undock-hover.png new file mode 100644 index 0000000..8db83fe Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/undock-hover.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/undock.png b/3rdparty/light_style_sheet/qlightstyle/rc/undock.png new file mode 100644 index 0000000..c7170ac Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/undock.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/up_arrow.png b/3rdparty/light_style_sheet/qlightstyle/rc/up_arrow.png new file mode 100644 index 0000000..6b7223c Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/up_arrow.png differ diff --git a/3rdparty/light_style_sheet/qlightstyle/rc/up_arrow_disabled.png b/3rdparty/light_style_sheet/qlightstyle/rc/up_arrow_disabled.png new file mode 100644 index 0000000..f99b6cc Binary files /dev/null and b/3rdparty/light_style_sheet/qlightstyle/rc/up_arrow_disabled.png differ diff --git a/3rdparty/light_style_sheet/svg/checkbox_checked.svg b/3rdparty/light_style_sheet/svg/checkbox_checked.svg new file mode 100644 index 0000000..a0f5045 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_checked.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_checked_disabled.svg b/3rdparty/light_style_sheet/svg/checkbox_checked_disabled.svg new file mode 100644 index 0000000..79e23f2 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_checked_disabled.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_checked_focus.svg b/3rdparty/light_style_sheet/svg/checkbox_checked_focus.svg new file mode 100644 index 0000000..2683c6b --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_checked_focus.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_indeterminate.svg b/3rdparty/light_style_sheet/svg/checkbox_indeterminate.svg new file mode 100644 index 0000000..648734a --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_indeterminate.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_indeterminate_disabled.svg b/3rdparty/light_style_sheet/svg/checkbox_indeterminate_disabled.svg new file mode 100644 index 0000000..79f9afb --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_indeterminate_disabled.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_indeterminate_focus.svg b/3rdparty/light_style_sheet/svg/checkbox_indeterminate_focus.svg new file mode 100644 index 0000000..22d7337 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_indeterminate_focus.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_unchecked.svg b/3rdparty/light_style_sheet/svg/checkbox_unchecked.svg new file mode 100644 index 0000000..b365e1b --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_unchecked.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_unchecked_disabled.svg b/3rdparty/light_style_sheet/svg/checkbox_unchecked_disabled.svg new file mode 100644 index 0000000..a2a2059 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_unchecked_disabled.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/checkbox_unchecked_focus.svg b/3rdparty/light_style_sheet/svg/checkbox_unchecked_focus.svg new file mode 100644 index 0000000..ffb2523 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/checkbox_unchecked_focus.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/radio_checked.svg b/3rdparty/light_style_sheet/svg/radio_checked.svg new file mode 100644 index 0000000..062c7ec --- /dev/null +++ b/3rdparty/light_style_sheet/svg/radio_checked.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/radio_checked_disabled.svg b/3rdparty/light_style_sheet/svg/radio_checked_disabled.svg new file mode 100644 index 0000000..c0d9720 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/radio_checked_disabled.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/radio_checked_focus.svg b/3rdparty/light_style_sheet/svg/radio_checked_focus.svg new file mode 100644 index 0000000..458c051 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/radio_checked_focus.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/radio_unchecked.svg b/3rdparty/light_style_sheet/svg/radio_unchecked.svg new file mode 100644 index 0000000..83db993 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/radio_unchecked.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/radio_unchecked_disabled.svg b/3rdparty/light_style_sheet/svg/radio_unchecked_disabled.svg new file mode 100644 index 0000000..0297243 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/radio_unchecked_disabled.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/light_style_sheet/svg/radio_unchecked_focus.svg b/3rdparty/light_style_sheet/svg/radio_unchecked_focus.svg new file mode 100644 index 0000000..3f5e289 --- /dev/null +++ b/3rdparty/light_style_sheet/svg/radio_unchecked_focus.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/3rdparty/zint-2.4.4/backend/2of5.c b/3rdparty/zint-2.4.4/backend/2of5.c deleted file mode 100644 index aea79ad..0000000 --- a/3rdparty/zint-2.4.4/backend/2of5.c +++ /dev/null @@ -1,357 +0,0 @@ -/* 2of5.c - Handles Code 2 of 5 barcodes */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include "common.h" -#ifdef _MSC_VER -#include -#endif - -static char *C25MatrixTable[10] = {"113311", "311131", "131131", "331111", "113131", "313111", - "133111", "111331", "311311", "131311"}; - -static char *C25IndustTable[10] = {"1111313111", "3111111131", "1131111131", "3131111111", "1111311131", - "3111311111", "1131311111", "1111113131", "3111113111", "1131113111"}; - -static char *C25InterTable[10] = {"11331", "31113", "13113", "33111", "11313", "31311", "13311", "11133", - "31131", "13131"}; - -static char check_digit(unsigned int count) -{ - return itoc((10 - (count % 10)) % 10); -} - -int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 2 of 5 Standard (Code 2 of 5 Matrix) */ - - int i, error_number; - char dest[512]; /* 6 + 80 * 6 + 6 + 1 ~ 512*/ - - error_number = 0; - - if(length > 80) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* start character */ - strcpy(dest, "411111"); - - for(i = 0; i < length; i++) { - lookup(NEON, C25MatrixTable, source[i], dest); - } - - /* Stop character */ - concat (dest, "41111"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return error_number; -} - -int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 2 of 5 Industrial */ - - int i, error_number; - char dest[512]; /* 6 + 40 * 10 + 6 + 1 */ - - error_number = 0; - - if(length > 45) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid character in data"); - return error_number; - } - - /* start character */ - strcpy(dest, "313111"); - - for(i = 0; i < length; i++) { - lookup(NEON, C25IndustTable, source[i], dest); - } - - /* Stop character */ - concat (dest, "31113"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return error_number; -} - -int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 2 of 5 IATA */ - int i, error_number; - char dest[512]; /* 4 + 45 * 10 + 3 + 1 */ - - error_number = 0; - - if(length > 45) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* start */ - strcpy(dest, "1111"); - - for(i = 0; i < length; i++) { - lookup(NEON, C25IndustTable, source[i], dest); - } - - /* stop */ - concat (dest, "311"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return error_number; -} - -int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 2 of 5 Data Logic */ - - int i, error_number; - char dest[512]; /* 4 + 80 * 6 + 3 + 1 */ - - error_number = 0; - - if(length > 80) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* start character */ - strcpy(dest, "1111"); - - for(i = 0; i < length; i++) { - lookup(NEON, C25MatrixTable, source[i], dest); - } - - /* Stop character */ - concat (dest, "311"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return error_number; -} - -int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 2 of 5 Interleaved */ - - int i, j, k, error_number; - char bars[7], spaces[7], mixed[14], dest[1000]; -#ifndef _MSC_VER - unsigned char temp[length + 2]; -#else - unsigned char* temp = (unsigned char *)_alloca((length + 2) * sizeof(unsigned char)); -#endif - - error_number = 0; - - if(length > 89) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if (error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - ustrcpy(temp, (unsigned char *) ""); - /* Input must be an even number of characters for Interlaced 2 of 5 to work: - if an odd number of characters has been entered then add a leading zero */ - if (length & 1) - { - ustrcpy(temp, (unsigned char *) "0"); - length++; - } - uconcat(temp, source); - - /* start character */ - strcpy(dest, "1111"); - - for(i = 0; i < length; i+=2 ) - { - /* look up the bars and the spaces and put them in two strings */ - strcpy(bars, ""); - lookup(NEON, C25InterTable, temp[i], bars); - strcpy(spaces, ""); - lookup(NEON, C25InterTable, temp[i + 1], spaces); - - /* then merge (interlace) the strings together */ - k = 0; - for(j = 0; j <= 4; j++) - { - mixed[k] = bars[j]; k++; - mixed[k] = spaces[j]; k++; - } - mixed[k] = '\0'; - concat (dest, mixed); - } - - /* Stop character */ - concat (dest, "311"); - - expand(symbol, dest); - ustrcpy(symbol->text, temp); - return error_number; - -} - -int itf14(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int i, error_number, zeroes; - unsigned int count; - char localstr[16]; - - error_number = 0; - - count = 0; - - if(length > 13) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid character in data"); - return error_number; - } - - /* Add leading zeros as required */ - zeroes = 13 - length; - for(i = 0; i < zeroes; i++) { - localstr[i] = '0'; - } - strcpy(localstr + zeroes, (char *)source); - - /* Calculate the check digit - the same method used for EAN-13 */ - - for (i = 12; i >= 0; i--) { - count += ctoi(localstr[i]); - - if (!(i & 1)) { - count += 2 * ctoi(localstr[i]); - } - } - localstr[13] = check_digit(count); - localstr[14] = '\0'; - error_number = interleaved_two_of_five(symbol, (unsigned char *)localstr, strlen(localstr)); - ustrcpy(symbol->text, (unsigned char*)localstr); - return error_number; -} - -int dpleit(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Deutshe Post Leitcode */ - int i, error_number; - unsigned int count; - char localstr[16]; - int zeroes; - - error_number = 0; - count = 0; - if(length > 13) { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - zeroes = 13 - length; - for(i = 0; i < zeroes; i++) - localstr[i] = '0'; - strcpy(localstr + zeroes, (char *)source); - - for (i = 12; i >= 0; i--) - { - count += 4 * ctoi(localstr[i]); - - if (i & 1) { - count += 5 * ctoi(localstr[i]); - } - } - localstr[13] = check_digit(count); - localstr[14] = '\0'; - error_number = interleaved_two_of_five(symbol, (unsigned char *)localstr, strlen(localstr)); - ustrcpy(symbol->text, (unsigned char*)localstr); - return error_number; -} - -int dpident(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Deutsche Post Identcode */ - int i, error_number, zeroes; - unsigned int count; - char localstr[16]; - - count = 0; - if(length > 11) { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - zeroes = 11 - length; - for(i = 0; i < zeroes; i++) - localstr[i] = '0'; - strcpy(localstr + zeroes, (char *)source); - - for (i = 10; i >= 0; i--) - { - count += 4 * ctoi(localstr[i]); - - if (i & 1) { - count += 5 * ctoi(localstr[i]); - } - } - localstr[11] = check_digit(count); - localstr[12] = '\0'; - error_number = interleaved_two_of_five(symbol, (unsigned char *)localstr, strlen(localstr)); - ustrcpy(symbol->text, (unsigned char*)localstr); - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/auspost.c b/3rdparty/zint-2.4.4/backend/auspost.c deleted file mode 100644 index 0278109..0000000 --- a/3rdparty/zint-2.4.4/backend/auspost.c +++ /dev/null @@ -1,246 +0,0 @@ -/* auspost.c - Handles Australia Post 4-State Barcode */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define GDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" - -static char *AusNTable[10] = {"00", "01", "02", "10", "11", "12", "20", "21", "22", "30"}; - -static char *AusCTable[64] = {"222", "300", "301", "302", "310", "311", "312", "320", "321", "322", - "000", "001", "002", "010", "011", "012", "020", "021", "022", "100", "101", "102", "110", - "111", "112", "120", "121", "122", "200", "201", "202", "210", "211", "212", "220", "221", - "023", "030", "031", "032", "033", "103", "113", "123", "130", "131", "132", "133", "203", - "213", "223", "230", "231", "232", "233", "303", "313", "323", "330", "331", "332", "333", - "003", "013"}; - -static char *AusBarTable[64] = {"000", "001", "002", "003", "010", "011", "012", "013", "020", "021", - "022", "023", "030", "031", "032", "033", "100", "101", "102", "103", "110", "111", "112", - "113", "120", "121", "122", "123", "130", "131", "132", "133", "200", "201", "202", "203", - "210", "211", "212", "213", "220", "221", "222", "223", "230", "231", "232", "233", "300", - "301", "302", "303", "310", "311", "312", "313", "320", "321", "322", "323", "330", "331", - "332", "333"}; - -#include -#include -#include -#include "common.h" -#include "reedsol.h" - -static char convert_pattern(char data, int shift) -{ - return (data - '0') << shift; -} - -void rs_error(char data_pattern[]) -{ - /* Adds Reed-Solomon error correction to auspost */ - - int reader, triple_writer = 0; - char triple[31], inv_triple[31]; - unsigned char result[5]; - - for(reader = 2; reader < (int)strlen(data_pattern); reader += 3, triple_writer++) - { - triple[triple_writer] = convert_pattern(data_pattern[reader], 4) - + convert_pattern(data_pattern[reader + 1], 2) - + convert_pattern(data_pattern[reader + 2], 0); - } - - for(reader = 0; reader < triple_writer; reader++) - { - inv_triple[reader] = triple[(triple_writer - 1) - reader]; - } - - rs_init_gf(0x43); - rs_init_code(4, 1); - rs_encode(triple_writer, (unsigned char*) inv_triple, result); - - for(reader = 4; reader > 0; reader--) - { - concat(data_pattern, AusBarTable[(int)result[reader - 1]]); - } - rs_free(); -} - -int australia_post(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Handles Australia Posts's 4 State Codes */ - /* Customer Standard Barcode, Barcode 2 or Barcode 3 system determined automatically - (i.e. the FCC doesn't need to be specified by the user) dependent - on the length of the input string */ - - /* The contents of data_pattern conform to the following standard: - 0 = Tracker, Ascender and Descender - 1 = Tracker and Ascender - 2 = Tracker and Descender - 3 = Tracker only */ - int error_number, zeroes; - int writer; - unsigned int loopey, reader, h; - - char data_pattern[200]; - char fcc[3], dpid[10]; - char localstr[30]; - - error_number = 0; - strcpy(localstr, ""); - - /* Do all of the length checking first to avoid stack smashing */ - if(symbol->symbology == BARCODE_AUSPOST) { - /* Format control code (FCC) */ - switch(length) - { - case 8: - strcpy(fcc, "11"); - break; - case 13: - strcpy(fcc, "59"); - break; - case 16: - strcpy(fcc, "59"); - error_number = is_sane(NEON, source, length); - break; - case 18: - strcpy(fcc, "62"); - break; - case 23: - strcpy(fcc, "62"); - error_number = is_sane(NEON, source, length); - break; - default: - strcpy(symbol->errtxt, "Auspost input is wrong length"); - return ERROR_TOO_LONG; - break; - } - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - } else { - if(length > 8) { - strcpy(symbol->errtxt, "Auspost input is too long"); - return ERROR_TOO_LONG; - } - switch(symbol->symbology) { - case BARCODE_AUSREPLY: strcpy(fcc, "45"); break; - case BARCODE_AUSROUTE: strcpy(fcc, "87"); break; - case BARCODE_AUSREDIRECT: strcpy(fcc, "92"); break; - } - - /* Add leading zeros as required */ - zeroes = 8 - length; - memset(localstr, '0', zeroes); - localstr[8] = '\0'; - } - - concat(localstr, (char*)source); - h = strlen(localstr); - error_number = is_sane(GDSET, (unsigned char *)localstr, h); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* Verifiy that the first 8 characters are numbers */ - memcpy(dpid, localstr, 8); - dpid[8] = '\0'; - error_number = is_sane(NEON, (unsigned char *)dpid, strlen(dpid)); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in DPID"); - return error_number; - } - - /* Start character */ - strcpy(data_pattern, "13"); - - /* Encode the FCC */ - for(reader = 0; reader < 2; reader++) - { - lookup(NEON, AusNTable, fcc[reader], data_pattern); - } - - /* printf("AUSPOST FCC: %s ", fcc); */ - - /* Delivery Point Identifier (DPID) */ - for(reader = 0; reader < 8; reader++) - { - lookup(NEON, AusNTable, dpid[reader], data_pattern); - } - - /* Customer Information */ - if(h > 8) - { - if((h == 13) || (h == 18)) { - for(reader = 8; reader < h; reader++) { - lookup(GDSET, AusCTable, localstr[reader], data_pattern); - } - } - else if((h == 16) || (h == 23)) { - for(reader = 8; reader < h; reader++) { - lookup(NEON, AusNTable, localstr[reader], data_pattern); - } - } - } - - /* Filler bar */ - h = strlen(data_pattern); - if(h == 22) { - concat(data_pattern, "3"); - } - else if(h == 37) { - concat(data_pattern, "3"); - } - else if(h == 52) { - concat(data_pattern, "3"); - } - - /* Reed Solomon error correction */ - rs_error(data_pattern); - - /* Stop character */ - concat(data_pattern, "13"); - - /* Turn the symbol into a bar pattern ready for plotting */ - writer = 0; - h = strlen(data_pattern); - for(loopey = 0; loopey < h; loopey++) - { - if((data_pattern[loopey] == '1') || (data_pattern[loopey] == '0')) - { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - if((data_pattern[loopey] == '2') || (data_pattern[loopey] == '0')) - { - set_module(symbol, 2, writer); - } - writer += 2; - } - - symbol->row_height[0] = 3; - symbol->row_height[1] = 2; - symbol->row_height[2] = 3; - - symbol->rows = 3; - symbol->width = writer - 1; - - return error_number; -} - diff --git a/3rdparty/zint-2.4.4/backend/aztec.c b/3rdparty/zint-2.4.4/backend/aztec.c deleted file mode 100644 index a93eba7..0000000 --- a/3rdparty/zint-2.4.4/backend/aztec.c +++ /dev/null @@ -1,1352 +0,0 @@ -/* aztec.c - Handles Aztec 2D Symbols */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "aztec.h" -#include "reedsol.h" - -void mapshorten(int *charmap, int *typemap, int start, int length) -{ /* Shorten the string by one character */ - - memmove(charmap + start + 1 , charmap + start + 2, (length - 1) * sizeof(int)); - memmove(typemap + start + 1 , typemap + start + 2, (length - 1) * sizeof(int)); -} - -void insert(char binary_string[], int posn, char newbit) -{ /* Insert a character into the middle of a string at position posn */ - int i, end; - - end = strlen(binary_string); - for(i = end; i > posn; i--) { - binary_string[i] = binary_string[i - 1]; - } - binary_string[posn] = newbit; -} - -int aztec_text_process(unsigned char source[], const unsigned int src_len, char binary_string[], int gs1) -{ /* Encode input data into a binary string */ - int i, j, k, bytes; - int curtable, newtable, lasttable, chartype, maplength, blocks, debug; -#ifndef _MSC_VER - int charmap[src_len * 2], typemap[src_len * 2]; - int blockmap[2][src_len]; -#else - int* charmap = (int*)_alloca(src_len * 2 * sizeof(int)); - int* typemap = (int*)_alloca(src_len * 2 * sizeof(int)); - int* blockmap[2]; - blockmap[0] = (int*)_alloca(src_len * sizeof(int)); - blockmap[1] = (int*)_alloca(src_len * sizeof(int)); -#endif - /* Lookup input string in encoding table */ - maplength = 0; - debug = 0; - - for(i = 0; i < (int)src_len; i++) { - if(gs1 && (i == 0)) { - /* Add FNC1 to beginning of GS1 messages */ - charmap[maplength] = 0; - typemap[maplength++] = PUNC; - charmap[maplength] = 400; - typemap[maplength++] = PUNC; - } - if((gs1) && (source[i] == '[')) { - /* FNC1 represented by FLG(0) */ - charmap[maplength] = 0; - typemap[maplength++] = PUNC; - charmap[maplength] = 400; - typemap[maplength++] = PUNC; - } else { - if(source[i] > 127) { - charmap[maplength] = source[i]; - typemap[maplength++] = BINARY; - } else { - charmap[maplength] = AztecSymbolChar[source[i]]; - typemap[maplength++] = AztecCodeSet[source[i]]; - } - } - } - - /* Look for double character encoding possibilities */ - i = 0; - do{ - if(((charmap[i] == 300) && (charmap[i + 1] == 11)) && ((typemap[i] == PUNC) && (typemap[i + 1] == PUNC))) { - /* CR LF combination */ - charmap[i] = 2; - typemap[i] = PUNC; - mapshorten(charmap, typemap, i, maplength); - maplength--; - } - - if(((charmap[i] == 302) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) { - /* . SP combination */ - charmap[i] = 3; - typemap[i] = PUNC; - mapshorten(charmap, typemap, i, maplength); - maplength--; - } - - if(((charmap[i] == 301) && (charmap[i + 1] == 1)) && ((typemap[i] == 24) && (typemap[i + 1] == 23))) { - /* , SP combination */ - charmap[i] = 4; - typemap[i] = PUNC; - mapshorten(charmap, typemap, i, maplength); - maplength--; - } - - if(((charmap[i] == 21) && (charmap[i + 1] == 1)) && ((typemap[i] == PUNC) && (typemap[i + 1] == 23))) { - /* : SP combination */ - charmap[i] = 5; - typemap[i] = PUNC; - mapshorten(charmap, typemap, i, maplength); - maplength--; - } - - i++; - }while(i < (maplength - 1)); - - /* look for blocks of characters which use the same table */ - blocks = 1; - blockmap[0][0] = typemap[0]; - blockmap[1][0] = 1; - for(i = 1; i < maplength; i++) { - if(typemap[i] == typemap[i - 1]) { - blockmap[1][blocks - 1]++; - } else { - blocks++; - blockmap[0][blocks - 1] = typemap[i]; - blockmap[1][blocks - 1] = 1; - } - } - - if(blockmap[0][0] & 1) { blockmap[0][0] = 1; } - if(blockmap[0][0] & 2) { blockmap[0][0] = 2; } - if(blockmap[0][0] & 4) { blockmap[0][0] = 4; } - if(blockmap[0][0] & 8) { blockmap[0][0] = 8; } - - if(blocks > 1) { - - /* look for adjacent blocks which can use the same table (left to right search) */ - for(i = 1; i < blocks; i++) { - if(blockmap[0][i] & blockmap[0][i - 1]) { - blockmap[0][i] = (blockmap[0][i] & blockmap[0][i - 1]); - } - } - - if(blockmap[0][blocks - 1] & 1) { blockmap[0][blocks - 1] = 1; } - if(blockmap[0][blocks - 1] & 2) { blockmap[0][blocks - 1] = 2; } - if(blockmap[0][blocks - 1] & 4) { blockmap[0][blocks - 1] = 4; } - if(blockmap[0][blocks - 1] & 8) { blockmap[0][blocks - 1] = 8; } - - /* look for adjacent blocks which can use the same table (right to left search) */ - for(i = blocks - 1; i > 0; i--) { - if(blockmap[0][i] & blockmap[0][i + 1]) { - blockmap[0][i] = (blockmap[0][i] & blockmap[0][i + 1]); - } - } - - /* determine the encoding table for characters which do not fit with adjacent blocks */ - for(i = 1; i < blocks; i++) { - if(blockmap[0][i] & 8) { blockmap[0][i] = 8; } - if(blockmap[0][i] & 4) { blockmap[0][i] = 4; } - if(blockmap[0][i] & 2) { blockmap[0][i] = 2; } - if(blockmap[0][i] & 1) { blockmap[0][i] = 1; } - } - - /* Combine blocks of the same type */ - i = 0; - do{ - if(blockmap[0][i] == blockmap[0][i + 1]) { - blockmap[1][i] += blockmap[1][i + 1]; - for(j = i + 1; j < blocks; j++) { - blockmap[0][j] = blockmap[0][j + 1]; - blockmap[1][j] = blockmap[1][j + 1]; - } - blocks--; - } else { - i++; - } - } while (i < blocks); - } - - /* Put the adjusted block data back into typemap */ - j = 0; - for(i = 0; i < blocks; i++) { - if((blockmap[1][i] < 3) && (blockmap[0][i] != 32)) { /* Shift character(s) needed */ - for(k = 0; k < blockmap[1][i]; k++) { - typemap[j + k] = blockmap[0][i] + 64; - } - } else { /* Latch character (or byte mode) needed */ - for(k = 0; k < blockmap[1][i]; k++) { - typemap[j + k] = blockmap[0][i]; - } - } - j += blockmap[1][i]; - } - - /* Don't shift an initial capital letter */ - if(typemap[0] == 65) { typemap[0] = 1; }; - - /* Problem characters (those that appear in different tables with different values) can now be resolved into their tables */ - for(i = 0; i < maplength; i++) { - if((charmap[i] >= 300) && (charmap[i] < 400)) { - curtable = typemap[i]; - if(curtable > 64) { - curtable -= 64; - } - switch(charmap[i]) { - case 300: /* Carriage Return */ - switch(curtable) { - case PUNC: charmap[i] = 1; break; - case MIXED: charmap[i] = 14; break; - } - break; - case 301: /* Comma */ - switch(curtable) { - case PUNC: charmap[i] = 17; break; - case DIGIT: charmap[i] = 12; break; - } - break; - case 302: /* Full Stop */ - switch(curtable) { - case PUNC: charmap[i] = 19; break; - case DIGIT: charmap[i] = 13; break; - } - break; - } - } - } - *binary_string = '\0'; - - curtable = UPPER; /* start with UPPER table */ - lasttable = UPPER; - for(i = 0; i < maplength; i++) { - newtable = curtable; - if((typemap[i] != curtable) && (charmap[i] < 400)) { - /* Change table */ - if(curtable == BINARY) { - /* If ending binary mode the current table is the same as when entering binary mode */ - curtable = lasttable; - newtable = lasttable; - } - if(typemap[i] > 64) { - /* Shift character */ - switch(typemap[i]) { - case (64 + UPPER): /* To UPPER */ - switch(curtable) { - case LOWER: /* US */ - concat(binary_string, hexbit[28]); - if(debug) printf("US "); - break; - case MIXED: /* UL */ - concat(binary_string, hexbit[29]); - if(debug) printf("UL "); - newtable = UPPER; - break; - case PUNC: /* UL */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - newtable = UPPER; - break; - case DIGIT: /* US */ - concat(binary_string, pentbit[15]); - if(debug) printf("US "); - break; - } - break; - case (64 + LOWER): /* To LOWER */ - switch(curtable) { - case UPPER: /* LL */ - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - case MIXED: /* LL */ - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - case PUNC: /* UL LL */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - case DIGIT: /* UL LL */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - } - break; - case (64 + MIXED): /* To MIXED */ - switch(curtable) { - case UPPER: /* ML */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - case LOWER: /* ML */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - case PUNC: /* UL ML */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - case DIGIT: /* UL ML */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - } - break; - case (64 + PUNC): /* To PUNC */ - switch(curtable) { - case UPPER: /* PS */ - concat(binary_string, hexbit[0]); - if(debug) printf("PS "); - break; - case LOWER: /* PS */ - concat(binary_string, hexbit[0]); - if(debug) printf("PS "); - break; - case MIXED: /* PS */ - concat(binary_string, hexbit[0]); - if(debug) printf("PS "); - break; - case DIGIT: /* PS */ - concat(binary_string, pentbit[0]); - if(debug) printf("PS "); - break; - } - break; - case (64 + DIGIT): /* To DIGIT */ - switch(curtable) { - case UPPER: /* DL */ - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - case LOWER: /* DL */ - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - case MIXED: /* UL DL */ - concat(binary_string, hexbit[29]); - if(debug) printf("UL "); - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - case PUNC: /* UL DL */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - } - break; - } - } else { - /* Latch character */ - switch(typemap[i]) { - case UPPER: /* To UPPER */ - switch(curtable) { - case LOWER: /* ML UL */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - concat(binary_string, hexbit[29]); - if(debug) printf("UL "); - newtable = UPPER; - break; - case MIXED: /* UL */ - concat(binary_string, hexbit[29]); - if(debug) printf("UL "); - newtable = UPPER; - break; - case PUNC: /* UL */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - newtable = UPPER; - break; - case DIGIT: /* UL */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - newtable = UPPER; - break; - } - break; - case LOWER: /* To LOWER */ - switch(curtable) { - case UPPER: /* LL */ - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - case MIXED: /* LL */ - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - case PUNC: /* UL LL */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - case DIGIT: /* UL LL */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - concat(binary_string, hexbit[28]); - if(debug) printf("LL "); - newtable = LOWER; - break; - } - break; - case MIXED: /* To MIXED */ - switch(curtable) { - case UPPER: /* ML */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - case LOWER: /* ML */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - case PUNC: /* UL ML */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - case DIGIT: /* UL ML */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - newtable = MIXED; - break; - } - break; - case PUNC: /* To PUNC */ - switch(curtable) { - case UPPER: /* ML PL */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - concat(binary_string, hexbit[30]); - if(debug) printf("PL "); - newtable = PUNC; - break; - case LOWER: /* ML PL */ - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - concat(binary_string, hexbit[30]); - if(debug) printf("PL "); - newtable = PUNC; - break; - case MIXED: /* PL */ - concat(binary_string, hexbit[30]); - if(debug) printf("PL "); - newtable = PUNC; - break; - case DIGIT: /* UL ML PL */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - concat(binary_string, hexbit[29]); - if(debug) printf("ML "); - concat(binary_string, hexbit[30]); - if(debug) printf("PL "); - newtable = PUNC; - break; - } - break; - case DIGIT: /* To DIGIT */ - switch(curtable) { - case UPPER: /* DL */ - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - case LOWER: /* DL */ - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - case MIXED: /* UL DL */ - concat(binary_string, hexbit[29]); - if(debug) printf("UL "); - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - case PUNC: /* UL DL */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[30]); - if(debug) printf("DL "); - newtable = DIGIT; - break; - } - break; - case BINARY: /* To BINARY */ - lasttable = curtable; - switch(curtable) { - case UPPER: /* BS */ - concat(binary_string, hexbit[31]); - if(debug) printf("BS "); - newtable = BINARY; - break; - case LOWER: /* BS */ - concat(binary_string, hexbit[31]); - if(debug) printf("BS "); - newtable = BINARY; - break; - case MIXED: /* BS */ - concat(binary_string, hexbit[31]); - if(debug) printf("BS "); - newtable = BINARY; - break; - case PUNC: /* UL BS */ - concat(binary_string, hexbit[31]); - if(debug) printf("UL "); - concat(binary_string, hexbit[31]); - if(debug) printf("BS "); - newtable = BINARY; - break; - case DIGIT: /* UL BS */ - concat(binary_string, pentbit[14]); - if(debug) printf("UL "); - concat(binary_string, hexbit[31]); - if(debug) printf("BS "); - newtable = BINARY; - break; - } - - bytes = 0; - do{ - bytes++; - }while(typemap[i + (bytes - 1)] == BINARY); - bytes--; - - if(bytes > 2079) { - return ERROR_TOO_LONG; - } - - if(bytes > 31) { /* Put 00000 followed by 11-bit number of bytes less 31 */ - int adjusted; - - adjusted = bytes - 31; - concat(binary_string, "00000"); - if(adjusted & 0x400) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x200) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x100) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(adjusted & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - } else { /* Put 5-bit number of bytes */ - if(bytes & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(bytes & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(bytes & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(bytes & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(bytes & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - } - if(debug) printf("(%d bytes) ", bytes); - - break; - } - } - } - /* Add data to the binary string */ - curtable = newtable; - chartype = typemap[i]; - if(chartype > 64) { chartype -= 64; } - switch(chartype) { - case UPPER: - case LOWER: - case MIXED: - case PUNC: - if(charmap[i] >= 400) { - concat(binary_string, tribit[charmap[i] - 400]); - if(debug) printf("FLG(%d) ",charmap[i] - 400); - } else { - concat(binary_string, hexbit[charmap[i]]); - if(!((chartype == PUNC) && (charmap[i] == 0))) - if(debug) printf("%d ",charmap[i]); - } - break; - case DIGIT: - concat(binary_string, pentbit[charmap[i]]); - if(debug) printf("%d ",charmap[i]); - break; - case BINARY: - if(charmap[i] & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(charmap[i] & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(debug) printf("%d ",charmap[i]); - break; - } - - } - - if(debug) printf("\n"); - - if(strlen(binary_string) > 14970) { - return ERROR_TOO_LONG; - } - - return 0; -} - -int aztec(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int x, y, i, j, data_blocks, ecc_blocks, layers, total_bits; - char binary_string[20000], bit_pattern[20045], descriptor[42]; - char adjusted_string[20000]; - unsigned char desc_data[4], desc_ecc[6]; - int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length; - int remainder, padbits, count, gs1, adjustment_size; - int debug = 0, reader = 0; - int comp_loop = 4; - -#ifndef _MSC_VER - unsigned char local_source[length + 1]; -#else - unsigned int* data_part; - unsigned int* ecc_part; - unsigned char* local_source = (unsigned char*)_alloca(length + 1); -#endif - - memset(binary_string,0,20000); - memset(adjusted_string,0,20000); - - if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } - if(symbol->output_options & READER_INIT) { reader = 1; comp_loop = 1; } - if((gs1 == 1) && (reader == 1)) { - strcpy(symbol->errtxt, "Cannot encode in GS1 and Reader Initialisation mode at the same time"); - return ERROR_INVALID_OPTION; - } - - switch(symbol->input_mode) { - case DATA_MODE: - case GS1_MODE: - memcpy(local_source, source, length); - local_source[length] = '\0'; - break; - case UNICODE_MODE: - err_code = latin1_process(symbol, source, local_source, &length); - if(err_code != 0) { return err_code; } - break; - } - - /* Aztec code can't handle NULL characters */ - for(i = 0; i < length; i++) { - if(local_source[i] == '\0') { - strcpy(symbol->errtxt, "Invalid character (NULL) in input data"); - return ERROR_INVALID_DATA1; - } - } - - err_code = aztec_text_process(local_source, length, binary_string, gs1); - - - if(err_code != 0) { - strcpy(symbol->errtxt, "Input too long or too many extended ASCII characters"); - return err_code; - } - - if(!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) { - strcpy(symbol->errtxt, "Invalid error correction level - using default instead"); - err_code = WARN_INVALID_OPTION; - symbol->option_1 = -1; - } - - ecc_level = symbol->option_1; - - if((ecc_level == -1) || (ecc_level == 0)) { - ecc_level = 2; - } - - data_length = strlen(binary_string); - - layers = 0; /* Keep compiler happy! */ - data_maxsize = 0; /* Keep compiler happy! */ - adjustment_size = 0; - if(symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */ - do { - /* Decide what size symbol to use - the smallest that fits the data */ - compact = 0; /* 1 = Aztec Compact, 0 = Normal Aztec */ - layers = 0; - - switch(ecc_level) { - /* For each level of error correction work out the smallest symbol which - the data will fit in */ - case 1: for(i = 32; i > 0; i--) { - if((data_length + adjustment_size) < Aztec10DataSizes[i - 1]) { - layers = i; - compact = 0; - data_maxsize = Aztec10DataSizes[i - 1]; - } - } - for(i = comp_loop; i > 0; i--) { - if((data_length + adjustment_size) < AztecCompact10DataSizes[i - 1]) { - layers = i; - compact = 1; - data_maxsize = AztecCompact10DataSizes[i - 1]; - } - } - break; - case 2: for(i = 32; i > 0; i--) { - if((data_length + adjustment_size) < Aztec23DataSizes[i - 1]) { - layers = i; - compact = 0; - data_maxsize = Aztec23DataSizes[i - 1]; - } - } - for(i = comp_loop; i > 0; i--) { - if((data_length + adjustment_size) < AztecCompact23DataSizes[i - 1]) { - layers = i; - compact = 1; - data_maxsize = AztecCompact23DataSizes[i - 1]; - } - } - break; - case 3: for(i = 32; i > 0; i--) { - if((data_length + adjustment_size) < Aztec36DataSizes[i - 1]) { - layers = i; - compact = 0; - data_maxsize = Aztec36DataSizes[i - 1]; - } - } - for(i = comp_loop; i > 0; i--) { - if((data_length + adjustment_size) < AztecCompact36DataSizes[i - 1]) { - layers = i; - compact = 1; - data_maxsize = AztecCompact36DataSizes[i - 1]; - } - } - break; - case 4: for(i = 32; i > 0; i--) { - if((data_length + adjustment_size) < Aztec50DataSizes[i - 1]) { - layers = i; - compact = 0; - data_maxsize = Aztec50DataSizes[i - 1]; - } - } - for(i = comp_loop; i > 0; i--) { - if((data_length + adjustment_size) < AztecCompact50DataSizes[i - 1]) { - layers = i; - compact = 1; - data_maxsize = AztecCompact50DataSizes[i - 1]; - } - } - break; - } - - if(layers == 0) { /* Couldn't find a symbol which fits the data */ - strcpy(symbol->errtxt, "Input too long (too many bits for selected ECC)"); - return ERROR_TOO_LONG; - } - - /* Determine codeword bitlength - Table 3 */ - codeword_size = 6; /* if (layers <= 2) */ - if((layers >= 3) && (layers <= 8)) { codeword_size = 8; } - if((layers >= 9) && (layers <= 22)) { codeword_size = 10; } - if(layers >= 23) { codeword_size = 12; } - - j = 0; i = 0; - do { - if((j + 1) % codeword_size == 0) { - /* Last bit of codeword */ - int t, done = 0; - count = 0; - - /* Discover how many '1's in current codeword */ - for(t = 0; t < (codeword_size - 1); t++) { - if(binary_string[(i - (codeword_size - 1)) + t] == '1') count++; - } - - if(count == (codeword_size - 1)) { - adjusted_string[j] = '0'; - j++; - done = 1; - } - - if(count == 0) { - adjusted_string[j] = '1'; - j++; - done = 1; - } - - if(done == 0) { - adjusted_string[j] = binary_string[i]; - j++; - i++; - } - } - adjusted_string[j] = binary_string[i]; - j++; - i++; - } while (i <= (data_length + 1)); - adjusted_string[j] = '\0'; - adjusted_length = strlen(adjusted_string); - adjustment_size = adjusted_length - data_length; - - /* Add padding */ - remainder = adjusted_length % codeword_size; - - padbits = codeword_size - remainder; - if(padbits == codeword_size) { padbits = 0; } - - for(i = 0; i < padbits; i++) { - concat(adjusted_string, "1"); - } - adjusted_length = strlen(adjusted_string); - - count = 0; - for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) { - if(adjusted_string[i] == '1') { count++; } - } - if(count == codeword_size) { adjusted_string[adjusted_length - 1] = '0'; } - - if(debug) { - printf("Codewords:\n"); - for(i = 0; i < (adjusted_length / codeword_size); i++) { - for(j = 0; j < codeword_size; j++) { - printf("%c", adjusted_string[(i * codeword_size) + j]); - } - printf("\n"); - } - } - - } while(adjusted_length > data_maxsize); - /* This loop will only repeat on the rare occasions when the rule about not having all 1s or all 0s - means that the binary string has had to be lengthened beyond the maximum number of bits that can - be encoded in a symbol of the selected size */ - - } else { /* The size of the symbol has been specified by the user */ - if((reader == 1) && ((symbol->option_2 >= 2) && (symbol->option_2 <= 4))) { - symbol->option_2 = 5; - } - if((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) { - compact = 1; - layers = symbol->option_2; - } - if((symbol->option_2 >= 5) && (symbol->option_2 <= 36)) { - compact = 0; - layers = symbol->option_2 - 4; - } - if((symbol->option_2 < 0) || (symbol->option_2 > 36)) { - strcpy(symbol->errtxt, "Invalid Aztec Code size"); - return ERROR_INVALID_OPTION; - } - - /* Determine codeword bitlength - Table 3 */ - if((layers >= 0) && (layers <= 2)) { codeword_size = 6; } - if((layers >= 3) && (layers <= 8)) { codeword_size = 8; } - if((layers >= 9) && (layers <= 22)) { codeword_size = 10; } - if(layers >= 23) { codeword_size = 12; } - - j = 0; i = 0; - do { - if((j + 1) % codeword_size == 0) { - /* Last bit of codeword */ - int t, done = 0; - count = 0; - - /* Discover how many '1's in current codeword */ - for(t = 0; t < (codeword_size - 1); t++) { - if(binary_string[(i - (codeword_size - 1)) + t] == '1') count++; - } - - if(count == (codeword_size - 1)) { - adjusted_string[j] = '0'; - j++; - done = 1; - } - - if(count == 0) { - adjusted_string[j] = '1'; - j++; - done = 1; - } - - if(done == 0) { - adjusted_string[j] = binary_string[i]; - j++; - i++; - } - } - adjusted_string[j] = binary_string[i]; - j++; - i++; - } while (i <= (data_length + 1)); - adjusted_string[j] = '\0'; - adjusted_length = strlen(adjusted_string); - - remainder = adjusted_length % codeword_size; - - padbits = codeword_size - remainder; - if(padbits == codeword_size) { padbits = 0; } - - for(i = 0; i < padbits; i++) { - concat(adjusted_string, "1"); - } - adjusted_length = strlen(adjusted_string); - - count = 0; - for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) { - if(adjusted_string[i] == '1') { count++; } - } - if(count == codeword_size) { adjusted_string[adjusted_length - 1] = '0'; } - - /* Check if the data actually fits into the selected symbol size */ - if (compact) { - data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3); - } else { - data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3); - } - - if(adjusted_length > data_maxsize) { - strcpy(symbol->errtxt, "Data too long for specified Aztec Code symbol size"); - return ERROR_TOO_LONG; - } - - if(debug) { - printf("Codewords:\n"); - for(i = 0; i < (adjusted_length / codeword_size); i++) { - for(j = 0; j < codeword_size; j++) { - printf("%c", adjusted_string[(i * codeword_size) + j]); - } - printf("\n"); - } - } - - } - - if(reader && (layers > 22)) { - strcpy(symbol->errtxt, "Data too long for reader initialisation symbol"); - return ERROR_TOO_LONG; - } - - data_blocks = adjusted_length / codeword_size; - - if(compact) { - ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks; - } else { - ecc_blocks = AztecSizes[layers - 1] - data_blocks; - } - - if(debug) { - printf("Generating a "); - if(compact) { printf("compact"); } else { printf("full-size"); } - printf(" symbol with %d layers\n", layers); - printf("Requires "); - if(compact) { printf("%d", AztecCompactSizes[layers - 1]); } else { printf("%d", AztecSizes[layers - 1]); } - printf(" codewords of %d-bits\n", codeword_size); - printf(" (%d data words, %d ecc words)\n", data_blocks, ecc_blocks); - } - -#ifndef _MSC_VER - unsigned int data_part[data_blocks + 3], ecc_part[ecc_blocks + 3]; -#else - data_part = (unsigned int*)_alloca((data_blocks + 3) * sizeof(unsigned int)); - ecc_part = (unsigned int*)_alloca((ecc_blocks + 3) * sizeof(unsigned int)); -#endif - /* Copy across data into separate integers */ - memset(data_part,0,(data_blocks + 2)*sizeof(int)); - memset(ecc_part,0,(ecc_blocks + 2)*sizeof(int)); - - /* Split into codewords and calculate reed-colomon error correction codes */ - switch(codeword_size) { - case 6: - for(i = 0; i < data_blocks; i++) { - if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 32; } - if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 16; } - if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 8; } - if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 4; } - if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 2; } - if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 1; } - } - rs_init_gf(0x43); - rs_init_code(ecc_blocks, 1); - rs_encode_long(data_blocks, data_part, ecc_part); - for(i = (ecc_blocks - 1); i >= 0; i--) { - if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - } - rs_free(); - break; - case 8: - for(i = 0; i < data_blocks; i++) { - if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 128; } - if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 64; } - if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 32; } - if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 16; } - if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 8; } - if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 4; } - if(adjusted_string[(i * codeword_size) + 6] == '1') { data_part[i] += 2; } - if(adjusted_string[(i * codeword_size) + 7] == '1') { data_part[i] += 1; } - } - rs_init_gf(0x12d); - rs_init_code(ecc_blocks, 1); - rs_encode_long(data_blocks, data_part, ecc_part); - for(i = (ecc_blocks - 1); i >= 0; i--) { - if(ecc_part[i] & 0x80) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x40) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - } - rs_free(); - break; - case 10: - for(i = 0; i < data_blocks; i++) { - if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 512; } - if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 256; } - if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 128; } - if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 64; } - if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 32; } - if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 16; } - if(adjusted_string[(i * codeword_size) + 6] == '1') { data_part[i] += 8; } - if(adjusted_string[(i * codeword_size) + 7] == '1') { data_part[i] += 4; } - if(adjusted_string[(i * codeword_size) + 8] == '1') { data_part[i] += 2; } - if(adjusted_string[(i * codeword_size) + 9] == '1') { data_part[i] += 1; } - } - rs_init_gf(0x409); - rs_init_code(ecc_blocks, 1); - rs_encode_long(data_blocks, data_part, ecc_part); - for(i = (ecc_blocks - 1); i >= 0; i--) { - if(ecc_part[i] & 0x200) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x100) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x80) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x40) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - } - rs_free(); - break; - case 12: - for(i = 0; i < data_blocks; i++) { - if(adjusted_string[i * codeword_size] == '1') { data_part[i] += 2048; } - if(adjusted_string[(i * codeword_size) + 1] == '1') { data_part[i] += 1024; } - if(adjusted_string[(i * codeword_size) + 2] == '1') { data_part[i] += 512; } - if(adjusted_string[(i * codeword_size) + 3] == '1') { data_part[i] += 256; } - if(adjusted_string[(i * codeword_size) + 4] == '1') { data_part[i] += 128; } - if(adjusted_string[(i * codeword_size) + 5] == '1') { data_part[i] += 64; } - if(adjusted_string[(i * codeword_size) + 6] == '1') { data_part[i] += 32; } - if(adjusted_string[(i * codeword_size) + 7] == '1') { data_part[i] += 16; } - if(adjusted_string[(i * codeword_size) + 8] == '1') { data_part[i] += 8; } - if(adjusted_string[(i * codeword_size) + 9] == '1') { data_part[i] += 4; } - if(adjusted_string[(i * codeword_size) + 10] == '1') { data_part[i] += 2; } - if(adjusted_string[(i * codeword_size) + 11] == '1') { data_part[i] += 1; } - } - rs_init_gf(0x1069); - rs_init_code(ecc_blocks, 1); - rs_encode_long(data_blocks, data_part, ecc_part); - for(i = (ecc_blocks - 1); i >= 0; i--) { - if(ecc_part[i] & 0x800) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x400) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x200) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x100) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x80) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x40) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x20) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x10) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x08) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x04) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x02) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - if(ecc_part[i] & 0x01) { concat(adjusted_string, "1"); } else { concat(adjusted_string, "0"); } - } - rs_free(); - break; - } - - /* Invert the data so that actual data is on the outside and reed-solomon on the inside */ - memset(bit_pattern,'0',20045); - - total_bits = (data_blocks + ecc_blocks) * codeword_size; - for(i = 0; i < total_bits; i++) { - bit_pattern[i] = adjusted_string[total_bits - i - 1]; - } - - /* Now add the symbol descriptor */ - memset(desc_data,0,4); - memset(desc_ecc,0,6); - memset(descriptor,0,42); - - if(compact) { - /* The first 2 bits represent the number of layers minus 1 */ - if((layers - 1) & 0x02) { descriptor[0] = '1'; } else { descriptor[0] = '0'; } - if((layers - 1) & 0x01) { descriptor[1] = '1'; } else { descriptor[1] = '0'; } - /* The next 6 bits represent the number of data blocks minus 1 */ - if(reader) { - descriptor[2] = '1'; - } else { - if((data_blocks - 1) & 0x20) { descriptor[2] = '1'; } else { descriptor[2] = '0'; } - } - if((data_blocks - 1) & 0x10) { descriptor[3] = '1'; } else { descriptor[3] = '0'; } - if((data_blocks - 1) & 0x08) { descriptor[4] = '1'; } else { descriptor[4] = '0'; } - if((data_blocks - 1) & 0x04) { descriptor[5] = '1'; } else { descriptor[5] = '0'; } - if((data_blocks - 1) & 0x02) { descriptor[6] = '1'; } else { descriptor[6] = '0'; } - if((data_blocks - 1) & 0x01) { descriptor[7] = '1'; } else { descriptor[7] = '0'; } - descriptor[8] = '\0'; - if(debug) printf("Mode Message = %s\n", descriptor); - } else { - /* The first 5 bits represent the number of layers minus 1 */ - if((layers - 1) & 0x10) { descriptor[0] = '1'; } else { descriptor[0] = '0'; } - if((layers - 1) & 0x08) { descriptor[1] = '1'; } else { descriptor[1] = '0'; } - if((layers - 1) & 0x04) { descriptor[2] = '1'; } else { descriptor[2] = '0'; } - if((layers - 1) & 0x02) { descriptor[3] = '1'; } else { descriptor[3] = '0'; } - if((layers - 1) & 0x01) { descriptor[4] = '1'; } else { descriptor[4] = '0'; } - /* The next 11 bits represent the number of data blocks minus 1 */ - if(reader) { - descriptor[5] = '1'; - } else { - if((data_blocks - 1) & 0x400) { descriptor[5] = '1'; } else { descriptor[5] = '0'; } - } - if((data_blocks - 1) & 0x200) { descriptor[6] = '1'; } else { descriptor[6] = '0'; } - if((data_blocks - 1) & 0x100) { descriptor[7] = '1'; } else { descriptor[7] = '0'; } - if((data_blocks - 1) & 0x80) { descriptor[8] = '1'; } else { descriptor[8] = '0'; } - if((data_blocks - 1) & 0x40) { descriptor[9] = '1'; } else { descriptor[9] = '0'; } - if((data_blocks - 1) & 0x20) { descriptor[10] = '1'; } else { descriptor[10] = '0'; } - if((data_blocks - 1) & 0x10) { descriptor[11] = '1'; } else { descriptor[11] = '0'; } - if((data_blocks - 1) & 0x08) { descriptor[12] = '1'; } else { descriptor[12] = '0'; } - if((data_blocks - 1) & 0x04) { descriptor[13] = '1'; } else { descriptor[13] = '0'; } - if((data_blocks - 1) & 0x02) { descriptor[14] = '1'; } else { descriptor[14] = '0'; } - if((data_blocks - 1) & 0x01) { descriptor[15] = '1'; } else { descriptor[15] = '0'; } - descriptor[16] = '\0'; - if(debug) printf("Mode Message = %s\n", descriptor); - } - - /* Split into 4-bit codewords */ - for(i = 0; i < 4; i++) { - if(descriptor[i * 4] == '1') { desc_data[i] += 8; } - if(descriptor[(i * 4) + 1] == '1') { desc_data[i] += 4; } - if(descriptor[(i * 4) + 2] == '1') { desc_data[i] += 2; } - if(descriptor[(i * 4) + 3] == '1') { desc_data[i] += 1; } - } - - /* Add reed-solomon error correction with Galois field GF(16) and prime modulus - x^4 + x + 1 (section 7.2.3)*/ - - rs_init_gf(0x13); - if(compact) { - rs_init_code(5, 1); - rs_encode(2, desc_data, desc_ecc); - for(i = 0; i < 5; i++) { - if(desc_ecc[4 - i] & 0x08) { descriptor[(i * 4) + 8] = '1'; } else { descriptor[(i * 4) + 8] = '0'; } - if(desc_ecc[4 - i] & 0x04) { descriptor[(i * 4) + 9] = '1'; } else { descriptor[(i * 4) + 9] = '0'; } - if(desc_ecc[4 - i] & 0x02) { descriptor[(i * 4) + 10] = '1'; } else { descriptor[(i * 4) + 10] = '0'; } - if(desc_ecc[4 - i] & 0x01) { descriptor[(i * 4) + 11] = '1'; } else { descriptor[(i * 4) + 11] = '0'; } - } - } else { - rs_init_code(6, 1); - rs_encode(4, desc_data, desc_ecc); - for(i = 0; i < 6; i++) { - if(desc_ecc[5 - i] & 0x08) { descriptor[(i * 4) + 16] = '1'; } else { descriptor[(i * 4) + 16] = '0'; } - if(desc_ecc[5 - i] & 0x04) { descriptor[(i * 4) + 17] = '1'; } else { descriptor[(i * 4) + 17] = '0'; } - if(desc_ecc[5 - i] & 0x02) { descriptor[(i * 4) + 18] = '1'; } else { descriptor[(i * 4) + 18] = '0'; } - if(desc_ecc[5 - i] & 0x01) { descriptor[(i * 4) + 19] = '1'; } else { descriptor[(i * 4) + 19] = '0'; } - } - } - rs_free(); - - /* Merge descriptor with the rest of the symbol */ - for(i = 0; i < 40; i++) { - if(compact) { - bit_pattern[2000 + i - 2] = descriptor[i]; - } else { - bit_pattern[20000 + i - 2] = descriptor[i]; - } - } - - /* Plot all of the data into the symbol in pre-defined spiral pattern */ - if(compact) { - - for(y = AztecCompactOffset[layers - 1]; y < (27 - AztecCompactOffset[layers - 1]); y++) { - for(x = AztecCompactOffset[layers - 1]; x < (27 - AztecCompactOffset[layers - 1]); x++) { - if(CompactAztecMap[(y * 27) + x] == 1) { - set_module(symbol, y - AztecCompactOffset[layers - 1], x - AztecCompactOffset[layers - 1]); - } - if(CompactAztecMap[(y * 27) + x] >= 2) { - if(bit_pattern[CompactAztecMap[(y * 27) + x] - 2] == '1') { - set_module(symbol, y - AztecCompactOffset[layers - 1], x - AztecCompactOffset[layers - 1]); - } - } - } - symbol->row_height[y - AztecCompactOffset[layers - 1]] = 1; - } - symbol->rows = 27 - (2 * AztecCompactOffset[layers - 1]); - symbol->width = 27 - (2 * AztecCompactOffset[layers - 1]); - } else { - - for(y = AztecOffset[layers - 1]; y < (151 - AztecOffset[layers - 1]); y++) { - for(x = AztecOffset[layers - 1]; x < (151 - AztecOffset[layers - 1]); x++) { - if(AztecMap[(y * 151) + x] == 1) { - set_module(symbol, y - AztecOffset[layers - 1], x - AztecOffset[layers - 1]); - } - if(AztecMap[(y * 151) + x] >= 2) { - if(bit_pattern[AztecMap[(y * 151) + x] - 2] == '1') { - set_module(symbol, y - AztecOffset[layers - 1], x - AztecOffset[layers - 1]); - } - } - } - symbol->row_height[y - AztecOffset[layers - 1]] = 1; - } - symbol->rows = 151 - (2 * AztecOffset[layers - 1]); - symbol->width = 151 - (2 * AztecOffset[layers - 1]); - } - - return err_code; -} - -int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int input_value, error_number, i, y, x; - char binary_string[28]; - unsigned char data_codewords[3], ecc_codewords[6]; - - error_number = 0; - input_value = 0; - if(length > 3) { - strcpy(symbol->errtxt, "Input too large"); - return ERROR_INVALID_DATA1; - } - error_number = is_sane(NEON, source, length); - if(error_number != 0) { - strcpy(symbol->errtxt, "Invalid characters in input"); - return ERROR_INVALID_DATA1; - } - switch(length) { - case 3: input_value = 100 * ctoi(source[0]); - input_value += 10 * ctoi(source[1]); - input_value += ctoi(source[2]); - break; - case 2: input_value = 10 * ctoi(source[0]); - input_value += ctoi(source[1]); - break; - case 1: input_value = ctoi(source[0]); - break; - } - - if(input_value > 255) { - strcpy(symbol->errtxt, "Input too large"); - return ERROR_INVALID_DATA1; - } - - strcpy(binary_string, ""); - if(input_value & 0x80) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x40) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x20) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x10) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x08) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x04) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x02) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - if(input_value & 0x01) { concat(binary_string, "1"); } else { concat(binary_string, "0"); } - - data_codewords[0] = 0; - data_codewords[1] = 0; - - for(i = 0; i < 2; i++) { - if(binary_string[i * 4] == '1') { data_codewords[i] += 8; } - if(binary_string[(i * 4) + 1] == '1') { data_codewords[i] += 4; } - if(binary_string[(i * 4) + 2] == '1') { data_codewords[i] += 2; } - if(binary_string[(i * 4) + 3] == '1') { data_codewords[i] += 1; } - } - - rs_init_gf(0x13); - rs_init_code(5, 1); - rs_encode(2, data_codewords, ecc_codewords); - rs_free(); - - strcpy(binary_string, ""); - - for(i = 0; i < 5; i++) { - if(ecc_codewords[4 - i] & 0x08) { binary_string[(i * 4) + 8] = '1'; } else { binary_string[(i * 4) + 8] = '0'; } - if(ecc_codewords[4 - i] & 0x04) { binary_string[(i * 4) + 9] = '1'; } else { binary_string[(i * 4) + 9] = '0'; } - if(ecc_codewords[4 - i] & 0x02) { binary_string[(i * 4) + 10] = '1'; } else { binary_string[(i * 4) + 10] = '0'; } - if(ecc_codewords[4 - i] & 0x01) { binary_string[(i * 4) + 11] = '1'; } else { binary_string[(i * 4) + 11] = '0'; } - } - - for(i = 0; i < 28; i += 2) { - if(binary_string[i] == '1') { binary_string[i] = '0'; } else { binary_string[i] = '1'; } - } - - for(y = 8; y < 19; y++) { - for(x = 8; x < 19; x++) { - if(CompactAztecMap[(y * 27) + x] == 1) { - set_module(symbol, y - 8, x - 8); - } - if(CompactAztecMap[(y * 27) + x] >= 2) { - if(binary_string[CompactAztecMap[(y * 27) + x] - 2000] == '1') { - set_module(symbol, y - 8, x - 8); - } - } - } - symbol->row_height[y - 8] = 1; - } - symbol->rows = 11; - symbol->width = 11; - - return 0; -} diff --git a/3rdparty/zint-2.4.4/backend/aztec.h b/3rdparty/zint-2.4.4/backend/aztec.h deleted file mode 100644 index 93e0e27..0000000 --- a/3rdparty/zint-2.4.4/backend/aztec.h +++ /dev/null @@ -1,291 +0,0 @@ -/* aztec.c - Handles Aztec Mesa 2D Symbols */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define UPPER 1 -#define LOWER 2 -#define MIXED 4 -#define PUNC 8 -#define DIGIT 16 -#define BINARY 32 - -static int AztecMap[] = { /* 151 x 151 data grid */ - 19969,19968,18851,18853,18855,18857,18859,18861,18863,18865,18867,0,18869,18871,18873,18875,18877,18879,18881,18883,18885,18887,18889,18891,18893,18895,18897,0,18899,18901,18903,18905,18907,18909,18911,18913,18915,18917,18919,18921,18923,18925,18927,0,18929,18931,18933,18935,18937,18939,18941,18943,18945,18947,18949,18951,18953,18955,18957,0,18959,18961,18963,18965,18967,18969,18971,18973,18975,18977,18979,18981,18983,18985,18987,0,18989,18991,18993,18995,18997,18999,19001,19003,19005,19007,19009,19011,19013,19015,19017,0,19019,19021,19023,19025,19027,19029,19031,19033,19035,19037,19039,19041,19043,19045,19047,0,19049,19051,19053,19055,19057,19059,19061,19063,19065,19067,19069,19071,19073,19075,19077,0,19079,19081,19083,19085,19087,19089,19091,19093,19095,19097,19099,19101,19103,19105,19107,0,19109,19111,19113,19115,19117,19119,19121,19123,19125,19127,19129, - 19967,19966,18850,18852,18854,18856,18858,18860,18862,18864,18866,1,18868,18870,18872,18874,18876,18878,18880,18882,18884,18886,18888,18890,18892,18894,18896,1,18898,18900,18902,18904,18906,18908,18910,18912,18914,18916,18918,18920,18922,18924,18926,1,18928,18930,18932,18934,18936,18938,18940,18942,18944,18946,18948,18950,18952,18954,18956,1,18958,18960,18962,18964,18966,18968,18970,18972,18974,18976,18978,18980,18982,18984,18986,1,18988,18990,18992,18994,18996,18998,19000,19002,19004,19006,19008,19010,19012,19014,19016,1,19018,19020,19022,19024,19026,19028,19030,19032,19034,19036,19038,19040,19042,19044,19046,1,19048,19050,19052,19054,19056,19058,19060,19062,19064,19066,19068,19070,19072,19074,19076,1,19078,19080,19082,19084,19086,19088,19090,19092,19094,19096,19098,19100,19102,19104,19106,1,19108,19110,19112,19114,19116,19118,19120,19122,19124,19126,19128, - 19965,19964,18849,18848,17763,17765,17767,17769,17771,17773,17775,0,17777,17779,17781,17783,17785,17787,17789,17791,17793,17795,17797,17799,17801,17803,17805,0,17807,17809,17811,17813,17815,17817,17819,17821,17823,17825,17827,17829,17831,17833,17835,0,17837,17839,17841,17843,17845,17847,17849,17851,17853,17855,17857,17859,17861,17863,17865,0,17867,17869,17871,17873,17875,17877,17879,17881,17883,17885,17887,17889,17891,17893,17895,0,17897,17899,17901,17903,17905,17907,17909,17911,17913,17915,17917,17919,17921,17923,17925,0,17927,17929,17931,17933,17935,17937,17939,17941,17943,17945,17947,17949,17951,17953,17955,0,17957,17959,17961,17963,17965,17967,17969,17971,17973,17975,17977,17979,17981,17983,17985,0,17987,17989,17991,17993,17995,17997,17999,18001,18003,18005,18007,18009,18011,18013,18015,0,18017,18019,18021,18023,18025,18027,18029,18031,18033,19130,19131, - 19963,19962,18847,18846,17762,17764,17766,17768,17770,17772,17774,1,17776,17778,17780,17782,17784,17786,17788,17790,17792,17794,17796,17798,17800,17802,17804,1,17806,17808,17810,17812,17814,17816,17818,17820,17822,17824,17826,17828,17830,17832,17834,1,17836,17838,17840,17842,17844,17846,17848,17850,17852,17854,17856,17858,17860,17862,17864,1,17866,17868,17870,17872,17874,17876,17878,17880,17882,17884,17886,17888,17890,17892,17894,1,17896,17898,17900,17902,17904,17906,17908,17910,17912,17914,17916,17918,17920,17922,17924,1,17926,17928,17930,17932,17934,17936,17938,17940,17942,17944,17946,17948,17950,17952,17954,1,17956,17958,17960,17962,17964,17966,17968,17970,17972,17974,17976,17978,17980,17982,17984,1,17986,17988,17990,17992,17994,17996,17998,18000,18002,18004,18006,18008,18010,18012,18014,1,18016,18018,18020,18022,18024,18026,18028,18030,18032,19132,19133, - 19961,19960,18845,18844,17761,17760,16707,16709,16711,16713,16715,0,16717,16719,16721,16723,16725,16727,16729,16731,16733,16735,16737,16739,16741,16743,16745,0,16747,16749,16751,16753,16755,16757,16759,16761,16763,16765,16767,16769,16771,16773,16775,0,16777,16779,16781,16783,16785,16787,16789,16791,16793,16795,16797,16799,16801,16803,16805,0,16807,16809,16811,16813,16815,16817,16819,16821,16823,16825,16827,16829,16831,16833,16835,0,16837,16839,16841,16843,16845,16847,16849,16851,16853,16855,16857,16859,16861,16863,16865,0,16867,16869,16871,16873,16875,16877,16879,16881,16883,16885,16887,16889,16891,16893,16895,0,16897,16899,16901,16903,16905,16907,16909,16911,16913,16915,16917,16919,16921,16923,16925,0,16927,16929,16931,16933,16935,16937,16939,16941,16943,16945,16947,16949,16951,16953,16955,0,16957,16959,16961,16963,16965,16967,16969,18034,18035,19134,19135, - 19959,19958,18843,18842,17759,17758,16706,16708,16710,16712,16714,1,16716,16718,16720,16722,16724,16726,16728,16730,16732,16734,16736,16738,16740,16742,16744,1,16746,16748,16750,16752,16754,16756,16758,16760,16762,16764,16766,16768,16770,16772,16774,1,16776,16778,16780,16782,16784,16786,16788,16790,16792,16794,16796,16798,16800,16802,16804,1,16806,16808,16810,16812,16814,16816,16818,16820,16822,16824,16826,16828,16830,16832,16834,1,16836,16838,16840,16842,16844,16846,16848,16850,16852,16854,16856,16858,16860,16862,16864,1,16866,16868,16870,16872,16874,16876,16878,16880,16882,16884,16886,16888,16890,16892,16894,1,16896,16898,16900,16902,16904,16906,16908,16910,16912,16914,16916,16918,16920,16922,16924,1,16926,16928,16930,16932,16934,16936,16938,16940,16942,16944,16946,16948,16950,16952,16954,1,16956,16958,16960,16962,16964,16966,16968,18036,18037,19136,19137, - 19957,19956,18841,18840,17757,17756,16705,16704,15683,15685,15687,0,15689,15691,15693,15695,15697,15699,15701,15703,15705,15707,15709,15711,15713,15715,15717,0,15719,15721,15723,15725,15727,15729,15731,15733,15735,15737,15739,15741,15743,15745,15747,0,15749,15751,15753,15755,15757,15759,15761,15763,15765,15767,15769,15771,15773,15775,15777,0,15779,15781,15783,15785,15787,15789,15791,15793,15795,15797,15799,15801,15803,15805,15807,0,15809,15811,15813,15815,15817,15819,15821,15823,15825,15827,15829,15831,15833,15835,15837,0,15839,15841,15843,15845,15847,15849,15851,15853,15855,15857,15859,15861,15863,15865,15867,0,15869,15871,15873,15875,15877,15879,15881,15883,15885,15887,15889,15891,15893,15895,15897,0,15899,15901,15903,15905,15907,15909,15911,15913,15915,15917,15919,15921,15923,15925,15927,0,15929,15931,15933,15935,15937,16970,16971,18038,18039,19138,19139, - 19955,19954,18839,18838,17755,17754,16703,16702,15682,15684,15686,1,15688,15690,15692,15694,15696,15698,15700,15702,15704,15706,15708,15710,15712,15714,15716,1,15718,15720,15722,15724,15726,15728,15730,15732,15734,15736,15738,15740,15742,15744,15746,1,15748,15750,15752,15754,15756,15758,15760,15762,15764,15766,15768,15770,15772,15774,15776,1,15778,15780,15782,15784,15786,15788,15790,15792,15794,15796,15798,15800,15802,15804,15806,1,15808,15810,15812,15814,15816,15818,15820,15822,15824,15826,15828,15830,15832,15834,15836,1,15838,15840,15842,15844,15846,15848,15850,15852,15854,15856,15858,15860,15862,15864,15866,1,15868,15870,15872,15874,15876,15878,15880,15882,15884,15886,15888,15890,15892,15894,15896,1,15898,15900,15902,15904,15906,15908,15910,15912,15914,15916,15918,15920,15922,15924,15926,1,15928,15930,15932,15934,15936,16972,16973,18040,18041,19140,19141, - 19953,19952,18837,18836,17753,17752,16701,16700,15681,15680,14691,0,14693,14695,14697,14699,14701,14703,14705,14707,14709,14711,14713,14715,14717,14719,14721,0,14723,14725,14727,14729,14731,14733,14735,14737,14739,14741,14743,14745,14747,14749,14751,0,14753,14755,14757,14759,14761,14763,14765,14767,14769,14771,14773,14775,14777,14779,14781,0,14783,14785,14787,14789,14791,14793,14795,14797,14799,14801,14803,14805,14807,14809,14811,0,14813,14815,14817,14819,14821,14823,14825,14827,14829,14831,14833,14835,14837,14839,14841,0,14843,14845,14847,14849,14851,14853,14855,14857,14859,14861,14863,14865,14867,14869,14871,0,14873,14875,14877,14879,14881,14883,14885,14887,14889,14891,14893,14895,14897,14899,14901,0,14903,14905,14907,14909,14911,14913,14915,14917,14919,14921,14923,14925,14927,14929,14931,0,14933,14935,14937,15938,15939,16974,16975,18042,18043,19142,19143, - 19951,19950,18835,18834,17751,17750,16699,16698,15679,15678,14690,1,14692,14694,14696,14698,14700,14702,14704,14706,14708,14710,14712,14714,14716,14718,14720,1,14722,14724,14726,14728,14730,14732,14734,14736,14738,14740,14742,14744,14746,14748,14750,1,14752,14754,14756,14758,14760,14762,14764,14766,14768,14770,14772,14774,14776,14778,14780,1,14782,14784,14786,14788,14790,14792,14794,14796,14798,14800,14802,14804,14806,14808,14810,1,14812,14814,14816,14818,14820,14822,14824,14826,14828,14830,14832,14834,14836,14838,14840,1,14842,14844,14846,14848,14850,14852,14854,14856,14858,14860,14862,14864,14866,14868,14870,1,14872,14874,14876,14878,14880,14882,14884,14886,14888,14890,14892,14894,14896,14898,14900,1,14902,14904,14906,14908,14910,14912,14914,14916,14918,14920,14922,14924,14926,14928,14930,1,14932,14934,14936,15940,15941,16976,16977,18044,18045,19144,19145, - 19949,19948,18833,18832,17749,17748,16697,16696,15677,15676,14689,0,14688,13731,13733,13735,13737,13739,13741,13743,13745,13747,13749,13751,13753,13755,13757,0,13759,13761,13763,13765,13767,13769,13771,13773,13775,13777,13779,13781,13783,13785,13787,0,13789,13791,13793,13795,13797,13799,13801,13803,13805,13807,13809,13811,13813,13815,13817,0,13819,13821,13823,13825,13827,13829,13831,13833,13835,13837,13839,13841,13843,13845,13847,0,13849,13851,13853,13855,13857,13859,13861,13863,13865,13867,13869,13871,13873,13875,13877,0,13879,13881,13883,13885,13887,13889,13891,13893,13895,13897,13899,13901,13903,13905,13907,0,13909,13911,13913,13915,13917,13919,13921,13923,13925,13927,13929,13931,13933,13935,13937,0,13939,13941,13943,13945,13947,13949,13951,13953,13955,13957,13959,13961,13963,13965,13967,0,13969,14938,14939,15942,15943,16978,16979,18046,18047,19146,19147, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19947,19946,18831,18830,17747,17746,16695,16694,15675,15674,14687,0,14686,13730,13732,13734,13736,13738,13740,13742,13744,13746,13748,13750,13752,13754,13756,0,13758,13760,13762,13764,13766,13768,13770,13772,13774,13776,13778,13780,13782,13784,13786,0,13788,13790,13792,13794,13796,13798,13800,13802,13804,13806,13808,13810,13812,13814,13816,0,13818,13820,13822,13824,13826,13828,13830,13832,13834,13836,13838,13840,13842,13844,13846,0,13848,13850,13852,13854,13856,13858,13860,13862,13864,13866,13868,13870,13872,13874,13876,0,13878,13880,13882,13884,13886,13888,13890,13892,13894,13896,13898,13900,13902,13904,13906,0,13908,13910,13912,13914,13916,13918,13920,13922,13924,13926,13928,13930,13932,13934,13936,0,13938,13940,13942,13944,13946,13948,13950,13952,13954,13956,13958,13960,13962,13964,13966,0,13968,14940,14941,15944,15945,16980,16981,18048,18049,19148,19149, - 19945,19944,18829,18828,17745,17744,16693,16692,15673,15672,14685,1,14684,13729,13728,12803,12805,12807,12809,12811,12813,12815,12817,12819,12821,12823,12825,1,12827,12829,12831,12833,12835,12837,12839,12841,12843,12845,12847,12849,12851,12853,12855,1,12857,12859,12861,12863,12865,12867,12869,12871,12873,12875,12877,12879,12881,12883,12885,1,12887,12889,12891,12893,12895,12897,12899,12901,12903,12905,12907,12909,12911,12913,12915,1,12917,12919,12921,12923,12925,12927,12929,12931,12933,12935,12937,12939,12941,12943,12945,1,12947,12949,12951,12953,12955,12957,12959,12961,12963,12965,12967,12969,12971,12973,12975,1,12977,12979,12981,12983,12985,12987,12989,12991,12993,12995,12997,12999,13001,13003,13005,1,13007,13009,13011,13013,13015,13017,13019,13021,13023,13025,13027,13029,13031,13033,13970,1,13971,14942,14943,15946,15947,16982,16983,18050,18051,19150,19151, - 19943,19942,18827,18826,17743,17742,16691,16690,15671,15670,14683,0,14682,13727,13726,12802,12804,12806,12808,12810,12812,12814,12816,12818,12820,12822,12824,0,12826,12828,12830,12832,12834,12836,12838,12840,12842,12844,12846,12848,12850,12852,12854,0,12856,12858,12860,12862,12864,12866,12868,12870,12872,12874,12876,12878,12880,12882,12884,0,12886,12888,12890,12892,12894,12896,12898,12900,12902,12904,12906,12908,12910,12912,12914,0,12916,12918,12920,12922,12924,12926,12928,12930,12932,12934,12936,12938,12940,12942,12944,0,12946,12948,12950,12952,12954,12956,12958,12960,12962,12964,12966,12968,12970,12972,12974,0,12976,12978,12980,12982,12984,12986,12988,12990,12992,12994,12996,12998,13000,13002,13004,0,13006,13008,13010,13012,13014,13016,13018,13020,13022,13024,13026,13028,13030,13032,13972,0,13973,14944,14945,15948,15949,16984,16985,18052,18053,19152,19153, - 19941,19940,18825,18824,17741,17740,16689,16688,15669,15668,14681,1,14680,13725,13724,12801,12800,11907,11909,11911,11913,11915,11917,11919,11921,11923,11925,1,11927,11929,11931,11933,11935,11937,11939,11941,11943,11945,11947,11949,11951,11953,11955,1,11957,11959,11961,11963,11965,11967,11969,11971,11973,11975,11977,11979,11981,11983,11985,1,11987,11989,11991,11993,11995,11997,11999,12001,12003,12005,12007,12009,12011,12013,12015,1,12017,12019,12021,12023,12025,12027,12029,12031,12033,12035,12037,12039,12041,12043,12045,1,12047,12049,12051,12053,12055,12057,12059,12061,12063,12065,12067,12069,12071,12073,12075,1,12077,12079,12081,12083,12085,12087,12089,12091,12093,12095,12097,12099,12101,12103,12105,1,12107,12109,12111,12113,12115,12117,12119,12121,12123,12125,12127,12129,13034,13035,13974,1,13975,14946,14947,15950,15951,16986,16987,18054,18055,19154,19155, - 19939,19938,18823,18822,17739,17738,16687,16686,15667,15666,14679,0,14678,13723,13722,12799,12798,11906,11908,11910,11912,11914,11916,11918,11920,11922,11924,0,11926,11928,11930,11932,11934,11936,11938,11940,11942,11944,11946,11948,11950,11952,11954,0,11956,11958,11960,11962,11964,11966,11968,11970,11972,11974,11976,11978,11980,11982,11984,0,11986,11988,11990,11992,11994,11996,11998,12000,12002,12004,12006,12008,12010,12012,12014,0,12016,12018,12020,12022,12024,12026,12028,12030,12032,12034,12036,12038,12040,12042,12044,0,12046,12048,12050,12052,12054,12056,12058,12060,12062,12064,12066,12068,12070,12072,12074,0,12076,12078,12080,12082,12084,12086,12088,12090,12092,12094,12096,12098,12100,12102,12104,0,12106,12108,12110,12112,12114,12116,12118,12120,12122,12124,12126,12128,13036,13037,13976,0,13977,14948,14949,15952,15953,16988,16989,18056,18057,19156,19157, - 19937,19936,18821,18820,17737,17736,16685,16684,15665,15664,14677,1,14676,13721,13720,12797,12796,11905,11904,11043,11045,11047,11049,11051,11053,11055,11057,1,11059,11061,11063,11065,11067,11069,11071,11073,11075,11077,11079,11081,11083,11085,11087,1,11089,11091,11093,11095,11097,11099,11101,11103,11105,11107,11109,11111,11113,11115,11117,1,11119,11121,11123,11125,11127,11129,11131,11133,11135,11137,11139,11141,11143,11145,11147,1,11149,11151,11153,11155,11157,11159,11161,11163,11165,11167,11169,11171,11173,11175,11177,1,11179,11181,11183,11185,11187,11189,11191,11193,11195,11197,11199,11201,11203,11205,11207,1,11209,11211,11213,11215,11217,11219,11221,11223,11225,11227,11229,11231,11233,11235,11237,1,11239,11241,11243,11245,11247,11249,11251,11253,11255,11257,12130,12131,13038,13039,13978,1,13979,14950,14951,15954,15955,16990,16991,18058,18059,19158,19159, - 19935,19934,18819,18818,17735,17734,16683,16682,15663,15662,14675,0,14674,13719,13718,12795,12794,11903,11902,11042,11044,11046,11048,11050,11052,11054,11056,0,11058,11060,11062,11064,11066,11068,11070,11072,11074,11076,11078,11080,11082,11084,11086,0,11088,11090,11092,11094,11096,11098,11100,11102,11104,11106,11108,11110,11112,11114,11116,0,11118,11120,11122,11124,11126,11128,11130,11132,11134,11136,11138,11140,11142,11144,11146,0,11148,11150,11152,11154,11156,11158,11160,11162,11164,11166,11168,11170,11172,11174,11176,0,11178,11180,11182,11184,11186,11188,11190,11192,11194,11196,11198,11200,11202,11204,11206,0,11208,11210,11212,11214,11216,11218,11220,11222,11224,11226,11228,11230,11232,11234,11236,0,11238,11240,11242,11244,11246,11248,11250,11252,11254,11256,12132,12133,13040,13041,13980,0,13981,14952,14953,15956,15957,16992,16993,18060,18061,19160,19161, - 19933,19932,18817,18816,17733,17732,16681,16680,15661,15660,14673,1,14672,13717,13716,12793,12792,11901,11900,11041,11040,10211,10213,10215,10217,10219,10221,1,10223,10225,10227,10229,10231,10233,10235,10237,10239,10241,10243,10245,10247,10249,10251,1,10253,10255,10257,10259,10261,10263,10265,10267,10269,10271,10273,10275,10277,10279,10281,1,10283,10285,10287,10289,10291,10293,10295,10297,10299,10301,10303,10305,10307,10309,10311,1,10313,10315,10317,10319,10321,10323,10325,10327,10329,10331,10333,10335,10337,10339,10341,1,10343,10345,10347,10349,10351,10353,10355,10357,10359,10361,10363,10365,10367,10369,10371,1,10373,10375,10377,10379,10381,10383,10385,10387,10389,10391,10393,10395,10397,10399,10401,1,10403,10405,10407,10409,10411,10413,10415,10417,11258,11259,12134,12135,13042,13043,13982,1,13983,14954,14955,15958,15959,16994,16995,18062,18063,19162,19163, - 19931,19930,18815,18814,17731,17730,16679,16678,15659,15658,14671,0,14670,13715,13714,12791,12790,11899,11898,11039,11038,10210,10212,10214,10216,10218,10220,0,10222,10224,10226,10228,10230,10232,10234,10236,10238,10240,10242,10244,10246,10248,10250,0,10252,10254,10256,10258,10260,10262,10264,10266,10268,10270,10272,10274,10276,10278,10280,0,10282,10284,10286,10288,10290,10292,10294,10296,10298,10300,10302,10304,10306,10308,10310,0,10312,10314,10316,10318,10320,10322,10324,10326,10328,10330,10332,10334,10336,10338,10340,0,10342,10344,10346,10348,10350,10352,10354,10356,10358,10360,10362,10364,10366,10368,10370,0,10372,10374,10376,10378,10380,10382,10384,10386,10388,10390,10392,10394,10396,10398,10400,0,10402,10404,10406,10408,10410,10412,10414,10416,11260,11261,12136,12137,13044,13045,13984,0,13985,14956,14957,15960,15961,16996,16997,18064,18065,19164,19165, - 19929,19928,18813,18812,17729,17728,16677,16676,15657,15656,14669,1,14668,13713,13712,12789,12788,11897,11896,11037,11036,10209,10208,9411,9413,9415,9417,1,9419,9421,9423,9425,9427,9429,9431,9433,9435,9437,9439,9441,9443,9445,9447,1,9449,9451,9453,9455,9457,9459,9461,9463,9465,9467,9469,9471,9473,9475,9477,1,9479,9481,9483,9485,9487,9489,9491,9493,9495,9497,9499,9501,9503,9505,9507,1,9509,9511,9513,9515,9517,9519,9521,9523,9525,9527,9529,9531,9533,9535,9537,1,9539,9541,9543,9545,9547,9549,9551,9553,9555,9557,9559,9561,9563,9565,9567,1,9569,9571,9573,9575,9577,9579,9581,9583,9585,9587,9589,9591,9593,9595,9597,1,9599,9601,9603,9605,9607,9609,10418,10419,11262,11263,12138,12139,13046,13047,13986,1,13987,14958,14959,15962,15963,16998,16999,18066,18067,19166,19167, - 19927,19926,18811,18810,17727,17726,16675,16674,15655,15654,14667,0,14666,13711,13710,12787,12786,11895,11894,11035,11034,10207,10206,9410,9412,9414,9416,0,9418,9420,9422,9424,9426,9428,9430,9432,9434,9436,9438,9440,9442,9444,9446,0,9448,9450,9452,9454,9456,9458,9460,9462,9464,9466,9468,9470,9472,9474,9476,0,9478,9480,9482,9484,9486,9488,9490,9492,9494,9496,9498,9500,9502,9504,9506,0,9508,9510,9512,9514,9516,9518,9520,9522,9524,9526,9528,9530,9532,9534,9536,0,9538,9540,9542,9544,9546,9548,9550,9552,9554,9556,9558,9560,9562,9564,9566,0,9568,9570,9572,9574,9576,9578,9580,9582,9584,9586,9588,9590,9592,9594,9596,0,9598,9600,9602,9604,9606,9608,10420,10421,11264,11265,12140,12141,13048,13049,13988,0,13989,14960,14961,15964,15965,17000,17001,18068,18069,19168,19169, - 19925,19924,18809,18808,17725,17724,16673,16672,15653,15652,14665,1,14664,13709,13708,12785,12784,11893,11892,11033,11032,10205,10204,9409,9408,8643,8645,1,8647,8649,8651,8653,8655,8657,8659,8661,8663,8665,8667,8669,8671,8673,8675,1,8677,8679,8681,8683,8685,8687,8689,8691,8693,8695,8697,8699,8701,8703,8705,1,8707,8709,8711,8713,8715,8717,8719,8721,8723,8725,8727,8729,8731,8733,8735,1,8737,8739,8741,8743,8745,8747,8749,8751,8753,8755,8757,8759,8761,8763,8765,1,8767,8769,8771,8773,8775,8777,8779,8781,8783,8785,8787,8789,8791,8793,8795,1,8797,8799,8801,8803,8805,8807,8809,8811,8813,8815,8817,8819,8821,8823,8825,1,8827,8829,8831,8833,9610,9611,10422,10423,11266,11267,12142,12143,13050,13051,13990,1,13991,14962,14963,15966,15967,17002,17003,18070,18071,19170,19171, - 19923,19922,18807,18806,17723,17722,16671,16670,15651,15650,14663,0,14662,13707,13706,12783,12782,11891,11890,11031,11030,10203,10202,9407,9406,8642,8644,0,8646,8648,8650,8652,8654,8656,8658,8660,8662,8664,8666,8668,8670,8672,8674,0,8676,8678,8680,8682,8684,8686,8688,8690,8692,8694,8696,8698,8700,8702,8704,0,8706,8708,8710,8712,8714,8716,8718,8720,8722,8724,8726,8728,8730,8732,8734,0,8736,8738,8740,8742,8744,8746,8748,8750,8752,8754,8756,8758,8760,8762,8764,0,8766,8768,8770,8772,8774,8776,8778,8780,8782,8784,8786,8788,8790,8792,8794,0,8796,8798,8800,8802,8804,8806,8808,8810,8812,8814,8816,8818,8820,8822,8824,0,8826,8828,8830,8832,9612,9613,10424,10425,11268,11269,12144,12145,13052,13053,13992,0,13993,14964,14965,15968,15969,17004,17005,18072,18073,19172,19173, - 19921,19920,18805,18804,17721,17720,16669,16668,15649,15648,14661,1,14660,13705,13704,12781,12780,11889,11888,11029,11028,10201,10200,9405,9404,8641,8640,1,7907,7909,7911,7913,7915,7917,7919,7921,7923,7925,7927,7929,7931,7933,7935,1,7937,7939,7941,7943,7945,7947,7949,7951,7953,7955,7957,7959,7961,7963,7965,1,7967,7969,7971,7973,7975,7977,7979,7981,7983,7985,7987,7989,7991,7993,7995,1,7997,7999,8001,8003,8005,8007,8009,8011,8013,8015,8017,8019,8021,8023,8025,1,8027,8029,8031,8033,8035,8037,8039,8041,8043,8045,8047,8049,8051,8053,8055,1,8057,8059,8061,8063,8065,8067,8069,8071,8073,8075,8077,8079,8081,8083,8085,1,8087,8089,8834,8835,9614,9615,10426,10427,11270,11271,12146,12147,13054,13055,13994,1,13995,14966,14967,15970,15971,17006,17007,18074,18075,19174,19175, - 19919,19918,18803,18802,17719,17718,16667,16666,15647,15646,14659,0,14658,13703,13702,12779,12778,11887,11886,11027,11026,10199,10198,9403,9402,8639,8638,0,7906,7908,7910,7912,7914,7916,7918,7920,7922,7924,7926,7928,7930,7932,7934,0,7936,7938,7940,7942,7944,7946,7948,7950,7952,7954,7956,7958,7960,7962,7964,0,7966,7968,7970,7972,7974,7976,7978,7980,7982,7984,7986,7988,7990,7992,7994,0,7996,7998,8000,8002,8004,8006,8008,8010,8012,8014,8016,8018,8020,8022,8024,0,8026,8028,8030,8032,8034,8036,8038,8040,8042,8044,8046,8048,8050,8052,8054,0,8056,8058,8060,8062,8064,8066,8068,8070,8072,8074,8076,8078,8080,8082,8084,0,8086,8088,8836,8837,9616,9617,10428,10429,11272,11273,12148,12149,13056,13057,13996,0,13997,14968,14969,15972,15973,17008,17009,18076,18077,19176,19177, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19917,19916,18801,18800,17717,17716,16665,16664,15645,15644,14657,0,14656,13701,13700,12777,12776,11885,11884,11025,11024,10197,10196,9401,9400,8637,8636,0,7905,7904,7203,7205,7207,7209,7211,7213,7215,7217,7219,7221,7223,7225,7227,0,7229,7231,7233,7235,7237,7239,7241,7243,7245,7247,7249,7251,7253,7255,7257,0,7259,7261,7263,7265,7267,7269,7271,7273,7275,7277,7279,7281,7283,7285,7287,0,7289,7291,7293,7295,7297,7299,7301,7303,7305,7307,7309,7311,7313,7315,7317,0,7319,7321,7323,7325,7327,7329,7331,7333,7335,7337,7339,7341,7343,7345,7347,0,7349,7351,7353,7355,7357,7359,7361,7363,7365,7367,7369,7371,7373,7375,7377,0,8090,8091,8838,8839,9618,9619,10430,10431,11274,11275,12150,12151,13058,13059,13998,0,13999,14970,14971,15974,15975,17010,17011,18078,18079,19178,19179, - 19915,19914,18799,18798,17715,17714,16663,16662,15643,15642,14655,1,14654,13699,13698,12775,12774,11883,11882,11023,11022,10195,10194,9399,9398,8635,8634,1,7903,7902,7202,7204,7206,7208,7210,7212,7214,7216,7218,7220,7222,7224,7226,1,7228,7230,7232,7234,7236,7238,7240,7242,7244,7246,7248,7250,7252,7254,7256,1,7258,7260,7262,7264,7266,7268,7270,7272,7274,7276,7278,7280,7282,7284,7286,1,7288,7290,7292,7294,7296,7298,7300,7302,7304,7306,7308,7310,7312,7314,7316,1,7318,7320,7322,7324,7326,7328,7330,7332,7334,7336,7338,7340,7342,7344,7346,1,7348,7350,7352,7354,7356,7358,7360,7362,7364,7366,7368,7370,7372,7374,7376,1,8092,8093,8840,8841,9620,9621,10432,10433,11276,11277,12152,12153,13060,13061,14000,1,14001,14972,14973,15976,15977,17012,17013,18080,18081,19180,19181, - 19913,19912,18797,18796,17713,17712,16661,16660,15641,15640,14653,0,14652,13697,13696,12773,12772,11881,11880,11021,11020,10193,10192,9397,9396,8633,8632,0,7901,7900,7201,7200,6531,6533,6535,6537,6539,6541,6543,6545,6547,6549,6551,0,6553,6555,6557,6559,6561,6563,6565,6567,6569,6571,6573,6575,6577,6579,6581,0,6583,6585,6587,6589,6591,6593,6595,6597,6599,6601,6603,6605,6607,6609,6611,0,6613,6615,6617,6619,6621,6623,6625,6627,6629,6631,6633,6635,6637,6639,6641,0,6643,6645,6647,6649,6651,6653,6655,6657,6659,6661,6663,6665,6667,6669,6671,0,6673,6675,6677,6679,6681,6683,6685,6687,6689,6691,6693,6695,6697,7378,7379,0,8094,8095,8842,8843,9622,9623,10434,10435,11278,11279,12154,12155,13062,13063,14002,0,14003,14974,14975,15978,15979,17014,17015,18082,18083,19182,19183, - 19911,19910,18795,18794,17711,17710,16659,16658,15639,15638,14651,1,14650,13695,13694,12771,12770,11879,11878,11019,11018,10191,10190,9395,9394,8631,8630,1,7899,7898,7199,7198,6530,6532,6534,6536,6538,6540,6542,6544,6546,6548,6550,1,6552,6554,6556,6558,6560,6562,6564,6566,6568,6570,6572,6574,6576,6578,6580,1,6582,6584,6586,6588,6590,6592,6594,6596,6598,6600,6602,6604,6606,6608,6610,1,6612,6614,6616,6618,6620,6622,6624,6626,6628,6630,6632,6634,6636,6638,6640,1,6642,6644,6646,6648,6650,6652,6654,6656,6658,6660,6662,6664,6666,6668,6670,1,6672,6674,6676,6678,6680,6682,6684,6686,6688,6690,6692,6694,6696,7380,7381,1,8096,8097,8844,8845,9624,9625,10436,10437,11280,11281,12156,12157,13064,13065,14004,1,14005,14976,14977,15980,15981,17016,17017,18084,18085,19184,19185, - 19909,19908,18793,18792,17709,17708,16657,16656,15637,15636,14649,0,14648,13693,13692,12769,12768,11877,11876,11017,11016,10189,10188,9393,9392,8629,8628,0,7897,7896,7197,7196,6529,6528,5891,5893,5895,5897,5899,5901,5903,5905,5907,0,5909,5911,5913,5915,5917,5919,5921,5923,5925,5927,5929,5931,5933,5935,5937,0,5939,5941,5943,5945,5947,5949,5951,5953,5955,5957,5959,5961,5963,5965,5967,0,5969,5971,5973,5975,5977,5979,5981,5983,5985,5987,5989,5991,5993,5995,5997,0,5999,6001,6003,6005,6007,6009,6011,6013,6015,6017,6019,6021,6023,6025,6027,0,6029,6031,6033,6035,6037,6039,6041,6043,6045,6047,6049,6698,6699,7382,7383,0,8098,8099,8846,8847,9626,9627,10438,10439,11282,11283,12158,12159,13066,13067,14006,0,14007,14978,14979,15982,15983,17018,17019,18086,18087,19186,19187, - 19907,19906,18791,18790,17707,17706,16655,16654,15635,15634,14647,1,14646,13691,13690,12767,12766,11875,11874,11015,11014,10187,10186,9391,9390,8627,8626,1,7895,7894,7195,7194,6527,6526,5890,5892,5894,5896,5898,5900,5902,5904,5906,1,5908,5910,5912,5914,5916,5918,5920,5922,5924,5926,5928,5930,5932,5934,5936,1,5938,5940,5942,5944,5946,5948,5950,5952,5954,5956,5958,5960,5962,5964,5966,1,5968,5970,5972,5974,5976,5978,5980,5982,5984,5986,5988,5990,5992,5994,5996,1,5998,6000,6002,6004,6006,6008,6010,6012,6014,6016,6018,6020,6022,6024,6026,1,6028,6030,6032,6034,6036,6038,6040,6042,6044,6046,6048,6700,6701,7384,7385,1,8100,8101,8848,8849,9628,9629,10440,10441,11284,11285,12160,12161,13068,13069,14008,1,14009,14980,14981,15984,15985,17020,17021,18088,18089,19188,19189, - 19905,19904,18789,18788,17705,17704,16653,16652,15633,15632,14645,0,14644,13689,13688,12765,12764,11873,11872,11013,11012,10185,10184,9389,9388,8625,8624,0,7893,7892,7193,7192,6525,6524,5889,5888,5283,5285,5287,5289,5291,5293,5295,0,5297,5299,5301,5303,5305,5307,5309,5311,5313,5315,5317,5319,5321,5323,5325,0,5327,5329,5331,5333,5335,5337,5339,5341,5343,5345,5347,5349,5351,5353,5355,0,5357,5359,5361,5363,5365,5367,5369,5371,5373,5375,5377,5379,5381,5383,5385,0,5387,5389,5391,5393,5395,5397,5399,5401,5403,5405,5407,5409,5411,5413,5415,0,5417,5419,5421,5423,5425,5427,5429,5431,5433,6050,6051,6702,6703,7386,7387,0,8102,8103,8850,8851,9630,9631,10442,10443,11286,11287,12162,12163,13070,13071,14010,0,14011,14982,14983,15986,15987,17022,17023,18090,18091,19190,19191, - 19903,19902,18787,18786,17703,17702,16651,16650,15631,15630,14643,1,14642,13687,13686,12763,12762,11871,11870,11011,11010,10183,10182,9387,9386,8623,8622,1,7891,7890,7191,7190,6523,6522,5887,5886,5282,5284,5286,5288,5290,5292,5294,1,5296,5298,5300,5302,5304,5306,5308,5310,5312,5314,5316,5318,5320,5322,5324,1,5326,5328,5330,5332,5334,5336,5338,5340,5342,5344,5346,5348,5350,5352,5354,1,5356,5358,5360,5362,5364,5366,5368,5370,5372,5374,5376,5378,5380,5382,5384,1,5386,5388,5390,5392,5394,5396,5398,5400,5402,5404,5406,5408,5410,5412,5414,1,5416,5418,5420,5422,5424,5426,5428,5430,5432,6052,6053,6704,6705,7388,7389,1,8104,8105,8852,8853,9632,9633,10444,10445,11288,11289,12164,12165,13072,13073,14012,1,14013,14984,14985,15988,15989,17024,17025,18092,18093,19192,19193, - 19901,19900,18785,18784,17701,17700,16649,16648,15629,15628,14641,0,14640,13685,13684,12761,12760,11869,11868,11009,11008,10181,10180,9385,9384,8621,8620,0,7889,7888,7189,7188,6521,6520,5885,5884,5281,5280,4707,4709,4711,4713,4715,0,4717,4719,4721,4723,4725,4727,4729,4731,4733,4735,4737,4739,4741,4743,4745,0,4747,4749,4751,4753,4755,4757,4759,4761,4763,4765,4767,4769,4771,4773,4775,0,4777,4779,4781,4783,4785,4787,4789,4791,4793,4795,4797,4799,4801,4803,4805,0,4807,4809,4811,4813,4815,4817,4819,4821,4823,4825,4827,4829,4831,4833,4835,0,4837,4839,4841,4843,4845,4847,4849,5434,5435,6054,6055,6706,6707,7390,7391,0,8106,8107,8854,8855,9634,9635,10446,10447,11290,11291,12166,12167,13074,13075,14014,0,14015,14986,14987,15990,15991,17026,17027,18094,18095,19194,19195, - 19899,19898,18783,18782,17699,17698,16647,16646,15627,15626,14639,1,14638,13683,13682,12759,12758,11867,11866,11007,11006,10179,10178,9383,9382,8619,8618,1,7887,7886,7187,7186,6519,6518,5883,5882,5279,5278,4706,4708,4710,4712,4714,1,4716,4718,4720,4722,4724,4726,4728,4730,4732,4734,4736,4738,4740,4742,4744,1,4746,4748,4750,4752,4754,4756,4758,4760,4762,4764,4766,4768,4770,4772,4774,1,4776,4778,4780,4782,4784,4786,4788,4790,4792,4794,4796,4798,4800,4802,4804,1,4806,4808,4810,4812,4814,4816,4818,4820,4822,4824,4826,4828,4830,4832,4834,1,4836,4838,4840,4842,4844,4846,4848,5436,5437,6056,6057,6708,6709,7392,7393,1,8108,8109,8856,8857,9636,9637,10448,10449,11292,11293,12168,12169,13076,13077,14016,1,14017,14988,14989,15992,15993,17028,17029,18096,18097,19196,19197, - 19897,19896,18781,18780,17697,17696,16645,16644,15625,15624,14637,0,14636,13681,13680,12757,12756,11865,11864,11005,11004,10177,10176,9381,9380,8617,8616,0,7885,7884,7185,7184,6517,6516,5881,5880,5277,5276,4705,4704,4163,4165,4167,0,4169,4171,4173,4175,4177,4179,4181,4183,4185,4187,4189,4191,4193,4195,4197,0,4199,4201,4203,4205,4207,4209,4211,4213,4215,4217,4219,4221,4223,4225,4227,0,4229,4231,4233,4235,4237,4239,4241,4243,4245,4247,4249,4251,4253,4255,4257,0,4259,4261,4263,4265,4267,4269,4271,4273,4275,4277,4279,4281,4283,4285,4287,0,4289,4291,4293,4295,4297,4850,4851,5438,5439,6058,6059,6710,6711,7394,7395,0,8110,8111,8858,8859,9638,9639,10450,10451,11294,11295,12170,12171,13078,13079,14018,0,14019,14990,14991,15994,15995,17030,17031,18098,18099,19198,19199, - 19895,19894,18779,18778,17695,17694,16643,16642,15623,15622,14635,1,14634,13679,13678,12755,12754,11863,11862,11003,11002,10175,10174,9379,9378,8615,8614,1,7883,7882,7183,7182,6515,6514,5879,5878,5275,5274,4703,4702,4162,4164,4166,1,4168,4170,4172,4174,4176,4178,4180,4182,4184,4186,4188,4190,4192,4194,4196,1,4198,4200,4202,4204,4206,4208,4210,4212,4214,4216,4218,4220,4222,4224,4226,1,4228,4230,4232,4234,4236,4238,4240,4242,4244,4246,4248,4250,4252,4254,4256,1,4258,4260,4262,4264,4266,4268,4270,4272,4274,4276,4278,4280,4282,4284,4286,1,4288,4290,4292,4294,4296,4852,4853,5440,5441,6060,6061,6712,6713,7396,7397,1,8112,8113,8860,8861,9640,9641,10452,10453,11296,11297,12172,12173,13080,13081,14020,1,14021,14992,14993,15996,15997,17032,17033,18100,18101,19200,19201, - 19893,19892,18777,18776,17693,17692,16641,16640,15621,15620,14633,0,14632,13677,13676,12753,12752,11861,11860,11001,11000,10173,10172,9377,9376,8613,8612,0,7881,7880,7181,7180,6513,6512,5877,5876,5273,5272,4701,4700,4161,4160,3651,0,3653,3655,3657,3659,3661,3663,3665,3667,3669,3671,3673,3675,3677,3679,3681,0,3683,3685,3687,3689,3691,3693,3695,3697,3699,3701,3703,3705,3707,3709,3711,0,3713,3715,3717,3719,3721,3723,3725,3727,3729,3731,3733,3735,3737,3739,3741,0,3743,3745,3747,3749,3751,3753,3755,3757,3759,3761,3763,3765,3767,3769,3771,0,3773,3775,3777,4298,4299,4854,4855,5442,5443,6062,6063,6714,6715,7398,7399,0,8114,8115,8862,8863,9642,9643,10454,10455,11298,11299,12174,12175,13082,13083,14022,0,14023,14994,14995,15998,15999,17034,17035,18102,18103,19202,19203, - 19891,19890,18775,18774,17691,17690,16639,16638,15619,15618,14631,1,14630,13675,13674,12751,12750,11859,11858,10999,10998,10171,10170,9375,9374,8611,8610,1,7879,7878,7179,7178,6511,6510,5875,5874,5271,5270,4699,4698,4159,4158,3650,1,3652,3654,3656,3658,3660,3662,3664,3666,3668,3670,3672,3674,3676,3678,3680,1,3682,3684,3686,3688,3690,3692,3694,3696,3698,3700,3702,3704,3706,3708,3710,1,3712,3714,3716,3718,3720,3722,3724,3726,3728,3730,3732,3734,3736,3738,3740,1,3742,3744,3746,3748,3750,3752,3754,3756,3758,3760,3762,3764,3766,3768,3770,1,3772,3774,3776,4300,4301,4856,4857,5444,5445,6064,6065,6716,6717,7400,7401,1,8116,8117,8864,8865,9644,9645,10456,10457,11300,11301,12176,12177,13084,13085,14024,1,14025,14996,14997,16000,16001,17036,17037,18104,18105,19204,19205, - 19889,19888,18773,18772,17689,17688,16637,16636,15617,15616,14629,0,14628,13673,13672,12749,12748,11857,11856,10997,10996,10169,10168,9373,9372,8609,8608,0,7877,7876,7177,7176,6509,6508,5873,5872,5269,5268,4697,4696,4157,4156,3649,0,3648,3171,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191,3193,3195,3197,0,3199,3201,3203,3205,3207,3209,3211,3213,3215,3217,3219,3221,3223,3225,3227,0,3229,3231,3233,3235,3237,3239,3241,3243,3245,3247,3249,3251,3253,3255,3257,0,3259,3261,3263,3265,3267,3269,3271,3273,3275,3277,3279,3281,3283,3285,3287,0,3289,3778,3779,4302,4303,4858,4859,5446,5447,6066,6067,6718,6719,7402,7403,0,8118,8119,8866,8867,9646,9647,10458,10459,11302,11303,12178,12179,13086,13087,14026,0,14027,14998,14999,16002,16003,17038,17039,18106,18107,19206,19207, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19887,19886,18771,18770,17687,17686,16635,16634,15615,15614,14627,0,14626,13671,13670,12747,12746,11855,11854,10995,10994,10167,10166,9371,9370,8607,8606,0,7875,7874,7175,7174,6507,6506,5871,5870,5267,5266,4695,4694,4155,4154,3647,0,3646,3170,3172,3174,3176,3178,3180,3182,3184,3186,3188,3190,3192,3194,3196,0,3198,3200,3202,3204,3206,3208,3210,3212,3214,3216,3218,3220,3222,3224,3226,0,3228,3230,3232,3234,3236,3238,3240,3242,3244,3246,3248,3250,3252,3254,3256,0,3258,3260,3262,3264,3266,3268,3270,3272,3274,3276,3278,3280,3282,3284,3286,0,3288,3780,3781,4304,4305,4860,4861,5448,5449,6068,6069,6720,6721,7404,7405,0,8120,8121,8868,8869,9648,9649,10460,10461,11304,11305,12180,12181,13088,13089,14028,0,14029,15000,15001,16004,16005,17040,17041,18108,18109,19208,19209, - 19885,19884,18769,18768,17685,17684,16633,16632,15613,15612,14625,1,14624,13669,13668,12745,12744,11853,11852,10993,10992,10165,10164,9369,9368,8605,8604,1,7873,7872,7173,7172,6505,6504,5869,5868,5265,5264,4693,4692,4153,4152,3645,1,3644,3169,3168,2723,2725,2727,2729,2731,2733,2735,2737,2739,2741,2743,2745,1,2747,2749,2751,2753,2755,2757,2759,2761,2763,2765,2767,2769,2771,2773,2775,1,2777,2779,2781,2783,2785,2787,2789,2791,2793,2795,2797,2799,2801,2803,2805,1,2807,2809,2811,2813,2815,2817,2819,2821,2823,2825,2827,2829,2831,2833,3290,1,3291,3782,3783,4306,4307,4862,4863,5450,5451,6070,6071,6722,6723,7406,7407,1,8122,8123,8870,8871,9650,9651,10462,10463,11306,11307,12182,12183,13090,13091,14030,1,14031,15002,15003,16006,16007,17042,17043,18110,18111,19210,19211, - 19883,19882,18767,18766,17683,17682,16631,16630,15611,15610,14623,0,14622,13667,13666,12743,12742,11851,11850,10991,10990,10163,10162,9367,9366,8603,8602,0,7871,7870,7171,7170,6503,6502,5867,5866,5263,5262,4691,4690,4151,4150,3643,0,3642,3167,3166,2722,2724,2726,2728,2730,2732,2734,2736,2738,2740,2742,2744,0,2746,2748,2750,2752,2754,2756,2758,2760,2762,2764,2766,2768,2770,2772,2774,0,2776,2778,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798,2800,2802,2804,0,2806,2808,2810,2812,2814,2816,2818,2820,2822,2824,2826,2828,2830,2832,3292,0,3293,3784,3785,4308,4309,4864,4865,5452,5453,6072,6073,6724,6725,7408,7409,0,8124,8125,8872,8873,9652,9653,10464,10465,11308,11309,12184,12185,13092,13093,14032,0,14033,15004,15005,16008,16009,17044,17045,18112,18113,19212,19213, - 19881,19880,18765,18764,17681,17680,16629,16628,15609,15608,14621,1,14620,13665,13664,12741,12740,11849,11848,10989,10988,10161,10160,9365,9364,8601,8600,1,7869,7868,7169,7168,6501,6500,5865,5864,5261,5260,4689,4688,4149,4148,3641,1,3640,3165,3164,2721,2720,2307,2309,2311,2313,2315,2317,2319,2321,2323,2325,1,2327,2329,2331,2333,2335,2337,2339,2341,2343,2345,2347,2349,2351,2353,2355,1,2357,2359,2361,2363,2365,2367,2369,2371,2373,2375,2377,2379,2381,2383,2385,1,2387,2389,2391,2393,2395,2397,2399,2401,2403,2405,2407,2409,2834,2835,3294,1,3295,3786,3787,4310,4311,4866,4867,5454,5455,6074,6075,6726,6727,7410,7411,1,8126,8127,8874,8875,9654,9655,10466,10467,11310,11311,12186,12187,13094,13095,14034,1,14035,15006,15007,16010,16011,17046,17047,18114,18115,19214,19215, - 19879,19878,18763,18762,17679,17678,16627,16626,15607,15606,14619,0,14618,13663,13662,12739,12738,11847,11846,10987,10986,10159,10158,9363,9362,8599,8598,0,7867,7866,7167,7166,6499,6498,5863,5862,5259,5258,4687,4686,4147,4146,3639,0,3638,3163,3162,2719,2718,2306,2308,2310,2312,2314,2316,2318,2320,2322,2324,0,2326,2328,2330,2332,2334,2336,2338,2340,2342,2344,2346,2348,2350,2352,2354,0,2356,2358,2360,2362,2364,2366,2368,2370,2372,2374,2376,2378,2380,2382,2384,0,2386,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2836,2837,3296,0,3297,3788,3789,4312,4313,4868,4869,5456,5457,6076,6077,6728,6729,7412,7413,0,8128,8129,8876,8877,9656,9657,10468,10469,11312,11313,12188,12189,13096,13097,14036,0,14037,15008,15009,16012,16013,17048,17049,18116,18117,19216,19217, - 19877,19876,18761,18760,17677,17676,16625,16624,15605,15604,14617,1,14616,13661,13660,12737,12736,11845,11844,10985,10984,10157,10156,9361,9360,8597,8596,1,7865,7864,7165,7164,6497,6496,5861,5860,5257,5256,4685,4684,4145,4144,3637,1,3636,3161,3160,2717,2716,2305,2304,1923,1925,1927,1929,1931,1933,1935,1937,1,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967,1,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987,1989,1991,1993,1995,1997,1,1999,2001,2003,2005,2007,2009,2011,2013,2015,2017,2410,2411,2838,2839,3298,1,3299,3790,3791,4314,4315,4870,4871,5458,5459,6078,6079,6730,6731,7414,7415,1,8130,8131,8878,8879,9658,9659,10470,10471,11314,11315,12190,12191,13098,13099,14038,1,14039,15010,15011,16014,16015,17050,17051,18118,18119,19218,19219, - 19875,19874,18759,18758,17675,17674,16623,16622,15603,15602,14615,0,14614,13659,13658,12735,12734,11843,11842,10983,10982,10155,10154,9359,9358,8595,8594,0,7863,7862,7163,7162,6495,6494,5859,5858,5255,5254,4683,4682,4143,4142,3635,0,3634,3159,3158,2715,2714,2303,2302,1922,1924,1926,1928,1930,1932,1934,1936,0,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956,1958,1960,1962,1964,1966,0,1968,1970,1972,1974,1976,1978,1980,1982,1984,1986,1988,1990,1992,1994,1996,0,1998,2000,2002,2004,2006,2008,2010,2012,2014,2016,2412,2413,2840,2841,3300,0,3301,3792,3793,4316,4317,4872,4873,5460,5461,6080,6081,6732,6733,7416,7417,0,8132,8133,8880,8881,9660,9661,10472,10473,11316,11317,12192,12193,13100,13101,14040,0,14041,15012,15013,16016,16017,17052,17053,18120,18121,19220,19221, - 19873,19872,18757,18756,17673,17672,16621,16620,15601,15600,14613,1,14612,13657,13656,12733,12732,11841,11840,10981,10980,10153,10152,9357,9356,8593,8592,1,7861,7860,7161,7160,6493,6492,5857,5856,5253,5252,4681,4680,4141,4140,3633,1,3632,3157,3156,2713,2712,2301,2300,1921,1920,1571,1573,1575,1577,1579,1581,1,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609,1611,1,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641,1,1643,1645,1647,1649,1651,1653,1655,1657,2018,2019,2414,2415,2842,2843,3302,1,3303,3794,3795,4318,4319,4874,4875,5462,5463,6082,6083,6734,6735,7418,7419,1,8134,8135,8882,8883,9662,9663,10474,10475,11318,11319,12194,12195,13102,13103,14042,1,14043,15014,15015,16018,16019,17054,17055,18122,18123,19222,19223, - 19871,19870,18755,18754,17671,17670,16619,16618,15599,15598,14611,0,14610,13655,13654,12731,12730,11839,11838,10979,10978,10151,10150,9355,9354,8591,8590,0,7859,7858,7159,7158,6491,6490,5855,5854,5251,5250,4679,4678,4139,4138,3631,0,3630,3155,3154,2711,2710,2299,2298,1919,1918,1570,1572,1574,1576,1578,1580,0,1582,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1608,1610,0,1612,1614,1616,1618,1620,1622,1624,1626,1628,1630,1632,1634,1636,1638,1640,0,1642,1644,1646,1648,1650,1652,1654,1656,2020,2021,2416,2417,2844,2845,3304,0,3305,3796,3797,4320,4321,4876,4877,5464,5465,6084,6085,6736,6737,7420,7421,0,8136,8137,8884,8885,9664,9665,10476,10477,11320,11321,12196,12197,13104,13105,14044,0,14045,15016,15017,16020,16021,17056,17057,18124,18125,19224,19225, - 19869,19868,18753,18752,17669,17668,16617,16616,15597,15596,14609,1,14608,13653,13652,12729,12728,11837,11836,10977,10976,10149,10148,9353,9352,8589,8588,1,7857,7856,7157,7156,6489,6488,5853,5852,5249,5248,4677,4676,4137,4136,3629,1,3628,3153,3152,2709,2708,2297,2296,1917,1916,1569,1568,1251,1253,1255,1257,1,1259,1261,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287,1,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307,1309,1311,1313,1315,1317,1,1319,1321,1323,1325,1327,1329,1658,1659,2022,2023,2418,2419,2846,2847,3306,1,3307,3798,3799,4322,4323,4878,4879,5466,5467,6086,6087,6738,6739,7422,7423,1,8138,8139,8886,8887,9666,9667,10478,10479,11322,11323,12198,12199,13106,13107,14046,1,14047,15018,15019,16022,16023,17058,17059,18126,18127,19226,19227, - 19867,19866,18751,18750,17667,17666,16615,16614,15595,15594,14607,0,14606,13651,13650,12727,12726,11835,11834,10975,10974,10147,10146,9351,9350,8587,8586,0,7855,7854,7155,7154,6487,6486,5851,5850,5247,5246,4675,4674,4135,4134,3627,0,3626,3151,3150,2707,2706,2295,2294,1915,1914,1567,1566,1250,1252,1254,1256,0,1258,1260,1262,1264,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1286,0,1288,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1310,1312,1314,1316,0,1318,1320,1322,1324,1326,1328,1660,1661,2024,2025,2420,2421,2848,2849,3308,0,3309,3800,3801,4324,4325,4880,4881,5468,5469,6088,6089,6740,6741,7424,7425,0,8140,8141,8888,8889,9668,9669,10480,10481,11324,11325,12200,12201,13108,13109,14048,0,14049,15020,15021,16024,16025,17060,17061,18128,18129,19228,19229, - 19865,19864,18749,18748,17665,17664,16613,16612,15593,15592,14605,1,14604,13649,13648,12725,12724,11833,11832,10973,10972,10145,10144,9349,9348,8585,8584,1,7853,7852,7153,7152,6485,6484,5849,5848,5245,5244,4673,4672,4133,4132,3625,1,3624,3149,3148,2705,2704,2293,2292,1913,1912,1565,1564,1249,1248,963,965,1,967,969,971,973,975,977,979,981,983,985,987,989,991,993,995,1,997,999,1001,1003,1005,1007,1009,1011,1013,1015,1017,1019,1021,1023,1025,1,1027,1029,1031,1033,1330,1331,1662,1663,2026,2027,2422,2423,2850,2851,3310,1,3311,3802,3803,4326,4327,4882,4883,5470,5471,6090,6091,6742,6743,7426,7427,1,8142,8143,8890,8891,9670,9671,10482,10483,11326,11327,12202,12203,13110,13111,14050,1,14051,15022,15023,16026,16027,17062,17063,18130,18131,19230,19231, - 19863,19862,18747,18746,17663,17662,16611,16610,15591,15590,14603,0,14602,13647,13646,12723,12722,11831,11830,10971,10970,10143,10142,9347,9346,8583,8582,0,7851,7850,7151,7150,6483,6482,5847,5846,5243,5242,4671,4670,4131,4130,3623,0,3622,3147,3146,2703,2702,2291,2290,1911,1910,1563,1562,1247,1246,962,964,0,966,968,970,972,974,976,978,980,982,984,986,988,990,992,994,0,996,998,1000,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,0,1026,1028,1030,1032,1332,1333,1664,1665,2028,2029,2424,2425,2852,2853,3312,0,3313,3804,3805,4328,4329,4884,4885,5472,5473,6092,6093,6744,6745,7428,7429,0,8144,8145,8892,8893,9672,9673,10484,10485,11328,11329,12204,12205,13112,13113,14052,0,14053,15024,15025,16028,16029,17064,17065,18132,18133,19232,19233, - 19861,19860,18745,18744,17661,17660,16609,16608,15589,15588,14601,1,14600,13645,13644,12721,12720,11829,11828,10969,10968,10141,10140,9345,9344,8581,8580,1,7849,7848,7149,7148,6481,6480,5845,5844,5241,5240,4669,4668,4129,4128,3621,1,3620,3145,3144,2701,2700,2289,2288,1909,1908,1561,1560,1245,1244,961,960,1,707,709,711,713,715,717,719,721,723,725,727,729,731,733,735,1,737,739,741,743,745,747,749,751,753,755,757,759,761,763,765,1,767,769,1034,1035,1334,1335,1666,1667,2030,2031,2426,2427,2854,2855,3314,1,3315,3806,3807,4330,4331,4886,4887,5474,5475,6094,6095,6746,6747,7430,7431,1,8146,8147,8894,8895,9674,9675,10486,10487,11330,11331,12206,12207,13114,13115,14054,1,14055,15026,15027,16030,16031,17066,17067,18134,18135,19234,19235, - 19859,19858,18743,18742,17659,17658,16607,16606,15587,15586,14599,0,14598,13643,13642,12719,12718,11827,11826,10967,10966,10139,10138,9343,9342,8579,8578,0,7847,7846,7147,7146,6479,6478,5843,5842,5239,5238,4667,4666,4127,4126,3619,0,3618,3143,3142,2699,2698,2287,2286,1907,1906,1559,1558,1243,1242,959,958,0,706,708,710,712,714,716,718,720,722,724,726,728,730,732,734,0,736,738,740,742,744,746,748,750,752,754,756,758,760,762,764,0,766,768,1036,1037,1336,1337,1668,1669,2032,2033,2428,2429,2856,2857,3316,0,3317,3808,3809,4332,4333,4888,4889,5476,5477,6096,6097,6748,6749,7432,7433,0,8148,8149,8896,8897,9676,9677,10488,10489,11332,11333,12208,12209,13116,13117,14056,0,14057,15028,15029,16032,16033,17068,17069,18136,18137,19236,19237, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19857,19856,18741,18740,17657,17656,16605,16604,15585,15584,14597,0,14596,13641,13640,12717,12716,11825,11824,10965,10964,10137,10136,9341,9340,8577,8576,0,7845,7844,7145,7144,6477,6476,5841,5840,5237,5236,4665,4664,4125,4124,3617,0,3616,3141,3140,2697,2696,2285,2284,1905,1904,1557,1556,1241,1240,957,956,0,705,704,483,485,487,489,491,493,495,497,499,501,503,505,507,0,509,511,513,515,517,519,521,523,525,527,529,531,533,535,537,0,770,771,1038,1039,1338,1339,1670,1671,2034,2035,2430,2431,2858,2859,3318,0,3319,3810,3811,4334,4335,4890,4891,5478,5479,6098,6099,6750,6751,7434,7435,0,8150,8151,8898,8899,9678,9679,10490,10491,11334,11335,12210,12211,13118,13119,14058,0,14059,15030,15031,16034,16035,17070,17071,18138,18139,19238,19239, - 19855,19854,18739,18738,17655,17654,16603,16602,15583,15582,14595,1,14594,13639,13638,12715,12714,11823,11822,10963,10962,10135,10134,9339,9338,8575,8574,1,7843,7842,7143,7142,6475,6474,5839,5838,5235,5234,4663,4662,4123,4122,3615,1,3614,3139,3138,2695,2694,2283,2282,1903,1902,1555,1554,1239,1238,955,954,1,703,702,482,484,486,488,490,492,494,496,498,500,502,504,506,1,508,510,512,514,516,518,520,522,524,526,528,530,532,534,536,1,772,773,1040,1041,1340,1341,1672,1673,2036,2037,2432,2433,2860,2861,3320,1,3321,3812,3813,4336,4337,4892,4893,5480,5481,6100,6101,6752,6753,7436,7437,1,8152,8153,8900,8901,9680,9681,10492,10493,11336,11337,12212,12213,13120,13121,14060,1,14061,15032,15033,16036,16037,17072,17073,18140,18141,19240,19241, - 19853,19852,18737,18736,17653,17652,16601,16600,15581,15580,14593,0,14592,13637,13636,12713,12712,11821,11820,10961,10960,10133,10132,9337,9336,8573,8572,0,7841,7840,7141,7140,6473,6472,5837,5836,5233,5232,4661,4660,4121,4120,3613,0,3612,3137,3136,2693,2692,2281,2280,1901,1900,1553,1552,1237,1236,953,952,0,701,700,481,480,291,293,295,297,299,301,303,305,307,309,311,0,313,315,317,319,321,323,325,327,329,331,333,335,337,538,539,0,774,775,1042,1043,1342,1343,1674,1675,2038,2039,2434,2435,2862,2863,3322,0,3323,3814,3815,4338,4339,4894,4895,5482,5483,6102,6103,6754,6755,7438,7439,0,8154,8155,8902,8903,9682,9683,10494,10495,11338,11339,12214,12215,13122,13123,14062,0,14063,15034,15035,16038,16039,17074,17075,18142,18143,19242,19243, - 19851,19850,18735,18734,17651,17650,16599,16598,15579,15578,14591,1,14590,13635,13634,12711,12710,11819,11818,10959,10958,10131,10130,9335,9334,8571,8570,1,7839,7838,7139,7138,6471,6470,5835,5834,5231,5230,4659,4658,4119,4118,3611,1,3610,3135,3134,2691,2690,2279,2278,1899,1898,1551,1550,1235,1234,951,950,1,699,698,479,478,290,292,294,296,298,300,302,304,306,308,310,1,312,314,316,318,320,322,324,326,328,330,332,334,336,540,541,1,776,777,1044,1045,1344,1345,1676,1677,2040,2041,2436,2437,2864,2865,3324,1,3325,3816,3817,4340,4341,4896,4897,5484,5485,6104,6105,6756,6757,7440,7441,1,8156,8157,8904,8905,9684,9685,10496,10497,11340,11341,12216,12217,13124,13125,14064,1,14065,15036,15037,16040,16041,17076,17077,18144,18145,19244,19245, - 19849,19848,18733,18732,17649,17648,16597,16596,15577,15576,14589,0,14588,13633,13632,12709,12708,11817,11816,10957,10956,10129,10128,9333,9332,8569,8568,0,7837,7836,7137,7136,6469,6468,5833,5832,5229,5228,4657,4656,4117,4116,3609,0,3608,3133,3132,2689,2688,2277,2276,1897,1896,1549,1548,1233,1232,949,948,0,697,696,477,476,289,288,131,133,135,137,139,141,143,145,147,0,149,151,153,155,157,159,161,163,165,167,169,338,339,542,543,0,778,779,1046,1047,1346,1347,1678,1679,2042,2043,2438,2439,2866,2867,3326,0,3327,3818,3819,4342,4343,4898,4899,5486,5487,6106,6107,6758,6759,7442,7443,0,8158,8159,8906,8907,9686,9687,10498,10499,11342,11343,12218,12219,13126,13127,14066,0,14067,15038,15039,16042,16043,17078,17079,18146,18147,19246,19247, - 19847,19846,18731,18730,17647,17646,16595,16594,15575,15574,14587,1,14586,13631,13630,12707,12706,11815,11814,10955,10954,10127,10126,9331,9330,8567,8566,1,7835,7834,7135,7134,6467,6466,5831,5830,5227,5226,4655,4654,4115,4114,3607,1,3606,3131,3130,2687,2686,2275,2274,1895,1894,1547,1546,1231,1230,947,946,1,695,694,475,474,287,286,130,132,134,136,138,140,142,144,146,1,148,150,152,154,156,158,160,162,164,166,168,340,341,544,545,1,780,781,1048,1049,1348,1349,1680,1681,2044,2045,2440,2441,2868,2869,3328,1,3329,3820,3821,4344,4345,4900,4901,5488,5489,6108,6109,6760,6761,7444,7445,1,8160,8161,8908,8909,9688,9689,10500,10501,11344,11345,12220,12221,13128,13129,14068,1,14069,15040,15041,16044,16045,17080,17081,18148,18149,19248,19249, - 19845,19844,18729,18728,17645,17644,16593,16592,15573,15572,14585,0,14584,13629,13628,12705,12704,11813,11812,10953,10952,10125,10124,9329,9328,8565,8564,0,7833,7832,7133,7132,6465,6464,5829,5828,5225,5224,4653,4652,4113,4112,3605,0,3604,3129,3128,2685,2684,2273,2272,1893,1892,1545,1544,1229,1228,945,944,0,693,692,473,472,285,284,129,128,3,5,7,9,11,13,15,0,17,19,21,23,25,27,29,31,33,170,171,342,343,546,547,0,782,783,1050,1051,1350,1351,1682,1683,2046,2047,2442,2443,2870,2871,3330,0,3331,3822,3823,4346,4347,4902,4903,5490,5491,6110,6111,6762,6763,7446,7447,0,8162,8163,8910,8911,9690,9691,10502,10503,11346,11347,12222,12223,13130,13131,14070,0,14071,15042,15043,16046,16047,17082,17083,18150,18151,19250,19251, - 19843,19842,18727,18726,17643,17642,16591,16590,15571,15570,14583,1,14582,13627,13626,12703,12702,11811,11810,10951,10950,10123,10122,9327,9326,8563,8562,1,7831,7830,7131,7130,6463,6462,5827,5826,5223,5222,4651,4650,4111,4110,3603,1,3602,3127,3126,2683,2682,2271,2270,1891,1890,1543,1542,1227,1226,943,942,1,691,690,471,470,283,282,127,126,2,4,6,8,10,12,14,1,16,18,20,22,24,26,28,30,32,172,173,344,345,548,549,1,784,785,1052,1053,1352,1353,1684,1685,2048,2049,2444,2445,2872,2873,3332,1,3333,3824,3825,4348,4349,4904,4905,5492,5493,6112,6113,6764,6765,7448,7449,1,8164,8165,8912,8913,9692,9693,10504,10505,11348,11349,12224,12225,13132,13133,14072,1,14073,15044,15045,16048,16049,17084,17085,18152,18153,19252,19253, - 19841,19840,18725,18724,17641,17640,16589,16588,15569,15568,14581,0,14580,13625,13624,12701,12700,11809,11808,10949,10948,10121,10120,9325,9324,8561,8560,0,7829,7828,7129,7128,6461,6460,5825,5824,5221,5220,4649,4648,4109,4108,3601,0,3600,3125,3124,2681,2680,2269,2268,1889,1888,1541,1540,1225,1224,941,940,0,689,688,469,468,281,280,125,124,1,1,20000,20001,20002,20003,20004,0,20005,20006,20007,20008,20009,0,1,34,35,174,175,346,347,550,551,0,786,787,1054,1055,1354,1355,1686,1687,2050,2051,2446,2447,2874,2875,3334,0,3335,3826,3827,4350,4351,4906,4907,5494,5495,6114,6115,6766,6767,7450,7451,0,8166,8167,8914,8915,9694,9695,10506,10507,11350,11351,12226,12227,13134,13135,14074,0,14075,15046,15047,16050,16051,17086,17087,18154,18155,19254,19255, - 19839,19838,18723,18722,17639,17638,16587,16586,15567,15566,14579,1,14578,13623,13622,12699,12698,11807,11806,10947,10946,10119,10118,9323,9322,8559,8558,1,7827,7826,7127,7126,6459,6458,5823,5822,5219,5218,4647,4646,4107,4106,3599,1,3598,3123,3122,2679,2678,2267,2266,1887,1886,1539,1538,1223,1222,939,938,1,687,686,467,466,279,278,123,122,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,36,37,176,177,348,349,552,553,1,788,789,1056,1057,1356,1357,1688,1689,2052,2053,2448,2449,2876,2877,3336,1,3337,3828,3829,4352,4353,4908,4909,5496,5497,6116,6117,6768,6769,7452,7453,1,8168,8169,8916,8917,9696,9697,10508,10509,11352,11353,12228,12229,13136,13137,14076,1,14077,15048,15049,16052,16053,17088,17089,18156,18157,19256,19257, - 19837,19836,18721,18720,17637,17636,16585,16584,15565,15564,14577,0,14576,13621,13620,12697,12696,11805,11804,10945,10944,10117,10116,9321,9320,8557,8556,0,7825,7824,7125,7124,6457,6456,5821,5820,5217,5216,4645,4644,4105,4104,3597,0,3596,3121,3120,2677,2676,2265,2264,1885,1884,1537,1536,1221,1220,937,936,0,685,684,465,464,277,276,121,120,20039,1,0,0,0,0,0,0,0,0,0,0,0,1,20010,38,39,178,179,350,351,554,555,0,790,791,1058,1059,1358,1359,1690,1691,2054,2055,2450,2451,2878,2879,3338,0,3339,3830,3831,4354,4355,4910,4911,5498,5499,6118,6119,6770,6771,7454,7455,0,8170,8171,8918,8919,9698,9699,10510,10511,11354,11355,12230,12231,13138,13139,14078,0,14079,15050,15051,16054,16055,17090,17091,18158,18159,19258,19259, - 19835,19834,18719,18718,17635,17634,16583,16582,15563,15562,14575,1,14574,13619,13618,12695,12694,11803,11802,10943,10942,10115,10114,9319,9318,8555,8554,1,7823,7822,7123,7122,6455,6454,5819,5818,5215,5214,4643,4642,4103,4102,3595,1,3594,3119,3118,2675,2674,2263,2262,1883,1882,1535,1534,1219,1218,935,934,1,683,682,463,462,275,274,119,118,20038,1,0,1,1,1,1,1,1,1,1,1,0,1,20011,40,41,180,181,352,353,556,557,1,792,793,1060,1061,1360,1361,1692,1693,2056,2057,2452,2453,2880,2881,3340,1,3341,3832,3833,4356,4357,4912,4913,5500,5501,6120,6121,6772,6773,7456,7457,1,8172,8173,8920,8921,9700,9701,10512,10513,11356,11357,12232,12233,13140,13141,14080,1,14081,15052,15053,16056,16057,17092,17093,18160,18161,19260,19261, - 19833,19832,18717,18716,17633,17632,16581,16580,15561,15560,14573,0,14572,13617,13616,12693,12692,11801,11800,10941,10940,10113,10112,9317,9316,8553,8552,0,7821,7820,7121,7120,6453,6452,5817,5816,5213,5212,4641,4640,4101,4100,3593,0,3592,3117,3116,2673,2672,2261,2260,1881,1880,1533,1532,1217,1216,933,932,0,681,680,461,460,273,272,117,116,20037,1,0,1,0,0,0,0,0,0,0,1,0,1,20012,42,43,182,183,354,355,558,559,0,794,795,1062,1063,1362,1363,1694,1695,2058,2059,2454,2455,2882,2883,3342,0,3343,3834,3835,4358,4359,4914,4915,5502,5503,6122,6123,6774,6775,7458,7459,0,8174,8175,8922,8923,9702,9703,10514,10515,11358,11359,12234,12235,13142,13143,14082,0,14083,15054,15055,16058,16059,17094,17095,18162,18163,19262,19263, - 19831,19830,18715,18714,17631,17630,16579,16578,15559,15558,14571,1,14570,13615,13614,12691,12690,11799,11798,10939,10938,10111,10110,9315,9314,8551,8550,1,7819,7818,7119,7118,6451,6450,5815,5814,5211,5210,4639,4638,4099,4098,3591,1,3590,3115,3114,2671,2670,2259,2258,1879,1878,1531,1530,1215,1214,931,930,1,679,678,459,458,271,270,115,114,20036,1,0,1,0,1,1,1,1,1,0,1,0,1,20013,44,45,184,185,356,357,560,561,1,796,797,1064,1065,1364,1365,1696,1697,2060,2061,2456,2457,2884,2885,3344,1,3345,3836,3837,4360,4361,4916,4917,5504,5505,6124,6125,6776,6777,7460,7461,1,8176,8177,8924,8925,9704,9705,10516,10517,11360,11361,12236,12237,13144,13145,14084,1,14085,15056,15057,16060,16061,17096,17097,18164,18165,19264,19265, - 19829,19828,18713,18712,17629,17628,16577,16576,15557,15556,14569,0,14568,13613,13612,12689,12688,11797,11796,10937,10936,10109,10108,9313,9312,8549,8548,0,7817,7816,7117,7116,6449,6448,5813,5812,5209,5208,4637,4636,4097,4096,3589,0,3588,3113,3112,2669,2668,2257,2256,1877,1876,1529,1528,1213,1212,929,928,0,677,676,457,456,269,268,113,112,20035,1,0,1,0,1,0,0,0,1,0,1,0,1,20014,46,47,186,187,358,359,562,563,0,798,799,1066,1067,1366,1367,1698,1699,2062,2063,2458,2459,2886,2887,3346,0,3347,3838,3839,4362,4363,4918,4919,5506,5507,6126,6127,6778,6779,7462,7463,0,8178,8179,8926,8927,9706,9707,10518,10519,11362,11363,12238,12239,13146,13147,14086,0,14087,15058,15059,16062,16063,17098,17099,18166,18167,19266,19267, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19827,19826,18711,18710,17627,17626,16575,16574,15555,15554,14567,0,14566,13611,13610,12687,12686,11795,11794,10935,10934,10107,10106,9311,9310,8547,8546,0,7815,7814,7115,7114,6447,6446,5811,5810,5207,5206,4635,4634,4095,4094,3587,0,3586,3111,3110,2667,2666,2255,2254,1875,1874,1527,1526,1211,1210,927,926,0,675,674,455,454,267,266,111,110,20034,1,0,1,0,1,0,0,0,1,0,1,0,1,20015,48,49,188,189,360,361,564,565,0,800,801,1068,1069,1368,1369,1700,1701,2064,2065,2460,2461,2888,2889,3348,0,3349,3840,3841,4364,4365,4920,4921,5508,5509,6128,6129,6780,6781,7464,7465,0,8180,8181,8928,8929,9708,9709,10520,10521,11364,11365,12240,12241,13148,13149,14088,0,14089,15060,15061,16064,16065,17100,17101,18168,18169,19268,19269, - 19825,19824,18709,18708,17625,17624,16573,16572,15553,15552,14565,1,14564,13609,13608,12685,12684,11793,11792,10933,10932,10105,10104,9309,9308,8545,8544,1,7813,7812,7113,7112,6445,6444,5809,5808,5205,5204,4633,4632,4093,4092,3585,1,3584,3109,3108,2665,2664,2253,2252,1873,1872,1525,1524,1209,1208,925,924,1,673,672,453,452,265,264,109,108,20033,1,0,1,0,1,1,1,1,1,0,1,0,1,20016,50,51,190,191,362,363,566,567,1,802,803,1070,1071,1370,1371,1702,1703,2066,2067,2462,2463,2890,2891,3350,1,3351,3842,3843,4366,4367,4922,4923,5510,5511,6130,6131,6782,6783,7466,7467,1,8182,8183,8930,8931,9710,9711,10522,10523,11366,11367,12242,12243,13150,13151,14090,1,14091,15062,15063,16066,16067,17102,17103,18170,18171,19270,19271, - 19823,19822,18707,18706,17623,17622,16571,16570,15551,15550,14563,0,14562,13607,13606,12683,12682,11791,11790,10931,10930,10103,10102,9307,9306,8543,8542,0,7811,7810,7111,7110,6443,6442,5807,5806,5203,5202,4631,4630,4091,4090,3583,0,3582,3107,3106,2663,2662,2251,2250,1871,1870,1523,1522,1207,1206,923,922,0,671,670,451,450,263,262,107,106,20032,1,0,1,0,0,0,0,0,0,0,1,0,1,20017,52,53,192,193,364,365,568,569,0,804,805,1072,1073,1372,1373,1704,1705,2068,2069,2464,2465,2892,2893,3352,0,3353,3844,3845,4368,4369,4924,4925,5512,5513,6132,6133,6784,6785,7468,7469,0,8184,8185,8932,8933,9712,9713,10524,10525,11368,11369,12244,12245,13152,13153,14092,0,14093,15064,15065,16068,16069,17104,17105,18172,18173,19272,19273, - 19821,19820,18705,18704,17621,17620,16569,16568,15549,15548,14561,1,14560,13605,13604,12681,12680,11789,11788,10929,10928,10101,10100,9305,9304,8541,8540,1,7809,7808,7109,7108,6441,6440,5805,5804,5201,5200,4629,4628,4089,4088,3581,1,3580,3105,3104,2661,2660,2249,2248,1869,1868,1521,1520,1205,1204,921,920,1,669,668,449,448,261,260,105,104,20031,1,0,1,1,1,1,1,1,1,1,1,0,1,20018,54,55,194,195,366,367,570,571,1,806,807,1074,1075,1374,1375,1706,1707,2070,2071,2466,2467,2894,2895,3354,1,3355,3846,3847,4370,4371,4926,4927,5514,5515,6134,6135,6786,6787,7470,7471,1,8186,8187,8934,8935,9714,9715,10526,10527,11370,11371,12246,12247,13154,13155,14094,1,14095,15066,15067,16070,16071,17106,17107,18174,18175,19274,19275, - 19819,19818,18703,18702,17619,17618,16567,16566,15547,15546,14559,0,14558,13603,13602,12679,12678,11787,11786,10927,10926,10099,10098,9303,9302,8539,8538,0,7807,7806,7107,7106,6439,6438,5803,5802,5199,5198,4627,4626,4087,4086,3579,0,3578,3103,3102,2659,2658,2247,2246,1867,1866,1519,1518,1203,1202,919,918,0,667,666,447,446,259,258,103,102,20030,1,0,0,0,0,0,0,0,0,0,0,0,1,20019,56,57,196,197,368,369,572,573,0,808,809,1076,1077,1376,1377,1708,1709,2072,2073,2468,2469,2896,2897,3356,0,3357,3848,3849,4372,4373,4928,4929,5516,5517,6136,6137,6788,6789,7472,7473,0,8188,8189,8936,8937,9716,9717,10528,10529,11372,11373,12248,12249,13156,13157,14096,0,14097,15068,15069,16072,16073,17108,17109,18176,18177,19276,19277, - 19817,19816,18701,18700,17617,17616,16565,16564,15545,15544,14557,1,14556,13601,13600,12677,12676,11785,11784,10925,10924,10097,10096,9301,9300,8537,8536,1,7805,7804,7105,7104,6437,6436,5801,5800,5197,5196,4625,4624,4085,4084,3577,1,3576,3101,3100,2657,2656,2245,2244,1865,1864,1517,1516,1201,1200,917,916,1,665,664,445,444,257,256,101,100,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,58,59,198,199,370,371,574,575,1,810,811,1078,1079,1378,1379,1710,1711,2074,2075,2470,2471,2898,2899,3358,1,3359,3850,3851,4374,4375,4930,4931,5518,5519,6138,6139,6790,6791,7474,7475,1,8190,8191,8938,8939,9718,9719,10530,10531,11374,11375,12250,12251,13158,13159,14098,1,14099,15070,15071,16074,16075,17110,17111,18178,18179,19278,19279, - 19815,19814,18699,18698,17615,17614,16563,16562,15543,15542,14555,0,14554,13599,13598,12675,12674,11783,11782,10923,10922,10095,10094,9299,9298,8535,8534,0,7803,7802,7103,7102,6435,6434,5799,5798,5195,5194,4623,4622,4083,4082,3575,0,3574,3099,3098,2655,2654,2243,2242,1863,1862,1515,1514,1199,1198,915,914,0,663,662,443,442,255,254,99,98,0,0,20029,20028,20027,20026,20025,0,20024,20023,20022,20021,20020,0,0,60,61,200,201,372,373,576,577,0,812,813,1080,1081,1380,1381,1712,1713,2076,2077,2472,2473,2900,2901,3360,0,3361,3852,3853,4376,4377,4932,4933,5520,5521,6140,6141,6792,6793,7476,7477,0,8192,8193,8940,8941,9720,9721,10532,10533,11376,11377,12252,12253,13160,13161,14100,0,14101,15072,15073,16076,16077,17112,17113,18180,18181,19280,19281, - 19813,19812,18697,18696,17613,17612,16561,16560,15541,15540,14553,1,14552,13597,13596,12673,12672,11781,11780,10921,10920,10093,10092,9297,9296,8533,8532,1,7801,7800,7101,7100,6433,6432,5797,5796,5193,5192,4621,4620,4081,4080,3573,1,3572,3097,3096,2653,2652,2241,2240,1861,1860,1513,1512,1197,1196,913,912,1,661,660,441,440,253,252,96,94,92,90,88,86,84,82,80,1,78,76,74,72,70,68,66,62,63,202,203,374,375,578,579,1,814,815,1082,1083,1382,1383,1714,1715,2078,2079,2474,2475,2902,2903,3362,1,3363,3854,3855,4378,4379,4934,4935,5522,5523,6142,6143,6794,6795,7478,7479,1,8194,8195,8942,8943,9722,9723,10534,10535,11378,11379,12254,12255,13162,13163,14102,1,14103,15074,15075,16078,16079,17114,17115,18182,18183,19282,19283, - 19811,19810,18695,18694,17611,17610,16559,16558,15539,15538,14551,0,14550,13595,13594,12671,12670,11779,11778,10919,10918,10091,10090,9295,9294,8531,8530,0,7799,7798,7099,7098,6431,6430,5795,5794,5191,5190,4619,4618,4079,4078,3571,0,3570,3095,3094,2651,2650,2239,2238,1859,1858,1511,1510,1195,1194,911,910,0,659,658,439,438,251,250,97,95,93,91,89,87,85,83,81,0,79,77,75,73,71,69,67,64,65,204,205,376,377,580,581,0,816,817,1084,1085,1384,1385,1716,1717,2080,2081,2476,2477,2904,2905,3364,0,3365,3856,3857,4380,4381,4936,4937,5524,5525,6144,6145,6796,6797,7480,7481,0,8196,8197,8944,8945,9724,9725,10536,10537,11380,11381,12256,12257,13164,13165,14104,0,14105,15076,15077,16080,16081,17116,17117,18184,18185,19284,19285, - 19809,19808,18693,18692,17609,17608,16557,16556,15537,15536,14549,1,14548,13593,13592,12669,12668,11777,11776,10917,10916,10089,10088,9293,9292,8529,8528,1,7797,7796,7097,7096,6429,6428,5793,5792,5189,5188,4617,4616,4077,4076,3569,1,3568,3093,3092,2649,2648,2237,2236,1857,1856,1509,1508,1193,1192,909,908,1,657,656,437,436,248,246,244,242,240,238,236,234,232,230,228,1,226,224,222,220,218,216,214,212,210,206,207,378,379,582,583,1,818,819,1086,1087,1386,1387,1718,1719,2082,2083,2478,2479,2906,2907,3366,1,3367,3858,3859,4382,4383,4938,4939,5526,5527,6146,6147,6798,6799,7482,7483,1,8198,8199,8946,8947,9726,9727,10538,10539,11382,11383,12258,12259,13166,13167,14106,1,14107,15078,15079,16082,16083,17118,17119,18186,18187,19286,19287, - 19807,19806,18691,18690,17607,17606,16555,16554,15535,15534,14547,0,14546,13591,13590,12667,12666,11775,11774,10915,10914,10087,10086,9291,9290,8527,8526,0,7795,7794,7095,7094,6427,6426,5791,5790,5187,5186,4615,4614,4075,4074,3567,0,3566,3091,3090,2647,2646,2235,2234,1855,1854,1507,1506,1191,1190,907,906,0,655,654,435,434,249,247,245,243,241,239,237,235,233,231,229,0,227,225,223,221,219,217,215,213,211,208,209,380,381,584,585,0,820,821,1088,1089,1388,1389,1720,1721,2084,2085,2480,2481,2908,2909,3368,0,3369,3860,3861,4384,4385,4940,4941,5528,5529,6148,6149,6800,6801,7484,7485,0,8200,8201,8948,8949,9728,9729,10540,10541,11384,11385,12260,12261,13168,13169,14108,0,14109,15080,15081,16084,16085,17120,17121,18188,18189,19288,19289, - 19805,19804,18689,18688,17605,17604,16553,16552,15533,15532,14545,1,14544,13589,13588,12665,12664,11773,11772,10913,10912,10085,10084,9289,9288,8525,8524,1,7793,7792,7093,7092,6425,6424,5789,5788,5185,5184,4613,4612,4073,4072,3565,1,3564,3089,3088,2645,2644,2233,2232,1853,1852,1505,1504,1189,1188,905,904,1,653,652,432,430,428,426,424,422,420,418,416,414,412,410,408,1,406,404,402,400,398,396,394,392,390,388,386,382,383,586,587,1,822,823,1090,1091,1390,1391,1722,1723,2086,2087,2482,2483,2910,2911,3370,1,3371,3862,3863,4386,4387,4942,4943,5530,5531,6150,6151,6802,6803,7486,7487,1,8202,8203,8950,8951,9730,9731,10542,10543,11386,11387,12262,12263,13170,13171,14110,1,14111,15082,15083,16086,16087,17122,17123,18190,18191,19290,19291, - 19803,19802,18687,18686,17603,17602,16551,16550,15531,15530,14543,0,14542,13587,13586,12663,12662,11771,11770,10911,10910,10083,10082,9287,9286,8523,8522,0,7791,7790,7091,7090,6423,6422,5787,5786,5183,5182,4611,4610,4071,4070,3563,0,3562,3087,3086,2643,2642,2231,2230,1851,1850,1503,1502,1187,1186,903,902,0,651,650,433,431,429,427,425,423,421,419,417,415,413,411,409,0,407,405,403,401,399,397,395,393,391,389,387,384,385,588,589,0,824,825,1092,1093,1392,1393,1724,1725,2088,2089,2484,2485,2912,2913,3372,0,3373,3864,3865,4388,4389,4944,4945,5532,5533,6152,6153,6804,6805,7488,7489,0,8204,8205,8952,8953,9732,9733,10544,10545,11388,11389,12264,12265,13172,13173,14112,0,14113,15084,15085,16088,16089,17124,17125,18192,18193,19292,19293, - 19801,19800,18685,18684,17601,17600,16549,16548,15529,15528,14541,1,14540,13585,13584,12661,12660,11769,11768,10909,10908,10081,10080,9285,9284,8521,8520,1,7789,7788,7089,7088,6421,6420,5785,5784,5181,5180,4609,4608,4069,4068,3561,1,3560,3085,3084,2641,2640,2229,2228,1849,1848,1501,1500,1185,1184,901,900,1,648,646,644,642,640,638,636,634,632,630,628,626,624,622,620,1,618,616,614,612,610,608,606,604,602,600,598,596,594,590,591,1,826,827,1094,1095,1394,1395,1726,1727,2090,2091,2486,2487,2914,2915,3374,1,3375,3866,3867,4390,4391,4946,4947,5534,5535,6154,6155,6806,6807,7490,7491,1,8206,8207,8954,8955,9734,9735,10546,10547,11390,11391,12266,12267,13174,13175,14114,1,14115,15086,15087,16090,16091,17126,17127,18194,18195,19294,19295, - 19799,19798,18683,18682,17599,17598,16547,16546,15527,15526,14539,0,14538,13583,13582,12659,12658,11767,11766,10907,10906,10079,10078,9283,9282,8519,8518,0,7787,7786,7087,7086,6419,6418,5783,5782,5179,5178,4607,4606,4067,4066,3559,0,3558,3083,3082,2639,2638,2227,2226,1847,1846,1499,1498,1183,1182,899,898,0,649,647,645,643,641,639,637,635,633,631,629,627,625,623,621,0,619,617,615,613,611,609,607,605,603,601,599,597,595,592,593,0,828,829,1096,1097,1396,1397,1728,1729,2092,2093,2488,2489,2916,2917,3376,0,3377,3868,3869,4392,4393,4948,4949,5536,5537,6156,6157,6808,6809,7492,7493,0,8208,8209,8956,8957,9736,9737,10548,10549,11392,11393,12268,12269,13176,13177,14116,0,14117,15088,15089,16092,16093,17128,17129,18196,18197,19296,19297, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19797,19796,18681,18680,17597,17596,16545,16544,15525,15524,14537,0,14536,13581,13580,12657,12656,11765,11764,10905,10904,10077,10076,9281,9280,8517,8516,0,7785,7784,7085,7084,6417,6416,5781,5780,5177,5176,4605,4604,4065,4064,3557,0,3556,3081,3080,2637,2636,2225,2224,1845,1844,1497,1496,1181,1180,896,894,0,892,890,888,886,884,882,880,878,876,874,872,870,868,866,864,0,862,860,858,856,854,852,850,848,846,844,842,840,838,836,834,0,830,831,1098,1099,1398,1399,1730,1731,2094,2095,2490,2491,2918,2919,3378,0,3379,3870,3871,4394,4395,4950,4951,5538,5539,6158,6159,6810,6811,7494,7495,0,8210,8211,8958,8959,9738,9739,10550,10551,11394,11395,12270,12271,13178,13179,14118,0,14119,15090,15091,16094,16095,17130,17131,18198,18199,19298,19299, - 19795,19794,18679,18678,17595,17594,16543,16542,15523,15522,14535,1,14534,13579,13578,12655,12654,11763,11762,10903,10902,10075,10074,9279,9278,8515,8514,1,7783,7782,7083,7082,6415,6414,5779,5778,5175,5174,4603,4602,4063,4062,3555,1,3554,3079,3078,2635,2634,2223,2222,1843,1842,1495,1494,1179,1178,897,895,1,893,891,889,887,885,883,881,879,877,875,873,871,869,867,865,1,863,861,859,857,855,853,851,849,847,845,843,841,839,837,835,1,832,833,1100,1101,1400,1401,1732,1733,2096,2097,2492,2493,2920,2921,3380,1,3381,3872,3873,4396,4397,4952,4953,5540,5541,6160,6161,6812,6813,7496,7497,1,8212,8213,8960,8961,9740,9741,10552,10553,11396,11397,12272,12273,13180,13181,14120,1,14121,15092,15093,16096,16097,17132,17133,18200,18201,19300,19301, - 19793,19792,18677,18676,17593,17592,16541,16540,15521,15520,14533,0,14532,13577,13576,12653,12652,11761,11760,10901,10900,10073,10072,9277,9276,8513,8512,0,7781,7780,7081,7080,6413,6412,5777,5776,5173,5172,4601,4600,4061,4060,3553,0,3552,3077,3076,2633,2632,2221,2220,1841,1840,1493,1492,1176,1174,1172,1170,0,1168,1166,1164,1162,1160,1158,1156,1154,1152,1150,1148,1146,1144,1142,1140,0,1138,1136,1134,1132,1130,1128,1126,1124,1122,1120,1118,1116,1114,1112,1110,0,1108,1106,1102,1103,1402,1403,1734,1735,2098,2099,2494,2495,2922,2923,3382,0,3383,3874,3875,4398,4399,4954,4955,5542,5543,6162,6163,6814,6815,7498,7499,0,8214,8215,8962,8963,9742,9743,10554,10555,11398,11399,12274,12275,13182,13183,14122,0,14123,15094,15095,16098,16099,17134,17135,18202,18203,19302,19303, - 19791,19790,18675,18674,17591,17590,16539,16538,15519,15518,14531,1,14530,13575,13574,12651,12650,11759,11758,10899,10898,10071,10070,9275,9274,8511,8510,1,7779,7778,7079,7078,6411,6410,5775,5774,5171,5170,4599,4598,4059,4058,3551,1,3550,3075,3074,2631,2630,2219,2218,1839,1838,1491,1490,1177,1175,1173,1171,1,1169,1167,1165,1163,1161,1159,1157,1155,1153,1151,1149,1147,1145,1143,1141,1,1139,1137,1135,1133,1131,1129,1127,1125,1123,1121,1119,1117,1115,1113,1111,1,1109,1107,1104,1105,1404,1405,1736,1737,2100,2101,2496,2497,2924,2925,3384,1,3385,3876,3877,4400,4401,4956,4957,5544,5545,6164,6165,6816,6817,7500,7501,1,8216,8217,8964,8965,9744,9745,10556,10557,11400,11401,12276,12277,13184,13185,14124,1,14125,15096,15097,16100,16101,17136,17137,18204,18205,19304,19305, - 19789,19788,18673,18672,17589,17588,16537,16536,15517,15516,14529,0,14528,13573,13572,12649,12648,11757,11756,10897,10896,10069,10068,9273,9272,8509,8508,0,7777,7776,7077,7076,6409,6408,5773,5772,5169,5168,4597,4596,4057,4056,3549,0,3548,3073,3072,2629,2628,2217,2216,1837,1836,1488,1486,1484,1482,1480,1478,0,1476,1474,1472,1470,1468,1466,1464,1462,1460,1458,1456,1454,1452,1450,1448,0,1446,1444,1442,1440,1438,1436,1434,1432,1430,1428,1426,1424,1422,1420,1418,0,1416,1414,1412,1410,1406,1407,1738,1739,2102,2103,2498,2499,2926,2927,3386,0,3387,3878,3879,4402,4403,4958,4959,5546,5547,6166,6167,6818,6819,7502,7503,0,8218,8219,8966,8967,9746,9747,10558,10559,11402,11403,12278,12279,13186,13187,14126,0,14127,15098,15099,16102,16103,17138,17139,18206,18207,19306,19307, - 19787,19786,18671,18670,17587,17586,16535,16534,15515,15514,14527,1,14526,13571,13570,12647,12646,11755,11754,10895,10894,10067,10066,9271,9270,8507,8506,1,7775,7774,7075,7074,6407,6406,5771,5770,5167,5166,4595,4594,4055,4054,3547,1,3546,3071,3070,2627,2626,2215,2214,1835,1834,1489,1487,1485,1483,1481,1479,1,1477,1475,1473,1471,1469,1467,1465,1463,1461,1459,1457,1455,1453,1451,1449,1,1447,1445,1443,1441,1439,1437,1435,1433,1431,1429,1427,1425,1423,1421,1419,1,1417,1415,1413,1411,1408,1409,1740,1741,2104,2105,2500,2501,2928,2929,3388,1,3389,3880,3881,4404,4405,4960,4961,5548,5549,6168,6169,6820,6821,7504,7505,1,8220,8221,8968,8969,9748,9749,10560,10561,11404,11405,12280,12281,13188,13189,14128,1,14129,15100,15101,16104,16105,17140,17141,18208,18209,19308,19309, - 19785,19784,18669,18668,17585,17584,16533,16532,15513,15512,14525,0,14524,13569,13568,12645,12644,11753,11752,10893,10892,10065,10064,9269,9268,8505,8504,0,7773,7772,7073,7072,6405,6404,5769,5768,5165,5164,4593,4592,4053,4052,3545,0,3544,3069,3068,2625,2624,2213,2212,1832,1830,1828,1826,1824,1822,1820,1818,0,1816,1814,1812,1810,1808,1806,1804,1802,1800,1798,1796,1794,1792,1790,1788,0,1786,1784,1782,1780,1778,1776,1774,1772,1770,1768,1766,1764,1762,1760,1758,0,1756,1754,1752,1750,1748,1746,1742,1743,2106,2107,2502,2503,2930,2931,3390,0,3391,3882,3883,4406,4407,4962,4963,5550,5551,6170,6171,6822,6823,7506,7507,0,8222,8223,8970,8971,9750,9751,10562,10563,11406,11407,12282,12283,13190,13191,14130,0,14131,15102,15103,16106,16107,17142,17143,18210,18211,19310,19311, - 19783,19782,18667,18666,17583,17582,16531,16530,15511,15510,14523,1,14522,13567,13566,12643,12642,11751,11750,10891,10890,10063,10062,9267,9266,8503,8502,1,7771,7770,7071,7070,6403,6402,5767,5766,5163,5162,4591,4590,4051,4050,3543,1,3542,3067,3066,2623,2622,2211,2210,1833,1831,1829,1827,1825,1823,1821,1819,1,1817,1815,1813,1811,1809,1807,1805,1803,1801,1799,1797,1795,1793,1791,1789,1,1787,1785,1783,1781,1779,1777,1775,1773,1771,1769,1767,1765,1763,1761,1759,1,1757,1755,1753,1751,1749,1747,1744,1745,2108,2109,2504,2505,2932,2933,3392,1,3393,3884,3885,4408,4409,4964,4965,5552,5553,6172,6173,6824,6825,7508,7509,1,8224,8225,8972,8973,9752,9753,10564,10565,11408,11409,12284,12285,13192,13193,14132,1,14133,15104,15105,16108,16109,17144,17145,18212,18213,19312,19313, - 19781,19780,18665,18664,17581,17580,16529,16528,15509,15508,14521,0,14520,13565,13564,12641,12640,11749,11748,10889,10888,10061,10060,9265,9264,8501,8500,0,7769,7768,7069,7068,6401,6400,5765,5764,5161,5160,4589,4588,4049,4048,3541,0,3540,3065,3064,2621,2620,2208,2206,2204,2202,2200,2198,2196,2194,2192,2190,0,2188,2186,2184,2182,2180,2178,2176,2174,2172,2170,2168,2166,2164,2162,2160,0,2158,2156,2154,2152,2150,2148,2146,2144,2142,2140,2138,2136,2134,2132,2130,0,2128,2126,2124,2122,2120,2118,2116,2114,2110,2111,2506,2507,2934,2935,3394,0,3395,3886,3887,4410,4411,4966,4967,5554,5555,6174,6175,6826,6827,7510,7511,0,8226,8227,8974,8975,9754,9755,10566,10567,11410,11411,12286,12287,13194,13195,14134,0,14135,15106,15107,16110,16111,17146,17147,18214,18215,19314,19315, - 19779,19778,18663,18662,17579,17578,16527,16526,15507,15506,14519,1,14518,13563,13562,12639,12638,11747,11746,10887,10886,10059,10058,9263,9262,8499,8498,1,7767,7766,7067,7066,6399,6398,5763,5762,5159,5158,4587,4586,4047,4046,3539,1,3538,3063,3062,2619,2618,2209,2207,2205,2203,2201,2199,2197,2195,2193,2191,1,2189,2187,2185,2183,2181,2179,2177,2175,2173,2171,2169,2167,2165,2163,2161,1,2159,2157,2155,2153,2151,2149,2147,2145,2143,2141,2139,2137,2135,2133,2131,1,2129,2127,2125,2123,2121,2119,2117,2115,2112,2113,2508,2509,2936,2937,3396,1,3397,3888,3889,4412,4413,4968,4969,5556,5557,6176,6177,6828,6829,7512,7513,1,8228,8229,8976,8977,9756,9757,10568,10569,11412,11413,12288,12289,13196,13197,14136,1,14137,15108,15109,16112,16113,17148,17149,18216,18217,19316,19317, - 19777,19776,18661,18660,17577,17576,16525,16524,15505,15504,14517,0,14516,13561,13560,12637,12636,11745,11744,10885,10884,10057,10056,9261,9260,8497,8496,0,7765,7764,7065,7064,6397,6396,5761,5760,5157,5156,4585,4584,4045,4044,3537,0,3536,3061,3060,2616,2614,2612,2610,2608,2606,2604,2602,2600,2598,2596,2594,0,2592,2590,2588,2586,2584,2582,2580,2578,2576,2574,2572,2570,2568,2566,2564,0,2562,2560,2558,2556,2554,2552,2550,2548,2546,2544,2542,2540,2538,2536,2534,0,2532,2530,2528,2526,2524,2522,2520,2518,2516,2514,2510,2511,2938,2939,3398,0,3399,3890,3891,4414,4415,4970,4971,5558,5559,6178,6179,6830,6831,7514,7515,0,8230,8231,8978,8979,9758,9759,10570,10571,11414,11415,12290,12291,13198,13199,14138,0,14139,15110,15111,16114,16115,17150,17151,18218,18219,19318,19319, - 19775,19774,18659,18658,17575,17574,16523,16522,15503,15502,14515,1,14514,13559,13558,12635,12634,11743,11742,10883,10882,10055,10054,9259,9258,8495,8494,1,7763,7762,7063,7062,6395,6394,5759,5758,5155,5154,4583,4582,4043,4042,3535,1,3534,3059,3058,2617,2615,2613,2611,2609,2607,2605,2603,2601,2599,2597,2595,1,2593,2591,2589,2587,2585,2583,2581,2579,2577,2575,2573,2571,2569,2567,2565,1,2563,2561,2559,2557,2555,2553,2551,2549,2547,2545,2543,2541,2539,2537,2535,1,2533,2531,2529,2527,2525,2523,2521,2519,2517,2515,2512,2513,2940,2941,3400,1,3401,3892,3893,4416,4417,4972,4973,5560,5561,6180,6181,6832,6833,7516,7517,1,8232,8233,8980,8981,9760,9761,10572,10573,11416,11417,12292,12293,13200,13201,14140,1,14141,15112,15113,16116,16117,17152,17153,18220,18221,19320,19321, - 19773,19772,18657,18656,17573,17572,16521,16520,15501,15500,14513,0,14512,13557,13556,12633,12632,11741,11740,10881,10880,10053,10052,9257,9256,8493,8492,0,7761,7760,7061,7060,6393,6392,5757,5756,5153,5152,4581,4580,4041,4040,3533,0,3532,3056,3054,3052,3050,3048,3046,3044,3042,3040,3038,3036,3034,3032,3030,0,3028,3026,3024,3022,3020,3018,3016,3014,3012,3010,3008,3006,3004,3002,3000,0,2998,2996,2994,2992,2990,2988,2986,2984,2982,2980,2978,2976,2974,2972,2970,0,2968,2966,2964,2962,2960,2958,2956,2954,2952,2950,2948,2946,2942,2943,3402,0,3403,3894,3895,4418,4419,4974,4975,5562,5563,6182,6183,6834,6835,7518,7519,0,8234,8235,8982,8983,9762,9763,10574,10575,11418,11419,12294,12295,13202,13203,14142,0,14143,15114,15115,16118,16119,17154,17155,18222,18223,19322,19323, - 19771,19770,18655,18654,17571,17570,16519,16518,15499,15498,14511,1,14510,13555,13554,12631,12630,11739,11738,10879,10878,10051,10050,9255,9254,8491,8490,1,7759,7758,7059,7058,6391,6390,5755,5754,5151,5150,4579,4578,4039,4038,3531,1,3530,3057,3055,3053,3051,3049,3047,3045,3043,3041,3039,3037,3035,3033,3031,1,3029,3027,3025,3023,3021,3019,3017,3015,3013,3011,3009,3007,3005,3003,3001,1,2999,2997,2995,2993,2991,2989,2987,2985,2983,2981,2979,2977,2975,2973,2971,1,2969,2967,2965,2963,2961,2959,2957,2955,2953,2951,2949,2947,2944,2945,3404,1,3405,3896,3897,4420,4421,4976,4977,5564,5565,6184,6185,6836,6837,7520,7521,1,8236,8237,8984,8985,9764,9765,10576,10577,11420,11421,12296,12297,13204,13205,14144,1,14145,15116,15117,16120,16121,17156,17157,18224,18225,19324,19325, - 19769,19768,18653,18652,17569,17568,16517,16516,15497,15496,14509,0,14508,13553,13552,12629,12628,11737,11736,10877,10876,10049,10048,9253,9252,8489,8488,0,7757,7756,7057,7056,6389,6388,5753,5752,5149,5148,4577,4576,4037,4036,3528,0,3526,3524,3522,3520,3518,3516,3514,3512,3510,3508,3506,3504,3502,3500,3498,0,3496,3494,3492,3490,3488,3486,3484,3482,3480,3478,3476,3474,3472,3470,3468,0,3466,3464,3462,3460,3458,3456,3454,3452,3450,3448,3446,3444,3442,3440,3438,0,3436,3434,3432,3430,3428,3426,3424,3422,3420,3418,3416,3414,3412,3410,3406,0,3407,3898,3899,4422,4423,4978,4979,5566,5567,6186,6187,6838,6839,7522,7523,0,8238,8239,8986,8987,9766,9767,10578,10579,11422,11423,12298,12299,13206,13207,14146,0,14147,15118,15119,16122,16123,17158,17159,18226,18227,19326,19327, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19767,19766,18651,18650,17567,17566,16515,16514,15495,15494,14507,0,14506,13551,13550,12627,12626,11735,11734,10875,10874,10047,10046,9251,9250,8487,8486,0,7755,7754,7055,7054,6387,6386,5751,5750,5147,5146,4575,4574,4035,4034,3529,0,3527,3525,3523,3521,3519,3517,3515,3513,3511,3509,3507,3505,3503,3501,3499,0,3497,3495,3493,3491,3489,3487,3485,3483,3481,3479,3477,3475,3473,3471,3469,0,3467,3465,3463,3461,3459,3457,3455,3453,3451,3449,3447,3445,3443,3441,3439,0,3437,3435,3433,3431,3429,3427,3425,3423,3421,3419,3417,3415,3413,3411,3408,0,3409,3900,3901,4424,4425,4980,4981,5568,5569,6188,6189,6840,6841,7524,7525,0,8240,8241,8988,8989,9768,9769,10580,10581,11424,11425,12300,12301,13208,13209,14148,0,14149,15120,15121,16124,16125,17160,17161,18228,18229,19328,19329, - 19765,19764,18649,18648,17565,17564,16513,16512,15493,15492,14505,1,14504,13549,13548,12625,12624,11733,11732,10873,10872,10045,10044,9249,9248,8485,8484,1,7753,7752,7053,7052,6385,6384,5749,5748,5145,5144,4573,4572,4032,4030,4028,1,4026,4024,4022,4020,4018,4016,4014,4012,4010,4008,4006,4004,4002,4000,3998,1,3996,3994,3992,3990,3988,3986,3984,3982,3980,3978,3976,3974,3972,3970,3968,1,3966,3964,3962,3960,3958,3956,3954,3952,3950,3948,3946,3944,3942,3940,3938,1,3936,3934,3932,3930,3928,3926,3924,3922,3920,3918,3916,3914,3912,3910,3908,1,3906,3902,3903,4426,4427,4982,4983,5570,5571,6190,6191,6842,6843,7526,7527,1,8242,8243,8990,8991,9770,9771,10582,10583,11426,11427,12302,12303,13210,13211,14150,1,14151,15122,15123,16126,16127,17162,17163,18230,18231,19330,19331, - 19763,19762,18647,18646,17563,17562,16511,16510,15491,15490,14503,0,14502,13547,13546,12623,12622,11731,11730,10871,10870,10043,10042,9247,9246,8483,8482,0,7751,7750,7051,7050,6383,6382,5747,5746,5143,5142,4571,4570,4033,4031,4029,0,4027,4025,4023,4021,4019,4017,4015,4013,4011,4009,4007,4005,4003,4001,3999,0,3997,3995,3993,3991,3989,3987,3985,3983,3981,3979,3977,3975,3973,3971,3969,0,3967,3965,3963,3961,3959,3957,3955,3953,3951,3949,3947,3945,3943,3941,3939,0,3937,3935,3933,3931,3929,3927,3925,3923,3921,3919,3917,3915,3913,3911,3909,0,3907,3904,3905,4428,4429,4984,4985,5572,5573,6192,6193,6844,6845,7528,7529,0,8244,8245,8992,8993,9772,9773,10584,10585,11428,11429,12304,12305,13212,13213,14152,0,14153,15124,15125,16128,16129,17164,17165,18232,18233,19332,19333, - 19761,19760,18645,18644,17561,17560,16509,16508,15489,15488,14501,1,14500,13545,13544,12621,12620,11729,11728,10869,10868,10041,10040,9245,9244,8481,8480,1,7749,7748,7049,7048,6381,6380,5745,5744,5141,5140,4568,4566,4564,4562,4560,1,4558,4556,4554,4552,4550,4548,4546,4544,4542,4540,4538,4536,4534,4532,4530,1,4528,4526,4524,4522,4520,4518,4516,4514,4512,4510,4508,4506,4504,4502,4500,1,4498,4496,4494,4492,4490,4488,4486,4484,4482,4480,4478,4476,4474,4472,4470,1,4468,4466,4464,4462,4460,4458,4456,4454,4452,4450,4448,4446,4444,4442,4440,1,4438,4436,4434,4430,4431,4986,4987,5574,5575,6194,6195,6846,6847,7530,7531,1,8246,8247,8994,8995,9774,9775,10586,10587,11430,11431,12306,12307,13214,13215,14154,1,14155,15126,15127,16130,16131,17166,17167,18234,18235,19334,19335, - 19759,19758,18643,18642,17559,17558,16507,16506,15487,15486,14499,0,14498,13543,13542,12619,12618,11727,11726,10867,10866,10039,10038,9243,9242,8479,8478,0,7747,7746,7047,7046,6379,6378,5743,5742,5139,5138,4569,4567,4565,4563,4561,0,4559,4557,4555,4553,4551,4549,4547,4545,4543,4541,4539,4537,4535,4533,4531,0,4529,4527,4525,4523,4521,4519,4517,4515,4513,4511,4509,4507,4505,4503,4501,0,4499,4497,4495,4493,4491,4489,4487,4485,4483,4481,4479,4477,4475,4473,4471,0,4469,4467,4465,4463,4461,4459,4457,4455,4453,4451,4449,4447,4445,4443,4441,0,4439,4437,4435,4432,4433,4988,4989,5576,5577,6196,6197,6848,6849,7532,7533,0,8248,8249,8996,8997,9776,9777,10588,10589,11432,11433,12308,12309,13216,13217,14156,0,14157,15128,15129,16132,16133,17168,17169,18236,18237,19336,19337, - 19757,19756,18641,18640,17557,17556,16505,16504,15485,15484,14497,1,14496,13541,13540,12617,12616,11725,11724,10865,10864,10037,10036,9241,9240,8477,8476,1,7745,7744,7045,7044,6377,6376,5741,5740,5136,5134,5132,5130,5128,5126,5124,1,5122,5120,5118,5116,5114,5112,5110,5108,5106,5104,5102,5100,5098,5096,5094,1,5092,5090,5088,5086,5084,5082,5080,5078,5076,5074,5072,5070,5068,5066,5064,1,5062,5060,5058,5056,5054,5052,5050,5048,5046,5044,5042,5040,5038,5036,5034,1,5032,5030,5028,5026,5024,5022,5020,5018,5016,5014,5012,5010,5008,5006,5004,1,5002,5000,4998,4996,4994,4990,4991,5578,5579,6198,6199,6850,6851,7534,7535,1,8250,8251,8998,8999,9778,9779,10590,10591,11434,11435,12310,12311,13218,13219,14158,1,14159,15130,15131,16134,16135,17170,17171,18238,18239,19338,19339, - 19755,19754,18639,18638,17555,17554,16503,16502,15483,15482,14495,0,14494,13539,13538,12615,12614,11723,11722,10863,10862,10035,10034,9239,9238,8475,8474,0,7743,7742,7043,7042,6375,6374,5739,5738,5137,5135,5133,5131,5129,5127,5125,0,5123,5121,5119,5117,5115,5113,5111,5109,5107,5105,5103,5101,5099,5097,5095,0,5093,5091,5089,5087,5085,5083,5081,5079,5077,5075,5073,5071,5069,5067,5065,0,5063,5061,5059,5057,5055,5053,5051,5049,5047,5045,5043,5041,5039,5037,5035,0,5033,5031,5029,5027,5025,5023,5021,5019,5017,5015,5013,5011,5009,5007,5005,0,5003,5001,4999,4997,4995,4992,4993,5580,5581,6200,6201,6852,6853,7536,7537,0,8252,8253,9000,9001,9780,9781,10592,10593,11436,11437,12312,12313,13220,13221,14160,0,14161,15132,15133,16136,16137,17172,17173,18240,18241,19340,19341, - 19753,19752,18637,18636,17553,17552,16501,16500,15481,15480,14493,1,14492,13537,13536,12613,12612,11721,11720,10861,10860,10033,10032,9237,9236,8473,8472,1,7741,7740,7041,7040,6373,6372,5736,5734,5732,5730,5728,5726,5724,5722,5720,1,5718,5716,5714,5712,5710,5708,5706,5704,5702,5700,5698,5696,5694,5692,5690,1,5688,5686,5684,5682,5680,5678,5676,5674,5672,5670,5668,5666,5664,5662,5660,1,5658,5656,5654,5652,5650,5648,5646,5644,5642,5640,5638,5636,5634,5632,5630,1,5628,5626,5624,5622,5620,5618,5616,5614,5612,5610,5608,5606,5604,5602,5600,1,5598,5596,5594,5592,5590,5588,5586,5582,5583,6202,6203,6854,6855,7538,7539,1,8254,8255,9002,9003,9782,9783,10594,10595,11438,11439,12314,12315,13222,13223,14162,1,14163,15134,15135,16138,16139,17174,17175,18242,18243,19342,19343, - 19751,19750,18635,18634,17551,17550,16499,16498,15479,15478,14491,0,14490,13535,13534,12611,12610,11719,11718,10859,10858,10031,10030,9235,9234,8471,8470,0,7739,7738,7039,7038,6371,6370,5737,5735,5733,5731,5729,5727,5725,5723,5721,0,5719,5717,5715,5713,5711,5709,5707,5705,5703,5701,5699,5697,5695,5693,5691,0,5689,5687,5685,5683,5681,5679,5677,5675,5673,5671,5669,5667,5665,5663,5661,0,5659,5657,5655,5653,5651,5649,5647,5645,5643,5641,5639,5637,5635,5633,5631,0,5629,5627,5625,5623,5621,5619,5617,5615,5613,5611,5609,5607,5605,5603,5601,0,5599,5597,5595,5593,5591,5589,5587,5584,5585,6204,6205,6856,6857,7540,7541,0,8256,8257,9004,9005,9784,9785,10596,10597,11440,11441,12316,12317,13224,13225,14164,0,14165,15136,15137,16140,16141,17176,17177,18244,18245,19344,19345, - 19749,19748,18633,18632,17549,17548,16497,16496,15477,15476,14489,1,14488,13533,13532,12609,12608,11717,11716,10857,10856,10029,10028,9233,9232,8469,8468,1,7737,7736,7037,7036,6368,6366,6364,6362,6360,6358,6356,6354,6352,6350,6348,1,6346,6344,6342,6340,6338,6336,6334,6332,6330,6328,6326,6324,6322,6320,6318,1,6316,6314,6312,6310,6308,6306,6304,6302,6300,6298,6296,6294,6292,6290,6288,1,6286,6284,6282,6280,6278,6276,6274,6272,6270,6268,6266,6264,6262,6260,6258,1,6256,6254,6252,6250,6248,6246,6244,6242,6240,6238,6236,6234,6232,6230,6228,1,6226,6224,6222,6220,6218,6216,6214,6212,6210,6206,6207,6858,6859,7542,7543,1,8258,8259,9006,9007,9786,9787,10598,10599,11442,11443,12318,12319,13226,13227,14166,1,14167,15138,15139,16142,16143,17178,17179,18246,18247,19346,19347, - 19747,19746,18631,18630,17547,17546,16495,16494,15475,15474,14487,0,14486,13531,13530,12607,12606,11715,11714,10855,10854,10027,10026,9231,9230,8467,8466,0,7735,7734,7035,7034,6369,6367,6365,6363,6361,6359,6357,6355,6353,6351,6349,0,6347,6345,6343,6341,6339,6337,6335,6333,6331,6329,6327,6325,6323,6321,6319,0,6317,6315,6313,6311,6309,6307,6305,6303,6301,6299,6297,6295,6293,6291,6289,0,6287,6285,6283,6281,6279,6277,6275,6273,6271,6269,6267,6265,6263,6261,6259,0,6257,6255,6253,6251,6249,6247,6245,6243,6241,6239,6237,6235,6233,6231,6229,0,6227,6225,6223,6221,6219,6217,6215,6213,6211,6208,6209,6860,6861,7544,7545,0,8260,8261,9008,9009,9788,9789,10600,10601,11444,11445,12320,12321,13228,13229,14168,0,14169,15140,15141,16144,16145,17180,17181,18248,18249,19348,19349, - 19745,19744,18629,18628,17545,17544,16493,16492,15473,15472,14485,1,14484,13529,13528,12605,12604,11713,11712,10853,10852,10025,10024,9229,9228,8465,8464,1,7733,7732,7032,7030,7028,7026,7024,7022,7020,7018,7016,7014,7012,7010,7008,1,7006,7004,7002,7000,6998,6996,6994,6992,6990,6988,6986,6984,6982,6980,6978,1,6976,6974,6972,6970,6968,6966,6964,6962,6960,6958,6956,6954,6952,6950,6948,1,6946,6944,6942,6940,6938,6936,6934,6932,6930,6928,6926,6924,6922,6920,6918,1,6916,6914,6912,6910,6908,6906,6904,6902,6900,6898,6896,6894,6892,6890,6888,1,6886,6884,6882,6880,6878,6876,6874,6872,6870,6868,6866,6862,6863,7546,7547,1,8262,8263,9010,9011,9790,9791,10602,10603,11446,11447,12322,12323,13230,13231,14170,1,14171,15142,15143,16146,16147,17182,17183,18250,18251,19350,19351, - 19743,19742,18627,18626,17543,17542,16491,16490,15471,15470,14483,0,14482,13527,13526,12603,12602,11711,11710,10851,10850,10023,10022,9227,9226,8463,8462,0,7731,7730,7033,7031,7029,7027,7025,7023,7021,7019,7017,7015,7013,7011,7009,0,7007,7005,7003,7001,6999,6997,6995,6993,6991,6989,6987,6985,6983,6981,6979,0,6977,6975,6973,6971,6969,6967,6965,6963,6961,6959,6957,6955,6953,6951,6949,0,6947,6945,6943,6941,6939,6937,6935,6933,6931,6929,6927,6925,6923,6921,6919,0,6917,6915,6913,6911,6909,6907,6905,6903,6901,6899,6897,6895,6893,6891,6889,0,6887,6885,6883,6881,6879,6877,6875,6873,6871,6869,6867,6864,6865,7548,7549,0,8264,8265,9012,9013,9792,9793,10604,10605,11448,11449,12324,12325,13232,13233,14172,0,14173,15144,15145,16148,16149,17184,17185,18252,18253,19352,19353, - 19741,19740,18625,18624,17541,17540,16489,16488,15469,15468,14481,1,14480,13525,13524,12601,12600,11709,11708,10849,10848,10021,10020,9225,9224,8461,8460,1,7728,7726,7724,7722,7720,7718,7716,7714,7712,7710,7708,7706,7704,7702,7700,1,7698,7696,7694,7692,7690,7688,7686,7684,7682,7680,7678,7676,7674,7672,7670,1,7668,7666,7664,7662,7660,7658,7656,7654,7652,7650,7648,7646,7644,7642,7640,1,7638,7636,7634,7632,7630,7628,7626,7624,7622,7620,7618,7616,7614,7612,7610,1,7608,7606,7604,7602,7600,7598,7596,7594,7592,7590,7588,7586,7584,7582,7580,1,7578,7576,7574,7572,7570,7568,7566,7564,7562,7560,7558,7556,7554,7550,7551,1,8266,8267,9014,9015,9794,9795,10606,10607,11450,11451,12326,12327,13234,13235,14174,1,14175,15146,15147,16150,16151,17186,17187,18254,18255,19354,19355, - 19739,19738,18623,18622,17539,17538,16487,16486,15467,15466,14479,0,14478,13523,13522,12599,12598,11707,11706,10847,10846,10019,10018,9223,9222,8459,8458,0,7729,7727,7725,7723,7721,7719,7717,7715,7713,7711,7709,7707,7705,7703,7701,0,7699,7697,7695,7693,7691,7689,7687,7685,7683,7681,7679,7677,7675,7673,7671,0,7669,7667,7665,7663,7661,7659,7657,7655,7653,7651,7649,7647,7645,7643,7641,0,7639,7637,7635,7633,7631,7629,7627,7625,7623,7621,7619,7617,7615,7613,7611,0,7609,7607,7605,7603,7601,7599,7597,7595,7593,7591,7589,7587,7585,7583,7581,0,7579,7577,7575,7573,7571,7569,7567,7565,7563,7561,7559,7557,7555,7552,7553,0,8268,8269,9016,9017,9796,9797,10608,10609,11452,11453,12328,12329,13236,13237,14176,0,14177,15148,15149,16152,16153,17188,17189,18256,18257,19356,19357, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19737,19736,18621,18620,17537,17536,16485,16484,15465,15464,14477,0,14476,13521,13520,12597,12596,11705,11704,10845,10844,10017,10016,9221,9220,8456,8454,0,8452,8450,8448,8446,8444,8442,8440,8438,8436,8434,8432,8430,8428,8426,8424,0,8422,8420,8418,8416,8414,8412,8410,8408,8406,8404,8402,8400,8398,8396,8394,0,8392,8390,8388,8386,8384,8382,8380,8378,8376,8374,8372,8370,8368,8366,8364,0,8362,8360,8358,8356,8354,8352,8350,8348,8346,8344,8342,8340,8338,8336,8334,0,8332,8330,8328,8326,8324,8322,8320,8318,8316,8314,8312,8310,8308,8306,8304,0,8302,8300,8298,8296,8294,8292,8290,8288,8286,8284,8282,8280,8278,8276,8274,0,8270,8271,9018,9019,9798,9799,10610,10611,11454,11455,12330,12331,13238,13239,14178,0,14179,15150,15151,16154,16155,17190,17191,18258,18259,19358,19359, - 19735,19734,18619,18618,17535,17534,16483,16482,15463,15462,14475,1,14474,13519,13518,12595,12594,11703,11702,10843,10842,10015,10014,9219,9218,8457,8455,1,8453,8451,8449,8447,8445,8443,8441,8439,8437,8435,8433,8431,8429,8427,8425,1,8423,8421,8419,8417,8415,8413,8411,8409,8407,8405,8403,8401,8399,8397,8395,1,8393,8391,8389,8387,8385,8383,8381,8379,8377,8375,8373,8371,8369,8367,8365,1,8363,8361,8359,8357,8355,8353,8351,8349,8347,8345,8343,8341,8339,8337,8335,1,8333,8331,8329,8327,8325,8323,8321,8319,8317,8315,8313,8311,8309,8307,8305,1,8303,8301,8299,8297,8295,8293,8291,8289,8287,8285,8283,8281,8279,8277,8275,1,8272,8273,9020,9021,9800,9801,10612,10613,11456,11457,12332,12333,13240,13241,14180,1,14181,15152,15153,16156,16157,17192,17193,18260,18261,19360,19361, - 19733,19732,18617,18616,17533,17532,16481,16480,15461,15460,14473,0,14472,13517,13516,12593,12592,11701,11700,10841,10840,10013,10012,9216,9214,9212,9210,0,9208,9206,9204,9202,9200,9198,9196,9194,9192,9190,9188,9186,9184,9182,9180,0,9178,9176,9174,9172,9170,9168,9166,9164,9162,9160,9158,9156,9154,9152,9150,0,9148,9146,9144,9142,9140,9138,9136,9134,9132,9130,9128,9126,9124,9122,9120,0,9118,9116,9114,9112,9110,9108,9106,9104,9102,9100,9098,9096,9094,9092,9090,0,9088,9086,9084,9082,9080,9078,9076,9074,9072,9070,9068,9066,9064,9062,9060,0,9058,9056,9054,9052,9050,9048,9046,9044,9042,9040,9038,9036,9034,9032,9030,0,9028,9026,9022,9023,9802,9803,10614,10615,11458,11459,12334,12335,13242,13243,14182,0,14183,15154,15155,16158,16159,17194,17195,18262,18263,19362,19363, - 19731,19730,18615,18614,17531,17530,16479,16478,15459,15458,14471,1,14470,13515,13514,12591,12590,11699,11698,10839,10838,10011,10010,9217,9215,9213,9211,1,9209,9207,9205,9203,9201,9199,9197,9195,9193,9191,9189,9187,9185,9183,9181,1,9179,9177,9175,9173,9171,9169,9167,9165,9163,9161,9159,9157,9155,9153,9151,1,9149,9147,9145,9143,9141,9139,9137,9135,9133,9131,9129,9127,9125,9123,9121,1,9119,9117,9115,9113,9111,9109,9107,9105,9103,9101,9099,9097,9095,9093,9091,1,9089,9087,9085,9083,9081,9079,9077,9075,9073,9071,9069,9067,9065,9063,9061,1,9059,9057,9055,9053,9051,9049,9047,9045,9043,9041,9039,9037,9035,9033,9031,1,9029,9027,9024,9025,9804,9805,10616,10617,11460,11461,12336,12337,13244,13245,14184,1,14185,15156,15157,16160,16161,17196,17197,18264,18265,19364,19365, - 19729,19728,18613,18612,17529,17528,16477,16476,15457,15456,14469,0,14468,13513,13512,12589,12588,11697,11696,10837,10836,10008,10006,10004,10002,10000,9998,0,9996,9994,9992,9990,9988,9986,9984,9982,9980,9978,9976,9974,9972,9970,9968,0,9966,9964,9962,9960,9958,9956,9954,9952,9950,9948,9946,9944,9942,9940,9938,0,9936,9934,9932,9930,9928,9926,9924,9922,9920,9918,9916,9914,9912,9910,9908,0,9906,9904,9902,9900,9898,9896,9894,9892,9890,9888,9886,9884,9882,9880,9878,0,9876,9874,9872,9870,9868,9866,9864,9862,9860,9858,9856,9854,9852,9850,9848,0,9846,9844,9842,9840,9838,9836,9834,9832,9830,9828,9826,9824,9822,9820,9818,0,9816,9814,9812,9810,9806,9807,10618,10619,11462,11463,12338,12339,13246,13247,14186,0,14187,15158,15159,16162,16163,17198,17199,18266,18267,19366,19367, - 19727,19726,18611,18610,17527,17526,16475,16474,15455,15454,14467,1,14466,13511,13510,12587,12586,11695,11694,10835,10834,10009,10007,10005,10003,10001,9999,1,9997,9995,9993,9991,9989,9987,9985,9983,9981,9979,9977,9975,9973,9971,9969,1,9967,9965,9963,9961,9959,9957,9955,9953,9951,9949,9947,9945,9943,9941,9939,1,9937,9935,9933,9931,9929,9927,9925,9923,9921,9919,9917,9915,9913,9911,9909,1,9907,9905,9903,9901,9899,9897,9895,9893,9891,9889,9887,9885,9883,9881,9879,1,9877,9875,9873,9871,9869,9867,9865,9863,9861,9859,9857,9855,9853,9851,9849,1,9847,9845,9843,9841,9839,9837,9835,9833,9831,9829,9827,9825,9823,9821,9819,1,9817,9815,9813,9811,9808,9809,10620,10621,11464,11465,12340,12341,13248,13249,14188,1,14189,15160,15161,16164,16165,17200,17201,18268,18269,19368,19369, - 19725,19724,18609,18608,17525,17524,16473,16472,15453,15452,14465,0,14464,13509,13508,12585,12584,11693,11692,10832,10830,10828,10826,10824,10822,10820,10818,0,10816,10814,10812,10810,10808,10806,10804,10802,10800,10798,10796,10794,10792,10790,10788,0,10786,10784,10782,10780,10778,10776,10774,10772,10770,10768,10766,10764,10762,10760,10758,0,10756,10754,10752,10750,10748,10746,10744,10742,10740,10738,10736,10734,10732,10730,10728,0,10726,10724,10722,10720,10718,10716,10714,10712,10710,10708,10706,10704,10702,10700,10698,0,10696,10694,10692,10690,10688,10686,10684,10682,10680,10678,10676,10674,10672,10670,10668,0,10666,10664,10662,10660,10658,10656,10654,10652,10650,10648,10646,10644,10642,10640,10638,0,10636,10634,10632,10630,10628,10626,10622,10623,11466,11467,12342,12343,13250,13251,14190,0,14191,15162,15163,16166,16167,17202,17203,18270,18271,19370,19371, - 19723,19722,18607,18606,17523,17522,16471,16470,15451,15450,14463,1,14462,13507,13506,12583,12582,11691,11690,10833,10831,10829,10827,10825,10823,10821,10819,1,10817,10815,10813,10811,10809,10807,10805,10803,10801,10799,10797,10795,10793,10791,10789,1,10787,10785,10783,10781,10779,10777,10775,10773,10771,10769,10767,10765,10763,10761,10759,1,10757,10755,10753,10751,10749,10747,10745,10743,10741,10739,10737,10735,10733,10731,10729,1,10727,10725,10723,10721,10719,10717,10715,10713,10711,10709,10707,10705,10703,10701,10699,1,10697,10695,10693,10691,10689,10687,10685,10683,10681,10679,10677,10675,10673,10671,10669,1,10667,10665,10663,10661,10659,10657,10655,10653,10651,10649,10647,10645,10643,10641,10639,1,10637,10635,10633,10631,10629,10627,10624,10625,11468,11469,12344,12345,13252,13253,14192,1,14193,15164,15165,16168,16169,17204,17205,18272,18273,19372,19373, - 19721,19720,18605,18604,17521,17520,16469,16468,15449,15448,14461,0,14460,13505,13504,12581,12580,11688,11686,11684,11682,11680,11678,11676,11674,11672,11670,0,11668,11666,11664,11662,11660,11658,11656,11654,11652,11650,11648,11646,11644,11642,11640,0,11638,11636,11634,11632,11630,11628,11626,11624,11622,11620,11618,11616,11614,11612,11610,0,11608,11606,11604,11602,11600,11598,11596,11594,11592,11590,11588,11586,11584,11582,11580,0,11578,11576,11574,11572,11570,11568,11566,11564,11562,11560,11558,11556,11554,11552,11550,0,11548,11546,11544,11542,11540,11538,11536,11534,11532,11530,11528,11526,11524,11522,11520,0,11518,11516,11514,11512,11510,11508,11506,11504,11502,11500,11498,11496,11494,11492,11490,0,11488,11486,11484,11482,11480,11478,11476,11474,11470,11471,12346,12347,13254,13255,14194,0,14195,15166,15167,16170,16171,17206,17207,18274,18275,19374,19375, - 19719,19718,18603,18602,17519,17518,16467,16466,15447,15446,14459,1,14458,13503,13502,12579,12578,11689,11687,11685,11683,11681,11679,11677,11675,11673,11671,1,11669,11667,11665,11663,11661,11659,11657,11655,11653,11651,11649,11647,11645,11643,11641,1,11639,11637,11635,11633,11631,11629,11627,11625,11623,11621,11619,11617,11615,11613,11611,1,11609,11607,11605,11603,11601,11599,11597,11595,11593,11591,11589,11587,11585,11583,11581,1,11579,11577,11575,11573,11571,11569,11567,11565,11563,11561,11559,11557,11555,11553,11551,1,11549,11547,11545,11543,11541,11539,11537,11535,11533,11531,11529,11527,11525,11523,11521,1,11519,11517,11515,11513,11511,11509,11507,11505,11503,11501,11499,11497,11495,11493,11491,1,11489,11487,11485,11483,11481,11479,11477,11475,11472,11473,12348,12349,13256,13257,14196,1,14197,15168,15169,16172,16173,17208,17209,18276,18277,19376,19377, - 19717,19716,18601,18600,17517,17516,16465,16464,15445,15444,14457,0,14456,13501,13500,12576,12574,12572,12570,12568,12566,12564,12562,12560,12558,12556,12554,0,12552,12550,12548,12546,12544,12542,12540,12538,12536,12534,12532,12530,12528,12526,12524,0,12522,12520,12518,12516,12514,12512,12510,12508,12506,12504,12502,12500,12498,12496,12494,0,12492,12490,12488,12486,12484,12482,12480,12478,12476,12474,12472,12470,12468,12466,12464,0,12462,12460,12458,12456,12454,12452,12450,12448,12446,12444,12442,12440,12438,12436,12434,0,12432,12430,12428,12426,12424,12422,12420,12418,12416,12414,12412,12410,12408,12406,12404,0,12402,12400,12398,12396,12394,12392,12390,12388,12386,12384,12382,12380,12378,12376,12374,0,12372,12370,12368,12366,12364,12362,12360,12358,12356,12354,12350,12351,13258,13259,14198,0,14199,15170,15171,16174,16175,17210,17211,18278,18279,19378,19379, - 19715,19714,18599,18598,17515,17514,16463,16462,15443,15442,14455,1,14454,13499,13498,12577,12575,12573,12571,12569,12567,12565,12563,12561,12559,12557,12555,1,12553,12551,12549,12547,12545,12543,12541,12539,12537,12535,12533,12531,12529,12527,12525,1,12523,12521,12519,12517,12515,12513,12511,12509,12507,12505,12503,12501,12499,12497,12495,1,12493,12491,12489,12487,12485,12483,12481,12479,12477,12475,12473,12471,12469,12467,12465,1,12463,12461,12459,12457,12455,12453,12451,12449,12447,12445,12443,12441,12439,12437,12435,1,12433,12431,12429,12427,12425,12423,12421,12419,12417,12415,12413,12411,12409,12407,12405,1,12403,12401,12399,12397,12395,12393,12391,12389,12387,12385,12383,12381,12379,12377,12375,1,12373,12371,12369,12367,12365,12363,12361,12359,12357,12355,12352,12353,13260,13261,14200,1,14201,15172,15173,16176,16177,17212,17213,18280,18281,19380,19381, - 19713,19712,18597,18596,17513,17512,16461,16460,15441,15440,14453,0,14452,13496,13494,13492,13490,13488,13486,13484,13482,13480,13478,13476,13474,13472,13470,0,13468,13466,13464,13462,13460,13458,13456,13454,13452,13450,13448,13446,13444,13442,13440,0,13438,13436,13434,13432,13430,13428,13426,13424,13422,13420,13418,13416,13414,13412,13410,0,13408,13406,13404,13402,13400,13398,13396,13394,13392,13390,13388,13386,13384,13382,13380,0,13378,13376,13374,13372,13370,13368,13366,13364,13362,13360,13358,13356,13354,13352,13350,0,13348,13346,13344,13342,13340,13338,13336,13334,13332,13330,13328,13326,13324,13322,13320,0,13318,13316,13314,13312,13310,13308,13306,13304,13302,13300,13298,13296,13294,13292,13290,0,13288,13286,13284,13282,13280,13278,13276,13274,13272,13270,13268,13266,13262,13263,14202,0,14203,15174,15175,16178,16179,17214,17215,18282,18283,19382,19383, - 19711,19710,18595,18594,17511,17510,16459,16458,15439,15438,14451,1,14450,13497,13495,13493,13491,13489,13487,13485,13483,13481,13479,13477,13475,13473,13471,1,13469,13467,13465,13463,13461,13459,13457,13455,13453,13451,13449,13447,13445,13443,13441,1,13439,13437,13435,13433,13431,13429,13427,13425,13423,13421,13419,13417,13415,13413,13411,1,13409,13407,13405,13403,13401,13399,13397,13395,13393,13391,13389,13387,13385,13383,13381,1,13379,13377,13375,13373,13371,13369,13367,13365,13363,13361,13359,13357,13355,13353,13351,1,13349,13347,13345,13343,13341,13339,13337,13335,13333,13331,13329,13327,13325,13323,13321,1,13319,13317,13315,13313,13311,13309,13307,13305,13303,13301,13299,13297,13295,13293,13291,1,13289,13287,13285,13283,13281,13279,13277,13275,13273,13271,13269,13267,13264,13265,14204,1,14205,15176,15177,16180,16181,17216,17217,18284,18285,19384,19385, - 19709,19708,18593,18592,17509,17508,16457,16456,15437,15436,14448,0,14446,14444,14442,14440,14438,14436,14434,14432,14430,14428,14426,14424,14422,14420,14418,0,14416,14414,14412,14410,14408,14406,14404,14402,14400,14398,14396,14394,14392,14390,14388,0,14386,14384,14382,14380,14378,14376,14374,14372,14370,14368,14366,14364,14362,14360,14358,0,14356,14354,14352,14350,14348,14346,14344,14342,14340,14338,14336,14334,14332,14330,14328,0,14326,14324,14322,14320,14318,14316,14314,14312,14310,14308,14306,14304,14302,14300,14298,0,14296,14294,14292,14290,14288,14286,14284,14282,14280,14278,14276,14274,14272,14270,14268,0,14266,14264,14262,14260,14258,14256,14254,14252,14250,14248,14246,14244,14242,14240,14238,0,14236,14234,14232,14230,14228,14226,14224,14222,14220,14218,14216,14214,14212,14210,14206,0,14207,15178,15179,16182,16183,17218,17219,18286,18287,19386,19387, - 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, - 19707,19706,18591,18590,17507,17506,16455,16454,15435,15434,14449,0,14447,14445,14443,14441,14439,14437,14435,14433,14431,14429,14427,14425,14423,14421,14419,0,14417,14415,14413,14411,14409,14407,14405,14403,14401,14399,14397,14395,14393,14391,14389,0,14387,14385,14383,14381,14379,14377,14375,14373,14371,14369,14367,14365,14363,14361,14359,0,14357,14355,14353,14351,14349,14347,14345,14343,14341,14339,14337,14335,14333,14331,14329,0,14327,14325,14323,14321,14319,14317,14315,14313,14311,14309,14307,14305,14303,14301,14299,0,14297,14295,14293,14291,14289,14287,14285,14283,14281,14279,14277,14275,14273,14271,14269,0,14267,14265,14263,14261,14259,14257,14255,14253,14251,14249,14247,14245,14243,14241,14239,0,14237,14235,14233,14231,14229,14227,14225,14223,14221,14219,14217,14215,14213,14211,14208,0,14209,15180,15181,16184,16185,17220,17221,18288,18289,19388,19389, - 19705,19704,18589,18588,17505,17504,16453,16452,15432,15430,15428,1,15426,15424,15422,15420,15418,15416,15414,15412,15410,15408,15406,15404,15402,15400,15398,1,15396,15394,15392,15390,15388,15386,15384,15382,15380,15378,15376,15374,15372,15370,15368,1,15366,15364,15362,15360,15358,15356,15354,15352,15350,15348,15346,15344,15342,15340,15338,1,15336,15334,15332,15330,15328,15326,15324,15322,15320,15318,15316,15314,15312,15310,15308,1,15306,15304,15302,15300,15298,15296,15294,15292,15290,15288,15286,15284,15282,15280,15278,1,15276,15274,15272,15270,15268,15266,15264,15262,15260,15258,15256,15254,15252,15250,15248,1,15246,15244,15242,15240,15238,15236,15234,15232,15230,15228,15226,15224,15222,15220,15218,1,15216,15214,15212,15210,15208,15206,15204,15202,15200,15198,15196,15194,15192,15190,15188,1,15186,15182,15183,16186,16187,17222,17223,18290,18291,19390,19391, - 19703,19702,18587,18586,17503,17502,16451,16450,15433,15431,15429,0,15427,15425,15423,15421,15419,15417,15415,15413,15411,15409,15407,15405,15403,15401,15399,0,15397,15395,15393,15391,15389,15387,15385,15383,15381,15379,15377,15375,15373,15371,15369,0,15367,15365,15363,15361,15359,15357,15355,15353,15351,15349,15347,15345,15343,15341,15339,0,15337,15335,15333,15331,15329,15327,15325,15323,15321,15319,15317,15315,15313,15311,15309,0,15307,15305,15303,15301,15299,15297,15295,15293,15291,15289,15287,15285,15283,15281,15279,0,15277,15275,15273,15271,15269,15267,15265,15263,15261,15259,15257,15255,15253,15251,15249,0,15247,15245,15243,15241,15239,15237,15235,15233,15231,15229,15227,15225,15223,15221,15219,0,15217,15215,15213,15211,15209,15207,15205,15203,15201,15199,15197,15195,15193,15191,15189,0,15187,15184,15185,16188,16189,17224,17225,18292,18293,19392,19393, - 19701,19700,18585,18584,17501,17500,16448,16446,16444,16442,16440,1,16438,16436,16434,16432,16430,16428,16426,16424,16422,16420,16418,16416,16414,16412,16410,1,16408,16406,16404,16402,16400,16398,16396,16394,16392,16390,16388,16386,16384,16382,16380,1,16378,16376,16374,16372,16370,16368,16366,16364,16362,16360,16358,16356,16354,16352,16350,1,16348,16346,16344,16342,16340,16338,16336,16334,16332,16330,16328,16326,16324,16322,16320,1,16318,16316,16314,16312,16310,16308,16306,16304,16302,16300,16298,16296,16294,16292,16290,1,16288,16286,16284,16282,16280,16278,16276,16274,16272,16270,16268,16266,16264,16262,16260,1,16258,16256,16254,16252,16250,16248,16246,16244,16242,16240,16238,16236,16234,16232,16230,1,16228,16226,16224,16222,16220,16218,16216,16214,16212,16210,16208,16206,16204,16202,16200,1,16198,16196,16194,16190,16191,17226,17227,18294,18295,19394,19395, - 19699,19698,18583,18582,17499,17498,16449,16447,16445,16443,16441,0,16439,16437,16435,16433,16431,16429,16427,16425,16423,16421,16419,16417,16415,16413,16411,0,16409,16407,16405,16403,16401,16399,16397,16395,16393,16391,16389,16387,16385,16383,16381,0,16379,16377,16375,16373,16371,16369,16367,16365,16363,16361,16359,16357,16355,16353,16351,0,16349,16347,16345,16343,16341,16339,16337,16335,16333,16331,16329,16327,16325,16323,16321,0,16319,16317,16315,16313,16311,16309,16307,16305,16303,16301,16299,16297,16295,16293,16291,0,16289,16287,16285,16283,16281,16279,16277,16275,16273,16271,16269,16267,16265,16263,16261,0,16259,16257,16255,16253,16251,16249,16247,16245,16243,16241,16239,16237,16235,16233,16231,0,16229,16227,16225,16223,16221,16219,16217,16215,16213,16211,16209,16207,16205,16203,16201,0,16199,16197,16195,16192,16193,17228,17229,18296,18297,19396,19397, - 19697,19696,18581,18580,17496,17494,17492,17490,17488,17486,17484,1,17482,17480,17478,17476,17474,17472,17470,17468,17466,17464,17462,17460,17458,17456,17454,1,17452,17450,17448,17446,17444,17442,17440,17438,17436,17434,17432,17430,17428,17426,17424,1,17422,17420,17418,17416,17414,17412,17410,17408,17406,17404,17402,17400,17398,17396,17394,1,17392,17390,17388,17386,17384,17382,17380,17378,17376,17374,17372,17370,17368,17366,17364,1,17362,17360,17358,17356,17354,17352,17350,17348,17346,17344,17342,17340,17338,17336,17334,1,17332,17330,17328,17326,17324,17322,17320,17318,17316,17314,17312,17310,17308,17306,17304,1,17302,17300,17298,17296,17294,17292,17290,17288,17286,17284,17282,17280,17278,17276,17274,1,17272,17270,17268,17266,17264,17262,17260,17258,17256,17254,17252,17250,17248,17246,17244,1,17242,17240,17238,17236,17234,17230,17231,18298,18299,19398,19399, - 19695,19694,18579,18578,17497,17495,17493,17491,17489,17487,17485,0,17483,17481,17479,17477,17475,17473,17471,17469,17467,17465,17463,17461,17459,17457,17455,0,17453,17451,17449,17447,17445,17443,17441,17439,17437,17435,17433,17431,17429,17427,17425,0,17423,17421,17419,17417,17415,17413,17411,17409,17407,17405,17403,17401,17399,17397,17395,0,17393,17391,17389,17387,17385,17383,17381,17379,17377,17375,17373,17371,17369,17367,17365,0,17363,17361,17359,17357,17355,17353,17351,17349,17347,17345,17343,17341,17339,17337,17335,0,17333,17331,17329,17327,17325,17323,17321,17319,17317,17315,17313,17311,17309,17307,17305,0,17303,17301,17299,17297,17295,17293,17291,17289,17287,17285,17283,17281,17279,17277,17275,0,17273,17271,17269,17267,17265,17263,17261,17259,17257,17255,17253,17251,17249,17247,17245,0,17243,17241,17239,17237,17235,17232,17233,18300,18301,19400,19401, - 19693,19692,18576,18574,18572,18570,18568,18566,18564,18562,18560,1,18558,18556,18554,18552,18550,18548,18546,18544,18542,18540,18538,18536,18534,18532,18530,1,18528,18526,18524,18522,18520,18518,18516,18514,18512,18510,18508,18506,18504,18502,18500,1,18498,18496,18494,18492,18490,18488,18486,18484,18482,18480,18478,18476,18474,18472,18470,1,18468,18466,18464,18462,18460,18458,18456,18454,18452,18450,18448,18446,18444,18442,18440,1,18438,18436,18434,18432,18430,18428,18426,18424,18422,18420,18418,18416,18414,18412,18410,1,18408,18406,18404,18402,18400,18398,18396,18394,18392,18390,18388,18386,18384,18382,18380,1,18378,18376,18374,18372,18370,18368,18366,18364,18362,18360,18358,18356,18354,18352,18350,1,18348,18346,18344,18342,18340,18338,18336,18334,18332,18330,18328,18326,18324,18322,18320,1,18318,18316,18314,18312,18310,18308,18306,18302,18303,19402,19403, - 19691,19690,18577,18575,18573,18571,18569,18567,18565,18563,18561,0,18559,18557,18555,18553,18551,18549,18547,18545,18543,18541,18539,18537,18535,18533,18531,0,18529,18527,18525,18523,18521,18519,18517,18515,18513,18511,18509,18507,18505,18503,18501,0,18499,18497,18495,18493,18491,18489,18487,18485,18483,18481,18479,18477,18475,18473,18471,0,18469,18467,18465,18463,18461,18459,18457,18455,18453,18451,18449,18447,18445,18443,18441,0,18439,18437,18435,18433,18431,18429,18427,18425,18423,18421,18419,18417,18415,18413,18411,0,18409,18407,18405,18403,18401,18399,18397,18395,18393,18391,18389,18387,18385,18383,18381,0,18379,18377,18375,18373,18371,18369,18367,18365,18363,18361,18359,18357,18355,18353,18351,0,18349,18347,18345,18343,18341,18339,18337,18335,18333,18331,18329,18327,18325,18323,18321,0,18319,18317,18315,18313,18311,18309,18307,18304,18305,19404,19405, - 19688,19686,19684,19682,19680,19678,19676,19674,19672,19670,19668,1,19666,19664,19662,19660,19658,19656,19654,19652,19650,19648,19646,19644,19642,19640,19638,1,19636,19634,19632,19630,19628,19626,19624,19622,19620,19618,19616,19614,19612,19610,19608,1,19606,19604,19602,19600,19598,19596,19594,19592,19590,19588,19586,19584,19582,19580,19578,1,19576,19574,19572,19570,19568,19566,19564,19562,19560,19558,19556,19554,19552,19550,19548,1,19546,19544,19542,19540,19538,19536,19534,19532,19530,19528,19526,19524,19522,19520,19518,1,19516,19514,19512,19510,19508,19506,19504,19502,19500,19498,19496,19494,19492,19490,19488,1,19486,19484,19482,19480,19478,19476,19474,19472,19470,19468,19466,19464,19462,19460,19458,1,19456,19454,19452,19450,19448,19446,19444,19442,19440,19438,19436,19434,19432,19430,19428,1,19426,19424,19422,19420,19418,19416,19414,19412,19410,19406,19407, - 19689,19687,19685,19683,19681,19679,19677,19675,19673,19671,19669,0,19667,19665,19663,19661,19659,19657,19655,19653,19651,19649,19647,19645,19643,19641,19639,0,19637,19635,19633,19631,19629,19627,19625,19623,19621,19619,19617,19615,19613,19611,19609,0,19607,19605,19603,19601,19599,19597,19595,19593,19591,19589,19587,19585,19583,19581,19579,0,19577,19575,19573,19571,19569,19567,19565,19563,19561,19559,19557,19555,19553,19551,19549,0,19547,19545,19543,19541,19539,19537,19535,19533,19531,19529,19527,19525,19523,19521,19519,0,19517,19515,19513,19511,19509,19507,19505,19503,19501,19499,19497,19495,19493,19491,19489,0,19487,19485,19483,19481,19479,19477,19475,19473,19471,19469,19467,19465,19463,19461,19459,0,19457,19455,19453,19451,19449,19447,19445,19443,19441,19439,19437,19435,19433,19431,19429,0,19427,19425,19423,19421,19419,19417,19415,19413,19411,19408,19409 -}; - -static int CompactAztecMap[] = { /* 27 x 27 data grid */ - 609,608,411,413,415,417,419,421,423,425,427,429,431,433,435,437,439,441,443,445,447,449,451,453,455,457,459, - 607,606,410,412,414,416,418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,454,456,458, - 605,604,409,408,243,245,247,249,251,253,255,257,259,261,263,265,267,269,271,273,275,277,279,281,283,460,461, - 603,602,407,406,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,462,463, - 601,600,405,404,241,240,107,109,111,113,115,117,119,121,123,125,127,129,131,133,135,137,139,284,285,464,465, - 599,598,403,402,239,238,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,286,287,466,467, - 597,596,401,400,237,236,105,104,3,5,7,9,11,13,15,17,19,21,23,25,27,140,141,288,289,468,469, - 595,594,399,398,235,234,103,102,2,4,6,8,10,12,14,16,18,20,22,24,26,142,143,290,291,470,471, - 593,592,397,396,233,232,101,100,1,1,2000,2001,2002,2003,2004,2005,2006,0,1,28,29,144,145,292,293,472,473, - 591,590,395,394,231,230,99,98,1,1,1,1,1,1,1,1,1,1,1,30,31,146,147,294,295,474,475, - 589,588,393,392,229,228,97,96,2027,1,0,0,0,0,0,0,0,1,2007,32,33,148,149,296,297,476,477, - 587,586,391,390,227,226,95,94,2026,1,0,1,1,1,1,1,0,1,2008,34,35,150,151,298,299,478,479, - 585,584,389,388,225,224,93,92,2025,1,0,1,0,0,0,1,0,1,2009,36,37,152,153,300,301,480,481, - 583,582,387,386,223,222,91,90,2024,1,0,1,0,1,0,1,0,1,2010,38,39,154,155,302,303,482,483, - 581,580,385,384,221,220,89,88,2023,1,0,1,0,0,0,1,0,1,2011,40,41,156,157,304,305,484,485, - 579,578,383,382,219,218,87,86,2022,1,0,1,1,1,1,1,0,1,2012,42,43,158,159,306,307,486,487, - 577,576,381,380,217,216,85,84,2021,1,0,0,0,0,0,0,0,1,2013,44,45,160,161,308,309,488,489, - 575,574,379,378,215,214,83,82,0,1,1,1,1,1,1,1,1,1,1,46,47,162,163,310,311,490,491, - 573,572,377,376,213,212,81,80,0,0,2020,2019,2018,2017,2016,2015,2014,0,0,48,49,164,165,312,313,492,493, - 571,570,375,374,211,210,78,76,74,72,70,68,66,64,62,60,58,56,54,50,51,166,167,314,315,494,495, - 569,568,373,372,209,208,79,77,75,73,71,69,67,65,63,61,59,57,55,52,53,168,169,316,317,496,497, - 567,566,371,370,206,204,202,200,198,196,194,192,190,188,186,184,182,180,178,176,174,170,171,318,319,498,499, - 565,564,369,368,207,205,203,201,199,197,195,193,191,189,187,185,183,181,179,177,175,172,173,320,321,500,501, - 563,562,366,364,362,360,358,356,354,352,350,348,346,344,342,340,338,336,334,332,330,328,326,322,323,502,503, - 561,560,367,365,363,361,359,357,355,353,351,349,347,345,343,341,339,337,335,333,331,329,327,324,325,504,505, - 558,556,554,552,550,548,546,544,542,540,538,536,534,532,530,528,526,524,522,520,518,516,514,512,510,506,507, - 559,557,555,553,551,549,547,545,543,541,539,537,535,533,531,529,527,525,523,521,519,517,515,513,511,508,509 -}; - -int AztecCodeSet[128] = { /* From Table 2 */ - 32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 12, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 4, 4, 4, 4, 4, 23, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 24, 8, 24, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, - 8, 8, 8, 8, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 4, 8, 4, 4, 4, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 8, 4, 8, 4, 4 -}; - -int AztecSymbolChar[128] = { /* From Table 2 */ - 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 300, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 1, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 301, 18, 302, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 22, - 23, 24, 25, 26, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 21, 28, 22, 23, 24, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 29, 25, 30, 26, 27 -}; - -/* Problem characters are: - 300: Carriage Return (ASCII 13) - 301: Comma (ASCII 44) - 302: Full Stop (ASCII 46) -*/ - -static char *hexbit[32] = {"00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", - "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", - "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111" -}; - -static char *pentbit[16] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", - "1010", "1011", "1100", "1101", "1110", "1111" -}; - -static char *tribit[8] = {"000", "001", "010", "011", "100", "101", "110", "111"}; - -static int AztecSizes[32] = { /* Codewords per symbol */ - 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, - 864, 940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664 -}; - -static int AztecCompactSizes[4] = { 17, 40, 51, 76 }; - -static int Aztec10DataSizes[32] = { /* Data bits per symbol maximum with 10% error correction */ - 96, 246, 408, 616, 840, 1104, 1392, 1704, 2040, 2420, 2820, 3250, 3720, 4200, 4730, - 5270, 5840, 6450, 7080, 7750, 8430, 9150, 9900, 10680, 11484, 12324, 13188, 14076, - 15000, 15948, 16920, 17940 -}; - -static int Aztec23DataSizes[32] = { /* Data bits per symbol maximum with 23% error correction */ - 84, 204, 352, 520, 720, 944, 1184, 1456, 1750, 2070, 2410, 2780, 3180, 3590, 4040, - 4500, 5000, 5520, 6060, 6630, 7210, 7830, 8472, 9132, 9816, 10536, 11280, 12036, - 12828, 13644, 14472, 15348 -}; - -static int Aztec36DataSizes[32] = { /* Data bits per symbol maximum with 36% error correction */ - 66, 168, 288, 432, 592, 776, 984, 1208, 1450, 1720, 2000, 2300, 2640, 2980, 3350, - 3740, 4150, 4580, 5030, 5500, 5990, 6500, 7032, 7584, 8160, 8760, 9372, 9996, 10656, - 11340, 12024, 12744 -}; - -static int Aztec50DataSizes[32] = { /* Data bits per symbol maximum with 50% error correction */ - 48, 126, 216, 328, 456, 600, 760, 936, 1120, 1330, 1550, 1790, 2050, 2320, 2610, - 2910, 3230, 3570, 3920, 4290, 4670, 5070, 5484, 5916, 6360, 6828, 7308, 7800, 8316, - 8844, 9384, 9948 -}; - -static int AztecCompact10DataSizes [4] = { 78, 198, 336, 520 }; -static int AztecCompact23DataSizes [4] = { 66, 168, 288, 440 }; -static int AztecCompact36DataSizes [4] = { 48, 138, 232, 360 }; -static int AztecCompact50DataSizes [4] = { 36, 102, 176, 280 }; - -static int AztecOffset[32] = { - 66, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, 42, 40, 38, 36, 34, 32, 30, 28, 25, 23, 21, - 19, 17, 15, 13, 10, 8, 6, 4, 2, 0 -}; - -static int AztecCompactOffset[4] = { 6, 4, 2, 0 }; diff --git a/3rdparty/zint-2.4.4/backend/code.c b/3rdparty/zint-2.4.4/backend/code.c deleted file mode 100644 index 553b972..0000000 --- a/3rdparty/zint-2.4.4/backend/code.c +++ /dev/null @@ -1,537 +0,0 @@ -/* code.c - Handles Code 11, 39, 39+ and 93 */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* In version 0.5 this file was 1,553 lines long! */ - -#include -#include -#include -#include "common.h" - -#define SODIUM "0123456789-" -#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd" - -static char *C11Table[11] = {"111121", "211121", "121121", "221111", "112121", "212111", "122111", - "111221", "211211", "211111", "112111"}; - - -/* Code 39 tables checked against ISO/IEC 16388:2007 */ - -/* Incorporates Table A1 */ - -static char *C39Table[43] = { "1112212111", "2112111121", "1122111121", "2122111111", "1112211121", - "2112211111", "1122211111", "1112112121", "2112112111", "1122112111", "2111121121", - "1121121121", "2121121111", "1111221121", "2111221111", "1121221111", "1111122121", - "2111122111", "1121122111", "1111222111", "2111111221", "1121111221", "2121111211", - "1111211221", "2111211211", "1121211211", "1111112221", "2111112211", "1121112211", - "1111212211", "2211111121", "1221111121", "2221111111", "1211211121", "2211211111", - "1221211111", "1211112121", "2211112111", "1221112111", "1212121111", "1212111211", - "1211121211", "1112121211"}; -/* Code 39 character assignments (Table 1) */ - -static char *EC39Ctrl[128] = {"%U", "$A", "$B", "$C", "$D", "$E", "$F", "$G", "$H", "$I", "$J", "$K", - "$L", "$M", "$N", "$O", "$P", "$Q", "$R", "$S", "$T", "$U", "$V", "$W", "$X", "$Y", "$Z", - "%A", "%B", "%C", "%D", "%E", " ", "/A", "/B", "/C", "/D", "/E", "/F", "/G", "/H", "/I", "/J", - "/K", "/L", "-", ".", "/O", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/Z", "%F", - "%G", "%H", "%I", "%J", "%V", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", - "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "%K", "%L", "%M", "%N", "%O", - "%W", "+A", "+B", "+C", "+D", "+E", "+F", "+G", "+H", "+I", "+J", "+K", "+L", "+M", "+N", "+O", - "+P", "+Q", "+R", "+S", "+T", "+U", "+V", "+W", "+X", "+Y", "+Z", "%P", "%Q", "%R", "%S", "%T"}; -/* Encoding the full ASCII character set in Code 39 (Table A2) */ - -static char *C93Ctrl[128] = {"bU", "aA", "aB", "aC", "aD", "aE", "aF", "aG", "aH", "aI", "aJ", "aK", - "aL", "aM", "aN", "aO", "aP", "aQ", "aR", "aS", "aT", "aU", "aV", "aW", "aX", "aY", "aZ", - "bA", "bB", "bC", "bD", "bE", " ", "cA", "cB", "cC", "cD", "cE", "cF", "cG", "cH", "cI", "cJ", - "cK", "cL", "cM", "cN", "cO", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "cZ", "bF", - "bG", "bH", "bI", "bJ", "bV", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", - "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bK", "bL", "bM", "bN", "bO", - "bW", "dA", "dB", "dC", "dD", "dE", "dF", "dG", "dH", "dI", "dJ", "dK", "dL", "dM", "dN", "dO", - "dP", "dQ", "dR", "dS", "dT", "dU", "dV", "dW", "dX", "dY", "dZ", "bP", "bQ", "bR", "bS", "bT"}; - -static char *C93Table[47] = {"131112", "111213", "111312", "111411", "121113", "121212", "121311", - "111114", "131211", "141111", "211113", "211212", "211311", "221112", "221211", "231111", - "112113", "112212", "112311", "122112", "132111", "111123", "111222", "111321", "121122", - "131121", "212112", "212211", "211122", "211221", "221121", "222111", "112122", "112221", - "122121", "123111", "121131", "311112", "311211", "321111", "112131", "113121", "211131", - "121221", "312111", "311121", "122211"}; - -/* Global Variables for Channel Code */ -int S[11], B[11]; -long value; -long target_value; -char pattern[30]; - -/* Function Prototypes */ -void NextS(int Chan, int i, int MaxS, int MaxB); -void NextB(int Chan, int i, int MaxB, int MaxS); - -/* *********************** CODE 11 ******************** */ - -int code_11(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 11 */ - - int i; - int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count; - int weight[128], error_number; - char dest[1024]; /* 6 + 121 * 6 + 2 * 6 + 5 + 1 ~ 1024*/ - char checkstr[3]; - - error_number = 0; - - if(length > 121) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(SODIUM, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - c_weight = 1; - c_count = 0; - k_weight = 1; - k_count = 0; - - /* start character */ - strcpy(dest, "112211"); - - /* Draw main body of barcode */ - for(i = 0; i < length; i++) { - lookup(SODIUM, C11Table, source[i], dest); - if(source[i] == '-') - weight[i] = 10; - else - weight[i] = ctoi(source[i]); - } - - /* Calculate C checksum */ - for(h = length - 1; h >= 0; h--) { - c_count += (c_weight * weight[h]); - c_weight++; - - if(c_weight > 10) { - c_weight = 1; - } - } - c_digit = c_count % 11; - - weight[length] = c_digit; - - /* Calculate K checksum */ - for(h = length; h >= 0; h--) { - k_count += (k_weight * weight[h]); - k_weight++; - - if(k_weight > 9) { - k_weight = 1; - } - } - k_digit = k_count % 11; - - checkstr[0] = itoc(c_digit); - checkstr[1] = itoc(k_digit); - if(checkstr[0] == 'A') { checkstr[0] = '-'; } - if(checkstr[1] == 'A') { checkstr[1] = '-'; } - checkstr[2] = '\0'; - lookup(SODIUM, C11Table, checkstr[0], dest); - lookup(SODIUM, C11Table, checkstr[1], dest); - - /* Stop character */ - concat (dest, "11221"); - - expand(symbol, dest); - - ustrcpy(symbol->text, source); - uconcat(symbol->text, (unsigned char*)checkstr); - return error_number; -} - -int c39(struct zint_symbol *symbol, unsigned char source[], unsigned int length) -{ /* Code 39 */ - unsigned int i; - unsigned int counter = 0; - char check_digit; - int error_number = 0; - char dest[775]; - char localstr[2] = { 0 }; - - if((symbol->option_2 < 0) || (symbol->option_2 > 1)) { - symbol->option_2 = 0; - } - - if((symbol->symbology == BARCODE_LOGMARS) && (length > 59)) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } else if(length > 74) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - to_upper(source); - error_number = is_sane(SILVER , source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* Start character */ - strcpy(dest, "1211212111"); - - for(i = 0; i < length; i++) { - lookup(SILVER, C39Table, source[i], dest); - counter += posn(SILVER, source[i]); - } - - if((symbol->symbology == BARCODE_LOGMARS) || (symbol->option_2 == 1)) { - - counter = counter % 43; - if(counter < 10) { - check_digit = itoc(counter); - } else { - if(counter < 36) { - check_digit = (counter - 10) + 'A'; - } else { - switch(counter) { - case 36: check_digit = '-'; break; - case 37: check_digit = '.'; break; - case 38: check_digit = ' '; break; - case 39: check_digit = '$'; break; - case 40: check_digit = '/'; break; - case 41: check_digit = '+'; break; - case 42: check_digit = 37; break; - default: check_digit = ' '; break; /* Keep compiler happy */ - } - } - } - lookup(SILVER, C39Table, check_digit, dest); - - /* Display a space check digit as _, otherwise it looks like an error */ - if(check_digit == ' ') { - check_digit = '_'; - } - - localstr[0] = check_digit; - localstr[1] = '\0'; - } - - /* Stop character */ - concat (dest, "121121211"); - - if((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) { - /* LOGMARS uses wider 'wide' bars than normal Code 39 */ - counter = strlen(dest); - for(i = 0; i < counter; i++) { - if(dest[i] == '2') { - dest[i] = '3'; - } - } - } - - expand(symbol, dest); - - if(symbol->symbology == BARCODE_CODE39) { - ustrcpy(symbol->text, (unsigned char*)"*"); - uconcat(symbol->text, source); - uconcat(symbol->text, (unsigned char*)localstr); - uconcat(symbol->text, (unsigned char*)"*"); - } else { - ustrcpy(symbol->text, source); - uconcat(symbol->text, (unsigned char*)localstr); - } - return error_number; -} - -int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Pharmazentral Nummer (PZN) */ - - int i, error_number, zeroes; - unsigned int count, check_digit; - char localstr[10]; - - error_number = 0; - - count = 0; - if(length > 6) { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - localstr[0] = '-'; - zeroes = 6 - length + 1; - for(i = 1; i < zeroes; i++) - localstr[i] = '0'; - strcpy(localstr + zeroes, (char *)source); - - for (i = 1; i < 7; i++) { - count += (i + 1) * ctoi(localstr[i]); - } - - check_digit = count%11; - if (check_digit == 11) { check_digit = 0; } - localstr[7] = itoc(check_digit); - localstr[8] = '\0'; - if(localstr[7] == 'A') { - strcpy(symbol->errtxt, "Invalid PZN Data"); - return ERROR_INVALID_DATA1; - } - error_number = c39(symbol, (unsigned char *)localstr, strlen(localstr)); - ustrcpy(symbol->text, (unsigned char *)"PZN"); - uconcat(symbol->text, (unsigned char *)localstr); - return error_number; -} - - -/* ************** EXTENDED CODE 39 *************** */ - -int ec39(struct zint_symbol *symbol, unsigned char source[], unsigned int length) -{ /* Extended Code 39 - ISO/IEC 16388:2007 Annex A */ - - unsigned char buffer[150] = { 0 }; - unsigned int i; - int error_number = 0; - - if(length > 74) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* Creates a buffer string and places control characters into it */ - for(i = 0; i < length; i++) { - if(source[i] > 127) { - /* Cannot encode extended ASCII */ - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - concat((char*)buffer, EC39Ctrl[source[i]]); - } - - /* Then sends the buffer to the C39 function */ - error_number = c39(symbol, buffer, ustrlen(buffer)); - - for(i = 0; i < length; i++) - symbol->text[i] = source[i] ? source[i] : ' '; - symbol->text[length] = '\0'; - - return error_number; -} - -/* ******************** CODE 93 ******************* */ - -int c93(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Code 93 is an advancement on Code 39 and the definition is a lot tighter */ - - /* SILVER includes the extra characters a, b, c and d to represent Code 93 specific - shift characters 1, 2, 3 and 4 respectively. These characters are never used by - c39() and ec39() */ - - int i; - int h, weight, c, k, values[128], error_number; - char buffer[220]; - char dest[670]; - char set_copy[] = SILVER; - - error_number = 0; - strcpy(buffer, ""); - - if(length > 107) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* Message Content */ - for (i = 0; i < length; i++) { - if (source[i] > 127) { - /* Cannot encode extended ASCII */ - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - concat(buffer, C93Ctrl[source[i]]); - symbol->text[i] = source[i] ? source[i] : ' '; - } - - /* Now we can check the true length of the barcode */ - h = strlen(buffer); - if (h > 107) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - for (i = 0; i < h; i++) { - values[i] = posn(SILVER, buffer[i]); - } - - /* Putting the data into dest[] is not done until after check digits are calculated */ - - /* Check digit C */ - c = 0; - weight = 1; - for (i = h - 1; i >= 0; i--) { - c += values[i] * weight; - weight++; - if (weight == 21) - weight = 1; - } - c = c % 47; - values[h] = c; - buffer[h] = set_copy[c]; - - /* Check digit K */ - k = 0; - weight = 1; - for (i = h; i >= 0; i--) { - k += values[i] * weight; - weight++; - if(weight == 16) - weight = 1; - } - k = k % 47; - buffer[++h] = set_copy[k]; - buffer[++h] = '\0'; - - /* Start character */ - strcpy(dest, "111141"); - - for(i = 0; i < h; i++) { - lookup(SILVER, C93Table, buffer[i], dest); - } - - /* Stop character */ - concat(dest, "1111411"); - expand(symbol, dest); - - symbol->text[length] = set_copy[c]; - symbol->text[length + 1] = set_copy[k]; - symbol->text[length + 2] = '\0'; - - return error_number; -} - -/* NextS() and NextB() are from ANSI/AIM BC12-1998 and are Copyright (c) AIM 1997 */ -/* Their are used here on the understanding that they form part of the specification - for Channel Code and therefore their use is permitted under the following terms - set out in that document: - - "It is the intent and understanding of AIM [t]hat the symbology presented in this - specification is entirely in the public domain and free of all use restrictions, - licenses and fees. AIM USA, its memer companies, or individual officers - assume no liability for the use of this document." */ - -void CheckCharacter() { - int i; - char part[3]; - - if(value == target_value) { - /* Target reached - save the generated pattern */ - strcpy(pattern, "11110"); - for(i = 0; i < 11; i++) { - part[0] = itoc(S[i]); - part[1] = itoc(B[i]); - part[2] = '\0'; - concat(pattern, part); - } - } -} - -void NextB(int Chan, int i, int MaxB, int MaxS) { - int b; - - b = (S[i]+B[i-1]+S[i-1]+B[i-2] > 4)? 1:2; - if (i < Chan+2) { - for (; b <= MaxB; b++) { - B[i] = b; - NextS(Chan,i+1,MaxS,MaxB+1-b); - } - } else if (b <= MaxB) { - B[i] = MaxB; - CheckCharacter(); - value++; - } -} - -void NextS(int Chan, int i, int MaxS, int MaxB) { - int s; - - for (s = (i 7) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - if((symbol->option_2 < 3) || (symbol->option_2 > 8)) { channels = 0; } else { channels = symbol->option_2; } - if(channels == 0) { channels = length + 1; } - if(channels == 2) { channels = 3; } - - for(i = 0; i < length; i++) { - target_value *= 10; - target_value += ctoi((char) source[i]); - } - - switch(channels) { - case 3: if(target_value > 26) { range = 1; } break; - case 4: if(target_value > 292) { range = 1; } break; - case 5: if(target_value > 3493) { range = 1; } break; - case 6: if(target_value > 44072) { range = 1; } break; - case 7: if(target_value > 576688) { range = 1; } break; - case 8: if(target_value > 7742862) { range = 1; } break; - } - if(range) { - strcpy(symbol->errtxt, "Value out of range"); - return ERROR_INVALID_DATA1; - } - - for(i = 0; i < 11; i++) { B[i] = 0; S[i] = 0; } - - B[0] = S[1] = B[1] = S[2] = B[2] = 1; - value = 0; - NextS(channels,3,channels,channels); - - zeroes = channels - 1 - length; - memset(hrt, '0', zeroes); - strcpy(hrt + zeroes, (char *)source); - ustrcpy(symbol->text, (unsigned char *)hrt); - - expand(symbol, pattern); - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/code1.c b/3rdparty/zint-2.4.4/backend/code1.c deleted file mode 100644 index 70f32d0..0000000 --- a/3rdparty/zint-2.4.4/backend/code1.c +++ /dev/null @@ -1,1515 +0,0 @@ -/* code1.c - USS Code One */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "common.h" -#include "code1.h" -#include "reedsol.h" -#include "large.h" -#include -#include -#ifdef __APPLE__ -#include -#else -#include -#endif - -void horiz(struct zint_symbol *symbol, int row_no, int full) -{ - int i; - - if(full) { - for(i = 0; i < symbol->width; i++) { - set_module(symbol, row_no, i); - } - } else { - for(i = 1; i < symbol->width - 1; i++) { - set_module(symbol, row_no, i); - } - } -} - -void central_finder(struct zint_symbol *symbol, int start_row, int row_count, int full_rows) -{ - int i; - - for(i = 0; i < row_count; i++) { - if(i < full_rows) { - horiz(symbol, start_row + (i * 2), 1); - } else { - horiz(symbol, start_row + (i * 2), 0); - if(i != row_count - 1) { - set_module(symbol, start_row + (i * 2) + 1, 1); - set_module(symbol, start_row + (i * 2) + 1, symbol->width - 2); - } - } - } -} - -void vert(struct zint_symbol *symbol, int column, int height, int top) -{ - int i; - - if(top) { - for (i = 0; i < height; i++) { - set_module(symbol, i, column); - } - } else { - for (i = 0; i < height; i++) { - set_module(symbol, symbol->rows - i - 1, column); - } - } -} - -void spigot(struct zint_symbol *symbol, int row_no) -{ - int i; - - for(i = symbol->width - 1; i > 0; i--) { - if(module_is_set(symbol, row_no, i - 1)) { - set_module(symbol, row_no, i); - } - } -} - -int isedi(unsigned char input) -{ - int result = 0; - - if(input == 13) { result = 1; } - if(input == '*') { result = 1; } - if(input == '>') { result = 1; } - if(input == ' ') { result = 1; } - if((input >= '0') && (input <= '9')) { result = 1; } - if((input >= 'A') && (input <= 'Z')) { result = 1; } - - return result; -} - -int dq4bi(unsigned char source[], int sourcelen, int position) -{ - int i; - - for(i = position; isedi(source[position + i]) && ((position + i) < sourcelen); i++); - - if((position + i) == sourcelen) { - /* Reached end of input */ - return 0; - } - - if (source[position + i - 1] == 13) { return 1; } - if (source[position + i - 1] == '*') { return 1; } - if (source[position + i - 1] == '>') { return 1; } - - return 0; -} - -int c1_look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) -{ - float ascii_count, c40_count, text_count, edi_count, byte_count; - char reduced_char; - int done, best_scheme, best_count, sp; - - /* Step J */ - if(current_mode == C1_ASCII) { - ascii_count = 0.0; - c40_count = 1.0; - text_count = 1.0; - edi_count = 1.0; - byte_count = 2.0; - } else { - ascii_count = 1.0; - c40_count = 2.0; - text_count = 2.0; - edi_count = 2.0; - byte_count = 3.0; - } - - switch(current_mode) { - case C1_C40: c40_count = 0.0; break; - case C1_TEXT: text_count = 0.0; break; - case C1_BYTE: byte_count = 0.0; break; - case C1_EDI: edi_count = 0.0; break; - } - - for(sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) { - - if(source[sp] <= 127) { reduced_char = source[sp]; } else { reduced_char = source[sp] - 127; } - - /* Step L */ - if((source[sp] >= '0') && (source[sp] <= '9')) { - ascii_count += 0.5; - } else { - ascii_count = froundup(ascii_count); - if(source[sp] > 127) { - ascii_count += 2.0; - } else { - ascii_count += 1.0; - } - } - - /* Step M */ - done = 0; - if(reduced_char == ' ') { c40_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= '0') && (reduced_char <= '9')) { c40_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= 'A') && (reduced_char <= 'Z')) { c40_count += (2.0 / 3.0); done = 1; } - if(source[sp] > 127) { c40_count += (4.0 / 3.0); } - if(done == 0) { c40_count += (4.0 / 3.0); } - - /* Step N */ - done = 0; - if(reduced_char == ' ') { text_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= '0') && (reduced_char <= '9')) { text_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= 'a') && (reduced_char <= 'z')) { text_count += (2.0 / 3.0); done = 1; } - if(source[sp] > 127) { text_count += (4.0 / 3.0); } - if(done == 0) { text_count += (4.0 / 3.0); } - - /* Step O */ - done = 0; - if(source[sp] == 13) { edi_count += (2.0 / 3.0); done = 1; } - if(source[sp] == '*') { edi_count += (2.0 / 3.0); done = 1; } - if(source[sp] == '>') { edi_count += (2.0 / 3.0); done = 1; } - if(source[sp] == ' ') { edi_count += (2.0 / 3.0); done = 1; } - if((source[sp] >= '0') && (source[sp] <= '9')) { edi_count += (2.0 / 3.0); done = 1; } - if((source[sp] >= 'A') && (source[sp] <= 'Z')) { edi_count += (2.0 / 3.0); done = 1; } - if(source[sp] > 127) { - edi_count += (13.0 / 3.0); - } else { - if(done == 0) { - edi_count += (10.0 / 3.0); - } - } - - /* Step P */ - if(gs1 && (source[sp] == '[')) { byte_count += 3.0; } else { byte_count += 1.0; } - - } - - ascii_count = froundup(ascii_count); - c40_count = froundup(c40_count); - text_count = froundup(text_count); - edi_count = froundup(edi_count); - byte_count = froundup(byte_count); - best_scheme = C1_ASCII; - - if(sp == sourcelen) { - /* Step K */ - best_count = edi_count; - - if(text_count <= best_count) { - best_count = text_count; - best_scheme = C1_TEXT; - } - - if(c40_count <= best_count) { - best_count = c40_count; - best_scheme = C1_C40; - } - - if(ascii_count <= best_count) { - best_count = ascii_count; - best_scheme = C1_ASCII; - } - - if(byte_count <= best_count) { - best_count = byte_count; - best_scheme = C1_BYTE; - } - } else { - /* Step Q */ - - if(((edi_count + 1.0 <= ascii_count) && (edi_count + 1.0 <= c40_count)) && - ((edi_count + 1.0 <= byte_count) && (edi_count + 1.0 <= text_count))) { - best_scheme = C1_EDI; - } - - if((c40_count + 1.0 <= ascii_count) && (c40_count + 1.0 <= text_count)) { - - if(c40_count < edi_count) { - best_scheme = C1_C40; - } else { - done = 0; - if(c40_count == edi_count) { - if(dq4bi(source, sourcelen, position)) { - best_scheme = C1_EDI; - } else { - best_scheme = C1_C40; - } - } - } - } - - if(((text_count + 1.0 <= ascii_count) && (text_count + 1.0 <= c40_count)) && - ((text_count + 1.0 <= byte_count) && (text_count + 1.0 <= edi_count))) { - best_scheme = C1_TEXT; - } - - if(((ascii_count + 1.0 <= byte_count) && (ascii_count + 1.0 <= c40_count)) && - ((ascii_count + 1.0 <= text_count) && (ascii_count + 1.0 <= edi_count))) { - best_scheme = C1_ASCII; - } - - if(((byte_count + 1.0 <= ascii_count) && (byte_count + 1.0 <= c40_count)) && - ((byte_count + 1.0 <= text_count) && (byte_count + 1.0 <= edi_count))) { - best_scheme = C1_BYTE; - } - } - - //printf("\n> scores: ASCII %.2f C40 %.2f TEXT %.2f EDI %.2f BYTE %.2f\n", ascii_count, c40_count, text_count, edi_count, byte_count); - - return best_scheme; -} - -int c1_encode(struct zint_symbol *symbol, unsigned char source[], unsigned int target[], int length) -{ - int current_mode, next_mode; - int sp, tp, gs1, i, j, latch; - int c40_buffer[6], c40_p; - int text_buffer[6], text_p; - int edi_buffer[6], edi_p; - char decimal_binary[40]; - int byte_start = 0; - - sp = 0; - tp = 0; - latch = 0; - memset(c40_buffer, 0, 6); - c40_p = 0; - memset(text_buffer, 0, 6); - text_p = 0; - memset(edi_buffer, 0, 6); - edi_p = 0; - strcpy(decimal_binary, ""); - - if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } - if(gs1) { target[tp] = 232; tp++; } /* FNC1 */ - - /* Step A */ - current_mode = C1_ASCII; - next_mode = C1_ASCII; - - do { - if(current_mode != next_mode) { - /* Change mode */ - switch(next_mode) { - case C1_C40: target[tp] = 230; tp++; break; - case C1_TEXT: target[tp] = 239; tp++; break; - case C1_EDI: target[tp] = 238; tp++; break; - case C1_BYTE: target[tp] = 231; tp++; break; - } - } - - if((current_mode != C1_BYTE) && (next_mode == C1_BYTE)) { byte_start = tp; } - current_mode = next_mode; - - if(current_mode == C1_ASCII) { /* Step B - ASCII encodation */ - next_mode = C1_ASCII; - - if((length - sp) >= 21) { /* Step B1 */ - j = 0; - - for(i = 0; i < 21; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 21) { - next_mode = C1_DECIMAL; - strcpy(decimal_binary, "1111"); - } - } - - if((next_mode == C1_ASCII) && ((length - sp) >= 13)) { /* Step B2 */ - j = 0; - - for(i = 0; i < 13; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 13) { - latch = 0; - for(i = sp + 13; i < length; i++) { - if(!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { latch = 1; } - } - - if(!(latch)) { - next_mode = C1_DECIMAL; - strcpy(decimal_binary, "1111"); - } - } - } - - if(next_mode == C1_ASCII) { /* Step B3 */ - if(istwodigits(source, sp) && ((sp + 1) != length)) { - target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130; - tp++; - sp += 2; - } else { - if((gs1) && (source[sp] == '[')) { - if((length - sp) >= 15) { /* Step B4 */ - j = 0; - - for(i = 0; i < 15; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 15) { - target[tp] = 236; /* FNC1 and change to Decimal */ - tp++; sp++; - next_mode = C1_DECIMAL; - } - } - - if((length - sp) >= 7) { /* Step B5 */ - j = 0; - - for(i = 0; i < 7; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 7) { - latch = 0; - for(i = sp + 7; i < length; i++) { - if(!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { latch = 1; } - } - - if(!(latch)) { - target[tp] = 236; /* FNC1 and change to Decimal */ - tp++; sp++; - next_mode = C1_DECIMAL; - } - } - } - } - - if(next_mode == C1_ASCII) { - - /* Step B6 */ - next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); - - if(next_mode == C1_ASCII) { - if(source[sp] > 127) { - /* Step B7 */ - target[tp] = 235; tp++; /* FNC4 */ - target[tp] = (source[sp] - 128) + 1; tp++; sp++; - } else { - /* Step B8 */ - if((gs1) && (source[sp] == '[')) { - target[tp] = 232; tp++; sp++; /* FNC1 */ - } else { - target[tp] = source[sp] + 1; tp++; sp++; - } - } - } - } - } - } - } - - if(current_mode == C1_C40) { /* Step C - C40 encodation */ - int shift_set, value, done = 0, latch = 0; - - next_mode = C1_C40; - if(c40_p == 0) { - if((length - sp) >= 12) { - j = 0; - - for(i = 0; i < 12; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 12) { - next_mode = C1_ASCII; done = 1; - } - } - - if((length - sp) >= 8) { - j = 0; - - for(i = 0; i < 8; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if((length - sp) == 8) { - latch = 1; - } else { - latch = 1; - for(j = sp + 8; j < length; j++) { - if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; } - } - } - - if ((j == 8) && latch) { - next_mode = C1_ASCII; done = 1; - } - } - - if(!(done)) { - next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); - } - } - - if(next_mode != C1_C40) { - target[tp] = 255; tp++; /* Unlatch */ - } else { - if(source[sp] > 127) { - c40_buffer[c40_p] = 1; c40_p++; - c40_buffer[c40_p] = 30; c40_p++; /* Upper Shift */ - shift_set = c40_shift[source[sp] - 128]; - value = c40_value[source[sp] - 128]; - } else { - shift_set = c40_shift[source[sp]]; - value = c40_value[source[sp]]; - } - - if(gs1 && (source[sp] == '[')) { - shift_set = 2; - value = 27; /* FNC1 */ - } - - if(shift_set != 0) { - c40_buffer[c40_p] = shift_set - 1; c40_p++; - } - c40_buffer[c40_p] = value; c40_p++; - - if(c40_p >= 3) { - int iv; - - iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - - c40_buffer[0] = c40_buffer[3]; - c40_buffer[1] = c40_buffer[4]; - c40_buffer[2] = c40_buffer[5]; - c40_buffer[3] = 0; - c40_buffer[4] = 0; - c40_buffer[5] = 0; - c40_p -= 3; - } - sp++; - } - } - - if(current_mode == C1_TEXT) { /* Step D - Text encodation */ - int shift_set, value, done = 0, latch = 0; - - next_mode = C1_TEXT; - if(text_p == 0) { - if((length - sp) >= 12) { - j = 0; - - for(i = 0; i < 12; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 12) { - next_mode = C1_ASCII; done = 1; - } - } - - if((length - sp) >= 8) { - j = 0; - - for(i = 0; i < 8; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if((length - sp) == 8) { - latch = 1; - } else { - latch = 1; - for(j = sp + 8; j < length; j++) { - if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; } - } - } - - if ((j == 8) && latch) { - next_mode = C1_ASCII; done = 1; - } - } - - if(!(done)) { - next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); - } - } - - if(next_mode != C1_TEXT) { - target[tp] = 255; tp++; /* Unlatch */ - } else { - if(source[sp] > 127) { - text_buffer[text_p] = 1; text_p++; - text_buffer[text_p] = 30; text_p++; /* Upper Shift */ - shift_set = text_shift[source[sp] - 128]; - value = text_value[source[sp] - 128]; - } else { - shift_set = text_shift[source[sp]]; - value = text_value[source[sp]]; - } - - if(gs1 && (source[sp] == '[')) { - shift_set = 2; - value = 27; /* FNC1 */ - } - - if(shift_set != 0) { - text_buffer[text_p] = shift_set - 1; text_p++; - } - text_buffer[text_p] = value; text_p++; - - if(text_p >= 3) { - int iv; - - iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - - text_buffer[0] = text_buffer[3]; - text_buffer[1] = text_buffer[4]; - text_buffer[2] = text_buffer[5]; - text_buffer[3] = 0; - text_buffer[4] = 0; - text_buffer[5] = 0; - text_p -= 3; - } - sp++; - } - } - - if(current_mode == C1_EDI) { /* Step E - EDI Encodation */ - int value = 0, done = 0, latch = 0; - - next_mode = C1_EDI; - if(edi_p == 0) { - if((length - sp) >= 12) { - j = 0; - - for(i = 0; i < 12; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if (j == 12) { - next_mode = C1_ASCII; done = 1; - } - } - - if((length - sp) >= 8) { - j = 0; - - for(i = 0; i < 8; i++) { - if((source[sp + i] >= '0') && (source[sp + i] <= '9')) { j++; } - } - - if((length - sp) == 8) { - latch = 1; - } else { - latch = 1; - for(j = sp + 8; j < length; j++) { - if((source[j] <= '0') || (source[j] >= '9')) { latch = 0; } - } - } - - if ((j == 8) && latch) { - next_mode = C1_ASCII; done = 1; - } - } - - if(!((isedi(source[sp]) && isedi(source[sp + 1])) && isedi(source[sp + 2]))) { - next_mode = C1_ASCII; - } - } - - if(next_mode != C1_EDI) { - target[tp] = 255; tp++; /* Unlatch */ - } else { - if(source[sp] == 13) { value = 0; } - if(source[sp] == '*') { value = 1; } - if(source[sp] == '>') { value = 2; } - if(source[sp] == ' ') { value = 3; } - if((source[sp] >= '0') && (source[sp] <= '9')) { value = source[sp] - '0' + 4; } - if((source[sp] >= 'A') && (source[sp] <= 'Z')) { value = source[sp] - 'A' + 14; } - - edi_buffer[edi_p] = value; edi_p++; - - if(edi_p >= 3) { - int iv; - - iv = (1600 * edi_buffer[0]) + (40 * edi_buffer[1]) + (edi_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - - edi_buffer[0] = edi_buffer[3]; - edi_buffer[1] = edi_buffer[4]; - edi_buffer[2] = edi_buffer[5]; - edi_buffer[3] = 0; - edi_buffer[4] = 0; - edi_buffer[5] = 0; - edi_p -= 3; - } - sp++; - } - } - - if(current_mode == C1_DECIMAL) { /* Step F - Decimal encodation */ - int value, decimal_count, data_left; - - next_mode = C1_DECIMAL; - - data_left = length - sp; - decimal_count = 0; - - if(data_left >= 1) { - if((source[sp] >= '0') && (source[sp] <= '9')) { decimal_count = 1; } - } - if(data_left >= 2) { - if((decimal_count == 1) && ((source[sp + 1] >= '0') && (source[sp + 1] <= '9'))) { decimal_count = 2; } - } - if(data_left >= 3) { - if((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) { decimal_count = 3; } - } - - if(decimal_count != 3) { - int bits_left_in_byte, target_count; - int sub_target; - /* Finish Decimal mode and go back to ASCII */ - - concat(decimal_binary, "111111"); /* Unlatch */ - - target_count = 3; - if(strlen(decimal_binary) <= 16) { target_count = 2; } - if(strlen(decimal_binary) <= 8) { target_count = 1; } - bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); - if(bits_left_in_byte == 8) { bits_left_in_byte = 0; } - - if(bits_left_in_byte == 2) { - concat(decimal_binary, "01"); - } - - if((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { - if(decimal_count >= 1) { - int sub_value = ctoi(source[sp]) + 1; - - if(sub_value & 0x08) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(sub_value & 0x04) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(sub_value & 0x02) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(sub_value & 0x01) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - sp++; - } else { - concat(decimal_binary, "1111"); - } - } - - if(bits_left_in_byte == 6) { - concat(decimal_binary, "01"); - } - - /* Binary buffer is full - transfer to target */ - if(target_count >= 1) { - sub_target = 0; - if(decimal_binary[0] == '1') { sub_target += 128; } - if(decimal_binary[1] == '1') { sub_target += 64; } - if(decimal_binary[2] == '1') { sub_target += 32; } - if(decimal_binary[3] == '1') { sub_target += 16; } - if(decimal_binary[4] == '1') { sub_target += 8; } - if(decimal_binary[5] == '1') { sub_target += 4; } - if(decimal_binary[6] == '1') { sub_target += 2; } - if(decimal_binary[7] == '1') { sub_target += 1; } - target[tp] = sub_target; tp++; - } - if(target_count >= 2) { - sub_target = 0; - if(decimal_binary[8] == '1') { sub_target += 128; } - if(decimal_binary[9] == '1') { sub_target += 64; } - if(decimal_binary[10] == '1') { sub_target += 32; } - if(decimal_binary[11] == '1') { sub_target += 16; } - if(decimal_binary[12] == '1') { sub_target += 8; } - if(decimal_binary[13] == '1') { sub_target += 4; } - if(decimal_binary[14] == '1') { sub_target += 2; } - if(decimal_binary[15] == '1') { sub_target += 1; } - target[tp] = sub_target; tp++; - } - if(target_count == 3) { - sub_target = 0; - if(decimal_binary[16] == '1') { sub_target += 128; } - if(decimal_binary[17] == '1') { sub_target += 64; } - if(decimal_binary[18] == '1') { sub_target += 32; } - if(decimal_binary[19] == '1') { sub_target += 16; } - if(decimal_binary[20] == '1') { sub_target += 8; } - if(decimal_binary[21] == '1') { sub_target += 4; } - if(decimal_binary[22] == '1') { sub_target += 2; } - if(decimal_binary[23] == '1') { sub_target += 1; } - target[tp] = sub_target; tp++; - } - - next_mode = C1_ASCII; - } else { - /* There are three digits - convert the value to binary */ - value = (100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1; - - if(value & 0x200) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x100) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x80) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x40) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x20) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x10) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x08) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x04) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x02) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - if(value & 0x01) { concat(decimal_binary, "1"); } else { concat(decimal_binary, "0"); } - - sp+= 3; - } - - if(strlen(decimal_binary) >= 24) { - int target1 = 0, target2 = 0, target3 = 0; - char temp_binary[40]; - - /* Binary buffer is full - transfer to target */ - if(decimal_binary[0] == '1') { target1 += 128; } - if(decimal_binary[1] == '1') { target1 += 64; } - if(decimal_binary[2] == '1') { target1 += 32; } - if(decimal_binary[3] == '1') { target1 += 16; } - if(decimal_binary[4] == '1') { target1 += 8; } - if(decimal_binary[5] == '1') { target1 += 4; } - if(decimal_binary[6] == '1') { target1 += 2; } - if(decimal_binary[7] == '1') { target1 += 1; } - if(decimal_binary[8] == '1') { target2 += 128; } - if(decimal_binary[9] == '1') { target2 += 64; } - if(decimal_binary[10] == '1') { target2 += 32; } - if(decimal_binary[11] == '1') { target2 += 16; } - if(decimal_binary[12] == '1') { target2 += 8; } - if(decimal_binary[13] == '1') { target2 += 4; } - if(decimal_binary[14] == '1') { target2 += 2; } - if(decimal_binary[15] == '1') { target2 += 1; } - if(decimal_binary[16] == '1') { target3 += 128; } - if(decimal_binary[17] == '1') { target3 += 64; } - if(decimal_binary[18] == '1') { target3 += 32; } - if(decimal_binary[19] == '1') { target3 += 16; } - if(decimal_binary[20] == '1') { target3 += 8; } - if(decimal_binary[21] == '1') { target3 += 4; } - if(decimal_binary[22] == '1') { target3 += 2; } - if(decimal_binary[23] == '1') { target3 += 1; } - target[tp] = target1; tp++; - target[tp] = target2; tp++; - target[tp] = target3; tp++; - - strcpy(temp_binary, ""); - if(strlen(decimal_binary) > 24) { - for(i = 0; i <= (strlen(decimal_binary) - 24); i++) { - temp_binary[i] = decimal_binary[i + 24]; - } - strcpy(decimal_binary, temp_binary); - } - } - } - - if(current_mode == C1_BYTE) { - next_mode = C1_BYTE; - - if(gs1 && (source[sp] == '[')) { - next_mode = C1_ASCII; - } else { - if(source[sp] <= 127) { - next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); - } - } - - if(next_mode != C1_BYTE) { - /* Insert byte field length */ - if((tp - byte_start) <= 249) { - for(i = tp; i >= byte_start; i--) { - target[i + 1] = target[i]; - } - target[byte_start] = (tp - byte_start); - tp++; - } else { - for(i = tp; i >= byte_start; i--) { - target[i + 2] = target[i]; - } - target[byte_start] = 249 + ((tp - byte_start) / 250); - target[byte_start + 1] = ((tp - byte_start) % 250); - tp += 2; - } - } else { - target[tp] = source[sp]; - tp++; - sp++; - } - } - - if(tp > 1480) { - /* Data is too large for symbol */ - strcpy(symbol->errtxt, "Input data too long"); - return 0; - } - } while (sp < length); - - /* Empty buffers */ - if(c40_p == 2) { - int iv; - - c40_buffer[2] = 1; - iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - target[tp] = 255; tp++; /* Unlatch */ - } - if(c40_p == 1) { - int iv; - - c40_buffer[1] = 1; - c40_buffer[2] = 31; /* Pad */ - iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - target[tp] = 255; tp++; /* Unlatch */ - } - if(text_p == 2) { - int iv; - - text_buffer[2] = 1; - iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - target[tp] = 255; tp++; /* Unlatch */ - } - if(text_p == 1) { - int iv; - - text_buffer[1] = 1; - text_buffer[2] = 31; /* Pad */ - iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - target[tp] = 255; tp++; /* Unlatch */ - } - - if(current_mode == C1_DECIMAL) { - int bits_left_in_byte, target_count; - int sub_target; - /* Finish Decimal mode and go back to ASCII */ - - concat(decimal_binary, "111111"); /* Unlatch */ - - target_count = 3; - if(strlen(decimal_binary) <= 16) { target_count = 2; } - if(strlen(decimal_binary) <= 8) { target_count = 1; } - bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); - if(bits_left_in_byte == 8) { bits_left_in_byte = 0; } - - if(bits_left_in_byte == 2) { - concat(decimal_binary, "01"); - } - - if((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { - concat(decimal_binary, "1111"); - } - - if(bits_left_in_byte == 6) { - concat(decimal_binary, "01"); - } - - /* Binary buffer is full - transfer to target */ - if(target_count >= 1) { - sub_target = 0; - if(decimal_binary[0] == '1') { sub_target += 128; } - if(decimal_binary[1] == '1') { sub_target += 64; } - if(decimal_binary[2] == '1') { sub_target += 32; } - if(decimal_binary[3] == '1') { sub_target += 16; } - if(decimal_binary[4] == '1') { sub_target += 8; } - if(decimal_binary[5] == '1') { sub_target += 4; } - if(decimal_binary[6] == '1') { sub_target += 2; } - if(decimal_binary[7] == '1') { sub_target += 1; } - target[tp] = sub_target; tp++; - } - if(target_count >= 2) { - sub_target = 0; - if(decimal_binary[8] == '1') { sub_target += 128; } - if(decimal_binary[9] == '1') { sub_target += 64; } - if(decimal_binary[10] == '1') { sub_target += 32; } - if(decimal_binary[11] == '1') { sub_target += 16; } - if(decimal_binary[12] == '1') { sub_target += 8; } - if(decimal_binary[13] == '1') { sub_target += 4; } - if(decimal_binary[14] == '1') { sub_target += 2; } - if(decimal_binary[15] == '1') { sub_target += 1; } - target[tp] = sub_target; tp++; - } - if(target_count == 3) { - sub_target = 0; - if(decimal_binary[16] == '1') { sub_target += 128; } - if(decimal_binary[17] == '1') { sub_target += 64; } - if(decimal_binary[18] == '1') { sub_target += 32; } - if(decimal_binary[19] == '1') { sub_target += 16; } - if(decimal_binary[20] == '1') { sub_target += 8; } - if(decimal_binary[21] == '1') { sub_target += 4; } - if(decimal_binary[22] == '1') { sub_target += 2; } - if(decimal_binary[23] == '1') { sub_target += 1; } - target[tp] = sub_target; tp++; - } - } - - if(current_mode == C1_BYTE) { - /* Insert byte field length */ - if((tp - byte_start) <= 249) { - for(i = tp; i >= byte_start; i--) { - target[i + 1] = target[i]; - } - target[byte_start] = (tp - byte_start); - tp++; - } else { - for(i = tp; i >= byte_start; i--) { - target[i + 2] = target[i]; - } - target[byte_start] = 249 + ((tp - byte_start) / 250); - target[byte_start + 1] = ((tp - byte_start) % 250); - tp += 2; - } - } - - /* Re-check length of data */ - if(tp > 1480) { - /* Data is too large for symbol */ - strcpy(symbol->errtxt, "Input data too long"); - return 0; - } - /* - printf("targets:\n"); - for(i = 0; i < tp; i++) { - printf("[%d]", target[i]); - } - printf("\n"); - */ - return tp; -} - -void block_copy(struct zint_symbol *symbol, char grid[][120], int start_row, int start_col, int height, int width, int row_offset, int col_offset) { - int i, j; - - for(i = start_row; i < (start_row + height); i++) { - for(j = start_col; j < (start_col + width); j++) { - if(grid[i][j] == '1') { - set_module(symbol, i + row_offset, j + col_offset); - } - } - } -} - -int code_one(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int size = 1, i, j, data_blocks; - - char datagrid[136][120]; - int row, col; - int sub_version = 0; - - if((symbol->option_2 < 0) || (symbol->option_2 > 10)) { - strcpy(symbol->errtxt, "Invalid symbol size"); - return ERROR_INVALID_OPTION; - } - - if(symbol->option_2 == 9) { - /* Version S */ - int codewords; - short int elreg[112]; - unsigned int data[15], ecc[15]; - int stream[30]; - int block_width; - - if(length > 18) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - if(is_sane(NEON, source, length) == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid input data (Version S encodes numeric input only)"); - return ERROR_INVALID_DATA1; - } - - sub_version = 3; codewords = 12; block_width = 6; /* Version S-30 */ - if(length <= 12) { sub_version = 2; codewords = 8; block_width = 4; } /* Version S-20 */ - if(length <= 6) { sub_version = 1; codewords = 4; block_width = 2; } /* Version S-10 */ - - binary_load(elreg, (char *)source, length); - hex_dump(elreg); - - for(i = 0; i < 15; i++) { - data[i] = 0; - ecc[i] = 0; - } - - for(i = 0; i < codewords; i++) { - data[codewords - i - 1] += 1 * elreg[(i * 5)]; - data[codewords - i - 1] += 2 * elreg[(i * 5) + 1]; - data[codewords - i - 1] += 4 * elreg[(i * 5) + 2]; - data[codewords - i - 1] += 8 * elreg[(i * 5) + 3]; - data[codewords - i - 1] += 16 * elreg[(i * 5) + 4]; - } - - rs_init_gf(0x25); - rs_init_code(codewords, 1); - rs_encode_long(codewords, data, ecc); - rs_free(); - - for(i = 0; i < codewords; i++) { - stream[i] = data[i]; - stream[i + codewords] = ecc[codewords - i - 1]; - } - - for(i = 0; i < 136; i++) { - for(j = 0; j < 120; j++) { - datagrid[i][j] = '0'; - } - } - - i = 0; - for(row = 0; row < 2; row++) { - for(col = 0; col < block_width; col++) { - if(stream[i] & 0x10) { datagrid[row * 2][col * 5] = '1'; } - if(stream[i] & 0x08) { datagrid[row * 2][(col * 5) + 1] = '1'; } - if(stream[i] & 0x04) { datagrid[row * 2][(col * 5) + 2] = '1'; } - if(stream[i] & 0x02) { datagrid[(row * 2) + 1][col * 5] = '1'; } - if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 5) + 1] = '1'; } - if(stream[i + 1] & 0x10) { datagrid[row * 2][(col * 5) + 3] = '1'; } - if(stream[i + 1] & 0x08) { datagrid[row * 2][(col * 5) + 4] = '1'; } - if(stream[i + 1] & 0x04) { datagrid[(row * 2) + 1][(col * 5) + 2] = '1'; } - if(stream[i + 1] & 0x02) { datagrid[(row * 2) + 1][(col * 5) + 3] = '1'; } - if(stream[i + 1] & 0x01) { datagrid[(row * 2) + 1][(col * 5) + 4] = '1'; } - i += 2; - } - } - - size = 9; - symbol->rows = 8; - symbol->width = 10 * sub_version + 1; - } - - if(symbol->option_2 == 10) { - /* Version T */ - unsigned int data[40], ecc[25]; - unsigned int stream[65]; - int data_length; - int data_cw, ecc_cw, block_width; - - for(i = 0; i < 40; i++) { data[i] = 0; } - data_length = c1_encode(symbol, source, data, length); - - if(data_length == 0) { - return ERROR_TOO_LONG; - } - - if(data_length > 38) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - - size = 10; - sub_version = 3; data_cw = 38; ecc_cw = 22; block_width = 12; - if(data_length <= 24) { sub_version = 2; data_cw = 24; ecc_cw = 16; block_width = 8; } - if(data_length <= 10) { sub_version = 1; data_cw = 10; ecc_cw = 10; block_width = 4; } - - for(i = data_length; i < data_cw; i++) { - data[i] = 129; /* Pad */ - } - - /* Calculate error correction data */ - rs_init_gf(0x12d); - rs_init_code(ecc_cw, 1); - rs_encode_long(data_cw, data, ecc); - rs_free(); - - /* "Stream" combines data and error correction data */ - for(i = 0; i < data_cw; i++) { - stream[i] = data[i]; - } - for(i = 0; i < ecc_cw; i++) { - stream[data_cw + i] = ecc[ecc_cw - i - 1]; - } - - for(i = 0; i < 136; i++) { - for(j = 0; j < 120; j++) { - datagrid[i][j] = '0'; - } - } - - i = 0; - for(row = 0; row < 5; row++) { - for(col = 0; col < block_width; col++) { - if(stream[i] & 0x80) { datagrid[row * 2][col * 4] = '1'; } - if(stream[i] & 0x40) { datagrid[row * 2][(col * 4) + 1] = '1'; } - if(stream[i] & 0x20) { datagrid[row * 2][(col * 4) + 2] = '1'; } - if(stream[i] & 0x10) { datagrid[row * 2][(col * 4) + 3] = '1'; } - if(stream[i] & 0x08) { datagrid[(row * 2) + 1][col * 4] = '1'; } - if(stream[i] & 0x04) { datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; } - if(stream[i] & 0x02) { datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; } - if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; } - i++; - } - } - - symbol->rows = 16; - symbol->width = (sub_version * 16) + 1; - } - - if((symbol->option_2 != 9) && (symbol->option_2 != 10)) { - /* Version A to H */ - unsigned int data[1500], ecc[600]; - unsigned int sub_data[190], sub_ecc[75]; - unsigned int stream[2100]; - int data_length; - - for(i = 0; i < 1500; i++) { data[i] = 0; } - data_length = c1_encode(symbol, source, data, length); - - if(data_length == 0) { - return ERROR_TOO_LONG; - } - - for(i = 7; i >= 0; i--) { - if(c1_data_length[i] >= data_length) { - size = i + 1; - } - } - - if(symbol->option_2 > size) { - size = symbol->option_2; - } - - for(i = data_length; i < c1_data_length[size - 1]; i++) { - data[i] = 129; /* Pad */ - } - - /* Calculate error correction data */ - data_length = c1_data_length[size - 1]; - for(i = 0; i < 190; i++) { sub_data[i] = 0; } - for(i = 0; i < 75; i++) { sub_ecc[i] = 0; } - - data_blocks = c1_blocks[size - 1]; - - rs_init_gf(0x12d); - rs_init_code(c1_ecc_blocks[size - 1], 0); - for(i = 0; i < data_blocks; i++) { - for(j = 0; j < c1_data_blocks[size - 1]; j++) { - - sub_data[j] = data[j * data_blocks + i]; - } - rs_encode_long(c1_data_blocks[size - 1], sub_data, sub_ecc); - for(j = 0; j < c1_ecc_blocks[size - 1]; j++) { - ecc[c1_ecc_length[size - 1] - (j * data_blocks + i) - 1] = sub_ecc[j]; - } - } - rs_free(); - - /* "Stream" combines data and error correction data */ - for(i = 0; i < data_length; i++) { - stream[i] = data[i]; - } - for(i = 0; i < c1_ecc_length[size - 1]; i++) { - stream[data_length + i] = ecc[i]; - } - - for(i = 0; i < 136; i++) { - for(j = 0; j < 120; j++) { - datagrid[i][j] = '0'; - } - } - - i = 0; - for(row = 0; row < c1_grid_height[size - 1]; row++) { - for(col = 0; col < c1_grid_width[size - 1]; col++) { - if(stream[i] & 0x80) { datagrid[row * 2][col * 4] = '1'; } - if(stream[i] & 0x40) { datagrid[row * 2][(col * 4) + 1] = '1'; } - if(stream[i] & 0x20) { datagrid[row * 2][(col * 4) + 2] = '1'; } - if(stream[i] & 0x10) { datagrid[row * 2][(col * 4) + 3] = '1'; } - if(stream[i] & 0x08) { datagrid[(row * 2) + 1][col * 4] = '1'; } - if(stream[i] & 0x04) { datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; } - if(stream[i] & 0x02) { datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; } - if(stream[i] & 0x01) { datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; } - i++; - } - } - - /* for(i = 0; i < (c1_grid_height[size - 1] * 2); i++) { - for(j = 0; j < (c1_grid_width[size - 1] * 4); j++) { - printf("%c", datagrid[i][j]); - } - printf("\n"); - } */ - - symbol->rows = c1_height[size - 1]; - symbol->width = c1_width[size - 1]; - } - - switch(size) { - case 1: /* Version A */ - central_finder(symbol, 6, 3, 1); - vert(symbol, 4, 6, 1); - vert(symbol, 12, 5, 0); - set_module(symbol, 5, 12); - spigot(symbol, 0); - spigot(symbol, 15); - block_copy(symbol, datagrid, 0, 0, 5, 4, 0, 0); - block_copy(symbol, datagrid, 0, 4, 5, 12, 0, 2); - block_copy(symbol, datagrid, 5, 0, 5, 12, 6, 0); - block_copy(symbol, datagrid, 5, 12, 5, 4, 6, 2); - break; - case 2: /* Version B */ - central_finder(symbol, 8, 4, 1); - vert(symbol, 4, 8, 1); - vert(symbol, 16, 7, 0); - set_module(symbol, 7, 16); - spigot(symbol, 0); - spigot(symbol, 21); - block_copy(symbol, datagrid, 0, 0, 7, 4, 0, 0); - block_copy(symbol, datagrid, 0, 4, 7, 16, 0, 2); - block_copy(symbol, datagrid, 7, 0, 7, 16, 8, 0); - block_copy(symbol, datagrid, 7, 16, 7, 4, 8, 2); - break; - case 3: /* Version C */ - central_finder(symbol, 11, 4, 2); - vert(symbol, 4, 11, 1); - vert(symbol, 26, 13, 1); - vert(symbol, 4, 10, 0); - vert(symbol, 26, 10, 0); - spigot(symbol, 0); - spigot(symbol, 27); - block_copy(symbol, datagrid, 0, 0, 10, 4, 0, 0); - block_copy(symbol, datagrid, 0, 4, 10, 20, 0, 2); - block_copy(symbol, datagrid, 0, 24, 10, 4, 0, 4); - block_copy(symbol, datagrid, 10, 0, 10, 4, 8, 0); - block_copy(symbol, datagrid, 10, 4, 10, 20, 8, 2); - block_copy(symbol, datagrid, 10, 24, 10, 4, 8, 4); - break; - case 4: /* Version D */ - central_finder(symbol, 16, 5, 1); - vert(symbol, 4, 16, 1); - vert(symbol, 20, 16, 1); - vert(symbol, 36, 16, 1); - vert(symbol, 4, 15, 0); - vert(symbol, 20, 15, 0); - vert(symbol, 36, 15, 0); - spigot(symbol, 0); - spigot(symbol, 12); - spigot(symbol, 27); - spigot(symbol, 39); - block_copy(symbol, datagrid, 0, 0, 15, 4, 0, 0); - block_copy(symbol, datagrid, 0, 4, 15, 14, 0, 2); - block_copy(symbol, datagrid, 0, 18, 15, 14, 0, 4); - block_copy(symbol, datagrid, 0, 32, 15, 4, 0, 6); - block_copy(symbol, datagrid, 15, 0, 15, 4, 10, 0); - block_copy(symbol, datagrid, 15, 4, 15, 14, 10, 2); - block_copy(symbol, datagrid, 15, 18, 15, 14, 10, 4); - block_copy(symbol, datagrid, 15, 32, 15, 4, 10, 6); - break; - case 5: /* Version E */ - central_finder(symbol, 22, 5, 2); - vert(symbol, 4, 22, 1); - vert(symbol, 26, 24, 1); - vert(symbol, 48, 22, 1); - vert(symbol, 4, 21, 0); - vert(symbol, 26, 21, 0); - vert(symbol, 48, 21, 0); - spigot(symbol, 0); - spigot(symbol, 12); - spigot(symbol, 39); - spigot(symbol, 51); - block_copy(symbol, datagrid, 0, 0, 21, 4, 0, 0); - block_copy(symbol, datagrid, 0, 4, 21, 20, 0, 2); - block_copy(symbol, datagrid, 0, 24, 21, 20, 0, 4); - block_copy(symbol, datagrid, 0, 44, 21, 4, 0, 6); - block_copy(symbol, datagrid, 21, 0, 21, 4, 10, 0); - block_copy(symbol, datagrid, 21, 4, 21, 20, 10, 2); - block_copy(symbol, datagrid, 21, 24, 21, 20, 10, 4); - block_copy(symbol, datagrid, 21, 44, 21, 4, 10, 6); - break; - case 6: /* Version F */ - central_finder(symbol, 31, 5, 3); - vert(symbol, 4, 31, 1); - vert(symbol, 26, 35, 1); - vert(symbol, 48, 31, 1); - vert(symbol, 70, 35, 1); - vert(symbol, 4, 30, 0); - vert(symbol, 26, 30, 0); - vert(symbol, 48, 30, 0); - vert(symbol, 70, 30, 0); - spigot(symbol, 0); - spigot(symbol, 12); - spigot(symbol, 24); - spigot(symbol, 45); - spigot(symbol, 57); - spigot(symbol, 69); - block_copy(symbol, datagrid, 0, 0, 30, 4, 0, 0); - block_copy(symbol, datagrid, 0, 4, 30, 20, 0, 2); - block_copy(symbol, datagrid, 0, 24, 30, 20, 0, 4); - block_copy(symbol, datagrid, 0, 44, 30, 20, 0, 6); - block_copy(symbol, datagrid, 0, 64, 30, 4, 0, 8); - block_copy(symbol, datagrid, 30, 0, 30, 4, 10, 0); - block_copy(symbol, datagrid, 30, 4, 30, 20, 10, 2); - block_copy(symbol, datagrid, 30, 24, 30, 20, 10, 4); - block_copy(symbol, datagrid, 30, 44, 30, 20, 10, 6); - block_copy(symbol, datagrid, 30, 64, 30, 4, 10, 8); - break; - case 7: /* Version G */ - central_finder(symbol, 47, 6, 2); - vert(symbol, 6, 47, 1); - vert(symbol, 27, 49, 1); - vert(symbol, 48, 47, 1); - vert(symbol, 69, 49, 1); - vert(symbol, 90, 47, 1); - vert(symbol, 6, 46, 0); - vert(symbol, 27, 46, 0); - vert(symbol, 48, 46, 0); - vert(symbol, 69, 46, 0); - vert(symbol, 90, 46, 0); - spigot(symbol, 0); - spigot(symbol, 12); - spigot(symbol, 24); - spigot(symbol, 36); - spigot(symbol, 67); - spigot(symbol, 79); - spigot(symbol, 91); - spigot(symbol, 103); - block_copy(symbol, datagrid, 0, 0, 46, 6, 0, 0); - block_copy(symbol, datagrid, 0, 6, 46, 19, 0, 2); - block_copy(symbol, datagrid, 0, 25, 46, 19, 0, 4); - block_copy(symbol, datagrid, 0, 44, 46, 19, 0, 6); - block_copy(symbol, datagrid, 0, 63, 46, 19, 0, 8); - block_copy(symbol, datagrid, 0, 82, 46, 6, 0, 10); - block_copy(symbol, datagrid, 46, 0, 46, 6, 12, 0); - block_copy(symbol, datagrid, 46, 6, 46, 19, 12, 2); - block_copy(symbol, datagrid, 46, 25, 46, 19, 12, 4); - block_copy(symbol, datagrid, 46, 44, 46, 19, 12, 6); - block_copy(symbol, datagrid, 46, 63, 46, 19, 12, 8); - block_copy(symbol, datagrid, 46, 82, 46, 6, 12, 10); - break; - case 8: /* Version H */ - central_finder(symbol, 69, 6, 3); - vert(symbol, 6, 69, 1); - vert(symbol, 26, 73, 1); - vert(symbol, 46, 69, 1); - vert(symbol, 66, 73, 1); - vert(symbol, 86, 69, 1); - vert(symbol, 106, 73, 1); - vert(symbol, 126, 69, 1); - vert(symbol, 6, 68, 0); - vert(symbol, 26, 68, 0); - vert(symbol, 46, 68, 0); - vert(symbol, 66, 68, 0); - vert(symbol, 86, 68, 0); - vert(symbol, 106, 68, 0); - vert(symbol, 126, 68, 0); - spigot(symbol, 0); - spigot(symbol, 12); - spigot(symbol, 24); - spigot(symbol, 36); - spigot(symbol, 48); - spigot(symbol, 60); - spigot(symbol, 87); - spigot(symbol, 99); - spigot(symbol, 111); - spigot(symbol, 123); - spigot(symbol, 135); - spigot(symbol, 147); - block_copy(symbol, datagrid, 0, 0, 68, 6, 0, 0); - block_copy(symbol, datagrid, 0, 6, 68, 18, 0, 2); - block_copy(symbol, datagrid, 0, 24, 68, 18, 0, 4); - block_copy(symbol, datagrid, 0, 42, 68, 18, 0, 6); - block_copy(symbol, datagrid, 0, 60, 68, 18, 0, 8); - block_copy(symbol, datagrid, 0, 78, 68, 18, 0, 10); - block_copy(symbol, datagrid, 0, 96, 68, 18, 0, 12); - block_copy(symbol, datagrid, 0, 114, 68, 6, 0, 14); - block_copy(symbol, datagrid, 68, 0, 68, 6, 12, 0); - block_copy(symbol, datagrid, 68, 6, 68, 18, 12, 2); - block_copy(symbol, datagrid, 68, 24, 68, 18, 12, 4); - block_copy(symbol, datagrid, 68, 42, 68, 18, 12, 6); - block_copy(symbol, datagrid, 68, 60, 68, 18, 12, 8); - block_copy(symbol, datagrid, 68, 78, 68, 18, 12, 10); - block_copy(symbol, datagrid, 68, 96, 68, 18, 12, 12); - block_copy(symbol, datagrid, 68, 114, 68, 6, 12, 14); - break; - case 9: /* Version S */ - horiz(symbol, 5, 1); - horiz(symbol, 7, 1); - set_module(symbol, 6, 0); - set_module(symbol, 6, symbol->width - 1); - unset_module(symbol, 7, 1); - unset_module(symbol, 7, symbol->width - 2); - switch(sub_version) { - case 1: /* Version S-10 */ - set_module(symbol, 0, 5); - block_copy(symbol, datagrid, 0, 0, 4, 5, 0, 0); - block_copy(symbol, datagrid, 0, 5, 4, 5, 0, 1); - break; - case 2: /* Version S-20 */ - set_module(symbol, 0, 10); - set_module(symbol, 4, 10); - block_copy(symbol, datagrid, 0, 0, 4, 10, 0, 0); - block_copy(symbol, datagrid, 0, 10, 4, 10, 0, 1); - break; - case 3: /* Version S-30 */ - set_module(symbol, 0, 15); - set_module(symbol, 4, 15); - set_module(symbol, 6, 15); - block_copy(symbol, datagrid, 0, 0, 4, 15, 0, 0); - block_copy(symbol, datagrid, 0, 15, 4, 15, 0, 1); - break; - } - break; - case 10: /* Version T */ - horiz(symbol, 11, 1); - horiz(symbol, 13, 1); - horiz(symbol, 15, 1); - set_module(symbol, 12, 0); - set_module(symbol, 12, symbol->width - 1); - set_module(symbol, 14, 0); - set_module(symbol, 14, symbol->width - 1); - unset_module(symbol, 13, 1); - unset_module(symbol, 13, symbol->width - 2); - unset_module(symbol, 15, 1); - unset_module(symbol, 15, symbol->width - 2); - switch(sub_version) { - case 1: /* Version T-16 */ - set_module(symbol, 0, 8); - set_module(symbol, 10, 8); - block_copy(symbol, datagrid, 0, 0, 10, 8, 0, 0); - block_copy(symbol, datagrid, 0, 8, 10, 8, 0, 1); - break; - case 2: /* Version T-32 */ - set_module(symbol, 0, 16); - set_module(symbol, 10, 16); - set_module(symbol, 12, 16); - block_copy(symbol, datagrid, 0, 0, 10, 16, 0, 0); - block_copy(symbol, datagrid, 0, 16, 10, 16, 0, 1); - break; - case 3: /* Verion T-48 */ - set_module(symbol, 0, 24); - set_module(symbol, 10, 24); - set_module(symbol, 12, 24); - set_module(symbol, 14, 24); - block_copy(symbol, datagrid, 0, 0, 10, 24, 0, 0); - block_copy(symbol, datagrid, 0, 24, 10, 24, 0, 1); - break; - } - break; - } - - for(i = 0; i < symbol->rows; i++) { - symbol->row_height[i] = 1; - } - - return 0; -} diff --git a/3rdparty/zint-2.4.4/backend/code1.h b/3rdparty/zint-2.4.4/backend/code1.h deleted file mode 100644 index 532dc77..0000000 --- a/3rdparty/zint-2.4.4/backend/code1.h +++ /dev/null @@ -1,61 +0,0 @@ -/* code1.h - Lookup info for USS Code One */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -static int c40_shift[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - -static int c40_value[] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, - 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, - 15,16,17,18,19,20,21,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39, - 22,23,24,25,26,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; - -static int text_shift[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 }; - -static int text_value[] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, - 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, - 15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, - 22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 }; - -static int c1_height[] = { 16, 22, 28, 40, 52, 70, 104, 148 }; -static int c1_width[] = { 18, 22, 32, 42, 54, 76, 98, 134 }; -static int c1_data_length[] = { 10, 19, 44, 91, 182, 370, 732, 1480 }; -static int c1_ecc_length[] = { 10, 16, 26, 44, 70, 140, 280, 560 }; -static int c1_blocks[] = { 1, 1, 1, 1, 1, 2, 4, 8 }; -static int c1_data_blocks[] = { 10, 19, 44, 91, 182, 185, 183, 185 }; -static int c1_ecc_blocks[] = { 10, 16, 26, 44, 70, 70, 70, 70 }; -static int c1_grid_width[] = { 4, 5, 7, 9, 12, 17, 22, 30 }; -static int c1_grid_height[] = { 5, 7, 10, 15, 21, 30, 46, 68 }; - -#define C1_ASCII 1 -#define C1_C40 2 -#define C1_DECIMAL 3 -#define C1_TEXT 4 -#define C1_EDI 5 -#define C1_BYTE 6 \ No newline at end of file diff --git a/3rdparty/zint-2.4.4/backend/code128.c b/3rdparty/zint-2.4.4/backend/code128.c deleted file mode 100644 index fc74c8e..0000000 --- a/3rdparty/zint-2.4.4/backend/code128.c +++ /dev/null @@ -1,997 +0,0 @@ -/* code128.c - Handles Code 128 and derivatives */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - Bugfixes thanks to Christian Sakowski and BogDan Vatra - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "gs1.h" - -#define TRUE 1 -#define FALSE 0 -#define SHIFTA 90 -#define LATCHA 91 -#define SHIFTB 92 -#define LATCHB 93 -#define SHIFTC 94 -#define LATCHC 95 -#define AORB 96 -#define ABORC 97 - -#define DPDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*" - -static int list[2][170]; - -/* Code 128 tables checked against ISO/IEC 15417:2007 */ - -static char *C128Table[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213", - "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", - "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", - "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", - "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", - "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", - "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", - "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", - "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", - "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", - "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", - "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", - "2331112"}; -/* Code 128 character encodation - Table 1 */ - -int parunmodd(unsigned char llyth) -{ - int modd; - modd = 0; - - if(llyth <= 31) { modd = SHIFTA; } - else if((llyth >= 48) && (llyth <= 57)) { modd = ABORC; } - else if(llyth <= 95) { modd = AORB; } - else if(llyth <= 127) { modd = SHIFTB; } - else if(llyth <= 159) { modd = SHIFTA; } - else if(llyth <= 223) { modd = AORB; } - else { modd = SHIFTB; } - - return modd; -} - -void grwp(int *indexliste) -{ - int i, j; - - /* bring together same type blocks */ - if(*(indexliste) > 1) { - i = 1; - while(i < *(indexliste)) { - if(list[1][i - 1] == list[1][i]) { - /* bring together */ - list[0][i - 1] = list[0][i - 1] + list[0][i]; - j = i + 1; - - /* decreace the list */ - while(j < *(indexliste)) { - list[0][j - 1] = list[0][j]; - list[1][j - 1] = list[1][j]; - j++; - } - *(indexliste) = *(indexliste) - 1; - i--; - } - i++; - } - } -} - -void dxsmooth(int *indexliste) -{ /* Implements rules from ISO 15417 Annex E */ - int i, current, last, next, length; - - for(i = 0; i < *(indexliste); i++) { - current = list[1][i]; - length = list[0][i]; - if(i != 0) { last = list[1][i - 1]; } else { last = FALSE; } - if(i != *(indexliste) - 1) { next = list[1][i + 1]; } else { next = FALSE; } - - if(i == 0) { /* first block */ - if((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) { /* Rule 1a */ list[1][i] = LATCHC; } - if(current == ABORC) { - if(length >= 4) {/* Rule 1b */ list[1][i] = LATCHC; } else { list[1][i] = AORB; current = AORB; } - } - if(current == SHIFTA) { /* Rule 1c */ list[1][i] = LATCHA; } - if((current == AORB) && (next == SHIFTA)) { /* Rule 1c */ list[1][i] = LATCHA; current = LATCHA; } - if(current == AORB) { /* Rule 1d */ list[1][i] = LATCHB; } - } else { - if((current == ABORC) && (length >= 4)) { /* Rule 3 */ list[1][i] = LATCHC; current = LATCHC; } - if(current == ABORC) { list[1][i] = AORB; current = AORB; } - if((current == AORB) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == AORB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; } - if((current == AORB) && (next == SHIFTA)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == AORB) && (next == SHIFTB)) { list[1][i] = LATCHB; current = LATCHB; } - if(current == AORB) { list[1][i] = LATCHB; current = LATCHB; } - if((current == SHIFTA) && (length > 1)) { /* Rule 4 */ list[1][i] = LATCHA; current = LATCHA; } - if((current == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; current = LATCHB; } - if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; } - if((current == SHIFTA) && (last == LATCHC)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == SHIFTB) && (last == LATCHC)) { list[1][i] = LATCHB; current = LATCHB; } - } /* Rule 2 is implimented elsewhere, Rule 6 is implied */ - } - grwp(indexliste); - -} - -void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) -{ /* Translate Code 128 Set A characters into barcodes */ - /* This set handles all control characters NULL to US */ - - if(source > 127) { - if(source < 160) { - concat(dest, C128Table[(source - 128) + 64]); - values[(*bar_chars)] = (source - 128) + 64; - } else { - concat(dest, C128Table[(source - 128) - 32]); - values[(*bar_chars)] = (source - 128) - 32; - } - } else { - if(source < 32) { - concat(dest, C128Table[source + 64]); - values[(*bar_chars)] = source + 64; - } else { - concat(dest, C128Table[source - 32]); - values[(*bar_chars)] = source - 32; - } - } - (*bar_chars)++; -} - -void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars) -{ /* Translate Code 128 Set B characters into barcodes */ - /* This set handles all characters which are not part of long numbers and not control characters */ - - if(source > 127) { - concat(dest, C128Table[source - 32 - 128]); - values[(*bar_chars)] = source - 32 - 128; - } else { - concat(dest, C128Table[source - 32]); - values[(*bar_chars)] = source - 32; - } - (*bar_chars)++; -} - -void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int values[], int *bar_chars) -{ /* Translate Code 128 Set C characters into barcodes */ - /* This set handles numbers in a compressed form */ - int weight; - - weight = (10 * ctoi(source_a)) + ctoi(source_b); - concat(dest, C128Table[weight]); - values[(*bar_chars)] = weight; - (*bar_chars)++; -} - -int code_128(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Handle Code 128 and NVE-18 */ - int i, j, k, e_count, values[170] = { 0 }, bar_characters, read, total_sum, nve_check; - int error_number, indexchaine, indexliste, sourcelen, f_state; - char set[170] = { ' ' }, fset[170] = { ' ' }, mode, last_set, last_fset, current_set = ' '; - float glyph_count; - char dest[1000]; - - error_number = 0; - strcpy(dest, ""); - - sourcelen = length; - - j = 0; - e_count = 0; - bar_characters = 0; - nve_check = 0; - f_state = 0; - - if(sourcelen > 160) { - /* This only blocks rediculously long input - the actual length of the - resulting barcode depends on the type of data, so this is trapped later */ - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* Detect extended ASCII characters */ - for(i = 0; i < sourcelen; i++) { - if(source[i] >= 128) - fset[i] = 'f'; - } - fset[i] = '\0'; - - /* Decide when to latch to extended mode - Annex E note 3 */ - j = 0; - for(i = 0; i < sourcelen; i++) { - if(fset[i] == 'f') { - j++; - } else { - j = 0; - } - - if(j >= 5) { - for(k = i; k > (i - 5); k--) { - fset[k] = 'F'; - } - } - - if((j >= 3) && (i == (sourcelen - 1))) { - for(k = i; k > (i - 3); k--) { - fset[k] = 'F'; - } - } - } - - /* Decide if it is worth reverting to 646 encodation for a few characters as described in 4.3.4.2 (d) */ - for(i = 1; i < sourcelen; i++) { - if((fset[i - 1] == 'F') && (fset[i] == ' ')) { - /* Detected a change from 8859-1 to 646 - count how long for */ - for(j = 0; (fset[i + j] == ' ') && ((i + j) < sourcelen); j++); - if((j < 5) || ((j < 3) && ((i + j) == (sourcelen - 1)))) { - /* Uses the same figures recommended by Annex E note 3 */ - /* Change to shifting back rather than latching back */ - for(k = 0; k < j; k++) { - fset[i + k] = 'n'; - } - } - } - } - - /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ - indexliste = 0; - indexchaine = 0; - - mode = parunmodd(source[indexchaine]); - if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { - mode = AORB; - } - - for(i = 0; i < 170; i++) { - list[0][i] = 0; - } - - do { - list[1][indexliste] = mode; - while ((list[1][indexliste] == mode) && (indexchaine < sourcelen)) { - list[0][indexliste]++; - indexchaine++; - mode = parunmodd(source[indexchaine]); - if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { - mode = AORB; - } - } - indexliste++; - } while (indexchaine < sourcelen); - - dxsmooth(&indexliste); - - /* Resolve odd length LATCHC blocks */ - if((list[1][0] == LATCHC) && (list[0][0] & 1)) { - /* Rule 2 */ - list[0][1]++; - list[0][0]--; - if(indexliste == 1) { - list[0][1] = 1; - list[1][1] = LATCHB; - indexliste = 2; - } - } - if(indexliste > 1) { - for(i = 1; i < indexliste; i++) { - if((list[1][i] == LATCHC) && (list[0][i] & 1)) { - /* Rule 3b */ - list[0][i - 1]++; - list[0][i]--; - } - } - } - - /* Put set data into set[] */ - - read = 0; - for(i = 0; i < indexliste; i++) { - for(j = 0; j < list[0][i]; j++) { - switch(list[1][i]) { - case SHIFTA: set[read] = 'a'; break; - case LATCHA: set[read] = 'A'; break; - case SHIFTB: set[read] = 'b'; break; - case LATCHB: set[read] = 'B'; break; - case LATCHC: set[read] = 'C'; break; - } - read++; - } - } - - /* Adjust for strings which start with shift characters - make them latch instead */ - if(set[0] == 'a') { - i = 0; - do { - set[i] = 'A'; - i++; - } while (set[i] == 'a'); - } - - if(set[0] == 'b') { - i = 0; - do { - set[i] = 'B'; - i++; - } while (set[i] == 'b'); - } - - /* Now we can calculate how long the barcode is going to be - and stop it from - being too long */ - last_set = ' '; - last_fset = ' '; - glyph_count = 0.0; - for(i = 0; i < sourcelen; i++) { - if((set[i] == 'a') || (set[i] == 'b')) { - glyph_count = glyph_count + 1.0; - } - if((fset[i] == 'f') || (fset[i] == 'n')) { - glyph_count = glyph_count + 1.0; - } - if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { - if(set[i] != last_set) { - last_set = set[i]; - glyph_count = glyph_count + 1.0; - } - } - if(i == 0) { - if(fset[i] == 'F') { - last_fset = 'F'; - glyph_count = glyph_count + 2.0; - } - } else { - if((fset[i] == 'F') && (fset[i - 1] != 'F')) { - last_fset = 'F'; - glyph_count = glyph_count + 2.0; - } - if((fset[i] != 'F') && (fset[i - 1] == 'F')) { - last_fset = ' '; - glyph_count = glyph_count + 2.0; - } - } - - if(set[i] == 'C') { - glyph_count = glyph_count + 0.5; - } else { - glyph_count = glyph_count + 1.0; - } - } - if(glyph_count > 80.0) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - - /* So now we know what start character to use - we can get on with it! */ - if(symbol->output_options & READER_INIT) { - /* Reader Initialisation mode */ - switch(set[0]) { - case 'A': /* Start A */ - concat(dest, C128Table[103]); - values[0] = 103; - current_set = 'A'; - concat(dest, C128Table[96]); /* FNC3 */ - values[1] = 96; - bar_characters++; - break; - case 'B': /* Start B */ - concat(dest, C128Table[104]); - values[0] = 104; - current_set = 'B'; - concat(dest, C128Table[96]); /* FNC3 */ - values[1] = 96; - bar_characters++; - break; - case 'C': /* Start C */ - concat(dest, C128Table[104]); /* Start B */ - values[0] = 105; - concat(dest, C128Table[96]); /* FNC3 */ - values[1] = 96; - concat(dest, C128Table[99]); /* Code C */ - values[2] = 99; - bar_characters += 2; - current_set = 'C'; - break; - } - } else { - /* Normal mode */ - switch(set[0]) { - case 'A': /* Start A */ - concat(dest, C128Table[103]); - values[0] = 103; - current_set = 'A'; - break; - case 'B': /* Start B */ - concat(dest, C128Table[104]); - values[0] = 104; - current_set = 'B'; - break; - case 'C': /* Start C */ - concat(dest, C128Table[105]); - values[0] = 105; - current_set = 'C'; - break; - } - } - bar_characters++; - last_set = set[0]; - - if(fset[0] == 'F') { - switch(current_set) { - case 'A': - concat(dest, C128Table[101]); - concat(dest, C128Table[101]); - values[bar_characters] = 101; - values[bar_characters + 1] = 101; - break; - case 'B': - concat(dest, C128Table[100]); - concat(dest, C128Table[100]); - values[bar_characters] = 100; - values[bar_characters + 1] = 100; - break; - } - bar_characters += 2; - f_state = 1; - } - - /* Encode the data */ - read = 0; - do { - - if((read != 0) && (set[read] != current_set)) - { /* Latch different code set */ - switch(set[read]) - { - case 'A': concat(dest, C128Table[101]); - values[bar_characters] = 101; - bar_characters++; - current_set = 'A'; - break; - case 'B': concat(dest, C128Table[100]); - values[bar_characters] = 100; - bar_characters++; - current_set = 'B'; - break; - case 'C': concat(dest, C128Table[99]); - values[bar_characters] = 99; - bar_characters++; - current_set = 'C'; - break; - } - } - - if(read != 0) { - if((fset[read] == 'F') && (f_state == 0)) { - /* Latch beginning of extended mode */ - switch(current_set) { - case 'A': - concat(dest, C128Table[101]); - concat(dest, C128Table[101]); - values[bar_characters] = 101; - values[bar_characters + 1] = 101; - break; - case 'B': - concat(dest, C128Table[100]); - concat(dest, C128Table[100]); - values[bar_characters] = 100; - values[bar_characters + 1] = 100; - break; - } - bar_characters += 2; - f_state = 1; - } - if((fset[read] == ' ') && (f_state == 1)) { - /* Latch end of extended mode */ - switch(current_set) { - case 'A': - concat(dest, C128Table[101]); - concat(dest, C128Table[101]); - values[bar_characters] = 101; - values[bar_characters + 1] = 101; - break; - case 'B': - concat(dest, C128Table[100]); - concat(dest, C128Table[100]); - values[bar_characters] = 100; - values[bar_characters + 1] = 100; - break; - } - bar_characters += 2; - f_state = 0; - } - } - - if((fset[read] == 'f') || (fset[read] == 'n')) { - /* Shift to or from extended mode */ - switch(current_set) { - case 'A': - concat(dest, C128Table[101]); /* FNC 4 */ - values[bar_characters] = 101; - break; - case 'B': - concat(dest, C128Table[100]); /* FNC 4 */ - values[bar_characters] = 100; - break; - } - bar_characters++; - } - - if((set[read] == 'a') || (set[read] == 'b')) { - /* Insert shift character */ - concat(dest, C128Table[98]); - values[bar_characters] = 98; - bar_characters++; - } - - switch(set[read]) - { /* Encode data characters */ - case 'a': - case 'A': c128_set_a(source[read], dest, values, &bar_characters); - read++; - break; - case 'b': - case 'B': c128_set_b(source[read], dest, values, &bar_characters); - read++; - break; - case 'C': c128_set_c(source[read], source[read + 1], dest, values, &bar_characters); - read += 2; - break; - } - - } while (read < sourcelen); - - /* check digit calculation */ - total_sum = 0; - /*for(i = 0; i < bar_characters; i++) { - printf("%d\n", values[i]); - }*/ - - for(i = 0; i < bar_characters; i++) - { - if(i > 0) - { - values[i] *= i; - } - total_sum += values[i]; - } - concat(dest, C128Table[total_sum%103]); - - /* Stop character */ - concat(dest, C128Table[106]); - expand(symbol, dest); - return error_number; -} - -int ean_128(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Handle EAN-128 (Now known as GS1-128) */ - int i, j, e_count, values[170], bar_characters, read, total_sum; - int error_number, indexchaine, indexliste; - char set[170], mode, last_set; - float glyph_count; - char dest[1000]; - int separator_row, linkage_flag, c_count; -#ifndef _MSC_VER - char reduced[length + 1]; -#else - char* reduced = (char*)_alloca(length + 1); -#endif - error_number = 0; - strcpy(dest, ""); - linkage_flag = 0; - - j = 0; - e_count = 0; - bar_characters = 0; - separator_row = 0; - - memset(values, 0, sizeof(values)); - memset(set, ' ', sizeof(set)); - - if(length > 160) { - /* This only blocks rediculously long input - the actual length of the - resulting barcode depends on the type of data, so this is trapped later */ - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - for(i = 0; i < length; i++) { - if(source[i] == '\0') { - /* Null characters not allowed! */ - strcpy(symbol->errtxt, "NULL character in input data"); - return ERROR_INVALID_DATA1; - } - } - - /* if part of a composite symbol make room for the separator pattern */ - if(symbol->symbology == BARCODE_EAN128_CC) { - separator_row = symbol->rows; - symbol->row_height[symbol->rows] = 1; - symbol->rows += 1; - } - - if(symbol->input_mode != GS1_MODE) { - /* GS1 data has not been checked yet */ - error_number = gs1_verify(symbol, source, length, reduced); - if(error_number != 0) { return error_number; } - } - - /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ - indexliste = 0; - indexchaine = 0; - - mode = parunmodd(reduced[indexchaine]); - if(reduced[indexchaine] == '[') { - mode = ABORC; - } - - for(i = 0; i < 170; i++) { - list[0][i] = 0; - } - - do { - list[1][indexliste] = mode; - while ((list[1][indexliste] == mode) && (indexchaine < strlen(reduced))) { - list[0][indexliste]++; - indexchaine++; - mode = parunmodd(reduced[indexchaine]); - if(reduced[indexchaine] == '[') { mode = ABORC; } - } - indexliste++; - } while (indexchaine < strlen(reduced)); - - dxsmooth(&indexliste); - - /* Put set data into set[] */ - read = 0; - for(i = 0; i < indexliste; i++) { - for(j = 0; j < list[0][i]; j++) { - switch(list[1][i]) { - case SHIFTA: set[read] = 'a'; break; - case LATCHA: set[read] = 'A'; break; - case SHIFTB: set[read] = 'b'; break; - case LATCHB: set[read] = 'B'; break; - case LATCHC: set[read] = 'C'; break; - } - read++; - } - } - - /* Watch out for odd-length Mode C blocks */ - c_count = 0; - for(i = 0; i < read; i++) { - if(set[i] == 'C') { - if(reduced[i] == '[') { - if(c_count & 1) { - if((i - c_count) != 0) { - set[i - c_count] = 'B'; - } else { - set[i - 1] = 'B'; - } - } - c_count = 0; - } else { - c_count++; - } - } else { - if(c_count & 1) { - if((i - c_count) != 0) { - set[i - c_count] = 'B'; - } else { - set[i - 1] = 'B'; - } - } - c_count = 0; - } - } - if(c_count & 1) { - if((i - c_count) != 0) { - set[i - c_count] = 'B'; - } else { - set[i - 1] = 'B'; - } - } - for(i = 1; i < read - 1; i++) { - if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { - set[i] = 'B'; - } - } - - /* for(i = 0; i < read; i++) { - printf("char %c mode %c\n", reduced[i], set[i]); - } */ - - /* Now we can calculate how long the barcode is going to be - and stop it from - being too long */ - last_set = ' '; - glyph_count = 0.0; - for(i = 0; i < strlen(reduced); i++) { - if((set[i] == 'a') || (set[i] == 'b')) { - glyph_count = glyph_count + 1.0; - } - if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { - if(set[i] != last_set) { - last_set = set[i]; - glyph_count = glyph_count + 1.0; - } - } - - if((set[i] == 'C') && (reduced[i] != '[')) { - glyph_count = glyph_count + 0.5; - } else { - glyph_count = glyph_count + 1.0; - } - } - if(glyph_count > 80.0) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* So now we know what start character to use - we can get on with it! */ - switch(set[0]) - { - case 'A': /* Start A */ - concat(dest, C128Table[103]); - values[0] = 103; - break; - case 'B': /* Start B */ - concat(dest, C128Table[104]); - values[0] = 104; - break; - case 'C': /* Start C */ - concat(dest, C128Table[105]); - values[0] = 105; - break; - } - bar_characters++; - - concat(dest, C128Table[102]); - values[1] = 102; - bar_characters++; - - /* Encode the data */ - read = 0; - do { - - if((read != 0) && (set[read] != set[read - 1])) - { /* Latch different code set */ - switch(set[read]) - { - case 'A': concat(dest, C128Table[101]); - values[bar_characters] = 101; - bar_characters++; - break; - case 'B': concat(dest, C128Table[100]); - values[bar_characters] = 100; - bar_characters++; - break; - case 'C': concat(dest, C128Table[99]); - values[bar_characters] = 99; - bar_characters++; - break; - } - } - - if((set[read] == 'a') || (set[read] == 'b')) { - /* Insert shift character */ - concat(dest, C128Table[98]); - values[bar_characters] = 98; - bar_characters++; - } - - if(reduced[read] != '[') { - switch(set[read]) - { /* Encode data characters */ - case 'A': - case 'a': - c128_set_a(reduced[read], dest, values, &bar_characters); - read++; - break; - case 'B': - case 'b': - c128_set_b(reduced[read], dest, values, &bar_characters); - read++; - break; - case 'C': - c128_set_c(reduced[read], reduced[read + 1], dest, values, &bar_characters); - read += 2; - break; - } - } else { - concat(dest, C128Table[102]); - values[bar_characters] = 102; - bar_characters++; - read++; - } - } while (read < strlen(reduced)); - - /* "...note that the linkage flag is an extra code set character between - the last data character and the Symbol Check Character" (GS1 Specification) */ - - /* Linkage flags in GS1-128 are determined by ISO/IEC 24723 section 7.4 */ - - switch(symbol->option_1) { - case 1: - case 2: - /* CC-A or CC-B 2D component */ - switch(set[strlen(reduced) - 1]) { - case 'A': linkage_flag = 100; break; - case 'B': linkage_flag = 99; break; - case 'C': linkage_flag = 101; break; - } - break; - case 3: - /* CC-C 2D component */ - switch(set[strlen(reduced) - 1]) { - case 'A': linkage_flag = 99; break; - case 'B': linkage_flag = 101; break; - case 'C': linkage_flag = 100; break; - } - break; - } - - if(linkage_flag != 0) { - concat(dest, C128Table[linkage_flag]); - values[bar_characters] = linkage_flag; - bar_characters++; - } - - /*for(i = 0; i < bar_characters; i++) { - printf("[%d] ", values[i]); - } - printf("\n");*/ - - /* check digit calculation */ - total_sum = 0; - for(i = 0; i < bar_characters; i++) - { - if(i > 0) - { - values[i] *= i; - - } - total_sum += values[i]; - } - concat(dest, C128Table[total_sum%103]); - values[bar_characters] = total_sum % 103; - bar_characters++; - - /* Stop character */ - concat(dest, C128Table[106]); - values[bar_characters] = 106; - bar_characters++; - expand(symbol, dest); - - /* Add the separator pattern for composite symbols */ - if(symbol->symbology == BARCODE_EAN128_CC) { - for(i = 0; i < symbol->width; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - set_module(symbol, separator_row, i); - } - } - } - - for(i = 0; i < length; i++) { - if((source[i] != '[') && (source[i] != ']')) { - symbol->text[i] = source[i]; - } - if(source[i] == '[') { - symbol->text[i] = '('; - } - if(source[i] == ']') { - symbol->text[i] = ')'; - } - } - - return error_number; -} - -int nve_18(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Add check digit if encoding an NVE18 symbol */ - int error_number, zeroes, i, nve_check, total_sum, sourcelen; - unsigned char ean128_equiv[25]; - - memset(ean128_equiv, 0, 25); - sourcelen = length; - - if(sourcelen > 17) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - zeroes = 17 - sourcelen; - strcpy((char *)ean128_equiv, "[00]"); - memset(ean128_equiv + 4, '0', zeroes); - strcpy((char*)ean128_equiv + 4 + zeroes, (char*)source); - - total_sum = 0; - for(i = sourcelen - 1; i >= 0; i--) - { - total_sum += ctoi(source[i]); - - if(!(i & 1)) { - total_sum += 2 * ctoi(source[i]); - } - } - nve_check = 10 - total_sum % 10; - if(nve_check == 10) { nve_check = 0; } - ean128_equiv[21] = itoc(nve_check); - ean128_equiv[22] = '\0'; - - error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); - - return error_number; -} - -int ean_14(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* EAN-14 - A version of EAN-128 */ - int i, count, check_digit; - int error_number, zeroes; - unsigned char ean128_equiv[20]; - - if(length > 13) { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid character in data"); - return error_number; - } - - zeroes = 13 - length; - strcpy((char*)ean128_equiv, "[01]"); - memset(ean128_equiv + 4, '0', zeroes); - ustrcpy(ean128_equiv + 4 + zeroes, source); - - count = 0; - for (i = length - 1; i >= 0; i--) { - count += ctoi(source[i]); - - if (!(i & 1)) { - count += 2 * ctoi(source[i]); - } - } - check_digit = 10 - (count % 10); - if (check_digit == 10) { check_digit = 0; } - ean128_equiv[17] = itoc(check_digit); - ean128_equiv[18] = '\0'; - - error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/code16k.c b/3rdparty/zint-2.4.4/backend/code16k.c deleted file mode 100644 index 638d786..0000000 --- a/3rdparty/zint-2.4.4/backend/code16k.c +++ /dev/null @@ -1,622 +0,0 @@ -/* code16k.c - Handles Code 16k stacked symbology */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* Updated to comply with BS EN 12323:2005 */ - -/* up to 77 characters or 154 numbers */ - -#include -#include -#include -#include "common.h" - -#define TRUE 1 -#define FALSE 0 -#define SHIFTA 90 -#define LATCHA 91 -#define SHIFTB 92 -#define LATCHB 93 -#define SHIFTC 94 -#define LATCHC 95 -#define AORB 96 -#define ABORC 97 -#define CANDB 98 -#define CANDBB 99 - -static int list[2][170]; - -/* EN 12323 Table 1 - "Code 16K" character encodations */ -static char *C16KTable[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213", - "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", - "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", - "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", - "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", - "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", - "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", - "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", - "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", - "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", - "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", - "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", - "211133"}; - -/* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */ -static char *C16KStartStop[8] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "3112"}; - -/* EN 12323 Table 5 - Start and stop values defining row numbers */ -static int C16KStartValues[16] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}; -static int C16KStopValues[16] = {0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3}; - -void grwp16(int *indexliste) -{ - int i, j; - - /* bring together same type blocks */ - if(*(indexliste) > 1) { - i = 1; - while(i < *(indexliste)) { - if(list[1][i - 1] == list[1][i]) { - /* bring together */ - list[0][i - 1] = list[0][i - 1] + list[0][i]; - j = i + 1; - - /* decreace the list */ - while(j < *(indexliste)) { - list[0][j - 1] = list[0][j]; - list[1][j - 1] = list[1][j]; - j++; - } - *(indexliste) = *(indexliste) - 1; - i--; - } - i++; - } - } -} - -void dxsmooth16(int *indexliste) -{ /* Implements rules from ISO 15417 Annex E */ - int i, current, last, next, length; - - for(i = 0; i < *(indexliste); i++) { - current = list[1][i]; - length = list[0][i]; - if(i != 0) { last = list[1][i - 1]; } else { last = FALSE; } - if(i != *(indexliste) - 1) { next = list[1][i + 1]; } else { next = FALSE; } - - if(i == 0) { /* first block */ - if((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) { /* Rule 1a */ list[1][i] = LATCHC; } - if(current == ABORC) { - if(length >= 4) {/* Rule 1b */ list[1][i] = LATCHC; } else { list[1][i] = AORB; current = AORB; } - } - if(current == SHIFTA) { /* Rule 1c */ list[1][i] = LATCHA; } - if((current == AORB) && (next == SHIFTA)) { /* Rule 1c */ list[1][i] = LATCHA; current = LATCHA; } - if(current == AORB) { /* Rule 1d */ list[1][i] = LATCHB; } - } else { - if((current == ABORC) && (length >= 4)) { /* Rule 3 */ list[1][i] = LATCHC; current = LATCHC; } - if(current == ABORC) { list[1][i] = AORB; current = AORB; } - if((current == AORB) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == AORB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; } - if((current == AORB) && (next == SHIFTA)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == AORB) && (next == SHIFTB)) { list[1][i] = LATCHB; current = LATCHB; } - if(current == AORB) { list[1][i] = LATCHB; current = LATCHB; } - if((current == SHIFTA) && (length > 1)) { /* Rule 4 */ list[1][i] = LATCHA; current = LATCHA; } - if((current == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; current = LATCHB; } - if((current == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; current = LATCHB; } - if((current == SHIFTA) && (last == LATCHC)) { list[1][i] = LATCHA; current = LATCHA; } - if((current == SHIFTB) && (last == LATCHC)) { list[1][i] = LATCHB; current = LATCHB; } - } /* Rule 2 is implimented elsewhere, Rule 6 is implied */ - } - grwp16(indexliste); - -} - -void c16k_set_a(unsigned char source, unsigned int values[], unsigned int *bar_chars) -{ - if(source > 127) { - if(source < 160) { - values[(*bar_chars)] = source + 64 - 128; - } else { - values[(*bar_chars)] = source - 32 - 128; - } - } else { - if(source < 32) { - values[(*bar_chars)] = source + 64; - } else { - values[(*bar_chars)] = source - 32; - } - } - (*bar_chars)++; -} - -void c16k_set_b(unsigned char source, unsigned int values[], unsigned int *bar_chars) -{ - if(source > 127) { - values[(*bar_chars)] = source - 32 - 128; - } else { - values[(*bar_chars)] = source - 32; - } - (*bar_chars)++; -} - -void c16k_set_c(unsigned char source_a, unsigned char source_b, unsigned int values[], unsigned int *bar_chars) -{ - int weight; - - weight = (10 * ctoi(source_a)) + ctoi(source_b); - values[(*bar_chars)] = weight; - (*bar_chars)++; -} - -int code16k(struct zint_symbol *symbol, unsigned char source[], int length) -{ - char width_pattern[100]; - int current_row, rows_needed, flip_flop, looper, first_check, second_check; - int indexliste, indexchaine, pads_needed, f_state; - char set[160] = { ' ' }, fset[160] = { ' ' }, mode, last_set, last_fset, current_set; - unsigned int i, j, k, m, e_count, read, mx_reader, writer; - unsigned int values[160] = { 0 }; - unsigned int bar_characters; - float glyph_count; - int errornum, first_sum, second_sum; - int input_length; - int gs1, c_count; - - errornum = 0; - strcpy(width_pattern, ""); - input_length = length; - - if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } - - if(input_length > 157) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - e_count = 0; - bar_characters = 0; - - /* Detect extended ASCII characters */ - for(i = 0; i < input_length; i++) { - if(source[i] >=128) { - fset[i] = 'f'; - } - } - fset[i] = '\0'; - - /* Decide when to latch to extended mode */ - for(i = 0; i < input_length; i++) { - j = 0; - if(fset[i] == 'f') { - do { - j++; - } while(fset[i + j] == 'f'); - if((j >= 5) || ((j >= 3) && ((i + j) == (input_length - 1)))) { - for(k = 0; k <= j; k++) { - fset[i + k] = 'F'; - } - } - } - } - - /* Decide if it is worth reverting to 646 encodation for a few characters */ - if(input_length > 1) { - for(i = 1; i < input_length; i++) { - if((fset[i - 1] == 'F') && (fset[i] == ' ')) { - /* Detected a change from 8859-1 to 646 - count how long for */ - for(j = 0; (fset[i + j] == ' ') && ((i + j) < input_length); j++); - if((j < 5) || ((j < 3) && ((i + j) == (input_length - 1)))) { - /* Change to shifting back rather than latching back */ - for(k = 0; k < j; k++) { - fset[i + k] = 'n'; - } - } - } - } - } - /* Detect mode A, B and C characters */ - indexliste = 0; - indexchaine = 0; - - mode = parunmodd(source[indexchaine]); - if((gs1) && (source[indexchaine] == '[')) { mode = ABORC; } /* FNC1 */ - - for(i = 0; i < 160; i++) { - list[0][i] = 0; - } - - do { - list[1][indexliste] = mode; - while ((list[1][indexliste] == mode) && (indexchaine < input_length)) { - list[0][indexliste]++; - indexchaine++; - mode = parunmodd(source[indexchaine]); - if((gs1) && (source[indexchaine] == '[')) { mode = ABORC; } /* FNC1 */ - } - indexliste++; - } while (indexchaine < input_length); - - dxsmooth16(&indexliste); - - /* Put set data into set[] */ - read = 0; - for(i = 0; i < indexliste; i++) { - for(j = 0; j < list[0][i]; j++) { - switch(list[1][i]) { - case SHIFTA: set[read] = 'a'; break; - case LATCHA: set[read] = 'A'; break; - case SHIFTB: set[read] = 'b'; break; - case LATCHB: set[read] = 'B'; break; - case LATCHC: set[read] = 'C'; break; - } - read++; - } - } - - /* Adjust for strings which start with shift characters - make them latch instead */ - if(set[0] == 'a') { - i = 0; - do { - set[i] = 'A'; - i++; - } while (set[i] == 'a'); - } - - if(set[0] == 'b') { - i = 0; - do { - set[i] = 'B'; - i++; - } while (set[i] == 'b'); - } - - /* Watch out for odd-length Mode C blocks */ - c_count = 0; - for(i = 0; i < read; i++) { - if(set[i] == 'C') { - if(source[i] == '[') { - if(c_count & 1) { - if((i - c_count) != 0) { - set[i - c_count] = 'B'; - } else { - set[i - 1] = 'B'; - } - } - c_count = 0; - } else { - c_count++; - } - } else { - if(c_count & 1) { - if((i - c_count) != 0) { - set[i - c_count] = 'B'; - } else { - set[i - 1] = 'B'; - } - } - c_count = 0; - } - } - if(c_count & 1) { - if((i - c_count) != 0) { - set[i - c_count] = 'B'; - } else { - set[i - 1] = 'B'; - } - } - for(i = 1; i < read - 1; i++) { - if((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { - set[i] = 'B'; - } - } - - /* Make sure the data will fit in the symbol */ - last_set = ' '; - last_fset = ' '; - glyph_count = 0.0; - for(i = 0; i < input_length; i++) { - if((set[i] == 'a') || (set[i] == 'b')) { - glyph_count = glyph_count + 1.0; - } - if((fset[i] == 'f') || (fset[i] == 'n')) { - glyph_count = glyph_count + 1.0; - } - if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { - if(set[i] != last_set) { - last_set = set[i]; - glyph_count = glyph_count + 1.0; - } - } - if(i == 0) { - if((set[i] == 'B') && (set[1] == 'C')) { - glyph_count = glyph_count - 1.0; - } - if((set[i] == 'B') && (set[1] == 'B')) { - if(set[2] == 'C') { - glyph_count = glyph_count - 1.0; - } - } - if(fset[i] == 'F') { - last_fset = 'F'; - glyph_count = glyph_count + 2.0; - } - } else { - if((fset[i] == 'F') && (fset[i - 1] != 'F')) { - last_fset = 'F'; - glyph_count = glyph_count + 2.0; - } - if((fset[i] != 'F') && (fset[i - 1] == 'F')) { - last_fset = ' '; - glyph_count = glyph_count + 2.0; - } - } - - if((set[i] == 'C') && (!((gs1) && (source[i] == '[')))) { - glyph_count = glyph_count + 0.5; - } else { - glyph_count = glyph_count + 1.0; - } - } - - if((gs1) && (set[0] != 'A')) { - /* FNC1 can be integrated with mode character */ - glyph_count--; - } - - if(glyph_count > 77.0) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* Calculate how tall the symbol will be */ - glyph_count = glyph_count + 2.0; - i = glyph_count; - rows_needed = (i/5); - if(i%5 > 0) { rows_needed++; } - - if(rows_needed == 1) { - rows_needed = 2; - } - - /* start with the mode character - Table 2 */ - m = 0; - switch(set[0]) { - case 'A': m = 0; break; - case 'B': m = 1; break; - case 'C': m = 2; break; - } - - if(symbol->output_options & READER_INIT) { - if(m == 2) { m = 5; } - if(gs1) { - strcpy(symbol->errtxt, "Cannot use both GS1 mode and Reader Initialisation"); - return ERROR_INVALID_OPTION; - } else { - if((set[0] == 'B') && (set[1] == 'C')) { m = 6; } - } - values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ - values[bar_characters + 1] = 96; /* FNC3 */ - bar_characters += 2; - } else { - if(gs1) { - /* Integrate FNC1 */ - switch(set[0]) { - case 'B': m = 3; break; - case 'C': m = 4; break; - } - } else { - if((set[0] == 'B') && (set[1] == 'C')) { m = 5; } - if(((set[0] == 'B') && (set[1] == 'B')) && (set[2] == 'C')) { m = 6; } - } - values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ - bar_characters++; - } - - current_set = set[0]; - f_state = 0; /* f_state remembers if we are in Extended ASCII mode (value 1) or - in ISO/IEC 646 mode (value 0) */ - if(fset[0] == 'F') { - switch(current_set) { - case 'A': - values[bar_characters] = 101; - values[bar_characters + 1] = 101; - break; - case 'B': - values[bar_characters] = 100; - values[bar_characters + 1] = 100; - break; - } - bar_characters += 2; - f_state = 1; - } - - read = 0; - - /* Encode the data */ - do { - - if((read != 0) && (set[read] != set[read - 1])) - { /* Latch different code set */ - switch(set[read]) - { - case 'A': - values[bar_characters] = 101; - bar_characters++; - current_set = 'A'; - break; - case 'B': - values[bar_characters] = 100; - bar_characters++; - current_set = 'B'; - break; - case 'C': - if(!((read == 1) && (set[0] == 'B'))) { /* Not Mode C/Shift B */ - if(!((read == 2) && ((set[0] == 'B') && (set[1] == 'B')))) { - /* Not Mode C/Double Shift B */ - values[bar_characters] = 99; - bar_characters++; - } - } - current_set = 'C'; - break; - } - } - /* printf("tp8\n"); */ - if(read != 0) { - if((fset[read] == 'F') && (f_state == 0)) { - /* Latch beginning of extended mode */ - switch(current_set) { - case 'A': - values[bar_characters] = 101; - values[bar_characters + 1] = 101; - break; - case 'B': - values[bar_characters] = 100; - values[bar_characters + 1] = 100; - break; - } - bar_characters += 2; - f_state = 1; - } - if((fset[read] == ' ') && (f_state == 1)) { - /* Latch end of extended mode */ - switch(current_set) { - case 'A': - values[bar_characters] = 101; - values[bar_characters + 1] = 101; - break; - case 'B': - values[bar_characters] = 100; - values[bar_characters + 1] = 100; - break; - } - bar_characters += 2; - f_state = 0; - } - } - - if((fset[i] == 'f') || (fset[i] == 'n')) { - /* Shift extended mode */ - switch(current_set) { - case 'A': - values[bar_characters] = 101; /* FNC 4 */ - break; - case 'B': - values[bar_characters] = 100; /* FNC 4 */ - break; - } - bar_characters++; - } - - if((set[i] == 'a') || (set[i] == 'b')) { - /* Insert shift character */ - values[bar_characters] = 98; - bar_characters++; - } - - if(!((gs1) && (source[read] == '['))) { - switch(set[read]) - { /* Encode data characters */ - case 'A': - case 'a': - c16k_set_a(source[read], values, &bar_characters); - read++; - break; - case 'B': - case 'b': - c16k_set_b(source[read], values, &bar_characters); - read++; - break; - case 'C': c16k_set_c(source[read], source[read + 1], values, &bar_characters); - read += 2; - break; - } - } else { - values[bar_characters] = 102; - bar_characters++; - read++; - } - /* printf("tp9 read=%d surrent set=%c\n", read, set[read]); */ - } while (read < ustrlen(source)); - - pads_needed = 5 - ((bar_characters + 2) % 5); - if(pads_needed == 5) { - pads_needed = 0; - } - if((bar_characters + pads_needed) < 8) { - pads_needed += 8 - (bar_characters + pads_needed); - } - for(i = 0; i < pads_needed; i++) { - values[bar_characters] = 106; - bar_characters++; - } - - /* Calculate check digits */ - first_sum = 0; - second_sum = 0; - for(i = 0; i < bar_characters; i++) - { - first_sum += (i+2) * values[i]; - second_sum += (i+1) * values[i]; - } - first_check = first_sum % 107; - second_sum += first_check * (bar_characters + 1); - second_check = second_sum % 107; - values[bar_characters] = first_check; - values[bar_characters + 1] = second_check; - bar_characters += 2; - - for(current_row = 0; current_row < rows_needed; current_row++) { - - strcpy(width_pattern, ""); - concat(width_pattern, C16KStartStop[C16KStartValues[current_row]]); - concat(width_pattern, "1"); - for(i = 0; i < 5; i++) { - concat(width_pattern, C16KTable[values[(current_row * 5) + i]]); - /* printf("[%d] ", values[(current_row * 5) + i]); */ - - } - concat(width_pattern, C16KStartStop[C16KStopValues[current_row]]); - /* printf("\n"); */ - - /* Write the information into the symbol */ - writer = 0; - flip_flop = 1; - for (mx_reader = 0; mx_reader < strlen(width_pattern); mx_reader++) { - for(looper = 0; looper < ctoi(width_pattern[mx_reader]); looper++) { - if(flip_flop == 1) { - set_module(symbol, current_row, writer); - writer++; } - else { - writer++; } - } - if(flip_flop == 0) { flip_flop = 1; } else { flip_flop = 0; } - } - symbol->row_height[current_row] = 10; - } - - symbol->rows = rows_needed; - symbol->width = 70; - return errornum; -} - - diff --git a/3rdparty/zint-2.4.4/backend/code49.c b/3rdparty/zint-2.4.4/backend/code49.c deleted file mode 100644 index c90fe10..0000000 --- a/3rdparty/zint-2.4.4/backend/code49.c +++ /dev/null @@ -1,315 +0,0 @@ -/* code49.c - Handles Code 49 */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include "common.h" -#include "code49.h" - -#define INSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%!&*" -/* "!" represents Shift 1 and "&" represents Shift 2, "*" represents FNC1 */ - -int code_49(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int i, j, rows, M, x_count, y_count, z_count, posn_val, local_value, h; - char intermediate[170]; - int codewords[170], codeword_count; - int c_grid[8][8]; /* Refers to table 3 */ - int w_grid[8][4]; /* Refets to table 2 */ - int pad_count = 0; - char pattern[40]; - int gs1; - - if(length > 81) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } - - strcpy(intermediate, gs1 ? "*" : ""); /* FNC1 */ - for(i = 0; i < length; i++) { - if(source[i] > 127) { - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - if(gs1 && (source[i] == '[')) - concat(intermediate, "*"); /* FNC1 */ - else - concat(intermediate, c49_table7[source[i]]); - } - - codeword_count = 0; - i = 0; - h = strlen(intermediate); - do { - if((intermediate[i] >= '0') && (intermediate[i] <= '9')) { - /* Numeric data */ - for(j = 0; (intermediate[i + j] >= '0') && (intermediate[i + j] <= '9'); j++); - if(j >= 5) { - /* Use Numeric Encodation Method */ - int block_count, c; - int block_remain; - int block_value; - - codewords[codeword_count] = 48; /* Numeric Shift */ - codeword_count++; - - block_count = j / 5; - block_remain = j % 5; - - for(c = 0; c < block_count; c++) { - if((c == block_count - 1) && (block_remain == 2)) { - /* Rule (d) */ - block_value = 100000; - block_value += ctoi(intermediate[i]) * 1000; - block_value += ctoi(intermediate[i + 1]) * 100; - block_value += ctoi(intermediate[i + 2]) * 10; - block_value += ctoi(intermediate[i + 3]); - - codewords[codeword_count] = block_value / (48 * 48); - block_value = block_value - (48 * 48) * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value / 48; - block_value = block_value - 48 * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value; - codeword_count++; - i += 4; - block_value = ctoi(intermediate[i]) * 100; - block_value += ctoi(intermediate[i + 1]) * 10; - block_value += ctoi(intermediate[i + 2]); - - codewords[codeword_count] = block_value / 48; - block_value = block_value - 48 * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value; - codeword_count++; - i += 3; - } else { - block_value = ctoi(intermediate[i]) * 10000; - block_value += ctoi(intermediate[i + 1]) * 1000; - block_value += ctoi(intermediate[i + 2]) * 100; - block_value += ctoi(intermediate[i + 3]) * 10; - block_value += ctoi(intermediate[i + 4]); - - codewords[codeword_count] = block_value / (48 * 48); - block_value = block_value - (48 * 48) * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value / 48; - block_value = block_value - 48 * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value; - codeword_count++; - i += 5; - } - } - - switch(block_remain) { - case 1: - /* Rule (a) */ - codewords[codeword_count] = posn(INSET, intermediate[i]); - codeword_count++; - i++; - break; - case 3: - /* Rule (b) */ - block_value = ctoi(intermediate[i]) * 100; - block_value += ctoi(intermediate[i + 1]) * 10; - block_value += ctoi(intermediate[i + 2]); - - codewords[codeword_count] = block_value / 48; - block_value = block_value - 48 * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value; - codeword_count++; - i += 3; - break; - case 4: - /* Rule (c) */ - block_value = 100000; - block_value += ctoi(intermediate[i]) * 1000; - block_value += ctoi(intermediate[i + 1]) * 100; - block_value += ctoi(intermediate[i + 2]) * 10; - block_value += ctoi(intermediate[i + 3]); - - codewords[codeword_count] = block_value / (48 * 48); - block_value = block_value - (48 * 48) * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value / 48; - block_value = block_value - 48 * codewords[codeword_count]; - codeword_count++; - codewords[codeword_count] = block_value; - codeword_count++; - i += 4; - break; - } - if(i < h) { - /* There is more to add */ - codewords[codeword_count] = 48; /* Numeric Shift */ - codeword_count++; - } - } else { - codewords[codeword_count] = posn(INSET, intermediate[i]); - codeword_count++; - i++; - } - } else { - codewords[codeword_count] = posn(INSET, intermediate[i]); - codeword_count++; - i++; - } - } while(i < h); - - switch(codewords[0]) { /* Set starting mode value */ - case 48: M = 2; break; - case 43: M = 4; break; - case 44: M = 5; break; - default: M = 0; break; - } - - if(M != 0) { - for(i = 0; i < codeword_count; i++) { - codewords[i] = codewords[i + 1]; - } - codeword_count--; - } - - if(codeword_count > 49) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* Place codewords in code character array (c grid) */ - rows = 0; - do{ - for(i = 0; i < 7; i++) { - if(((rows * 7) + i) < codeword_count) { - c_grid[rows][i] = codewords[(rows * 7) + i]; - } else { - c_grid[rows][i] = 48; /* Pad */ - pad_count++; - } - } - rows++; - } while ((rows * 7) < codeword_count); - - if((((rows <= 6) && (pad_count < 5))) || (rows > 6) || (rows == 1)) { - /* Add a row */ - for(i = 0; i < 7; i++) { - c_grid[rows][i] = 48; /* Pad */ - } - rows++; - } - - /* Add row count and mode character */ - c_grid[rows - 1][6] = (7 * (rows - 2)) + M; - - /* Add row check character */ - for(i = 0; i < rows - 1; i++) { - int row_sum = 0; - - for(j = 0; j < 7; j++) { - row_sum += c_grid[i][j]; - } - c_grid[i][7] = row_sum % 49; - } - - /* Calculate Symbol Check Characters */ - posn_val = 0; - x_count = c_grid[rows - 1][6] * 20; - y_count = c_grid[rows - 1][6] * 16; - z_count = c_grid[rows - 1][6] * 38; - for(i = 0; i < rows - 1; i++) { - for(j = 0; j < 4; j++) { - local_value = (c_grid[i][2 * j] * 49) + c_grid[i][(2 * j) + 1]; - x_count += c49_x_weight[posn_val] * local_value; - y_count += c49_y_weight[posn_val] * local_value; - z_count += c49_z_weight[posn_val] * local_value; - posn_val++; - } - } - - if(rows > 6) { - /* Add Z Symbol Check */ - c_grid[rows - 1][0] = (z_count % 2401) / 49; - c_grid[rows - 1][1] = (z_count % 2401) % 49; - } - - local_value = (c_grid[rows - 1][0] * 49) + c_grid[rows - 1][1]; - x_count += c49_x_weight[posn_val] * local_value; - y_count += c49_y_weight[posn_val] * local_value; - posn_val++; - - /* Add Y Symbol Check */ - c_grid[rows - 1][2] = (y_count % 2401) / 49; - c_grid[rows - 1][3] = (y_count % 2401) % 49; - - local_value = (c_grid[rows - 1][2] * 49) + c_grid[rows - 1][3]; - x_count += c49_x_weight[posn_val] * local_value; - - /* Add X Symbol Check */ - c_grid[rows - 1][4] = (x_count % 2401) / 49; - c_grid[rows - 1][5] = (x_count % 2401) % 49; - - /* Add last row check character */ - j = 0; - for(i = 0; i < 7; i++) { - j += c_grid[rows - 1][i]; - } - c_grid[rows - 1][7] = j % 49; - - /* Transfer data to symbol character array (w grid) */ - for(i = 0; i < rows; i++) { - for(j = 0; j < 4; j ++) { - w_grid[i][j] = (c_grid[i][2 * j] * 49) + c_grid[i][(2 * j) + 1]; - } - } - - for(i = 0; i < rows; i++) { - strcpy(pattern, "11"); /* Start character */ - for(j = 0; j < 4; j++) { - if(i != (rows - 1)) { - if(c49_table4[i][j] == 'E') { - /* Even Parity */ - concat(pattern, c49_appxe_even[w_grid[i][j]]); - } else { - /* Odd Parity */ - concat(pattern, c49_appxe_odd[w_grid[i][j]]); - } - } else { - /* Last row uses all even parity */ - concat(pattern, c49_appxe_even[w_grid[i][j]]); - } - } - concat(pattern, "4"); /* Stop character */ - - /* Expand into symbol */ - symbol->row_height[i] = 10; - expand(symbol, pattern); - } - - symbol->whitespace_width = 10; - symbol->output_options = BARCODE_BIND; - symbol->border_width = 2; - - return 0; -} diff --git a/3rdparty/zint-2.4.4/backend/code49.h b/3rdparty/zint-2.4.4/backend/code49.h deleted file mode 100644 index 2b27bc1..0000000 --- a/3rdparty/zint-2.4.4/backend/code49.h +++ /dev/null @@ -1,1175 +0,0 @@ -/* code49.h - Code 49 Tables */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* This data set taken from ANSI/AIM-BC6-2000, 4th April 2000 */ - -static char *c49_table7[128] = { - /* Table 7: Code 49 ASCII Chart */ - "! ", "!A", "!B", "!C", "!D", "!E", "!F", "!G", "!H", "!I", "!J", "!K", "!L", - "!M", "!N", "!O", "!P", "!Q", "!R", "!S", "!T", "!U", "!V", "!W", "!X", "!Y", - "!Z", "!1", "!2", "!3", "!4", "!5", " ", "!6", "!7", "!8", "$", "%", "!9", "!0", - "!-", "!.", "!$", "+", "!/", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", - "7", "8", "9", "!+", "&1", "&2", "&3", "&4", "&5", "&6", "A", "B", "C", "D", "E", - "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", - "V", "W", "X", "Y", "Z", "&7", "&8", "&9", "&0", "&-", "&.", "&A", "&B", "&C", - "&D", "&E", "&F", "&G", "&H", "&I", "&J", "&K", "&L", "&M", "&N", "&O", "&P", - "&Q", "&R", "&S", "&T", "&U", "&V", "&W", "&X", "&Y", "&Z", "&$", "&/", "&+", - "&%", "& " -}; - -/* Table 5: Check Character Weighting Values */ -int c49_x_weight[] = { - 1, 9, 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, - 39, 11, 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10 -}; - -int c49_y_weight[] = { - 9, 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, 39, - 11, 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10, 24 -}; - -int c49_z_weight[] = { - 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, 39, 11, - 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10, 24, 30 -}; - -static char *c49_table4[8] = { - /* Table 4: Row Parity Pattern for Code 49 Symbols */ - "OEEO", "EOEO", "OOEE", "EEOO", "OEOE", "EOOE", "OOOO", "EEEE" -}; - -static char *c49_appxe_even[2401] = { - /* Appendix E - Code 49 Encodation Patterns (Even Symbol Character Parity) */ - /* Column 1 */ - "11521132", - "25112131", "14212132", "25121221", "14221222", "12412132", - "23321221", "12421222", "21521221", "15112222", "15121312", - "13312222", "24221311", "13321312", "11512222", "22421311", - "11521312", "25112311", "14212312", "23312311", "12412312", - "21512311", "16121131", "14321131", "12521131", "15212131", - "15221221", "13412131", "13421221", "11612131", "16112221", - "16121311", "14312221", "14321311", "12512221", "12521311", - "15212311", "13412311", "11612311", "11131135", "31131133", - "51131131", "21122134", "41122132", "21131224", "41131222", - "11113135", "31113133", "51113131", "11122225", "31122223", - "51122221", "11131315", "31131313", "51131311", "21113224", - "41113222", "21122314", - /* Column 2 */ - "41122312", "11113315", "31113313", - "51113311", "12131134", "32131132", "21231133", "41231131", - "22122133", "42122131", "11222134", "22131223", "42131221", - "11231224", "31231222", "12113134", "32113132", "12122224", - "32122222", "12131314", "32131312", "21231313", "41231311", - "22113223", "42113221", "11213224", "22122313", "42122311", - "11222314", "31222312", "12113314", "32113312", "21213313", - "41213311", "13131133", "33131131", "22231132", "11331133", - "31331131", "23122132", "12222133", "23131222", "12231223", - "32231221", "21331222", "13113133", "33113131", "13122223", - "33122221", "11313133", "13131313", "33131311", "11322223", - "22231312", "11331313", "31331311", "23113222", "12213223", - /* Column 3 */ - "23122312", "12222313", "32222311", "21322312", "13113313", - "33113311", "22213312", "11313313", "31313311", "14131132", - "23231131", "12331132", "21431131", "24122131", "13222132", - "24131221", "13231222", "11422132", "22331221", "11431222", - "14113132", "14122222", "12313132", "14131312", "12322222", - "23231311", "12331312", "21431311", "24113221", "13213222", - "24122311", "13222312", "11413222", "22322311", "11422312", - "14113312", "23213311", "12313312", "21413311", "15131131", - "13331131", "14222131", "14231221", "12422131", "12431221", - "15113131", "15122221", "13313131", "15131311", "13322221", - "11513131", "13331311", "11522221", "14213221", "14222311", - "12413221", "12422311", "15113311", - /* Column 4 */ - "13313311", "11513311", - "11141134", "31141132", "21132133", "41132131", "21141223", - "41141221", "11123134", "31123132", "11132224", "31132222", - "11141314", "31141312", "21114133", "41114131", "21123223", - "41123221", "21132313", "41132311", "11114224", "31114222", - "11123314", "31123312", "21114313", "41114311", "12141133", - "32141131", "21241132", "22132132", "11232133", "22141222", - "11241223", "31241221", "12123133", "32123131", "12132223", - "32132221", "12141313", "32141311", "21241312", "22114132", - "11214133", "22123222", "11223223", "22132312", "11232313", - "31232311", "12114223", "32114221", "12123313", "32123311", - "21223312", "22114312", "11214313", "31214311", "13141132", - "22241131", - /* Column 5 */ - "11341132", "23132131", "12232132", "23141221", - "12241222", "21341221", "13123132", "13132222", "11323132", - "13141312", "11332222", "22241311", "11341312", "23114131", - "12214132", "23123221", "12223222", "23132311", "12232312", - "21332311", "13114222", "13123312", "11314222", "22223311", - "11323312", "23114311", "12214312", "21314311", "14141131", - "12341131", "13232131", "13241221", "11432131", "14123131", - "14132221", "12323131", "14141311", "12332221", "12341311", - "13214131", "13223221", "11414131", "13232311", "11423221", - "11432311", "14114221", "14123311", "12314221", "12323311", - "13214311", "11414311", "11151133", "31151131", "21142132", - "21151222", "11133133", "31133131", "11142223", - /* Column 6 */ - "31142221", - "11151313", "31151311", "21124132", "21133222", "21142312", - "11115133", "31115131", "11124223", "31124221", "11133313", - "31133311", "21115222", "21124312", "12151132", "21251131", - "22142131", "11242132", "22151221", "11251222", "12133132", - "12142222", "12151312", "21251311", "22124131", "11224132", - "22133221", "11233222", "22142311", "11242312", "12115132", - "12124222", "12133312", "21233311", "22115221", "11215222", - "22124311", "11224312", "13151131", "12242131", "12251221", - "13133131", "13142221", "11333131", "13151311", "11342221", - "12224131", "12233221", "12242311", "13115131", "13124221", - "11315131", "13133311", "11324221", "11333311", "12215221", - "12224311", "11161132", - /* Column 7 */ - "21152131", "21161221", "11143132", - "11152222", "11161312", "21134131", "21143221", "21152311", - "11125132", "11134222", "11143312", "21116131", "21125221", - "21134311", "12161131", "11252131", "12143131", "12152221", - "12161311", "11234131", "11243221", "11252311", "12125131", - "12134221", "12143311", "11216131", "11225221", "11234311", - "11111236", "31111234", "51111232", "21111325", "41111323", - "61111321", "11111416", "31111414", "51111412", "31211143", - "51211141", "12111235", "32111233", "52111231", "21211234", - "41211232", "22111324", "42111322", "11211325", "31211323", - "51211321", "12111415", "32111413", "52111411", "21211414", - "41211412", "12211144", "32211142", "21311143", "41311141", - /* Column 8 */ - "13111234", "33111232", "22211233", "42211231", "11311234", - "31311232", "23111323", "43111321", "12211324", "32211322", - "21311323", "41311321", "13111414", "33111412", "22211413", - "42211411", "11311414", "31311412", "13211143", "33211141", - "22311142", "11411143", "31411141", "14111233", "34111231", - "23211232", "12311233", "32311231", "21411232", "24111322", - "13211323", "33211321", "22311322", "11411323", "31411321", - "14111413", "34111411", "23211412", "12311413", "32311411", - "21411412", "14211142", "23311141", "12411142", "21511141", - "15111232", "24211231", "13311232", "22411231", "11511232", - "25111321", "14211322", "23311321", "12411322", "21511321", - "15111412", "24211411", "13311412", - /* Column 9 */ - "22411411", "11511412", - "15211141", "13411141", "11611141", "16111231", "14311231", - "12511231", "15211321", "13411321", "11611321", "16111411", - "14311411", "12511411", "21121144", "41121142", "11112145", - "31112143", "51112141", "11121235", "31121233", "51121231", - "21112234", "41112232", "21121324", "41121322", "11112325", - "31112323", "51112321", "11121415", "31121413", "51121411", - "21112414", "41112412", "22121143", "42121141", "11221144", - "31221142", "12112144", "32112142", "12121234", "32121232", - "21221233", "41221231", "22112233", "42112231", "11212234", - "22121323", "42121321", "11221324", "31221322", "12112324", - "32112322", "12121414", "32121412", "21221413", "41221411", - "22112413", - /* Column 10 */ - "42112411", "11212414", "31212412", "23121142", - "12221143", "32221141", "21321142", "13112143", "33112141", - "13121233", "33121231", "11312143", "22221232", "11321233", - "31321231", "23112232", "12212233", "23121322", "12221323", - "32221321", "21321322", "13112323", "33112321", "13121413", - "33121411", "11312323", "22221412", "11321413", "31321411", - "23112412", "12212413", "32212411", "21312412", "24121141", - "13221142", "22321141", "11421142", "14112142", "14121232", - "12312142", "23221231", "12321232", "21421231", "24112231", - "13212232", "24121321", "13221322", "11412232", "22321321", - "11421322", "14112322", "14121412", "12312322", "23221411", - "12321412", "21421411", "24112411", "13212412", - /* Column 11 */ - "22312411", - "11412412", "14221141", "12421141", "15112141", "15121231", - "13312141", "13321231", "11512141", "11521231", "14212231", - "14221321", "12412231", "12421321", "15112321", "15121411", - "13312321", "13321411", "11512321", "11521411", "14212411", - "12412411", "21131143", "41131141", "11122144", "31122142", - "11131234", "31131232", "21113143", "41113141", "21122233", - "41122231", "21131323", "41131321", "11113234", "31113232", - "11122324", "31122322", "11131414", "31131412", "21113323", - "41113321", "21122413", "41122411", "11113414", "31113412", - "22131142", "11231143", "31231141", "12122143", "32122141", - "12131233", "32131231", "21231232", "22113142", "11213143", - "22122232", "11222233", - /* Column 12 */ - "22131322", "11231323", "31231321", - "12113233", "32113231", "12122323", "32122321", "12131413", - "32131411", "21231412", "22113322", "11213323", "22122412", - "11222413", "31222411", "12113413", "32113411", "21213412", - "23131141", "12231142", "21331141", "13122142", "13131232", - "11322142", "22231231", "11331232", "23113141", "12213142", - "23122231", "12222232", "23131321", "12231322", "21331321", - "13113232", "13122322", "11313232", "13131412", "11322322", - "22231411", "11331412", "23113321", "12213322", "23122411", - "12222412", "21322411", "13113412", "22213411", "11313412", - "13231141", "11431141", "14122141", "14131231", "12322141", - "12331231", "13213141", "13222231", "11413141", "13231321", - /* Column 13 */ - "11422231", "11431321", "14113231", "14122321", "12313231", - "14131411", "12322321", "12331411", "13213321", "13222411", - "11413321", "11422411", "14113411", "12313411", "21141142", - "11132143", "31132141", "11141233", "31141231", "21123142", - "21132232", "21141322", "11114143", "31114141", "11123233", - "31123231", "11132323", "31132321", "11141413", "31141411", - "21114232", "21123322", "21132412", "11114323", "31114321", - "11123413", "31123411", "22141141", "11241142", "12132142", - "12141232", "21241231", "22123141", "11223142", "22132231", - "11232232", "22141321", "11241322", "12114142", "12123232", - "12132322", "12141412", "21241411", "22114231", "11214232", - "22123321", "11223322", "22132411", - /* Column 14 */ - "11232412", "12114322", - "12123412", "21223411", "12241141", "13132141", "13141231", - "11332141", "11341231", "12223141", "12232231", "12241321", - "13114141", "13123231", "11314141", "13132321", "11323231", - "13141411", "11332321", "11341411", "12214231", "12223321", - "12232411", "13114321", "13123411", "11314321", "11323411", - "21151141", "11142142", "11151232", "21133141", "21142231", - "21151321", "11124142", "11133232", "11142322", "11151412", - "21115141", "21124231", "21133321", "21142411", "11115232", - "11124322", "11133412", "11251141", "12142141", "12151231", - "11233141", "11242231", "11251321", "12124141", "12133231", - "12142321", "12151411", "11215141", "11224231", "11233321", - "11242411", - /* Column 15 */ - "12115231", "12124321", "12133411", "11152141", - "11161231", "11134141", "11143231", "11152321", "11161411", - "11116141", "11125231", "11134321", "11143411", "21111244", - "41111242", "11111335", "31111333", "51111331", "21111424", - "41111422", "11111515", "31111513", "51111511", "21211153", - "41211151", "22111243", "42111241", "11211244", "31211242", - "12111334", "32111332", "21211333", "41211331", "22111423", - "42111421", "11211424", "31211422", "12111514", "32111512", - "21211513", "41211511", "22211152", "11311153", "31311151", - "23111242", "12211243", "32211241", "21311242", "13111333", - "33111331", "22211332", "11311333", "31311331", "23111422", - "12211423", "32211421", "21311422", "13111513", - /* Column 16 */ - "33111511", - "22211512", "11311513", "31311511", "23211151", "12311152", - "21411151", "24111241", "13211242", "22311241", "11411242", - "14111332", "23211331", "12311332", "21411331", "24111421", - "13211422", "22311421", "11411422", "14111512", "23211511", - "12311512", "21411511", "13311151", "11511151", "14211241", - "12411241", "15111331", "13311331", "11511331", "14211421", - "12411421", "15111511", "13311511", "11511511", "31121152", - "21112153", "41112151", "21121243", "41121241", "11112244", - "31112242", "11121334", "31121332", "21112333", "41112331", - "21121423", "41121421", "11112424", "31112422", "11121514", - "31121512", "21112513", "41112511", "12121153", "32121151", - "21221152", "22112152", - /* Column 17 */ - "11212153", "22121242", "11221243", - "31221241", "12112243", "32112241", "12121333", "32121331", - "21221332", "22112332", "11212333", "22121422", "11221423", - "31221421", "12112423", "32112421", "12121513", "32121511", - "21221512", "22112512", "11212513", "31212511", "13121152", - "22221151", "11321152", "23112151", "12212152", "23121241", - "12221242", "21321241", "13112242", "13121332", "11312242", - "22221331", "11321332", "23112331", "12212332", "23121421", - "12221422", "21321421", "13112422", "13121512", "11312422", - "22221511", "11321512", "23112511", "12212512", "21312511", - "14121151", "12321151", "13212151", "13221241", "11412151", - "11421241", "14112241", "14121331", "12312241", "12321331", - /* Column 18 */ - "13212331", "13221421", "11412331", "11421421", "14112421", - "14121511", "12312421", "12321511", "13212511", "11412511", - "11131153", "31131151", "21122152", "21131242", "11113153", - "31113151", "11122243", "31122241", "11131333", "31131331", - "21113242", "21122332", "21131422", "11113333", "31113331", - "11122423", "31122421", "11131513", "31131511", "21113422", - "21122512", "12131152", "21231151", "22122151", "11222152", - "22131241", "11231242", "12113152", "12122242", "12131332", - "21231331", "22113241", "11213242", "22122331", "11222332", - "22131421", "11231422", "12113332", "12122422", "12131512", - "21231511", "22113421", "11213422", "22122511", "11222512", - "13131151", "11331151", "12222151", - /* Column 19 */ - "12231241", "13113151", - "13122241", "11313151", "13131331", "11322241", "11331331", - "12213241", "12222331", "12231421", "13113331", "13122421", - "11313331", "13131511", "11322421", "11331511", "12213421", - "12222511", "11141152", "21132151", "21141241", "11123152", - "11132242", "11141332", "21114151", "21123241", "21132331", - "21141421", "11114242", "11123332", "11132422", "11141512", - "21114331", "21123421", "21132511", "12141151", "11232151", - "11241241", "12123151", "12132241", "12141331", "11214151", - "11223241", "11232331", "11241421", "12114241", "12123331", - "12132421", "12141511", "11214331", "11223421", "11232511", - "11151151", "11133151", "11142241", "11151331", "11115151", - "11124241", - /* Column 20 */ - "11133331", "11142421", "11151511", "11111254", - "31111252", "21111343", "41111341", "11111434", "31111432", - "21111523", "41111521", "11111614", "31111612", "31211161", - "12111253", "32111251", "21211252", "22111342", "11211343", - "31211341", "12111433", "32111431", "21211432", "22111522", - "11211523", "31211521", "12111613", "32111611", "21211612", - "12211162", "21311161", "13111252", "22211251", "11311252", - "23111341", "12211342", "21311341", "13111432", "22211431", - "11311432", "23111521", "12211522", "21311521", "13111612", - "22211611", "11311612", "13211161", "11411161", "14111251", - "12311251", "13211341", "11411341", "14111431", "12311431", - "13211521", "11411521", "14111611", "12311611", - /* Column 21 */ - "21121162", - "11112163", "31112161", "11121253", "31121251", "21112252", - "21121342", "11112343", "31112341", "11121433", "31121431", - "21112432", "21121522", "11112523", "31112521", "11121613", - "31121611", "22121161", "11221162", "12112162", "12121252", - "21221251", "22112251", "11212252", "22121341", "11221342", - "12112342", "12121432", "21221431", "22112431", "11212432", - "22121521", "11221522", "12112522", "12121612", "21221611", - "12221161", "13112161", "13121251", "11312161", "11321251", - "32121115", "52121113", "21221116", "41221114", "61221112", - "22112116", "42112114", "31212115", "51212113", "13121116", - "33121114", "22221115", "42221113", "11321116", "31321114", - "51321112", "23112115", - /* Column 22 */ - "43112113", "12212116", "32212114", - "52212112", "21312115", "41312113", "61312111", "14121115", - "34121113", "23221114", "43221112", "12321115", "32321113", - "52321111", "21421114", "41421112", "24112114", "13212115", - "33212113", "22312114", "42312112", "11412115", "31412113", - "51412111", "15121114", "24221113", "13321114", "33321112", - "22421113", "42421111", "11521114", "31521112", "25112113", - "14212114", "34212112", "23312113", "43312111", "12412114", - "32412112", "21512113", "41512111", "16121113", "25221112", - "14321113", "34321111", "23421112", "12521113", "32521111", - "15212113", "24312112", "13412113", "33412111", "22512112", - "11612113", "31612111", "31131115", "51131113", "21122116", - /* Column 23 */ - "41122114", "61122112", "31113115", "51113113", "12131116", - "32131114", "52131112", "21231115", "41231113", "61231111", - "22122115", "42122113", "11222116", "31222114", "51222112", - "12113116", "32113114", "52113112", "21213115", "41213113", - "61213111", "13131115", "33131113", "22231114", "42231112", - "11331115", "31331113", "51331111", "23122114", "43122112", - "12222115", "32222113", "52222111", "21322114", "41322112", - "13113115", "33113113", "22213114", "42213112", "11313115", - "31313113", "51313111", "14131114", "34131112", "23231113", - "43231111", "12331114", "32331112", "21431113", "41431111", - "24122113", "13222114", "33222112", "22322113", "42322111", - "11422114", "31422112", "14113114", - /* Column 24 */ - "34113112", "23213113", - "43213111", "12313114", "32313112", "21413113", "41413111", - "15131113", "24231112", "13331113", "33331111", "22431112", - "25122112", "14222113", "34222111", "23322112", "12422113", - "32422111", "21522112", "15113113", "24213112", "13313113", - "33313111", "22413112", "11513113", "31513111", "16131112", - "25231111", "14331112", "23431111", "15222112", "24322111", - "13422112", "22522111", "16113112", "25213111", "14313112", - "23413111", "12513112", "21613111", "11141116", "31141114", - "51141112", "21132115", "41132113", "61132111", "11123116", - "31123114", "51123112", "21114115", "41114113", "61114111", - "12141115", "32141113", "52141111", "21241114", "41241112", - "22132114", - /* Column 25 */ - "42132112", "11232115", "31232113", "51232111", - "12123115", "32123113", "52123111", "21223114", "41223112", - "22114114", "42114112", "11214115", "31214113", "51214111", - "13141114", "33141112", "22241113", "42241111", "11341114", - "31341112", "23132113", "43132111", "12232114", "32232112", - "21332113", "41332111", "13123114", "33123112", "22223113", - "42223111", "11323114", "31323112", "23114113", "43114111", - "12214114", "32214112", "21314113", "41314111", "14141113", - "34141111", "23241112", "12341113", "32341111", "24132112", - "13232113", "33232111", "22332112", "11432113", "31432111", - "14123113", "34123111", "23223112", "12323113", "32323111", - "21423112", "24114112", "13214113", "33214111", - /* Column 26 */ - "22314112", - "11414113", "31414111", "15141112", "24241111", "13341112", - "25132111", "14232112", "23332111", "12432112", "15123112", - "24223111", "13323112", "22423111", "11523112", "25114111", - "14214112", "23314111", "12414112", "21514111", "16141111", - "14341111", "15232111", "13432111", "16123111", "14323111", - "12523111", "15214111", "13414111", "11614111", "11151115", - "31151113", "51151111", "21142114", "41142112", "11133115", - "31133113", "51133111", "21124114", "41124112", "11115115", - "31115113", "51115111", "12151114", "32151112", "21251113", - "41251111", "22142113", "42142111", "11242114", "31242112", - "12133114", "32133112", "21233113", "41233111", "22124113", - "42124111", "11224114", - /* Column 27 */ - "31224112", "12115114", "32115112", - "21215113", "41215111", "13151113", "33151111", "22251112", - "23142112", "12242113", "32242111", "21342112", "13133113", - "33133111", "22233112", "11333113", "31333111", "23124112", - "12224113", "32224111", "21324112", "13115113", "33115111", - "22215112", "11315113", "31315111", "14151112", "23251111", - "24142111", "13242112", "22342111", "14133112", "23233111", - "12333112", "21433111", "24124111", "13224112", "22324111", - "11424112", "14115112", "23215111", "12315112", "21415111", - "15151111", "14242111", "15133111", "13333111", "14224111", - "12424111", "15115111", "13315111", "11515111", "11161114", - "31161112", "21152113", "41152111", "11143114", "31143112", - /* Column 28 */ - "21134113", "41134111", "11125114", "31125112", "21116113", - "41116111", "12161113", "32161111", "22152112", "11252113", - "31252111", "12143113", "32143111", "21243112", "22134112", - "11234113", "31234111", "12125113", "32125111", "21225112", - "22116112", "11216113", "31216111", "13161112", "23152111", - "12252112", "13143112", "22243111", "11343112", "23134111", - "12234112", "21334111", "13125112", "22225111", "11325112", - "23116111", "12216112", "21316111", "14161111", "13252111", - "14143111", "12343111", "13234111", "11434111", "14125111", - "12325111", "13216111", "11416111", "31111216", "51111214", - "31211125", "51211123", "32111215", "52111213", "21211216", - "41211214", "61211212", "12211126", - /* Column 29 */ - "32211124", "52211122", - "21311125", "41311123", "61311121", "13111216", "33111214", - "22211215", "42211213", "11311216", "31311214", "51311212", - "13211125", "33211123", "22311124", "42311122", "11411125", - "31411123", "51411121", "14111215", "34111213", "23211214", - "43211212", "12311215", "32311213", "52311211", "21411214", - "41411212", "14211124", "34211122", "23311123", "43311121", - "12411124", "32411122", "21511123", "41511121", "15111214", - "24211213", "13311214", "33311212", "22411213", "42411211", - "11511214", "31511212", "15211123", "24311122", "13411123", - "33411121", "22511122", "11611123", "31611121", "16111213", - "25211212", "14311213", "34311211", "23411212", "12511213", - "32511211", - /* Column 30 */ - "21611212", "21121126", "41121124", "61121122", - "31112125", "51112123", "31121215", "51121213", "21112216", - "41112214", "61112212", "22121125", "42121123", "11221126", - "31221124", "51221122", "12112126", "32112124", "52112122", - "12121216", "32121214", "52121212", "21221215", "41221213", - "61221211", "22112215", "42112213", "11212216", "31212214", - "51212212", "23121124", "43121122", "12221125", "32221123", - "52221121", "21321124", "41321122", "13112125", "33112123", - "13121215", "33121213", "11312125", "22221214", "42221212", - "11321215", "31321213", "51321211", "23112214", "43112212", - "12212215", "32212213", "52212211", "21312214", "41312212", - "24121123", "13221124", "33221122", "22321123", - /* Column 31 */ - "42321121", - "11421124", "31421122", "14112124", "34112122", "14121214", - "34121212", "12312124", "23221213", "43221211", "12321214", - "32321212", "21421213", "41421211", "24112213", "13212214", - "33212212", "22312213", "42312211", "11412214", "31412212", - "25121122", "14221123", "34221121", "23321122", "12421123", - "32421121", "21521122", "15112123", "15121213", "13312123", - "24221212", "13321213", "33321211", "11512123", "22421212", - "11521213", "31521211", "25112212", "14212213", "34212211", - "23312212", "12412213", "32412211", "21512212", "15221122", - "24321121", "13421122", "22521121", "16112122", "16121212", - "14312122", "25221211", "14321212", "12512122", "23421211", - "12521212", "15212212", - /* Column 32 */ - "24312211", "13412212", "22512211", - "11612212", "21131125", "41131123", "61131121", "11122126", - "31122124", "51122122", "11131216", "31131214", "51131212", - "21113125", "41113123", "61113121", "21122215", "41122213", - "61122211", "11113216", "31113214", "51113212", "22131124", - "42131122", "11231125", "31231123", "51231121", "12122125", - "32122123", "52122121", "12131215", "32131213", "52131211", - "21231214", "41231212", "22113124", "42113122", "11213125", - "22122214", "42122212", "11222215", "31222213", "51222211", - "12113215", "32113213", "52113211", "21213214", "41213212", - "23131123", "43131121", "12231124", "32231122", "21331123", - "41331121", "13122124", "33122122", "13131214", "33131212", - /* Column 33 */ - "11322124", "22231213", "42231211", "11331214", "31331212", - "23113123", "43113121", "12213124", "23122213", "43122211", - "12222214", "32222212", "21322213", "41322211", "13113214", - "33113212", "22213213", "42213211", "11313214", "31313212", - "24131122", "13231123", "33231121", "22331122", "11431123", - "31431121", "14122123", "34122121", "14131213", "34131211", - "12322123", "23231212", "12331213", "32331211", "21431212", - "24113122", "13213123", "24122212", "13222213", "33222211", - "11413123", "22322212", "11422213", "31422211", "14113213", - "34113211", "23213212", "12313213", "32313211", "21413212", - "25131121", "14231122", "23331121", "12431122", "15122122", - "15131212", "13322122", "24231211", - /* Column 34 */ - "13331212", "11522122", - "22431211", "25113121", "14213122", "25122211", "14222212", - "12413122", "23322211", "12422212", "21522211", "15113212", - "24213211", "13313212", "22413211", "11513212", "15231121", - "13431121", "16122121", "16131211", "14322121", "14331211", - "12522121", "15213121", "15222211", "13413121", "13422211", - "11613121", "16113211", "14313211", "12513211", "21141124", - "41141122", "11132125", "31132123", "51132121", "11141215", - "31141213", "51141211", "21123124", "41123122", "21132214", - "41132212", "11114125", "31114123", "51114121", "11123215", - "31123213", "51123211", "21114214", "41114212", "22141123", - "42141121", "11241124", "31241122", "12132124", "32132122", - "12141214", - /* Column 35 */ - "32141212", "21241213", "41241211", "22123123", - "42123121", "11223124", "22132213", "42132211", "11232214", - "31232212", "12114124", "32114122", "12123214", "32123212", - "21223213", "41223211", "22114213", "42114211", "11214214", - "31214212", "23141122", "12241123", "32241121", "21341122", - "13132123", "33132121", "13141213", "33141211", "11332123", - "22241212", "11341213", "31341211", "23123122", "12223123", - "23132212", "12232213", "32232211", "21332212", "13114123", - "33114121", "13123213", "33123211", "11314123", "22223212", - "11323213", "31323211", "23114212", "12214213", "32214211", - "21314212", "24141121", "13241122", "22341121", "14132122", - "14141212", "12332122", "23241211", "12341212", - /* Column 36 */ - "24123121", - "13223122", "24132211", "13232212", "11423122", "22332211", - "11432212", "14114122", "14123212", "12314122", "23223211", - "12323212", "21423211", "24114211", "13214212", "22314211", - "11414212", "14241121", "15132121", "15141211", "13332121", - "13341211", "14223121", "14232211", "12423121", "12432211", - "15114121", "15123211", "13314121", "13323211", "11514121", - "11523211", "14214211", "12414211", "21151123", "41151121", - "11142124", "31142122", "11151214", "31151212", "21133123", - "41133121", "21142213", "41142211", "11124124", "31124122", - "11133214", "31133212", "21115123", "41115121", "21124213", - "41124211", "11115214", "31115212", "22151122", "11251123", - "31251121", "12142123", - /* Column 37 */ - "32142121", "12151213", "32151211", - "21251212", "22133122", "11233123", "22142212", "11242213", - "31242211", "12124123", "32124121", "12133213", "32133211", - "21233212", "22115122", "11215123", "22124212", "11224213", - "31224211", "12115213", "32115211", "21215212", "23151121", - "12251122", "13142122", "13151212", "11342122", "22251211", - "23133121", "12233122", "23142211", "12242212", "21342211", - "13124122", "13133212", "11324122", "22233211", "11333212", - "23115121", "12215122", "23124211", "12224212", "21324211", - "13115212", "22215211", "11315212", "13251121", "14142121", - "14151211", "12342121", "13233121", "13242211", "11433121", - "14124121", "14133211", "12324121", "12333211", "13215121", - /* Column 38 */ - "13224211", "11415121", "11424211", "14115211", "12315211", - "21161122", "11152123", "31152121", "11161213", "31161211", - "21143122", "21152212", "11134123", "31134121", "11143213", - "31143211", "21125122", "21134212", "11116123", "31116121", - "11125213", "31125211", "22161121", "12152122", "12161212", - "22143121", "11243122", "22152211", "11252212", "12134122", - "12143212", "21243211", "22125121", "11225122", "22134211", - "11234212", "12116122", "12125212", "21225211", "13152121", - "13161211", "12243121", "12252211", "13134121", "13143211", - "11334121", "11343211", "12225121", "12234211", "13116121", - "13125211", "11316121", "11325211", "21111226", "41111224", - "61111222", "31111315", "51111313", - /* Column 39 */ - "21211135", "41211133", - "61211131", "22111225", "42111223", "11211226", "31211224", - "51211222", "12111316", "32111314", "52111312", "21211315", - "41211313", "61211311", "22211134", "42211132", "11311135", - "31311133", "51311131", "23111224", "43111222", "12211225", - "32211223", "52211221", "21311224", "41311222", "13111315", - "33111313", "22211314", "42211312", "11311315", "31311313", - "51311311", "23211133", "43211131", "12311134", "32311132", - "21411133", "41411131", "24111223", "13211224", "33211222", - "22311223", "42311221", "11411224", "31411222", "14111314", - "34111312", "23211313", "43211311", "12311314", "32311312", - "21411313", "41411311", "24211132", "13311133", "33311131", - "22411132", - /* Column 40 */ - "11511133", "31511131", "25111222", "14211223", - "34211221", "23311222", "12411223", "32411221", "21511222", - "15111313", "24211312", "13311313", "33311311", "22411312", - "11511313", "31511311", "25211131", "14311132", "23411131", - "12511132", "21611131", "15211222", "24311221", "13411222", - "22511221", "11611222", "16111312", "25211311", "14311312", - "23411311", "12511312", "21611311", "31121134", "51121132", - "21112135", "41112133", "61112131", "21121225", "41121223", - "61121221", "11112226", "31112224", "51112222", "11121316", - "31121314", "51121312", "21112315", "41112313", "61112311", - "12121135", "32121133", "52121131", "21221134", "41221132", - "22112134", "42112132", "11212135", "22121224", - /* Column 41 */ - "42121222", - "11221225", "31221223", "51221221", "12112225", "32112223", - "52112221", "12121315", "32121313", "52121311", "21221314", - "41221312", "22112314", "42112312", "11212315", "31212313", - "51212311", "13121134", "33121132", "22221133", "42221131", - "11321134", "31321132", "23112133", "43112131", "12212134", - "23121223", "43121221", "12221224", "32221222", "21321223", - "41321221", "13112224", "33112222", "13121314", "33121312", - "11312224", "22221313", "42221311", "11321314", "31321312", - /* Column 42 */ - "23112313", "43112311", "12212314", "32212312", "21312313", - "41312311", "14121133", "34121131", "23221132", "12321133", - "32321131", "21421132", "24112132", "13212133", "24121222", - "13221223", "33221221", "11412133", "22321222", "11421223", - "31421221", "14112223", "34112221", "14121313", "34121311", - "12312223", "23221312", "12321313", "32321311", "21421312", - "24112312", "13212313", "33212311", "22312312", "11412313", - "31412311", "15121132", "24221131", "13321132", "22421131" -}; - -static char *c49_appxe_odd[2401] = { - /* Appendix E - Code 49 Encodation Patterns (Odd Symbol Character Parity) */ - /* Column 1 */ - "22121116", - "42121114", "31221115", "51221113", "32112115", "52112113", - "21212116", "41212114", "61212112", "23121115", "43121113", - "12221116", "32221114", "52221112", "21321115", "41321113", - "61321111", "13112116", "33112114", "22212115", "42212113", - "11312116", "31312114", "51312112", "24121114", "13221115", - "33221113", "22321114", "42321112", "11421115", "31421113", - "51421111", "14112115", "34112113", "23212114", "43212112", - "12312115", "32312113", "52312111", "21412114", "41412112", - "25121113", "14221114", "34221112", "23321113", "43321111", - "12421114", "32421112", "21521113", "41521111", "15112114", - "24212113", "13312114", "33312112", "22412113", "42412111", - "11512114", "31512112", - /* Column 2 */ - "15221113", "24321112", "13421113", - "33421111", "22521112", "16112113", "25212112", "14312113", - "34312111", "23412112", "12512113", "32512111", "21612112", - "21131116", "41131114", "61131112", "31122115", "51122113", - "21113116", "41113114", "61113112", "22131115", "42131113", - "11231116", "31231114", "51231112", "12122116", "32122114", - "52122112", "21222115", "41222113", "61222111", "22113115", - "42113113", "11213116", "31213114", "51213112", "23131114", - "43131112", "12231115", "32231113", "52231111", "21331114", - "41331112", "13122115", "33122113", "22222114", "42222112", - "11322115", "31322113", "51322111", "23113114", "43113112", - "12213115", "32213113", "52213111", "21313114", "41313112", - /* Column 3 */ - "24131113", "13231114", "33231112", "22331113", "42331111", - "11431114", "31431112", "14122114", "34122112", "23222113", - "43222111", "12322114", "32322112", "21422113", "41422111", - "24113113", "13213114", "33213112", "22313113", "42313111", - "11413114", "31413112", "25131112", "14231113", "34231111", - "23331112", "12431113", "32431111", "15122113", "24222112", - "13322113", "33322111", "22422112", "11522113", "31522111", - "25113112", "14213113", "34213111", "23313112", "12413113", - "32413111", "21513112", "15231112", "24331111", "13431112", - "16122112", "25222111", "14322112", "23422111", "12522112", - "15213112", "24313111", "13413112", "22513111", "11613112", - "21141115", "41141113", "61141111", - /* Column 4 */ - "11132116", "31132114", - "51132112", "21123115", "41123113", "61123111", "11114116", - "31114114", "51114112", "22141114", "42141112", "11241115", - "31241113", "51241111", "12132115", "32132113", "52132111", - "21232114", "41232112", "22123114", "42123112", "11223115", - "31223113", "51223111", "12114115", "32114113", "52114111", - "21214114", "41214112", "23141113", "43141111", "12241114", - "32241112", "21341113", "41341111", "13132114", "33132112", - "22232113", "42232111", "11332114", "31332112", "23123113", - "43123111", "12223114", "32223112", "21323113", "41323111", - "13114114", "33114112", "22214113", "42214111", "11314114", - "31314112", "24141112", "13241113", "33241111", "22341112", - "14132113", - /* Column 5 */ - "34132111", "23232112", "12332113", "32332111", - "21432112", "24123112", "13223113", "33223111", "22323112", - "11423113", "31423111", "14114113", "34114111", "23214112", - "12314113", "32314111", "21414112", "25141111", "14241112", - "23341111", "15132112", "24232111", "13332112", "22432111", - "25123111", "14223112", "23323111", "12423112", "21523111", - "15114112", "24214111", "13314112", "22414111", "11514112", - "15241111", "16132111", "14332111", "15223111", "13423111", - "16114111", "14314111", "12514111", "21151114", "41151112", - "11142115", "31142113", "51142111", "21133114", "41133112", - "11124115", "31124113", "51124111", "21115114", "41115112", - "22151113", "42151111", "11251114", "31251112", - /* Column 6 */ - "12142114", - "32142112", "21242113", "41242111", "22133113", "42133111", - "11233114", "31233112", "12124114", "32124112", "21224113", - "41224111", "22115113", "42115111", "11215114", "31215112", - "23151112", "12251113", "32251111", "13142113", "33142111", - "22242112", "11342113", "31342111", "23133112", "12233113", - "32233111", "21333112", "13124113", "33124111", "22224112", - "11324113", "31324111", "23115112", "12215113", "32215111", - "21315112", "24151111", "13251112", "14142112", "23242111", - "12342112", "24133111", "13233112", "22333111", "11433112", - "14124112", "23224111", "12324112", "21424111", "24115111", - "13215112", "22315111", "11415112", "14251111", "15142111", - "13342111", "14233111", - /* Column 7 */ - "12433111", "15124111", "13324111", - "11524111", "14215111", "12415111", "21161113", "41161111", - "11152114", "31152112", "21143113", "41143111", "11134114", - "31134112", "21125113", "41125111", "11116114", "31116112", - "22161112", "12152113", "32152111", "21252112", "22143112", - "11243113", "31243111", "12134113", "32134111", "21234112", - "22125112", "11225113", "31225111", "12116113", "32116111", - "21216112", "23161111", "13152112", "22252111", "23143111", - "12243112", "21343111", "13134112", "22234111", "11334112", - "23125111", "12225112", "21325111", "13116112", "22216111", - "11316112", "14152111", "13243111", "14134111", "12334111", - "13225111", "11425111", "14116111", "12316111", "41111215", - /* Column 8 */ - "61111213", "21211126", "41211124", "61211122", "22111216", - "42111214", "31211215", "51211213", "22211125", "42211123", - "11311126", "31311124", "51311122", "23111215", "43111213", - "12211216", "32211214", "52211212", "21311215", "41311213", - "61311211", "23211124", "43211122", "12311125", "32311123", - "52311121", "21411124", "41411122", "24111214", "13211215", - "33211213", "22311214", "42311212", "11411215", "31411213", - "51411211", "24211123", "13311124", "33311122", "22411123", - "42411121", "11511124", "31511122", "25111213", "14211214", - "34211212", "23311213", "43311211", "12411214", "32411212", - "21511213", "41511211", "25211122", "14311123", "34311121", - "23411122", "12511123", "32511121", - /* Column 9 */ - "21611122", "15211213", - "24311212", "13411213", "33411211", "22511212", "11611213", - "31611211", "31121125", "51121123", "21112126", "41112124", - "61112122", "21121216", "41121214", "61121212", "31112215", - "51112213", "12121126", "32121124", "52121122", "21221125", - "41221123", "61221121", "22112125", "42112123", "11212126", - "22121215", "42121213", "11221216", "31221214", "51221212", - "12112216", "32112214", "52112212", "21212215", "41212213", - "61212211", "13121125", "33121123", "22221124", "42221122", - "11321125", "31321123", "51321121", "23112124", "43112122", - "12212125", "23121214", "43121212", "12221215", "32221213", - "52221211", "21321214", "41321212", "13112215", "33112213", - "22212214", - /* Column 10 */ - "42212212", "11312215", "31312213", "51312211", - "14121124", "34121122", "23221123", "43221121", "12321124", - "32321122", "21421123", "41421121", "24112123", "13212124", - "24121213", "13221214", "33221212", "11412124", "22321213", - "42321211", "11421214", "31421212", "14112214", "34112212", - "23212213", "43212211", "12312214", "32312212", "21412213", - "41412211", "15121123", "24221122", "13321123", "33321121", - "22421122", "11521123", "31521121", "25112122", "14212123", - "25121212", "14221213", "34221211", "12412123", "23321212", - "12421213", "32421211", "21521212", "15112213", "24212212", - "13312213", "33312211", "22412212", "11512213", "31512211", - "16121122", "25221121", "14321122", "23421121", - /* Column 11 */ - "12521122", - "15212122", "15221212", "13412122", "24321211", "13421212", - "11612122", "22521211", "16112212", "25212211", "14312212", - "23412211", "12512212", "21612211", "11131126", "31131124", - "51131122", "21122125", "41122123", "61122121", "21131215", - "41131213", "61131211", "11113126", "31113124", "51113122", - "11122216", "31122214", "51122212", "21113215", "41113213", - "61113211", "12131125", "32131123", "52131121", "21231124", - "41231122", "22122124", "42122122", "11222125", "22131214", - "42131212", "11231215", "31231213", "51231211", "12113125", - "32113123", "52113121", "12122215", "32122213", "52122211", - "21222214", "41222212", "22113214", "42113212", "11213215", - "31213213", "51213211", - /* Column 12 */ - "13131124", "33131122", "22231123", - "42231121", "11331124", "31331122", "23122123", "43122121", - "12222124", "23131213", "43131211", "12231214", "32231212", - "21331213", "41331211", "13113124", "33113122", "13122214", - "33122212", "11313124", "22222213", "42222211", "11322214", - "31322212", "23113213", "43113211", "12213214", "32213212", - "21313213", "41313211", "14131123", "34131121", "23231122", - "12331123", "32331121", "21431122", "24122122", "13222123", - "24131212", "13231213", "33231211", "11422123", "22331212", - "11431213", "31431211", "14113123", "34113121", "14122213", - "34122211", "12313123", "23222212", "12322213", "32322211", - "21422212", "24113212", "13213213", "33213211", "22313212", - /* Column 13 */ - "11413213", "31413211", "15131122", "24231121", "13331122", - "22431121", "25122121", "14222122", "25131211", "14231212", - "12422122", "23331211", "12431212", "15113122", "15122212", - "13313122", "24222211", "13322212", "11513122", "22422211", - "11522212", "25113211", "14213212", "23313211", "12413212", - "21513211", "16131121", "14331121", "15222121", "15231211", - "13422121", "13431211", "16113121", "16122211", "14313121", - "14322211", "12513121", "12522211", "15213211", "13413211", - "11613211", "11141125", "31141123", "51141121", "21132124", - "41132122", "21141214", "41141212", "11123125", "31123123", - "51123121", "11132215", "31132213", "51132211", "21114124", - "41114122", "21123214", "41123212", - /* Column 14 */ - "11114215", "31114213", - "51114211", "12141124", "32141122", "21241123", "41241121", - "22132123", "42132121", "11232124", "22141213", "42141211", - "11241214", "31241212", "12123124", "32123122", "12132214", - "32132212", "21232213", "41232211", "22114123", "42114121", - "11214124", "22123213", "42123211", "11223214", "31223212", - "12114214", "32114212", "21214213", "41214211", "13141123", - "33141121", "22241122", "11341123", "31341121", "23132122", - "12232123", "23141212", "12241213", "32241211", "21341212", - "13123123", "33123121", "13132213", "33132211", "11323123", - "22232212", "11332213", "31332211", "23114122", "12214123", - "23123212", "12223213", "32223211", "21323212", "13114213", - "33114211", - /* Column 15 */ - "22214212", "11314213", "31314211", "14141122", - "23241121", "12341122", "24132121", "13232122", "24141211", - "13241212", "11432122", "22341211", "14123122", "14132212", - "12323122", "23232211", "12332212", "21432211", "24114121", - "13214122", "24123211", "13223212", "11414122", "22323211", - "11423212", "14114212", "23214211", "12314212", "21414211", - "15141121", "13341121", "14232121", "14241211", "12432121", - "15123121", "15132211", "13323121", "13332211", "11523121", - "14214121", "14223211", "12414121", "12423211", "15114211", - "13314211", "11514211", "11151124", "31151122", "21142123", - "41142121", "21151213", "41151211", "11133124", "31133122", - "11142214", "31142212", "21124123", "41124121", - /* Column 16 */ - "21133213", - "41133211", "11115124", "31115122", "11124214", "31124212", - "21115213", "41115211", "12151123", "32151121", "21251122", - "22142122", "11242123", "22151212", "11251213", "31251211", - "12133123", "32133121", "12142213", "32142211", "21242212", - "22124122", "11224123", "22133212", "11233213", "31233211", - "12115123", "32115121", "12124213", "32124211", "21224212", - "22115212", "11215213", "31215211", "13151122", "22251121", - "23142121", "12242122", "23151211", "12251212", "13133122", - "13142212", "11333122", "22242211", "11342212", "23124121", - "12224122", "23133211", "12233212", "21333211", "13115122", - "13124212", "11315122", "22224211", "11324212", "23115211", - "12215212", "21315211", - /* Column 17 */ - "14151121", "13242121", "13251211", - "14133121", "14142211", "12333121", "12342211", "13224121", - "13233211", "11424121", "11433211", "14115121", "14124211", - "12315121", "12324211", "13215211", "11415211", "11161123", - "31161121", "21152122", "21161212", "11143123", "31143121", - "11152213", "31152211", "21134122", "21143212", "11125123", - "31125121", "11134213", "31134211", "21116122", "21125212", - "12161122", "22152121", "11252122", "22161211", "12143122", - "12152212", "21252211", "22134121", "11234122", "22143211", - "11243212", "12125122", "12134212", "21234211", "22116121", - "11216122", "22125211", "11225212", "13161121", "12252121", - "13143121", "13152211", "11343121", "12234121", "12243211", - /* Column 18 */ - "13125121", "13134211", "11325121", "11334211", "12216121", - "12225211", "31111225", "51111223", "21111316", "41111314", - "61111312", "31211134", "51211132", "12111226", "32111224", - "52111222", "21211225", "41211223", "61211221", "22111315", - "42111313", "11211316", "31211314", "51211312", "12211135", - "32211133", "52211131", "21311134", "41311132", "13111225", - "33111223", "22211224", "42211222", "11311225", "31311223", - "51311221", "23111314", "43111312", "12211315", "32211313", - "52211311", "21311314", "41311312", "13211134", "33211132", - "22311133", "42311131", "11411134", "31411132", "14111224", - "34111222", "23211223", "43211221", "12311224", "32311222", - "21411223", "41411221", "24111313", - /* Column 19 */ - "13211314", "33211312", - "22311313", "42311311", "11411314", "31411312", "14211133", - "34211131", "23311132", "12411133", "32411131", "21511132", - "15111223", "24211222", "13311223", "33311221", "22411222", - "11511223", "31511221", "25111312", "14211313", "34211311", - "23311312", "12411313", "32411311", "21511312", "15211132", - "24311131", "13411132", "22511131", "11611132", "16111222", - "25211221", "14311222", "23411221", "12511222", "21611221", - "15211312", "24311311", "13411312", "22511311", "11611312", - "21121135", "41121133", "61121131", "11112136", "31112134", - "51112132", "11121226", "31121224", "51121222", "21112225", - "41112223", "61112221", "21121315", "41121313", "61121311", - "11112316", - /* Column 20 */ - "31112314", "51112312", "22121134", "42121132", - "11221135", "31221133", "51221131", "12112135", "32112133", - "52112131", "12121225", "32121223", "52121221", "21221224", - "41221222", "22112224", "42112222", "11212225", "22121314", - "42121312", "11221315", "31221313", "51221311", "12112315", - "32112313", "52112311", "21212314", "41212312", "23121133", - "43121131", "12221134", "32221132", "21321133", "41321131", - "13112134", "33112132", "13121224", "33121222", "11312134", - "22221223", "42221221", "11321224", "31321222", "23112223", - "43112221", "12212224", "23121313", "43121311", "12221314", - "32221312", "21321313", "41321311", "13112314", "33112312", - "22212313", "42212311", "11312314", "31312312", - /* Column 21 */ - "24121132", - "13221133", "33221131", "22321132", "11421133", "31421131", - "14112133", "34112131", "14121223", "34121221", "12312133", - "23221222", "12321223", "32321221", "21421222", "24112222", - "13212223", "24121312", "13221313", "33221311", "11412223", - "22321312", "11421313", "31421311", "14112313", "34112311", - "23212312", "12312313", "32312311", "21412312", "25121131", - "14221132", "23321131", "12421132", "21521131", "15112132", - "15121222", "13312132", "24221221", "13321222", "11512132", - "22421221", "11521222", "25112221", "14212222", "25121311", - "14221312", "12412222", "23321311", "12421312", "21521311", - "15112312", "24212311", "13312312", "22412311", "11512312", - "15221131", "13421131", - /* Column 22 */ - "16112131", "16121221", "14312131", - "14321221", "12512131", "12521221", "15212221", "15221311", - "13412221", "13421311", "11612221", "16112311", "14312311", - "12512311", "21131134", "41131132", "11122135", "31122133", - "51122131", "11131225", "31131223", "51131221", "21113134", - "41113132", "21122224", "41122222", "21131314", "41131312", - "11113225", "31113223", "51113221", "11122315", "31122313", - "51122311", "21113314", "41113312", "22131133", "42131131", - "11231134", "31231132", "12122134", "32122132", "12131224", - "32131222", "21231223", "41231221", "22113133", "42113131", - "11213134", "22122223", "42122221", "11222224", "22131313", - "42131311", "11231314", "31231312", "12113224", "32113222", - /* Column 23 */ - "12122314", "32122312", "21222313", "41222311", "22113313", - "42113311", "11213314", "31213312", "23131132", "12231133", - "32231131", "21331132", "13122133", "33122131", "13131223", - "33131221", "11322133", "22231222", "11331223", "31331221", - "23113132", "12213133", "23122222", "12222223", "23131312", - "12231313", "32231311", "21331312", "13113223", "33113221", - "13122313", "33122311", "11313223", "22222312", "11322313", - "31322311", "23113312", "12213313", "32213311", "21313312", - "24131131", "13231132", "22331131", "11431132", "14122132", - "14131222", "12322132", "23231221", "12331222", "21431221", - "24113131", "13213132", "24122221", "13222222", "24131311", - "11413132", "13231312", "11422222", - /* Column 24 */ - "22331311", "11431312", - "14113222", "14122312", "12313222", "23222311", "12322312", - "21422311", "24113311", "13213312", "22313311", "11413312", - "14231131", "12431131", "15122131", "15131221", "13322131", - "13331221", "11522131", "14213131", "14222221", "12413131", - "14231311", "12422221", "12431311", "15113221", "15122311", - "13313221", "13322311", "11513221", "11522311", "14213311", - "12413311", "21141133", "41141131", "11132134", "31132132", - "11141224", "31141222", "21123133", "41123131", "21132223", - "41132221", "21141313", "41141311", "11114134", "31114132", - "11123224", "31123222", "11132314", "31132312", "21114223", - "41114221", "21123313", "41123311", "11114314", "31114312", - "22141132", - /* Column 25 */ - "11241133", "31241131", "12132133", "32132131", - "12141223", "32141221", "21241222", "22123132", "11223133", - "22132222", "11232223", "22141312", "11241313", "31241311", - "12114133", "32114131", "12123223", "32123221", "12132313", - "32132311", "21232312", "22114222", "11214223", "22123312", - "11223313", "31223311", "12114313", "32114311", "21214312", - "23141131", "12241132", "21341131", "13132132", "13141222", - "11332132", "22241221", "11341222", "23123131", "12223132", - "23132221", "12232222", "23141311", "12241312", "21341311", - "13114132", "13123222", "11314132", "13132312", "11323222", - "22232311", "11332312", "23114221", "12214222", "23123311", - "12223312", "21323311", "13114312", "22214311", - /* Column 26 */ - "11314312", - "13241131", "14132131", "14141221", "12332131", "12341221", - "13223131", "13232221", "11423131", "13241311", "11432221", - "14114131", "14123221", "12314131", "14132311", "12323221", - "12332311", "13214221", "13223311", "11414221", "11423311", - "14114311", "12314311", "21151132", "11142133", "31142131", - "11151223", "31151221", "21133132", "21142222", "21151312", - "11124133", "31124131", "11133223", "31133221", "11142313", - "31142311", "21115132", "21124222", "21133312", "11115223", - "31115221", "11124313", "31124311", "22151131", "11251132", - "12142132", "12151222", "21251221", "22133131", "11233132", - "22142221", "11242222", "22151311", "11251312", "12124132", - "12133222", "12142312", - /* Column 27 */ - "21242311", "22115131", "11215132", - "22124221", "11224222", "22133311", "11233312", "12115222", - "12124312", "21224311", "12251131", "13142131", "13151221", - "11342131", "12233131", "12242221", "12251311", "13124131", - "13133221", "11324131", "13142311", "11333221", "11342311", - "12215131", "12224221", "12233311", "13115221", "13124311", - "11315221", "11324311", "21161131", "11152132", "11161222", - "21143131", "21152221", "21161311", "11134132", "11143222", - "11152312", "21125131", "21134221", "21143311", "11116132", - "11125222", "11134312", "12152131", "12161221", "11243131", - "11252221", "12134131", "12143221", "12152311", "11225131", - "11234221", "11243311", "12116131", "12125221", "12134311", - /* Column 28 */ - "21111235", "41111233", "61111231", "11111326", "31111324", - "51111322", "21111415", "41111413", "61111411", "21211144", - "41211142", "22111234", "42111232", "11211235", "31211233", - "51211231", "12111325", "32111323", "52111321", "21211324", - "41211322", "22111414", "42111412", "11211415", "31211413", - "51211411", "22211143", "42211141", "11311144", "31311142", - "23111233", "43111231", "12211234", "32211232", "21311233", - "41311231", "13111324", "33111322", "22211323", "42211321", - "11311324", "31311322", "23111413", "43111411", "12211414", - "32211412", "21311413", "41311411", "23211142", "12311143", - "32311141", "21411142", "24111232", "13211233", "33211231", - "22311232", "11411233", "31411231", - /* Column 29 */ - "14111323", "34111321", - "23211322", "12311323", "32311321", "21411322", "24111412", - "13211413", "33211411", "22311412", "11411413", "31411411", - "24211141", "13311142", "22411141", "11511142", "25111231", - "14211232", "23311231", "12411232", "21511231", "15111322", - "24211321", "13311322", "22411321", "11511322", "25111411", - "14211412", "23311411", "12411412", "21511411", "14311141", - "12511141", "15211231", "13411231", "11611231", "16111321", - "14311321", "12511321", "15211411", "13411411", "11611411", - "31121143", "51121141", "21112144", "41112142", "21121234", - "41121232", "11112235", "31112233", "51112231", "11121325", - "31121323", "51121321", "21112324", "41112322", "21121414", - "41121412", - /* Column 30 */ - "11112415", "31112413", "51112411", "12121144", - "32121142", "21221143", "41221141", "22112143", "42112141", - "11212144", "22121233", "42121231", "11221234", "31221232", - "12112234", "32112232", "12121324", "32121322", "21221323", - "41221321", "22112323", "42112321", "11212324", "22121413", - "42121411", "11221414", "31221412", "12112414", "32112412", - "21212413", "41212411", "13121143", "33121141", "22221142", - "11321143", "31321141", "23112142", "12212143", "23121232", - "12221233", "32221231", "21321232", "13112233", "33112231", - "13121323", "33121321", "11312233", "22221322", "11321323", - "31321321", "23112322", "12212323", "23121412", "12221413", - "32221411", "21321412", "13112413", "33112411", - /* Column 31 */ - "22212412", - "11312413", "31312411", "14121142", "23221141", "12321142", - "21421141", "24112141", "13212142", "24121231", "13221232", - "11412142", "22321231", "11421232", "14112232", "14121322", - "12312232", "23221321", "12321322", "21421321", "24112321", - "13212322", "24121411", "13221412", "11412322", "22321411", - "11421412", "14112412", "23212411", "12312412", "21412411", - "15121141", "13321141", "11521141", "14212141", "14221231", - "12412141", "12421231", "15112231", "15121321", "13312231", - "13321321", "11512231", "11521321", "14212321", "14221411", - "12412321", "12421411", "15112411", "13312411", "11512411", - "11131144", "31131142", "21122143", "41122141", "21131233", - "41131231", "11113144", - /* Column 32 */ - "31113142", "11122234", "31122232", - "11131324", "31131322", "21113233", "41113231", "21122323", - "41122321", "21131413", "41131411", "11113324", "31113322", - "11122414", "31122412", "21113413", "41113411", "12131143", - "32131141", "21231142", "22122142", "11222143", "22131232", - "11231233", "31231231", "12113143", "32113141", "12122233", - "32122231", "12131323", "32131321", "21231322", "22113232", - "11213233", "22122322", "11222323", "22131412", "11231413", - "31231411", "12113323", "32113321", "12122413", "32122411", - "21222412", "22113412", "11213413", "31213411", "13131142", - "22231141", "11331142", "23122141", "12222142", "23131231", - "12231232", "21331231", "13113142", "13122232", "11313142", - /* Column 33 */ - "13131322", "11322232", "22231321", "11331322", "23113231", - "12213232", "23122321", "12222322", "23131411", "12231412", - "21331411", "13113322", "13122412", "11313322", "22222411", - "11322412", "23113411", "12213412", "21313411", "14131141", - "12331141", "13222141", "13231231", "11422141", "11431231", - "14113141", "14122231", "12313141", "14131321", "12322231", - "12331321", "13213231", "13222321", "11413231", "13231411", - "11422321", "11431411", "14113321", "14122411", "12313321", - "12322411", "13213411", "11413411", "11141143", "31141141", - "21132142", "21141232", "11123143", "31123141", "11132233", - "31132231", "11141323", "31141321", "21114142", "21123232", - "21132322", "21141412", "11114233", - /* Column 34 */ - "31114231", "11123323", - "31123321", "11132413", "31132411", "21114322", "21123412", - "12141142", "21241141", "22132141", "11232142", "22141231", - "11241232", "12123142", "12132232", "12141322", "21241321", - "22114141", "11214142", "22123231", "11223232", "22132321", - "11232322", "22141411", "11241412", "12114232", "12123322", - "12132412", "21232411", "22114321", "11214322", "22123411", - "11223412", "13141141", "11341141", "12232141", "12241231", - "13123141", "13132231", "11323141", "13141321", "11332231", - "11341321", "12214141", "12223231", "12232321", "12241411", - "13114231", "13123321", "11314231", "13132411", "11323321", - "11332411", "12214321", "12223411", "11151142", "21142141", - "21151231", - /* Column 35 */ - "11133142", "11142232", "11151322", "21124141", - "21133231", "21142321", "21151411", "11115142", "11124232", - "11133322", "11142412", "21115231", "21124321", "21133411", - "12151141", "11242141", "11251231", "12133141", "12142231", - "12151321", "11224141", "11233231", "11242321", "11251411", - "12115141", "12124231", "12133321", "12142411", "11215231", - "11224321", "11233411", "11161141", "11143141", "11152231", - "11161321", "11125141", "11134231", "11143321", "11152411", - "11111245", "31111243", "51111241", "21111334", "41111332", - "11111425", "31111423", "51111421", "21111514", "41111512", - "31211152", "12111244", "32111242", "21211243", "41211241", - "22111333", "42111331", "11211334", "31211332", - /* Column 36 */ - "12111424", - "32111422", "21211423", "41211421", "22111513", "42111511", - "11211514", "31211512", "12211153", "32211151", "21311152", - "13111243", "33111241", "22211242", "11311243", "31311241", - "23111332", "12211333", "32211331", "21311332", "13111423", - "33111421", "22211422", "11311423", "31311421", "23111512", - "12211513", "32211511", "21311512", "13211152", "22311151", - "11411152", "14111242", "23211241", "12311242", "21411241", - "24111331", "13211332", "22311331", "11411332", "14111422", - "23211421", "12311422", "21411421", "24111511", "13211512", - "22311511", "11411512", "14211151", "12411151", "15111241", - "13311241", "11511241", "14211331", "12411331", "15111421", - "13311421", "11511421", - /* Column 37 */ - "14211511", "12411511", "21121153", - "41121151", "11112154", "31112152", "11121244", "31121242", - "21112243", "41112241", "21121333", "41121331", "11112334", - "31112332", "11121424", "31121422", "21112423", "41112421", - "21121513", "41121511", "11112514", "31112512", "22121152", - "11221153", "31221151", "12112153", "32112151", "12121243", - "32121241", "21221242", "22112242", "11212243", "22121332", - "11221333", "31221331", "12112333", "32112331", "12121423", - "32121421", "21221422", "22112422", "11212423", "22121512", - "11221513", "31221511", "12112513", "32112511", "21212512", - "23121151", "12221152", "21321151", "13112152", "13121242", - "11312152", "22221241", "11321242", "23112241", "12212242", - /* Column 38 */ - "23121331", "12221332", "21321331", "13112332", "13121422", - "11312332", "22221421", "11321422", "23112421", "12212422", - "23121511", "12221512", "21321511", "13112512", "22212511", - "11312512", "13221151", "11421151", "14112151", "14121241", - "12312151", "12321241", "13212241", "13221331", "11412241", - "11421331", "14112331", "14121421", "12312331", "12321421", - "13212421", "13221511", "11412421", "11421511", "14112511", - "12312511", "21131152", "11122153", "31122151", "11131243", - "31131241", "21113152", "21122242", "21131332", "11113243", - "31113241", "11122333", "31122331", "11131423", "31131421", - "21113332", "21122422", "21131512", "11113423", "31113421", - "11122513", "31122511", "22131151", - /* Column 39 */ - "11231152", "12122152", - "12131242", "21231241", "22113151", "11213152", "22122241", - "11222242", "22131331", "11231332", "12113242", "12122332", - "12131422", "21231421", "22113331", "11213332", "22122421", - "11222422", "22131511", "11231512", "12113422", "12122512", - "21222511", "12231151", "13122151", "13131241", "11322151", - "11331241", "12213151", "12222241", "12231331", "13113241", - "13122331", "11313241", "13131421", "11322331", "11331421", - "12213331", "12222421", "12231511", "13113421", "13122511", - "11313421", "11322511", "21141151", "11132152", "11141242", - "21123151", "21132241", "21141331", "11114152", "11123242", - "11132332", "11141422", "21114241", "21123331", "21132421", - "21141511", - /* Column 40 */ - "11114332", "11123422", "11132512", "11241151", - "12132151", "12141241", "11223151", "11232241", "11241331", - "12114151", "12123241", "12132331", "12141421", "11214241", - "11223331", "11232421", "11241511", "12114331", "12123421", - "12132511", "11142151", "11151241", "11124151", "11133241", - "11142331", "11151421", "11115241", "11124331", "11133421", - "11142511", "21111253", "41111251", "11111344", "31111342", - "21111433", "41111431", "11111524", "31111522", "21111613", - "41111611", "21211162", "22111252", "11211253", "31211251", - "12111343", "32111341", "21211342", "22111432", "11211433", - "31211431", "12111523", "32111521", "21211522", "22111612", - "11211613", "31211611", "22211161", "11311162", - /* Column 41 */ - "23111251", - "12211252", "21311251", "13111342", "22211341", "11311342", - "23111431", "12211432", "21311431", "13111522", "22211521", - "11311522", "23111611", "12211612", "21311611", "12311161", - "13211251", "11411251", "14111341", "12311341", "13211431", - "11411431", "14111521", "12311521", "13211611", "11411611", - "31121161", "21112162", "21121252", "11112253", "31112251", - "11121343", "31121341", "21112342", "21121432", "11112433", - "31112431", "11121523", "31121521", "21112522", "21121612", - /* Column 42 */ - "12121162", "21221161", "22112161", "11212162", "22121251", - "11221252", "12112252", "12121342", "21221341", "22112341", - "11212342", "22121431", "11221432", "12112432", "12121522", - "21221521", "22112521", "11212522", "22121611", "11221612", - "13121161", "11321161", "12212161", "12221251", "13112251", - "13121341", "11312251", "11321341", "12212341", "12221431", - "13112431", "13121521", "11312431", "11321521", "12212521", - "12221611", "11131162", "21122161", "21131251", "11113162" -}; diff --git a/3rdparty/zint-2.4.4/backend/common.c b/3rdparty/zint-2.4.4/backend/common.c deleted file mode 100644 index 981902e..0000000 --- a/3rdparty/zint-2.4.4/backend/common.c +++ /dev/null @@ -1,374 +0,0 @@ -/* common.c - Contains functions needed for a number of barcodes */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#include -#include -#include -#include "common.h" - -int ustrlen(unsigned char data[]) { - /* Local replacement for strlen() with unsigned char strings */ - int i; - for (i=0;data[i];i++); - - return i; -} - -void ustrcpy(unsigned char target[], unsigned char source[]) { - /* Local replacement for strcpy() with unsigned char strings */ - int i, len; - - len = ustrlen(source); - for(i = 0; i < len; i++) { - target[i] = source[i]; - } - target[i] = '\0'; -} - -void concat(char dest[], char source[]) -{ /* Concatinates dest[] with the contents of source[], copying /0 as well */ - unsigned int i, j, n; - - j = strlen(dest); - n = strlen(source); - for(i = 0; i <= n; i++) { - dest[i + j] = source[i]; } -} - -void uconcat(unsigned char dest[], unsigned char source[]) -{ /* Concatinates dest[] with the contents of source[], copying /0 as well */ - unsigned int i, j; - - j = ustrlen(dest); - for(i = 0; i <= ustrlen(source); i++) { - dest[i + j] = source[i]; } -} - - -int ctoi(char source) -{ /* Converts a character 0-9 to its equivalent integer value */ - if((source >= '0') && (source <= '9')) - return (source - '0'); - return(source - 'A' + 10); -} - -char itoc(int source) -{ /* Converts an integer value to its hexadecimal character */ - if ((source >= 0) && (source <= 9)) { - return ('0' + source); } - else { - return ('A' + (source - 10)); } -} - -void to_upper(unsigned char source[]) -{ /* Converts lower case characters to upper case in a string source[] */ - unsigned int i, src_len = ustrlen(source); - - for (i = 0; i < src_len; i++) { - if ((source[i] >= 'a') && (source[i] <= 'z')) { - source [i] = (source[i] - 'a') + 'A'; } - } -} - -int is_sane(char test_string[], unsigned char source[], int length) -{ /* Verifies that a string only uses valid characters */ - unsigned int i, j, latch; - unsigned int lt = strlen(test_string); - - for(i = 0; i < length; i++) { - latch = FALSE; - for(j = 0; j < lt; j++) { - if (source[i] == test_string[j]) { - latch = TRUE; - break; - } - } - if (!(latch)) { - return ERROR_INVALID_DATA1; - } - } - - return 0; -} - -int posn(char set_string[], char data) -{ /* Returns the position of data in set_string */ - unsigned int i, n = strlen(set_string); - - for(i = 0; i < n; i++) { - if (data == set_string[i]) { return i; } } - return 0; -} - -void lookup(char set_string[], char *table[], char data, char dest[]) -{ /* Replaces huge switch statements for looking up in tables */ - unsigned int i, n = strlen(set_string); - - for(i = 0; i < n; i++) { - if (data == set_string[i]) { concat(dest, table[i]); } } -} - -int module_is_set(struct zint_symbol *symbol, int y_coord, int x_coord) -{ - return (symbol->encoded_data[y_coord][x_coord / 7] >> (x_coord % 7)) & 1; -#if 0 - switch(x_sub) { - case 0: if((symbol->encoded_data[y_coord][x_char] & 0x01) != 0) { result = 1; } break; - case 1: if((symbol->encoded_data[y_coord][x_char] & 0x02) != 0) { result = 1; } break; - case 2: if((symbol->encoded_data[y_coord][x_char] & 0x04) != 0) { result = 1; } break; - case 3: if((symbol->encoded_data[y_coord][x_char] & 0x08) != 0) { result = 1; } break; - case 4: if((symbol->encoded_data[y_coord][x_char] & 0x10) != 0) { result = 1; } break; - case 5: if((symbol->encoded_data[y_coord][x_char] & 0x20) != 0) { result = 1; } break; - case 6: if((symbol->encoded_data[y_coord][x_char] & 0x40) != 0) { result = 1; } break; - } - - return result; -#endif -} - -void set_module(struct zint_symbol *symbol, int y_coord, int x_coord) -{ - symbol->encoded_data[y_coord][x_coord / 7] |= 1 << (x_coord % 7); -#if 0 - int x_char, x_sub; - - - x_char = x_coord / 7; - x_sub = x_coord % 7; - - switch(x_sub) { - case 0: symbol->encoded_data[y_coord][x_char] += 0x01; break; - case 1: symbol->encoded_data[y_coord][x_char] += 0x02; break; - case 2: symbol->encoded_data[y_coord][x_char] += 0x04; break; - case 3: symbol->encoded_data[y_coord][x_char] += 0x08; break; - case 4: symbol->encoded_data[y_coord][x_char] += 0x10; break; - case 5: symbol->encoded_data[y_coord][x_char] += 0x20; break; - case 6: symbol->encoded_data[y_coord][x_char] += 0x40; break; - } /* The last binary digit is reserved for colour barcodes */ -#endif -} - -void unset_module(struct zint_symbol *symbol, int y_coord, int x_coord) -{ - symbol->encoded_data[y_coord][x_coord / 7] &= ~(1 << (x_coord % 7)); -#if 0 - int x_char, x_sub; - - x_char = x_coord / 7; - x_sub = x_coord % 7; - - switch(x_sub) { - case 0: symbol->encoded_data[y_coord][x_char] -= 0x01; break; - case 1: symbol->encoded_data[y_coord][x_char] -= 0x02; break; - case 2: symbol->encoded_data[y_coord][x_char] -= 0x04; break; - case 3: symbol->encoded_data[y_coord][x_char] -= 0x08; break; - case 4: symbol->encoded_data[y_coord][x_char] -= 0x10; break; - case 5: symbol->encoded_data[y_coord][x_char] -= 0x20; break; - case 6: symbol->encoded_data[y_coord][x_char] -= 0x40; break; - } /* The last binary digit is reserved for colour barcodes */ -#endif -} - -void expand(struct zint_symbol *symbol, char data[]) -{ /* Expands from a width pattern to a bit pattern */ - - unsigned int reader, n = strlen(data); - int writer, i; - char latch; - - writer = 0; - latch = '1'; - - for(reader = 0; reader < n; reader++) { - for(i = 0; i < ctoi(data[reader]); i++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer); } - writer++; - } - - latch = (latch == '1' ? '0' : '1'); - } - - if(symbol->symbology != BARCODE_PHARMA) { - if(writer > symbol->width) { - symbol->width = writer; - } - } else { - /* Pharmacode One ends with a space - adjust for this */ - if(writer > symbol->width + 2) { - symbol->width = writer - 2; - } - } - symbol->rows = symbol->rows + 1; -} - -int is_stackable(int symbology) { - /* Indicates which symbologies can have row binding */ - if(symbology < BARCODE_PDF417) { return 1; } - if(symbology == BARCODE_CODE128B) { return 1; } - if(symbology == BARCODE_ISBNX) { return 1; } - if(symbology == BARCODE_EAN14) { return 1; } - if(symbology == BARCODE_NVE18) { return 1; } - if(symbology == BARCODE_KOREAPOST) { return 1; } - if(symbology == BARCODE_PLESSEY) { return 1; } - if(symbology == BARCODE_TELEPEN_NUM) { return 1; } - if(symbology == BARCODE_ITF14) { return 1; } - if(symbology == BARCODE_CODE32) { return 1; } - - return 0; -} - -int is_extendable(int symbology) { - /* Indicates which symbols can have addon */ - if(symbology == BARCODE_EANX) { return 1; } - if(symbology == BARCODE_UPCA) { return 1; } - if(symbology == BARCODE_UPCE) { return 1; } - if(symbology == BARCODE_ISBNX) { return 1; } - if(symbology == BARCODE_UPCA_CC) { return 1; } - if(symbology == BARCODE_UPCE_CC) { return 1; } - if(symbology == BARCODE_EANX_CC) { return 1; } - - return 0; -} - -int roundup(float input) -{ - float remainder; - int integer_part; - - integer_part = (int)input; - remainder = input - integer_part; - - if(remainder > 0.1) { - integer_part++; - } - - return integer_part; -} - -int istwodigits(unsigned char source[], int position) -{ - if((source[position] >= '0') && (source[position] <= '9')) { - if((source[position + 1] >= '0') && (source[position + 1] <= '9')) { - return 1; - } - } - - return 0; -} - -float froundup(float input) -{ - float fraction, output = 0.0; - - fraction = input - (int)input; - if(fraction > 0.01) { output = (input - fraction) + 1.0; } else { output = input; } - - return output; -} - -int latin1_process(struct zint_symbol *symbol, unsigned char source[], unsigned char preprocessed[], int *length) -{ - int j, i, next; - - /* Convert Unicode to Latin-1 for those symbologies which only support Latin-1 */ - j = 0; - i = 0; - do { - next = -1; - if(source[i] < 128) { - preprocessed[j] = source[i]; - j++; - next = i + 1; - } else { - if(source[i] == 0xC2) { - preprocessed[j] = source[i + 1]; - j++; - next = i + 2; - } - if(source[i] == 0xC3) { - preprocessed[j] = source[i + 1] + 64; - j++; - next = i + 2; - } - } - if(next == -1) { - strcpy(symbol->errtxt, "error: Invalid character in input string (only Latin-1 characters supported)"); - return ERROR_INVALID_DATA1; - } - i = next; - } while(i < *length); - preprocessed[j] = '\0'; - *length = j; - - return 0; -} - -int utf8toutf16(struct zint_symbol *symbol, unsigned char source[], int vals[], int *length) -{ - int bpos, jpos, error_number; - int next; - - bpos = 0; - jpos = 0; - error_number = 0; - next = 0; - - do { - if(source[bpos] <= 0x7f) { - /* 1 byte mode (7-bit ASCII) */ - vals[jpos] = source[bpos]; - next = bpos + 1; - jpos++; - } else { - if((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) { - strcpy(symbol->errtxt, "Corrupt Unicode data"); - return ERROR_INVALID_DATA1; - } - if((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) { - strcpy(symbol->errtxt, "Overlong encoding not supported"); - return ERROR_INVALID_DATA1; - } - - if((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) { - /* 2 byte mode */ - vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f); - next = bpos + 2; - jpos++; - } else - if((source[bpos] >= 0xe0) && (source[bpos] <= 0xef)) { - /* 3 byte mode */ - vals[jpos] = ((source[bpos] & 0x0f) << 12) + ((source[bpos + 1] & 0x3f) << 6) + (source[bpos + 2] & 0x3f); - next = bpos + 3; - jpos ++; - } else - if(source[bpos] >= 0xf0) { - strcpy(symbol->errtxt, "Unicode sequences of more than 3 bytes not supported"); - return ERROR_INVALID_DATA1; - } - } - - bpos = next; - - } while(bpos < *length); - *length = jpos; - - return error_number; -} - diff --git a/3rdparty/zint-2.4.4/backend/common.h b/3rdparty/zint-2.4.4/backend/common.h deleted file mode 100644 index 52bc911..0000000 --- a/3rdparty/zint-2.4.4/backend/common.h +++ /dev/null @@ -1,70 +0,0 @@ -/* common.h - Header for all common functions in common.c */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* Used in some logic */ -#ifndef __COMMON_H -#define __COMMON_H - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -/* The most commonly used set */ -#define NEON "0123456789" - -#include "zint.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -extern int ustrlen(unsigned char source[]); -extern void ustrcpy(unsigned char target[], unsigned char source[]); -extern void concat(char dest[], char source[]); -extern void uconcat(unsigned char dest[], unsigned char source[]); -extern int ctoi(char source); -extern char itoc(int source); -extern void to_upper(unsigned char source[]); -extern int is_sane(char test_string[], unsigned char source[], int length); -extern void lookup(char set_string[], char *table[], char data, char dest[]); -extern int posn(char set_string[], char data); -extern void expand(struct zint_symbol *symbol, char data[]); -extern int is_stackable(int symbology); -extern int is_extendable(int symbology); -extern int roundup(float input); -extern int module_is_set(struct zint_symbol *symbol, int y_coord, int x_coord); -extern void set_module(struct zint_symbol *symbol, int y_coord, int x_coord); -extern void unset_module(struct zint_symbol *symbol, int y_coord, int x_coord); -extern int istwodigits(unsigned char source[], int position); -extern float froundup(float input); -extern int parunmodd(unsigned char llyth); -extern int latin1_process(struct zint_symbol *symbol, unsigned char source[], unsigned char preprocessed[], int *length); -extern int utf8toutf16(struct zint_symbol *symbol, unsigned char source[], int vals[], int *length); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __COMMON_H */ diff --git a/3rdparty/zint-2.4.4/backend/composite.c b/3rdparty/zint-2.4.4/backend/composite.c deleted file mode 100644 index 5b21d13..0000000 --- a/3rdparty/zint-2.4.4/backend/composite.c +++ /dev/null @@ -1,1957 +0,0 @@ -/* composite.c - Handles UCC.EAN Composite Symbols */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* The functions "getBit", "init928" and "encode928" are copyright BSI and are - released with permission under the following terms: - - "Copyright subsists in all BSI publications. BSI also holds the copyright, in the - UK, of the international standardisation bodies. Except as - permitted under the Copyright, Designs and Patents Act 1988 no extract may be - reproduced, stored in a retrieval system or transmitted in any form or by any - means - electronic, photocopying, recording or otherwise - without prior written - permission from BSI. - - "This does not preclude the free use, in the course of implementing the standard, - of necessary details such as symbols, and size, type or grade designations. If these - details are to be used for any other purpose than implementation then the prior - written permission of BSI must be obtained." - - The date of publication for these functions is 31 May 2006 -*/ - -#include -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "large.h" -#include "composite.h" -#include "pdf417.h" -#include "gs1.h" - -#define UINT unsigned short - -extern int general_rules(char field[], char type[]); -extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); -extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); -extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); -extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); -extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); - -static UINT pwr928[69][7]; - -int _min(int first, int second) { - - if(first <= second) - return first; - else - return second; -} - -/* gets bit in bitString at bitPos */ -int getBit(UINT *bitStr, int bitPos) { - return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15))); -} - -/* initialize pwr928 encoding table */ -void init928(void) { - int i, j, v; - int cw[7]; - cw[6] = 1L; - for (i = 5; i >= 0; i--) - cw[i] = 0; - - for (i = 0; i < 7; i++) - pwr928[0][i] = cw[i]; - for (j = 1; j < 69; j++) { - for (v = 0, i = 6; i >= 1; i--) { - v = (2 * cw[i]) + (v / 928); - pwr928[j][i] = cw[i] = v % 928; - } - pwr928[j][0] = cw[0] = (2 * cw[0]) + (v / 928); - } - return; -} - -/* converts bit string to base 928 values, codeWords[0] is highest order */ -int encode928(UINT bitString[], UINT codeWords[], int bitLng) { - int i, j, b, bitCnt, cwNdx, cwCnt, cwLng; - for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) { - bitCnt = _min(bitLng-b, 69); - cwLng += cwCnt = bitCnt/10 + 1; - for (i = 0; i < cwCnt; i++) - codeWords[cwNdx+i] = 0; /* init 0 */ - for (i = 0; i < bitCnt; i++) { - if (getBit(bitString, b+bitCnt-i-1)) { - for (j = 0; j < cwCnt; j++) - codeWords[cwNdx+j] += pwr928[i][j+7-cwCnt]; - } - } - for (i = cwCnt-1; i > 0; i--) { - /* add "carries" */ - codeWords[cwNdx+i-1] += codeWords[cwNdx+i]/928L; - codeWords[cwNdx+i] %= 928L; - } - } - return (cwLng); -} - -int cc_a(struct zint_symbol *symbol, char source[], int cc_width) -{ /* CC-A 2D component */ - int i, strpos, segment, bitlen, cwCnt, variant, rows; - int k, offset, j, total, rsCodeWords[8]; - int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster; - int LeftRAP, RightRAP, CentreRAP, Cluster, dummy[5]; - int writer, flip, loop; - UINT codeWords[28]; - UINT bitStr[13]; - char codebarre[100], pattern[580]; - char local_source[210]; /* A copy of source but with padding zeroes to make 208 bits */ - - variant=0; - - for(i = 0; i < 13; i++) { bitStr[i] = 0; } - for(i = 0; i < 28; i++) { codeWords[i] = 0; } - - bitlen = strlen(source); - - for(i = 0; i < 208; i++) { local_source[i] = '0'; } - for(i = 0; i < bitlen; i++) { local_source[i] = source[i]; } - local_source[208] = '\0'; - - for(segment = 0; segment < 13; segment++) { - strpos = segment * 16; - if(local_source[strpos] == '1') { bitStr[segment] += 0x8000; } - if(local_source[strpos + 1] == '1') { bitStr[segment] += 0x4000; } - if(local_source[strpos + 2] == '1') { bitStr[segment] += 0x2000; } - if(local_source[strpos + 3] == '1') { bitStr[segment] += 0x1000; } - if(local_source[strpos + 4] == '1') { bitStr[segment] += 0x800; } - if(local_source[strpos + 5] == '1') { bitStr[segment] += 0x400; } - if(local_source[strpos + 6] == '1') { bitStr[segment] += 0x200; } - if(local_source[strpos + 7] == '1') { bitStr[segment] += 0x100; } - if(local_source[strpos + 8] == '1') { bitStr[segment] += 0x80; } - if(local_source[strpos + 9] == '1') { bitStr[segment] += 0x40; } - if(local_source[strpos + 10] == '1') { bitStr[segment] += 0x20; } - if(local_source[strpos + 11] == '1') { bitStr[segment] += 0x10; } - if(local_source[strpos + 12] == '1') { bitStr[segment] += 0x08; } - if(local_source[strpos + 13] == '1') { bitStr[segment] += 0x04; } - if(local_source[strpos + 14] == '1') { bitStr[segment] += 0x02; } - if(local_source[strpos + 15] == '1') { bitStr[segment] += 0x01; } - } - - init928(); - /* encode codeWords from bitStr */ - cwCnt = encode928(bitStr, codeWords, bitlen); - - switch(cc_width) { - case 2: - switch(cwCnt) { - case 6: variant = 0; break; - case 8: variant = 1; break; - case 9: variant = 2; break; - case 11: variant = 3; break; - case 12: variant = 4; break; - case 14: variant = 5; break; - case 17: variant = 6; break; - } - break; - case 3: - switch(cwCnt) { - case 8: variant = 7; break; - case 10: variant = 8; break; - case 12: variant = 9; break; - case 14: variant = 10; break; - case 17: variant = 11; break; - } - break; - case 4: - switch(cwCnt) { - case 8: variant = 12; break; - case 11: variant = 13; break; - case 14: variant = 14; break; - case 17: variant = 15; break; - case 20: variant = 16; break; - } - break; - } - - rows = ccaVariants[variant]; - k = ccaVariants[17 + variant]; - offset = ccaVariants[34 + variant]; - - /* Reed-Solomon error correction */ - - for(i = 0; i < 8; i++) { - rsCodeWords[i] = 0; - } - total = 0; - for(i = 0; i < cwCnt; i++) { - total = (codeWords[i] + rsCodeWords[k - 1]) % 929; - for(j = k - 1; j >= 0; j--) { - if(j == 0) { - rsCodeWords[j] = (929 - (total * ccaCoeffs[offset + j]) % 929) % 929; - } else { - rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - (total * ccaCoeffs[offset + j]) % 929) % 929; - } - } - } - - for(j = 0; j < k; j++) { - if(rsCodeWords[j] != 0) { rsCodeWords[j] = 929 - rsCodeWords[j]; } - } - - for(i = k - 1; i >= 0; i--) { - codeWords[cwCnt] = rsCodeWords[i]; - cwCnt++; - } - - /* Place data into table */ - LeftRAPStart = aRAPTable[variant]; - CentreRAPStart = aRAPTable[variant + 17]; - RightRAPStart = aRAPTable[variant + 34]; - StartCluster = aRAPTable[variant + 51] / 3; - - LeftRAP = LeftRAPStart; - CentreRAP = CentreRAPStart; - RightRAP = RightRAPStart; - Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ - - for(i = 0; i < rows; i++) { - strcpy(codebarre, ""); - offset = 929 * Cluster; - for(j = 0; j < 5; j++) { - dummy[j] = 0; - } - for(j = 0; j < cc_width ; j++) { - dummy[j + 1] = codeWords[i * cc_width + j]; - } - /* Copy the data into codebarre */ - concat(codebarre, RAPLR[LeftRAP]); - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[1]]); - concat(codebarre, "1"); - if(cc_width == 3) { - concat(codebarre, RAPC[CentreRAP]); - } - if(cc_width >= 2) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[2]]); - concat(codebarre, "1"); - } - if(cc_width == 4) { - concat(codebarre, RAPC[CentreRAP]); - } - if(cc_width >= 3) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[3]]); - concat(codebarre, "1"); - } - if(cc_width == 4) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[4]]); - concat(codebarre, "1"); - } - concat(codebarre, RAPLR[RightRAP]); - concat(codebarre, "1"); /* stop */ - - /* Now codebarre is a mixture of letters and numbers */ - - writer = 0; - flip = 1; - strcpy(pattern, ""); - for(loop = 0; loop < strlen(codebarre); loop++) { - if((codebarre[loop] >= '0') && (codebarre[loop] <= '9')) { - for(k = 0; k < ctoi(codebarre[loop]); k++) { - if(flip == 0) { - pattern[writer] = '0'; - } else { - pattern[writer] = '1'; - } - writer++; - } - pattern[writer] = '\0'; - if(flip == 0) { - flip = 1; - } else { - flip = 0; - } - } else { - lookup(BRSET, PDFttf, codebarre[loop], pattern); - writer += 5; - } - } - symbol->width = writer; - - /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for(loop = 0; loop < strlen(pattern); loop++) { - if(pattern[loop] == '1') { set_module(symbol, i, loop); } - } - symbol->row_height[i] = 2; - symbol->rows++; - - /* Set up RAPs and Cluster for next row */ - LeftRAP++; - CentreRAP++; - RightRAP++; - Cluster++; - - if(LeftRAP == 53) { - LeftRAP = 1; - } - if(CentreRAP == 53) { - CentreRAP = 1; - } - if(RightRAP == 53) { - RightRAP = 1; - } - if(Cluster == 3) { - Cluster = 0; - } - } - - return 0; -} - -int cc_b(struct zint_symbol *symbol, char source[], int cc_width) -{ /* CC-B 2D component */ - int length, i, binloc; -#ifndef _MSC_VER - unsigned char data_string[(strlen(source) / 8) + 3]; -#else - unsigned char* data_string = (unsigned char*)_alloca((strlen(source) / 8) + 3); -#endif - int chainemc[180], mclength; - int k, j, longueur, mccorrection[50], offset; - int total, dummy[5]; - char codebarre[100], pattern[580]; - int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; - int LeftRAP, CentreRAP, RightRAP, Cluster, writer, flip, loop; - - length = strlen(source) / 8; - - for(i = 0; i < length; i++) { - binloc = i * 8; - - data_string[i] = 0; - if(source[binloc] == '1') { data_string[i] += 0x80; } - if(source[binloc + 1] == '1') { data_string[i] += 0x40; } - if(source[binloc + 2] == '1') { data_string[i] += 0x20; } - if(source[binloc + 3] == '1') { data_string[i] += 0x10; } - if(source[binloc + 4] == '1') { data_string[i] += 0x08; } - if(source[binloc + 5] == '1') { data_string[i] += 0x04; } - if(source[binloc + 6] == '1') { data_string[i] += 0x02; } - if(source[binloc + 7] == '1') { data_string[i] += 0x01; } - } - - - mclength = 0; - - /* "the CC-B component shall have codeword 920 in the first symbol character position" (section 9a) */ - chainemc[mclength] = 920; - mclength++; - - byteprocess(chainemc, &mclength, data_string, 0, length, 0); - - /* Now figure out which variant of the symbol to use and load values accordingly */ - - variant = 0; - - if(cc_width == 2) { - variant = 13; - if(mclength <= 33) { variant = 12; } - if(mclength <= 29) { variant = 11; } - if(mclength <= 24) { variant = 10; } - if(mclength <= 19) { variant = 9; } - if(mclength <= 13) { variant = 8; } - if(mclength <= 8) { variant = 7; } - } - - if(cc_width == 3) { - variant = 23; - if(mclength <= 70) { variant = 22; } - if(mclength <= 58) { variant = 21; } - if(mclength <= 46) { variant = 20; } - if(mclength <= 34) { variant = 19; } - if(mclength <= 24) { variant = 18; } - if(mclength <= 18) { variant = 17; } - if(mclength <= 14) { variant = 16; } - if(mclength <= 10) { variant = 15; } - if(mclength <= 6) { variant = 14; } - } - - if(cc_width == 4) { - variant = 34; - if(mclength <= 108) { variant = 33; } - if(mclength <= 90) { variant = 32; } - if(mclength <= 72) { variant = 31; } - if(mclength <= 54) { variant = 30; } - if(mclength <= 39) { variant = 29; } - if(mclength <= 30) { variant = 28; } - if(mclength <= 24) { variant = 27; } - if(mclength <= 18) { variant = 26; } - if(mclength <= 12) { variant = 25; } - if(mclength <= 8) { variant = 24; } - } - - /* Now we have the variant we can load the data - from here on the same as MicroPDF417 code */ - variant --; - symbol->option_2 = MicroVariants[variant]; /* columns */ - symbol->rows = MicroVariants[variant + 34]; /* rows */ - k = MicroVariants[variant + 68]; /* number of EC CWs */ - longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */ - i = longueur - mclength; /* amount of padding required */ - offset = MicroVariants[variant + 102]; /* coefficient offset */ - - /* We add the padding */ - while (i > 0) { - chainemc[mclength] = 900; - mclength++; - i--; - } - - /* Reed-Solomon error correction */ - longueur = mclength; - for(loop = 0; loop < 50; loop++) { - mccorrection[loop] = 0; - } - total = 0; - for(i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[k - 1]) % 929; - for(j = k - 1; j >= 0; j--) { - if(j == 0) { - mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929; - } else { - mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929; - } - } - } - - for(j = 0; j < k; j++) { - if(mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } - } - /* we add these codes to the string */ - for(i = k - 1; i >= 0; i--) { - chainemc[mclength] = mccorrection[i]; - mclength++; - } - - /* Now get the RAP (Row Address Pattern) start values */ - LeftRAPStart = RAPTable[variant]; - CentreRAPStart = RAPTable[variant + 34]; - RightRAPStart = RAPTable[variant + 68]; - StartCluster = RAPTable[variant + 102] / 3; - - /* That's all values loaded, get on with the encoding */ - - LeftRAP = LeftRAPStart; - CentreRAP = CentreRAPStart; - RightRAP = RightRAPStart; - Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ - - for(i = 0; i < symbol->rows; i++) { - strcpy(codebarre, ""); - offset = 929 * Cluster; - for(j = 0; j < 5; j++) { - dummy[j] = 0; - } - for(j = 0; j < symbol->option_2 ; j++) { - dummy[j + 1] = chainemc[i * symbol->option_2 + j]; - } - /* Copy the data into codebarre */ - concat(codebarre, RAPLR[LeftRAP]); - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[1]]); - concat(codebarre, "1"); - if(cc_width == 3) { - concat(codebarre, RAPC[CentreRAP]); - } - if(cc_width >= 2) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[2]]); - concat(codebarre, "1"); - } - if(cc_width == 4) { - concat(codebarre, RAPC[CentreRAP]); - } - if(cc_width >= 3) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[3]]); - concat(codebarre, "1"); - } - if(cc_width == 4) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[4]]); - concat(codebarre, "1"); - } - concat(codebarre, RAPLR[RightRAP]); - concat(codebarre, "1"); /* stop */ - - /* Now codebarre is a mixture of letters and numbers */ - - writer = 0; - flip = 1; - strcpy(pattern, ""); - for(loop = 0; loop < strlen(codebarre); loop++) { - if((codebarre[loop] >= '0') && (codebarre[loop] <= '9')) { - for(k = 0; k < ctoi(codebarre[loop]); k++) { - if(flip == 0) { - pattern[writer] = '0'; - } else { - pattern[writer] = '1'; - } - writer++; - } - pattern[writer] = '\0'; - if(flip == 0) { - flip = 1; - } else { - flip = 0; - } - } else { - lookup(BRSET, PDFttf, codebarre[loop], pattern); - writer += 5; - } - } - symbol->width = writer; - - /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for(loop = 0; loop < strlen(pattern); loop++) { - if(pattern[loop] == '1') { set_module(symbol, i, loop); } - } - symbol->row_height[i] = 2; - - /* Set up RAPs and Cluster for next row */ - LeftRAP++; - CentreRAP++; - RightRAP++; - Cluster++; - - if(LeftRAP == 53) { - LeftRAP = 1; - } - if(CentreRAP == 53) { - CentreRAP = 1; - } - if(RightRAP == 53) { - RightRAP = 1; - } - if(Cluster == 3) { - Cluster = 0; - } - } - - return 0; -} - -int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level) -{ /* CC-C 2D component - byte compressed PDF417 */ - int length, i, binloc; -#ifndef _MSC_VER - unsigned char data_string[(strlen(source) / 8) + 4]; -#else - unsigned char* data_string = (unsigned char*)_alloca((strlen(source) / 8) + 4); -#endif - int chainemc[1000], mclength, k; - int offset, longueur, loop, total, j, mccorrection[520]; - int c1, c2, c3, dummy[35]; - char codebarre[100], pattern[580]; - - length = strlen(source) / 8; - - for(i = 0; i < length; i++) { - binloc = i * 8; - - data_string[i] = 0; - if(source[binloc] == '1') { data_string[i] += 0x80; } - if(source[binloc + 1] == '1') { data_string[i] += 0x40; } - if(source[binloc + 2] == '1') { data_string[i] += 0x20; } - if(source[binloc + 3] == '1') { data_string[i] += 0x10; } - if(source[binloc + 4] == '1') { data_string[i] += 0x08; } - if(source[binloc + 5] == '1') { data_string[i] += 0x04; } - if(source[binloc + 6] == '1') { data_string[i] += 0x02; } - if(source[binloc + 7] == '1') { data_string[i] += 0x01; } - } - - mclength = 0; - - chainemc[mclength] = 0; /* space for length descriptor */ - mclength++; - chainemc[mclength] = 920; /* CC-C identifier */ - mclength++; - - byteprocess(chainemc, &mclength, data_string, 0, length, 0); - - chainemc[0] = mclength; - - k = 1; - for(i = 1; i <= (ecc_level + 1); i++) - { - k *= 2; - } - - /* 796 - we now take care of the Reed Solomon codes */ - switch(ecc_level) { - case 1: offset = 2; break; - case 2: offset = 6; break; - case 3: offset = 14; break; - case 4: offset = 30; break; - case 5: offset = 62; break; - case 6: offset = 126; break; - case 7: offset = 254; break; - case 8: offset = 510; break; - default: offset = 0; break; - } - - longueur = mclength; - for(loop = 0; loop < 520; loop++) { - mccorrection[loop] = 0; - } - total = 0; - for(i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[k - 1]) % 929; - for(j = k - 1; j >= 0; j--) { - if(j == 0) { - mccorrection[j] = (929 - (total * coefrs[offset + j]) % 929) % 929; - } else { - mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; - } - } - } - - for(j = 0; j < k; j++) { - if(mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } - } - /* we add these codes to the string */ - for(i = k - 1; i >= 0; i--) { - chainemc[mclength] = mccorrection[i]; - mclength++; - } - - /* 818 - The CW string is finished */ - c1 = (mclength / cc_width - 1) / 3; - c2 = ecc_level * 3 + (mclength / cc_width - 1) % 3; - c3 = cc_width - 1; - - /* we now encode each row */ - for(i = 0; i <= (mclength / cc_width) - 1; i++) { - for(j = 0; j < cc_width ; j++) { - dummy[j + 1] = chainemc[i * cc_width + j]; - } - k = (i / 3) * 30; - switch(i % 3) { - /* follows this pattern from US Patent 5,243,655: - Row 0: L0 (row #, # of rows) R0 (row #, # of columns) - Row 1: L1 (row #, security level) R1 (row #, # of rows) - Row 2: L2 (row #, # of columns) R2 (row #, security level) - Row 3: L3 (row #, # of rows) R3 (row #, # of columns) - etc. */ - case 0: - dummy[0] = k + c1; - dummy[cc_width + 1] = k + c3; - break; - case 1: - dummy[0] = k + c2; - dummy[cc_width + 1] = k + c1; - break; - case 2: - dummy[0] = k + c3; - dummy[cc_width + 1] = k + c2; - break; - } - strcpy(codebarre, "+*"); /* Start with a start char and a separator */ - - for(j = 0; j <= cc_width + 1; j++) { - switch(i % 3) { - case 1: offset = 929; /* cluster(3) */ break; - case 2: offset = 1858; /* cluster(6) */ break; - default: offset = 0; /* cluster(0) */ break; - } - concat(codebarre, codagemc[offset + dummy[j]]); - concat(codebarre, "*"); - } - concat(codebarre, "-"); - - strcpy(pattern, ""); - for(loop = 0; loop < strlen(codebarre); loop++) { - lookup(BRSET, PDFttf, codebarre[loop], pattern); - } - for(loop = 0; loop < strlen(pattern); loop++) { - if(pattern[loop] == '1') { set_module(symbol, i, loop); } - } - symbol->row_height[i] = 3; - } - symbol->rows = (mclength / cc_width); - symbol->width = strlen(pattern); - - return 0; -} - -int cc_binary_string(struct zint_symbol *symbol, const char source[], char binary_string[], int cc_mode, int *cc_width, int *ecc, int lin_width) -{ /* Handles all data encodation from section 5 of ISO/IEC 24723 */ - int encoding_method, read_posn, d1, d2, value, alpha_pad; - int i, j, mask, ai_crop, ai_crop_posn, fnc1_latch; - long int group_val; - int ai90_mode, latch, remainder, binary_length; - char date_str[4]; -#ifndef _MSC_VER - char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1]; -#else - char* general_field = (char*)_alloca(strlen(source) + 1); - char* general_field_type = (char*)_alloca(strlen(source) + 1); -#endif - int target_bitsize; - - encoding_method = 1; - read_posn = 0; - ai_crop = 0; - ai_crop_posn = -1; - fnc1_latch = 0; - alpha_pad = 0; - ai90_mode = 0; - *ecc = 0; - value = 0; - target_bitsize = 0; - - if((source[0] == '1') && ((source[1] == '0') || (source[1] == '1') || (source[1] == '7')) && (strlen(source) > 8)) { - /* Source starts (10), (11) or (17) */ - encoding_method = 2; - } - - if((source[0] == '9') && (source[1] == '0')) { - /* Source starts (90) */ - encoding_method = 3; - } - - if(encoding_method == 1) { - concat(binary_string, "0"); - } - - if(encoding_method == 2) { - /* Encoding Method field "10" - date and lot number */ - - concat(binary_string, "10"); - - if(source[1] == '0') { - /* No date data */ - concat(binary_string, "11"); - read_posn = 2; - } else { - /* Production Date (11) or Expiration Date (17) */ - date_str[0] = source[2]; - date_str[1] = source[3]; - date_str[2] = '\0'; - group_val = atoi(date_str) * 384; - - date_str[0] = source[4]; - date_str[1] = source[5]; - group_val += (atoi(date_str) - 1) * 32; - - date_str[0] = source[6]; - date_str[1] = source[7]; - group_val += atoi(date_str); - - mask = 0x8000; - for(j = 0; j < 16; j++) { - if((group_val & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - - if(source[1] == '1') { - /* Production Date AI 11 */ - concat(binary_string, "0"); - } else { - /* Expiration Date AI 17 */ - concat(binary_string, "1"); - } - read_posn = 8; - } - - if((source[read_posn] == '1') && (source[read_posn + 1] == '0')) { - /* Followed by AI 10 - strip this from general field */ - read_posn += 2; - } else { - /* An FNC1 character needs to be inserted in the general field */ - fnc1_latch = 1; - } - } - - if (encoding_method == 3) { - /* Encodation Method field of "11" - AI 90 */ -#ifndef _MSC_VER - char ninety[strlen(source) + 1]; -#else - char* ninety = (char*)_alloca(strlen(source) + 1); -#endif - char numeric_part[4]; - int alpha, alphanum, numeric, test1, test2, test3, next_ai_posn; - int numeric_value, table3_letter, mask; - - /* "This encodation method may be used if an element string with an AI - 90 occurs at the start of the data message, and if the data field - following the two-digit AI 90 starts with an alphanumeric string which - complies with a specific format." (para 5.2.2) */ - - i = 0; - do { - ninety[i] = source[i + 2]; - i++; - } while ((strlen(source) > i + 2) && ('[' != source[i + 2])); - ninety[i] = '\0'; - - /* Find out if the AI 90 data is alphabetic or numeric or both */ - - alpha = 0; - alphanum = 0; - numeric = 0; - - for(i = 0; i < strlen(ninety); i++) { - - if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) { - /* Character is alphabetic */ - alpha += 1; - } - - if ((ninety[i] >= '0') && (ninety[i] <= '9')) { - /* Character is numeric */ - numeric += 1; - } - - switch(ninety[i]) { - case '*': - case ',': - case '-': - case '.': - case '/': alphanum += 1; break; - } - - if (!(((ninety[i] >= '0') && (ninety[i] <= '9')) || ((ninety[i] >= 'A') && (ninety[i] <= 'Z')))) { - if((ninety[i] != '*') && (ninety[i] != ',') && (ninety[i] != '-') && (ninety[i] != '.') && (ninety[i] != '/')) { - /* An Invalid AI 90 character */ - strcpy(symbol->errtxt, "Invalid AI 90 data"); - return ERROR_INVALID_DATA1; - } - } - } - - /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */ - test1 = -1; - for(i = 3; i >= 0; i--) { - if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) { - test1 = i; - } - } - - test2 = 0; - for(i = 0; i < test1; i++) { - if (!((ninety[i] >= '0') && (ninety[i] <= '9'))) { - test2 = 1; - } - } - - /* leading zeros are not permitted */ - test3 = 0; - if((test1 >= 1) && (ninety[0] == '0')) { test3 = 1; } - - if((test1 != -1) && (test2 != 1) && (test3 == 0)) { - /* Encodation method "11" can be used */ - concat(binary_string, "11"); - - numeric -= test1; - alpha --; - - /* Decide on numeric, alpha or alphanumeric mode */ - /* Alpha mode is a special mode for AI 90 */ - - if(alphanum > 0) { - /* Alphanumeric mode */ - concat(binary_string, "0"); - ai90_mode = 1; - } else { - if(alpha > numeric) { - /* Alphabetic mode */ - concat(binary_string, "11"); - ai90_mode = 2; - } else { - /* Numeric mode */ - concat(binary_string, "10"); - ai90_mode = 3; - } - } - - next_ai_posn = 2 + strlen(ninety); - - if(source[next_ai_posn] == '[') { - /* There are more AIs afterwords */ - if((source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) { - /* AI 21 follows */ - ai_crop = 1; - ai_crop_posn = next_ai_posn + 1; - } - - if((source[next_ai_posn + 1] == '8') && (source[next_ai_posn + 2] == '0') && (source[next_ai_posn + 3] == '0') && (source[next_ai_posn + 4] == '4')) { - /* AI 8004 follows */ - ai_crop = 2; - ai_crop_posn = next_ai_posn + 1; - } - } - - switch(ai_crop) { - case 0: concat(binary_string, "0"); break; - case 1: concat(binary_string, "10"); break; - case 2: concat(binary_string, "11"); break; - } - - if(test1 == 0) { - strcpy(numeric_part, "0"); - } else { - for(i = 0; i < test1; i++) { - numeric_part[i] = ninety[i]; - } - numeric_part[i] = '\0'; - } - - numeric_value = atoi(numeric_part); - - table3_letter = -1; - if(numeric_value < 31) { - switch(ninety[test1]) { - case 'B': table3_letter = 0; break; - case 'D': table3_letter = 1; break; - case 'H': table3_letter = 2; break; - case 'I': table3_letter = 3; break; - case 'J': table3_letter = 4; break; - case 'K': table3_letter = 5; break; - case 'L': table3_letter = 6; break; - case 'N': table3_letter = 7; break; - case 'P': table3_letter = 8; break; - case 'Q': table3_letter = 9; break; - case 'R': table3_letter = 10; break; - case 'S': table3_letter = 11; break; - case 'T': table3_letter = 12; break; - case 'V': table3_letter = 13; break; - case 'W': table3_letter = 14; break; - case 'Z': table3_letter = 15; break; - } - } - - if(table3_letter != -1) { - /* Encoding can be done according to 5.2.2 c) 2) */ - /* five bit binary string representing value before letter */ - mask = 0x10; - for(j = 0; j < 5; j++) { - if((numeric_value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - - /* followed by four bit representation of letter from Table 3 */ - mask = 0x08; - for(j = 0; j < 4; j++) { - if((table3_letter & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } else { - /* Encoding is done according to 5.2.2 c) 3) */ - concat(binary_string, "11111"); - /* ten bit representation of number */ - mask = 0x200; - for(j = 0; j < 10; j++) { - if((numeric_value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - - /* five bit representation of ASCII character */ - mask = 0x10; - for(j = 0; j < 5; j++) { - if(((ninety[test1] - 65) & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - read_posn = test1 + 3; - } else { - /* Use general field encodation instead */ - concat(binary_string, "0"); - read_posn = 0; - } - } - - /* Now encode the rest of the AI 90 data field */ - if(ai90_mode == 2) { - /* Alpha encodation (section 5.2.3) */ - do { - if((source[read_posn] >= '0') && (source[read_posn] <= '9')) { - mask = 0x10; - for(j = 0; j < 5; j++) { - if(((source[read_posn] + 4) & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { - mask = 0x20; - for(j = 0; j < 6; j++) { - if(((source[read_posn] - 65) & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if(source[read_posn] == '[') { - concat(binary_string, "11111"); - } - - read_posn++; - } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0')); - alpha_pad = 1; /* This is overwritten if a general field is encoded */ - } - - if(ai90_mode == 1) { - /* Alphanumeric mode */ - do { - if((source[read_posn] >= '0') && (source[read_posn] <= '9')) { - mask = 0x10; - for(j = 0; j < 5; j++) { - if(((source[read_posn] - 43) & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { - mask = 0x20; - for(j = 0; j < 6; j++) { - if(((source[read_posn] - 33) & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - switch(source[read_posn]) { - case '[': concat(binary_string, "01111"); break; - case '*': concat(binary_string, "111010"); break; - case ',': concat(binary_string, "111011"); break; - case '-': concat(binary_string, "111100"); break; - case '.': concat(binary_string, "111101"); break; - case '/': concat(binary_string, "111110"); break; - } - - read_posn++; - } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0')); - } - - read_posn += (2 * ai_crop); - - /* The compressed data field has been processed if appropriate - the - rest of the data (if any) goes into a general-purpose data compaction field */ - - j = 0; - if(fnc1_latch == 1) { - /* Encodation method "10" has been used but it is not followed by - AI 10, so a FNC1 character needs to be added */ - general_field[j] = '['; - j++; - } - - for(i = read_posn; i < strlen(source); i++) { - general_field[j] = source[i]; - j++; - } - general_field[j] = '\0'; - - if(strlen(general_field) != 0) { alpha_pad = 0; } - - latch = 0; - for(i = 0; i < strlen(general_field); i++) { - /* Table 13 - ISO/IEC 646 encodation */ - if((general_field[i] < ' ') || (general_field[i] > 'z')) { - general_field_type[i] = INVALID_CHAR; latch = 1; - } else { - general_field_type[i] = ISOIEC; - } - - if(general_field[i] == '#') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == '$') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == '@') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == 92) { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == '^') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == 96) { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - - /* Table 12 - Alphanumeric encodation */ - if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '*') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == ',') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '-') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '.') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '/') { - general_field_type[i] = ALPHA_OR_ISO; - } - - /* Numeric encodation */ - if((general_field[i] >= '0') && (general_field[i] <= '9')) { - general_field_type[i] = ANY_ENC; - } - if(general_field[i] == '[') { - /* FNC1 can be encoded in any system */ - general_field_type[i] = ANY_ENC; - } - - } - - general_field_type[strlen(general_field)] = '\0'; - - if(latch == 1) { - /* Invalid characters in input data */ - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - - for(i = 0; i < strlen(general_field); i++) { - if((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) { - general_field_type[i + 1] = ISOIEC; - } - } - - for(i = 0; i < strlen(general_field); i++) { - if((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) { - general_field_type[i + 1] = ALPHA_OR_ISO; - } - } - - latch = general_rules(general_field, general_field_type); - - i = 0; - do { - switch(general_field_type[i]) { - case NUMERIC: - - if(i != 0) { - if((general_field_type[i - 1] != NUMERIC) && (general_field[i - 1] != '[')) { - concat(binary_string, "000"); /* Numeric latch */ - } - } - - if(general_field[i] != '[') { - d1 = ctoi(general_field[i]); - } else { - d1 = 10; - } - - if(general_field[i + 1] != '[') { - d2 = ctoi(general_field[i + 1]); - } else { - d2 = 10; - } - - value = (11 * d1) + d2 + 8; - - mask = 0x40; - for(j = 0; j < 7; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - - i += 2; - break; - - case ALPHA: - - if(i != 0) { - if((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) { - concat(binary_string, "0000"); /* Alphanumeric latch */ - } - if(general_field_type[i - 1] == ISOIEC) { - concat(binary_string, "00100"); /* ISO/IEC 646 latch */ - } - } - - if((general_field[i] >= '0') && (general_field[i] <= '9')) { - - value = general_field[i] - 43; - - mask = 0x10; - for(j = 0; j < 5; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - - value = general_field[i] - 33; - - mask = 0x20; - for(j = 0; j < 6; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if(general_field[i] == '[') concat(binary_string, "01111"); /* FNC1/Numeric latch */ - if(general_field[i] == '*') concat(binary_string, "111010"); /* asterisk */ - if(general_field[i] == ',') concat(binary_string, "111011"); /* comma */ - if(general_field[i] == '-') concat(binary_string, "111100"); /* minus or hyphen */ - if(general_field[i] == '.') concat(binary_string, "111101"); /* period or full stop */ - if(general_field[i] == '/') concat(binary_string, "111110"); /* slash or solidus */ - - i++; - break; - - case ISOIEC: - - if(i != 0) { - if((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) { - concat(binary_string, "0000"); /* Alphanumeric latch */ - concat(binary_string, "00100"); /* ISO/IEC 646 latch */ - } - if(general_field_type[i - 1] == ALPHA) { - concat(binary_string, "00100"); /* ISO/IEC 646 latch */ - } - } - - if((general_field[i] >= '0') && (general_field[i] <= '9')) { - - value = general_field[i] - 43; - - mask = 0x10; - for(j = 0; j < 5; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - - value = general_field[i] - 1; - - mask = 0x40; - for(j = 0; j < 7; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if((general_field[i] >= 'a') && (general_field[i] <= 'z')) { - - value = general_field[i] - 7; - - mask = 0x40; - for(j = 0; j < 7; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } - - if(general_field[i] == '[') concat(binary_string, "01111"); /* FNC1/Numeric latch */ - if(general_field[i] == '!') concat(binary_string, "11101000"); /* exclamation mark */ - if(general_field[i] == 34) concat(binary_string, "11101001"); /* quotation mark */ - if(general_field[i] == 37) concat(binary_string, "11101010"); /* percent sign */ - if(general_field[i] == '&') concat(binary_string, "11101011"); /* ampersand */ - if(general_field[i] == 39) concat(binary_string, "11101100"); /* apostrophe */ - if(general_field[i] == '(') concat(binary_string, "11101101"); /* left parenthesis */ - if(general_field[i] == ')') concat(binary_string, "11101110"); /* right parenthesis */ - if(general_field[i] == '*') concat(binary_string, "11101111"); /* asterisk */ - if(general_field[i] == '+') concat(binary_string, "11110000"); /* plus sign */ - if(general_field[i] == ',') concat(binary_string, "11110001"); /* comma */ - if(general_field[i] == '-') concat(binary_string, "11110010"); /* minus or hyphen */ - if(general_field[i] == '.') concat(binary_string, "11110011"); /* period or full stop */ - if(general_field[i] == '/') concat(binary_string, "11110100"); /* slash or solidus */ - if(general_field[i] == ':') concat(binary_string, "11110101"); /* colon */ - if(general_field[i] == ';') concat(binary_string, "11110110"); /* semicolon */ - if(general_field[i] == '<') concat(binary_string, "11110111"); /* less-than sign */ - if(general_field[i] == '=') concat(binary_string, "11111000"); /* equals sign */ - if(general_field[i] == '>') concat(binary_string, "11111001"); /* greater-than sign */ - if(general_field[i] == '?') concat(binary_string, "11111010"); /* question mark */ - if(general_field[i] == '_') concat(binary_string, "11111011"); /* underline or low line */ - if(general_field[i] == ' ') concat(binary_string, "11111100"); /* space */ - - i++; - break; - } - } while (i + latch < strlen(general_field)); - - binary_length = strlen(binary_string); - if(cc_mode == 1) { - /* CC-A 2D component - calculate remaining space */ - switch(*(cc_width)) { - case 2: - if(binary_length > 167) { return ERROR_TOO_LONG; } - if(binary_length <= 167) { target_bitsize = 167; } - if(binary_length <= 138) { target_bitsize = 138; } - if(binary_length <= 118) { target_bitsize = 118; } - if(binary_length <= 108) { target_bitsize = 108; } - if(binary_length <= 88) { target_bitsize = 88; } - if(binary_length <= 78) { target_bitsize = 78; } - if(binary_length <= 59) { target_bitsize = 59; } - break; - case 3: - if(binary_length > 167) { return ERROR_TOO_LONG; } - if(binary_length <= 167) { target_bitsize = 167; } - if(binary_length <= 138) { target_bitsize = 138; } - if(binary_length <= 118) { target_bitsize = 118; } - if(binary_length <= 98) { target_bitsize = 98; } - if(binary_length <= 78) { target_bitsize = 78; } - break; - case 4: - if(binary_length > 197) { return ERROR_TOO_LONG; } - if(binary_length <= 197) { target_bitsize = 197; } - if(binary_length <= 167) { target_bitsize = 167; } - if(binary_length <= 138) { target_bitsize = 138; } - if(binary_length <= 108) { target_bitsize = 108; } - if(binary_length <= 78) { target_bitsize = 78; } - break; - } - } - - if(cc_mode == 2) { - /* CC-B 2D component - calculated from ISO/IEC 24728 Table 1 */ - switch(*(cc_width)) { - case 2: - if(binary_length > 336) { return ERROR_TOO_LONG; } - if(binary_length <= 336) { target_bitsize = 336; } - if(binary_length <= 296) { target_bitsize = 296; } - if(binary_length <= 256) { target_bitsize = 256; } - if(binary_length <= 208) { target_bitsize = 208; } - if(binary_length <= 160) { target_bitsize = 160; } - if(binary_length <= 104) { target_bitsize = 104; } - if(binary_length <= 56) { target_bitsize = 56; } - break; - case 3: - if(binary_length > 768) { return ERROR_TOO_LONG; } - if(binary_length <= 768) { target_bitsize = 768; } - if(binary_length <= 648) { target_bitsize = 648; } - if(binary_length <= 536) { target_bitsize = 536; } - if(binary_length <= 416) { target_bitsize = 416; } - if(binary_length <= 304) { target_bitsize = 304; } - if(binary_length <= 208) { target_bitsize = 208; } - if(binary_length <= 152) { target_bitsize = 152; } - if(binary_length <= 112) { target_bitsize = 112; } - if(binary_length <= 72) { target_bitsize = 72; } - if(binary_length <= 32) { target_bitsize = 32; } - break; - case 4: - if(binary_length > 1184) { return ERROR_TOO_LONG; } - if(binary_length <= 1184) { target_bitsize = 1184; } - if(binary_length <= 1016) { target_bitsize = 1016; } - if(binary_length <= 840) { target_bitsize = 840; } - if(binary_length <= 672) { target_bitsize = 672; } - if(binary_length <= 496) { target_bitsize = 496; } - if(binary_length <= 352) { target_bitsize = 352; } - if(binary_length <= 264) { target_bitsize = 264; } - if(binary_length <= 208) { target_bitsize = 208; } - if(binary_length <= 152) { target_bitsize = 152; } - if(binary_length <= 96) { target_bitsize = 96; } - if(binary_length <= 56) { target_bitsize = 56; } - break; - } - } - - if (cc_mode == 3) { - /* CC-C 2D Component is a bit more complex! */ - int byte_length, codewords_used, ecc_level, ecc_codewords, rows; - int codewords_total, target_codewords, target_bytesize; - - byte_length = binary_length / 8; - if(binary_length % 8 != 0) { byte_length++; } - - codewords_used = (byte_length / 6) * 5; - codewords_used += byte_length % 6; - - ecc_level = 7; - if(codewords_used <= 1280) { ecc_level = 6; } - if(codewords_used <= 640) { ecc_level = 5; } - if(codewords_used <= 320) { ecc_level = 4; } - if(codewords_used <= 160) { ecc_level = 3; } - if(codewords_used <= 40) { ecc_level = 2; } - *(ecc) = ecc_level; - ecc_codewords = 1; - for(i = 1; i <= (ecc_level + 1); i++){ - ecc_codewords *= 2; - } - - codewords_used += ecc_codewords; - codewords_used += 3; - - if(codewords_used > symbol->option_3) { - return ERROR_TOO_LONG; - } - /* *(cc_width) = 0.5 + sqrt((codewords_used) / 3); */ - *(cc_width) = (lin_width - 62) / 17; - if((codewords_used / *(cc_width)) > 90) { - /* stop the symbol from becoming too high */ - *(cc_width) = *(cc_width) + 1; - } - - rows = codewords_used / *(cc_width); - if(codewords_used % *(cc_width) != 0) { - rows++; - } - - codewords_total = *(cc_width) * rows; - - target_codewords = codewords_total - ecc_codewords; - target_codewords -= 3; - - target_bytesize = 6 * (target_codewords / 5); - target_bytesize += target_codewords % 5; - - target_bitsize = 8 * target_bytesize; - } - - remainder = binary_length - target_bitsize; - - if(latch == 1) { - i = 0; - /* There is still one more numeric digit to encode */ - - if((remainder >= 4) && (remainder <= 6)) { - d1 = ctoi(general_field[i]); - d1++; - - mask = 0x08; - for(j = 0; j < 4; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - } else { - d1 = ctoi(general_field[i]); - d2 = 10; - - value = (11 * d1) + d2 + 8; - - mask = 0x40; - for(j = 0; j < 7; j++) { - if((value & mask) == 0x00) { - concat(binary_string, "0"); - } else { - concat(binary_string, "1"); - } - mask = mask >> 1; - } - /* This may push the symbol up to the next size */ - } - } - - if(strlen(binary_string) > 11805) { /* (2361 * 5) */ - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* all the code below is repeated from above - it needs to be calculated again because the - size of the symbol may have changed when adding data in the above sequence */ - - binary_length = strlen(binary_string); - if(cc_mode == 1) { - /* CC-A 2D component - calculate padding required */ - switch(*(cc_width)) { - case 2: - if(binary_length > 167) { return ERROR_TOO_LONG; } - if(binary_length <= 167) { target_bitsize = 167; } - if(binary_length <= 138) { target_bitsize = 138; } - if(binary_length <= 118) { target_bitsize = 118; } - if(binary_length <= 108) { target_bitsize = 108; } - if(binary_length <= 88) { target_bitsize = 88; } - if(binary_length <= 78) { target_bitsize = 78; } - if(binary_length <= 59) { target_bitsize = 59; } - break; - case 3: - if(binary_length > 167) { return ERROR_TOO_LONG; } - if(binary_length <= 167) { target_bitsize = 167; } - if(binary_length <= 138) { target_bitsize = 138; } - if(binary_length <= 118) { target_bitsize = 118; } - if(binary_length <= 98) { target_bitsize = 98; } - if(binary_length <= 78) { target_bitsize = 78; } - break; - case 4: - if(binary_length > 197) { return ERROR_TOO_LONG; } - if(binary_length <= 197) { target_bitsize = 197; } - if(binary_length <= 167) { target_bitsize = 167; } - if(binary_length <= 138) { target_bitsize = 138; } - if(binary_length <= 108) { target_bitsize = 108; } - if(binary_length <= 78) { target_bitsize = 78; } - break; - } - } - - if(cc_mode == 2) { - /* CC-B 2D component */ - switch(*(cc_width)) { - case 2: - if(binary_length > 336) { return ERROR_TOO_LONG; } - if(binary_length <= 336) { target_bitsize = 336; } - if(binary_length <= 296) { target_bitsize = 296; } - if(binary_length <= 256) { target_bitsize = 256; } - if(binary_length <= 208) { target_bitsize = 208; } - if(binary_length <= 160) { target_bitsize = 160; } - if(binary_length <= 104) { target_bitsize = 104; } - if(binary_length <= 56) { target_bitsize = 56; } - break; - case 3: - if(binary_length > 768) { return ERROR_TOO_LONG; } - if(binary_length <= 768) { target_bitsize = 768; } - if(binary_length <= 648) { target_bitsize = 648; } - if(binary_length <= 536) { target_bitsize = 536; } - if(binary_length <= 416) { target_bitsize = 416; } - if(binary_length <= 304) { target_bitsize = 304; } - if(binary_length <= 208) { target_bitsize = 208; } - if(binary_length <= 152) { target_bitsize = 152; } - if(binary_length <= 112) { target_bitsize = 112; } - if(binary_length <= 72) { target_bitsize = 72; } - if(binary_length <= 32) { target_bitsize = 32; } - break; - case 4: - if(binary_length > 1184) { return ERROR_TOO_LONG; } - if(binary_length <= 1184) { target_bitsize = 1184; } - if(binary_length <= 1016) { target_bitsize = 1016; } - if(binary_length <= 840) { target_bitsize = 840; } - if(binary_length <= 672) { target_bitsize = 672; } - if(binary_length <= 496) { target_bitsize = 496; } - if(binary_length <= 352) { target_bitsize = 352; } - if(binary_length <= 264) { target_bitsize = 264; } - if(binary_length <= 208) { target_bitsize = 208; } - if(binary_length <= 152) { target_bitsize = 152; } - if(binary_length <= 96) { target_bitsize = 96; } - if(binary_length <= 56) { target_bitsize = 56; } - break; - } - } - - if (cc_mode == 3) { - /* CC-C 2D Component is a bit more complex! */ - int byte_length, codewords_used, ecc_level, ecc_codewords, rows; - int codewords_total, target_codewords, target_bytesize; - - byte_length = binary_length / 8; - if(binary_length % 8 != 0) { byte_length++; } - - codewords_used = (byte_length / 6) * 5; - codewords_used += byte_length % 6; - - ecc_level = 7; - if(codewords_used <= 1280) { ecc_level = 6; } - if(codewords_used <= 640) { ecc_level = 5; } - if(codewords_used <= 320) { ecc_level = 4; } - if(codewords_used <= 160) { ecc_level = 3; } - if(codewords_used <= 40) { ecc_level = 2; } - *(ecc) = ecc_level; - ecc_codewords = 1; - for(i = 1; i <= (ecc_level + 1); i++){ - ecc_codewords *= 2; - } - - codewords_used += ecc_codewords; - codewords_used += 3; - - if(codewords_used > symbol->option_3) { - return ERROR_TOO_LONG; - } - /* *(cc_width) = 0.5 + sqrt((codewords_used) / 3); */ - *(cc_width) = (lin_width - 62) / 17; - if((codewords_used / *(cc_width)) > 90) { - /* stop the symbol from becoming too high */ - *(cc_width) = *(cc_width) + 1; - } - - rows = codewords_used / *(cc_width); - if(codewords_used % *(cc_width) != 0) { - rows++; - } - - codewords_total = *(cc_width) * rows; - - target_codewords = codewords_total - ecc_codewords; - target_codewords -= 3; - - target_bytesize = 6 * (target_codewords / 5); - target_bytesize += target_codewords % 5; - - target_bitsize = 8 * target_bytesize; - } - - if(binary_length < target_bitsize) { - /* Now add padding to binary string */ - if (alpha_pad == 1) { - concat(binary_string, "11111"); - alpha_pad = 0; - /* Extra FNC1 character required after Alpha encodation (section 5.2.3) */ - } - - if ((strlen(general_field) != 0) && (general_field_type[strlen(general_field) - 1] == NUMERIC)) { - concat(binary_string, "0000"); - } - - while (strlen(binary_string) < target_bitsize) { - concat(binary_string, "00100"); - } - - if(strlen(binary_string) > target_bitsize) { - binary_string[target_bitsize] = '\0'; - } - } - - return 0; -} - -void add_leading_zeroes(struct zint_symbol *symbol) -{ - int with_addon = 0; - int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h, n = 0; - - h = strlen(symbol->primary); - for(i = 0; i < h; i++) { - if(symbol->primary[i] == '+') { - with_addon = 1; - } else { - if(with_addon == 0) { - first_len++; - } else { - second_len++; - } - } - } - - /* Calculate target lengths */ - if(first_len <= 12) { zfirst_len = 12; } - if(first_len <= 7) { zfirst_len = 7; } - if(second_len <= 5) { zsecond_len = 5; } - if(second_len <= 2) { zsecond_len = 2; } - if(second_len == 0) { zsecond_len = 0; } - - /* Add leading zeroes */ - n = zfirst_len - first_len; - if (n > 0) - { - memmove(symbol->primary + n, symbol->primary, h); - memset(symbol->primary, '0', n); - } - n += first_len + 1; - if (zsecond_len) - { - memmove(symbol->primary + n + zsecond_len, symbol->primary + n, second_len); - memset(symbol->primary + n , '0', zsecond_len); - n += zsecond_len + second_len; - } - symbol->primary[n] = '\0'; -} - -int composite(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int error_number, cc_mode, cc_width, ecc_level; - int j, i, k, separator_row; - unsigned int rs = length + 1; - unsigned int bs = 20 * rs; - unsigned int pri_len; -#ifndef _MSC_VER - char reduced[rs]; - char binary_string[bs]; -#else - char* reduced = (char*)_alloca(rs); - char* binary_string = (char*)_alloca(bs); -#endif - struct zint_symbol *linear; - int top_shift, bottom_shift; - - error_number = 0; - separator_row = 0; - pri_len = strlen(symbol->primary); - if(pri_len == 0) { - strcpy(symbol->errtxt, "No primary (linear) message in 2D composite"); - return ERROR_INVALID_OPTION; - } - - if(length > 2990) { - strcpy(symbol->errtxt, "2D component input data too long"); - return ERROR_TOO_LONG; - } - - linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */ - - error_number = gs1_verify(symbol, source, length, reduced); - if(error_number != 0) { return error_number; } - - cc_mode = symbol->option_1; - - if((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) { - /* CC-C can only be used with a GS1-128 linear part */ - strcpy(symbol->errtxt, "Invalid mode (CC-C only valid with GS1-128 linear component)"); - return ERROR_INVALID_OPTION; - } - - linear->symbology = symbol->symbology; - - if(linear->symbology != BARCODE_EAN128_CC) { - /* Set the "component linkage" flag in the linear component */ - linear->option_1 = 2; - } else { - /* GS1-128 needs to know which type of 2D component is used */ - linear->option_1 = cc_mode; - } - - switch(symbol->symbology) { - case BARCODE_EANX_CC: error_number = eanx(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_EAN128_CC: error_number = ean_128(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_RSS14_CC: error_number = rss14(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_RSS_LTD_CC: error_number = rsslimited(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_RSS_EXP_CC: error_number = rssexpanded(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_UPCA_CC: error_number = eanx(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_UPCE_CC: error_number = eanx(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_RSS14STACK_CC: error_number = rss14(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_RSS14_OMNI_CC: error_number = rss14(linear, (unsigned char *)symbol->primary, pri_len); break; - case BARCODE_RSS_EXPSTACK_CC: error_number = rssexpanded(linear, (unsigned char *)symbol->primary, pri_len); break; - } - - if(error_number != 0) { - strcpy(symbol->errtxt, linear->errtxt); - concat(symbol->errtxt, " in linear component"); - return error_number; - } - - switch(symbol->symbology) { - /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */ - case BARCODE_EANX_CC: - switch(pri_len) { - case 7: /* EAN-8 */ - case 10: /* EAN-8 + 2 */ - case 13: /* EAN-8 + 5 */ - cc_width = 3; - break; - case 12: /* EAN-13 */ - case 15: /* EAN-13 + 2 */ - case 18: /* EAN-13 + 5 */ - cc_width = 4; - break; - } - break; - case BARCODE_EAN128_CC: cc_width = 4; break; - case BARCODE_RSS14_CC: cc_width = 4; break; - case BARCODE_RSS_LTD_CC: cc_width = 3; break; - case BARCODE_RSS_EXP_CC: cc_width = 4; break; - case BARCODE_UPCA_CC: cc_width = 4; break; - case BARCODE_UPCE_CC: cc_width = 2; break; - case BARCODE_RSS14STACK_CC: cc_width = 2; break; - case BARCODE_RSS14_OMNI_CC: cc_width = 2; break; - case BARCODE_RSS_EXPSTACK_CC: cc_width = 4; break; - } - - memset(binary_string, 0, bs); - - if(cc_mode < 1 || cc_mode > 3) { cc_mode = 1; } - - if(cc_mode == 1) { - i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width); - if (i == ERROR_TOO_LONG) { - cc_mode = 2; - } - } - - if(cc_mode == 2) { /* If the data didn't fit into CC-A it is recalculated for CC-B */ - i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width); - if (i == ERROR_TOO_LONG) { - if(symbol->symbology != BARCODE_EAN128_CC) { - return ERROR_TOO_LONG; - } else { - cc_mode = 3; - } - } - } - - if(cc_mode == 3) { /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated - for CC-C */ - i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear->width); - if (i == ERROR_TOO_LONG) { - return ERROR_TOO_LONG; - } - } - - switch(cc_mode) { /* Note that ecc_level is only relevant to CC-C */ - case 1: error_number = cc_a(symbol, binary_string, cc_width); break; - case 2: error_number = cc_b(symbol, binary_string, cc_width); break; - case 3: error_number = cc_c(symbol, binary_string, cc_width, ecc_level); break; - } - - if(error_number != 0) { - return ERROR_ENCODING_PROBLEM; - } - - /* Merge the linear component with the 2D component */ - - top_shift = 0; - bottom_shift = 0; - - switch(symbol->symbology) { - /* Determine horizontal alignment (according to section 12.3) */ - case BARCODE_EANX_CC: - switch(pri_len) { - case 7: /* EAN-8 */ - case 10: /* EAN-8 + 2 */ - case 13: /* EAN-8 + 5 */ - bottom_shift = 13; - break; - case 12: /* EAN-13 */ - case 15: /* EAN-13 + 2 */ - case 18: /* EAN-13 + 5 */ - bottom_shift = 2; - break; - } - break; - case BARCODE_EAN128_CC: if(cc_mode == 3) { - bottom_shift = 7; - } - break; - case BARCODE_RSS14_CC: bottom_shift = 4; break; - case BARCODE_RSS_LTD_CC: bottom_shift = 9; break; - case BARCODE_RSS_EXP_CC: k = 1; - while((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) { - /* while((linear->encoded_data[1][k - 1] != '1') && (linear->encoded_data[1][k] != '0')) { */ - k++; - } - top_shift = k; - break; - case BARCODE_UPCA_CC: bottom_shift = 2; break; - case BARCODE_UPCE_CC: bottom_shift = 2; break; - case BARCODE_RSS14STACK_CC: top_shift = 1; break; - case BARCODE_RSS14_OMNI_CC: top_shift = 1; break; - case BARCODE_RSS_EXPSTACK_CC: k = 1; - while((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) { - /* while((linear->encoded_data[1][k - 1] != '1') && (linear->encoded_data[1][k] != '0')) { */ - k++; - } - top_shift = k; - break; - } - - if(top_shift != 0) { - /* Move the 2d component of the symbol horizontally */ - for(i = 0; i <= symbol->rows; i++) { - for(j = (symbol->width + top_shift); j >= top_shift; j--) { - if(module_is_set(symbol, i, j - top_shift)) { set_module(symbol, i, j); } else { unset_module(symbol, i, j); } - } - for(j = 0; j < top_shift; j++) { - unset_module(symbol, i, j); - } - } - } - - /* Merge linear and 2D components into one structure */ - for(i = 0; i <= linear->rows; i++) { - symbol->row_height[symbol->rows + i] = linear->row_height[i]; - for(j = 0; j <= linear->width; j++) { - if(module_is_set(linear, i, j)) { set_module(symbol, i + symbol->rows, j + bottom_shift); } else { unset_module(symbol, i + symbol->rows, j + bottom_shift); } - } - } - if((linear->width + bottom_shift) > symbol->width) { - symbol->width = linear->width + bottom_shift; - } - if((symbol->width + top_shift) > symbol->width) { - symbol->width += top_shift; - } - symbol->rows += linear->rows; - ustrcpy(symbol->text, (unsigned char *)linear->text); - - ZBarcode_Delete(linear); - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/composite.h b/3rdparty/zint-2.4.4/backend/composite.h deleted file mode 100644 index 30ace7f..0000000 --- a/3rdparty/zint-2.4.4/backend/composite.h +++ /dev/null @@ -1,62 +0,0 @@ -/* composite.c - Tables for UCC.EAN Composite Symbols */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define NUMERIC 110 -#define ALPHA 97 -#define ISOIEC 105 -#define INVALID_CHAR 100 -#define ANY_ENC 120 -#define ALPHA_OR_ISO 121 - -/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */ -static int ccaCoeffs[30] = { - /* k = 4 */ - 522, 568, 723, 809, - - /* k = 5 */ - 427, 919, 460, 155, 566, - - /* k = 6 */ - 861, 285, 19, 803, 17, 766, - - /* k = 7 */ - 76, 925, 537, 597, 784, 691, 437, - - /* k = 8 */ - 237, 308, 436, 284, 646, 653, 428, 379 -}; - -/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */ -static int ccaVariants[51] = { - 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, - 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8, - 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22 -}; - -/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables 10 and 11 */ -static int aRAPTable[68] = { - 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29, - 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9, - 19, 33, 12, 40, 46, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41, - 6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3 -}; - -/* Row Address Patterns are as defined in pdf417.h */ diff --git a/3rdparty/zint-2.4.4/backend/dmatrix.c b/3rdparty/zint-2.4.4/backend/dmatrix.c deleted file mode 100644 index f98e737..0000000 --- a/3rdparty/zint-2.4.4/backend/dmatrix.c +++ /dev/null @@ -1,910 +0,0 @@ -/* dmatrix.c Handles Data Matrix ECC 200 symbols */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - developed from and including some functions from: - IEC16022 bar code generation - Adrian Kennard, Andrews & Arnold Ltd - with help from Cliff Hones on the RS coding - - (c) 2004 Adrian Kennard, Andrews & Arnold Ltd - (c) 2006 Stefan Schmidt - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "reedsol.h" -#include "common.h" -#include "dmatrix.h" - -// Annex M placement alorithm low level -static void ecc200placementbit(int *array, int NR, int NC, int r, int c, int p, char b) -{ - if (r < 0) { - r += NR; - c += 4 - ((NR + 4) % 8); - } - if (c < 0) { - c += NC; - r += 4 - ((NC + 4) % 8); - } - array[r * NC + c] = (p << 3) + b; -} - -static void ecc200placementblock(int *array, int NR, int NC, int r, - int c, int p) -{ - ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7); - ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6); - ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5); - ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4); - ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3); - ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2); - ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1); - ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0); -} - -static void ecc200placementcornerA(int *array, int NR, int NC, int p) -{ - ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7); - ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6); - ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5); - ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); - ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); - ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2); - ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1); - ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0); -} - -static void ecc200placementcornerB(int *array, int NR, int NC, int p) -{ - ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7); - ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6); - ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5); - ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4); - ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3); - ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2); - ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1); - ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0); -} - -static void ecc200placementcornerC(int *array, int NR, int NC, int p) -{ - ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7); - ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6); - ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5); - ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); - ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); - ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2); - ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1); - ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0); -} - -static void ecc200placementcornerD(int *array, int NR, int NC, int p) -{ - ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7); - ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6); - ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5); - ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); - ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); - ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2); - ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1); - ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0); -} - -// Annex M placement alorithm main function -static void ecc200placement(int *array, int NR, int NC) -{ - int r, c, p; - // invalidate - for (r = 0; r < NR; r++) - for (c = 0; c < NC; c++) - array[r * NC + c] = 0; - // start - p = 1; - r = 4; - c = 0; - do { - // check corner - if (r == NR && !c) - ecc200placementcornerA(array, NR, NC, p++); - if (r == NR - 2 && !c && NC % 4) - ecc200placementcornerB(array, NR, NC, p++); - if (r == NR - 2 && !c && (NC % 8) == 4) - ecc200placementcornerC(array, NR, NC, p++); - if (r == NR + 4 && c == 2 && !(NC % 8)) - ecc200placementcornerD(array, NR, NC, p++); - // up/right - do { - if (r < NR && c >= 0 && !array[r * NC + c]) - ecc200placementblock(array, NR, NC, r, c, p++); - r -= 2; - c += 2; - } - while (r >= 0 && c < NC); - r++; - c += 3; - // down/left - do { - if (r >= 0 && c < NC && !array[r * NC + c]) - ecc200placementblock(array, NR, NC, r, c, p++); - r += 2; - c -= 2; - } - while (r < NR && c >= 0); - r += 3; - c++; - } - while (r < NR || c < NC); - // unfilled corner - if (!array[NR * NC - 1]) - array[NR * NC - 1] = array[NR * NC - NC - 2] = 1; -} - -// calculate and append ecc code, and if necessary interleave -static void ecc200(unsigned char *binary, int bytes, int datablock, int rsblock, int skew) -{ - int blocks = (bytes + 2) / datablock, b; - int n, p; - rs_init_gf(0x12d); - rs_init_code(rsblock, 1); - for (b = 0; b < blocks; b++) { - unsigned char buf[256], ecc[256]; - p = 0; - for (n = b; n < bytes; n += blocks) - buf[p++] = binary[n]; - rs_encode(p, buf, ecc); - p = rsblock - 1; // comes back reversed - for (n = b; n < rsblock * blocks; n += blocks) { - if (skew) { - /* Rotate ecc data to make 144x144 size symbols acceptable */ - /* See http://groups.google.com/group/postscriptbarcode/msg/5ae8fda7757477da */ - if(b < 8) { - binary[bytes + n + 2] = ecc[p--]; - } else { - binary[bytes + n - 8] = ecc[p--]; - } - } else { - binary[bytes + n] = ecc[p--]; - } - } - } - rs_free(); -} - -int isx12(unsigned char source) -{ - if(source == 13) { return 1; } - if(source == 42) { return 1; } - if(source == 62) { return 1; } - if(source == 32) { return 1; } - if((source >= '0') && (source <= '9')) { return 1; } - if((source >= 'A') && (source <= 'Z')) { return 1; } - - return 0; -} - -void dminsert(char binary_string[], int posn, char newbit) -{ /* Insert a character into the middle of a string at position posn */ - int i, end; - - end = strlen(binary_string); - for(i = end; i > posn; i--) { - binary_string[i] = binary_string[i - 1]; - } - binary_string[posn] = newbit; -} - -void insert_value(unsigned char binary_stream[], int posn, int streamlen, char newbit) -{ - int i; - - for(i = streamlen; i > posn; i--) { - binary_stream[i] = binary_stream[i - 1]; - } - binary_stream[posn] = newbit; -} - -int look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) -{ - /* A custom version of the 'look ahead test' from Annex P */ - /* This version is deliberately very reluctant to end a data stream with EDIFACT encoding */ - - float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count; - int sp, done, best_scheme; - char reduced_char; - - /* step (j) */ - if(current_mode == DM_ASCII) { - ascii_count = 0.0; - c40_count = 1.0; - text_count = 1.0; - x12_count = 1.0; - edf_count = 1.0; - b256_count = 1.25; - } else { - ascii_count = 1.0; - c40_count = 2.0; - text_count = 2.0; - x12_count = 2.0; - edf_count = 2.0; - b256_count = 2.25; - } - - switch(current_mode) { - case DM_C40: c40_count = 0.0; break; - case DM_TEXT: text_count = 0.0; break; - case DM_X12: x12_count = 0.0; break; - case DM_EDIFACT: edf_count = 0.0; break; - case DM_BASE256: b256_count = 0.0; break; - } - - for(sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) { - - if(source[sp] <= 127) { reduced_char = source[sp]; } else { reduced_char = source[sp] - 127; } - - if((source[sp] >= '0') && (source[sp] <= '9')) { ascii_count += 0.5; } else { ascii_count += 1.0; } - if(source[sp] > 127) { ascii_count += 1.0; } - - done = 0; - if(reduced_char == ' ') { c40_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= '0') && (reduced_char <= '9')) { c40_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= 'A') && (reduced_char <= 'Z')) { c40_count += (2.0 / 3.0); done = 1; } - if(source[sp] > 127) { c40_count += (4.0 / 3.0); } - if(done == 0) { c40_count += (4.0 / 3.0); } - - done = 0; - if(reduced_char == ' ') { text_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= '0') && (reduced_char <= '9')) { text_count += (2.0 / 3.0); done = 1; } - if((reduced_char >= 'a') && (reduced_char <= 'z')) { text_count += (2.0 / 3.0); done = 1; } - if(source[sp] > 127) { text_count += (4.0 / 3.0); } - if(done == 0) { text_count += (4.0 / 3.0); } - - if(isx12(source[sp])) { x12_count += (2.0 / 3.0); } else { x12_count += 4.0; } - - /* step (p) */ - done = 0; - if((source[sp] >= ' ') && (source[sp] <= '^')) { edf_count += (3.0 / 4.0); } else { edf_count += 6.0; } - if(gs1 && (source[sp] == '[')) { edf_count += 6.0; } - if(sp >= (sourcelen - 5)) { edf_count += 6.0; } /* MMmmm fudge! */ - - /* step (q) */ - if(gs1 && (source[sp] == '[')) { b256_count += 4.0; } else { b256_count += 1.0; } - - /* printf("%c lat a%.2f c%.2f t%.2f x%.2f e%.2f b%.2f\n", source[sp], ascii_count, c40_count, text_count, x12_count, edf_count, b256_count); */ - - } - - best_count = ascii_count; - best_scheme = DM_ASCII; - - if(b256_count <= best_count) { - best_count = b256_count; - best_scheme = DM_BASE256; - } - - if(edf_count <= best_count) { - best_count = edf_count; - best_scheme = DM_EDIFACT; - } - - if(text_count <= best_count) { - best_count = text_count; - best_scheme = DM_TEXT; - } - - if(x12_count <= best_count) { - best_count = x12_count; - best_scheme = DM_X12; - } - - if(c40_count <= best_count) { - best_count = c40_count; - best_scheme = DM_C40; - } - - return best_scheme; -} - -int dm200encode(struct zint_symbol *symbol, unsigned char source[], unsigned char target[], int *last_mode, int length) -{ - /* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate */ - /* Supports encoding FNC1 in supporting systems */ - - int sp, tp, i, gs1; - int current_mode, next_mode; - int inputlen = length; - int c40_buffer[6], c40_p; - int text_buffer[6], text_p; - int x12_buffer[6], x12_p; - int edifact_buffer[8], edifact_p; - int debug = 0; -#ifndef _MSC_VER - char binary[2 * inputlen]; -#else - char* binary = (char*)_alloca(2 * inputlen); -#endif - - sp = 0; - tp = 0; - memset(c40_buffer, 0, 6); - c40_p = 0; - memset(text_buffer, 0, 6); - text_p = 0; - memset(x12_buffer, 0, 6); - x12_p = 0; - memset(edifact_buffer, 0, 8); - edifact_p = 0; - strcpy(binary, ""); - - /* step (a) */ - current_mode = DM_ASCII; - next_mode = DM_ASCII; - - if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; } - - if(gs1) { - target[tp] = 232; tp++; - concat(binary, " "); - if(debug) printf("FN1 "); - } /* FNC1 */ - - if(symbol->output_options & READER_INIT) { - if(gs1) { - strcpy(symbol->errtxt, "Cannot encode in GS1 mode and Reader Initialisation at the same time"); - return ERROR_INVALID_OPTION; - } else { - target[tp] = 234; tp++; /* Reader Programming */ - concat(binary, " "); - if(debug) printf("RP "); - } - } - - while (sp < inputlen) { - - current_mode = next_mode; - - /* step (b) - ASCII encodation */ - if(current_mode == DM_ASCII) { - next_mode = DM_ASCII; - - if(istwodigits(source, sp) && ((sp + 1) != inputlen)) { - target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130; - if(debug) printf("N%d ", target[tp] - 130); - tp++; concat(binary, " "); - sp += 2; - } else { - next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); - - if(next_mode != DM_ASCII) { - switch(next_mode) { - case DM_C40: target[tp] = 230; tp++; concat(binary, " "); - if(debug) printf("C40 "); break; - case DM_TEXT: target[tp] = 239; tp++; concat(binary, " "); - if(debug) printf("TEX "); break; - case DM_X12: target[tp] = 238; tp++; concat(binary, " "); - if(debug) printf("X12 "); break; - case DM_EDIFACT: target[tp] = 240; tp++; concat(binary, " "); - if(debug) printf("EDI "); break; - case DM_BASE256: target[tp] = 231; tp++; concat(binary, " "); - if(debug) printf("BAS "); break; - } - } else { - if(source[sp] > 127) { - target[tp] = 235; /* FNC4 */ - if(debug) printf("FN4 "); - tp++; - target[tp] = (source[sp] - 128) + 1; - if(debug) printf("A%02X ", target[tp] - 1); - tp++; concat(binary, " "); - } else { - if(gs1 && (source[sp] == '[')) { - target[tp] = 232; /* FNC1 */ - if(debug) printf("FN1 "); - } else { - target[tp] = source[sp] + 1; - if(debug) printf("A%02X ", target[tp] - 1); - } - tp++; - concat(binary, " "); - } - sp++; - } - } - - } - - /* step (c) C40 encodation */ - if(current_mode == DM_C40) { - int shift_set, value; - - next_mode = DM_C40; - if(c40_p == 0) { - next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); - } - - if(next_mode != DM_C40) { - target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */ - next_mode = DM_ASCII; - if (debug) printf("ASC "); - } else { - if(source[sp] > 127) { - c40_buffer[c40_p] = 1; c40_p++; - c40_buffer[c40_p] = 30; c40_p++; /* Upper Shift */ - shift_set = c40_shift[source[sp] - 128]; - value = c40_value[source[sp] - 128]; - } else { - shift_set = c40_shift[source[sp]]; - value = c40_value[source[sp]]; - } - - if(gs1 && (source[sp] == '[')) { - shift_set = 2; - value = 27; /* FNC1 */ - } - - if(shift_set != 0) { - c40_buffer[c40_p] = shift_set - 1; c40_p++; - } - c40_buffer[c40_p] = value; c40_p++; - - if(c40_p >= 3) { - int iv; - - iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - concat(binary, " "); - if (debug) printf("[%d %d %d] ", c40_buffer[0], c40_buffer[1], c40_buffer[2]); - - c40_buffer[0] = c40_buffer[3]; - c40_buffer[1] = c40_buffer[4]; - c40_buffer[2] = c40_buffer[5]; - c40_buffer[3] = 0; - c40_buffer[4] = 0; - c40_buffer[5] = 0; - c40_p -= 3; - } - sp++; - } - } - - /* step (d) Text encodation */ - if(current_mode == DM_TEXT) { - int shift_set, value; - - next_mode = DM_TEXT; - if(text_p == 0) { - next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); - } - - if(next_mode != DM_TEXT) { - target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */ - next_mode = DM_ASCII; - if (debug) printf("ASC "); - } else { - if(source[sp] > 127) { - text_buffer[text_p] = 1; text_p++; - text_buffer[text_p] = 30; text_p++; /* Upper Shift */ - shift_set = text_shift[source[sp] - 128]; - value = text_value[source[sp] - 128]; - } else { - shift_set = text_shift[source[sp]]; - value = text_value[source[sp]]; - } - - if(gs1 && (source[sp] == '[')) { - shift_set = 2; - value = 27; /* FNC1 */ - } - - if(shift_set != 0) { - text_buffer[text_p] = shift_set - 1; text_p++; - } - text_buffer[text_p] = value; text_p++; - - if(text_p >= 3) { - int iv; - - iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - concat(binary, " "); - if (debug) printf("[%d %d %d] ", text_buffer[0], text_buffer[1], text_buffer[2]); - - text_buffer[0] = text_buffer[3]; - text_buffer[1] = text_buffer[4]; - text_buffer[2] = text_buffer[5]; - text_buffer[3] = 0; - text_buffer[4] = 0; - text_buffer[5] = 0; - text_p -= 3; - } - sp++; - } - } - - /* step (e) X12 encodation */ - if(current_mode == DM_X12) { - int value = 0; - - next_mode = DM_X12; - if(text_p == 0) { - next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); - } - - if(next_mode != DM_X12) { - target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */ - next_mode = DM_ASCII; - if (debug) printf("ASC "); - } else { - if(source[sp] == 13) { value = 0; } - if(source[sp] == '*') { value = 1; } - if(source[sp] == '>') { value = 2; } - if(source[sp] == ' ') { value = 3; } - if((source[sp] >= '0') && (source[sp] <= '9')) { value = (source[sp] - '0') + 4; } - if((source[sp] >= 'A') && (source[sp] <= 'Z')) { value = (source[sp] - 'A') + 14; } - - x12_buffer[x12_p] = value; x12_p++; - - if(x12_p >= 3) { - int iv; - - iv = (1600 * x12_buffer[0]) + (40 * x12_buffer[1]) + (x12_buffer[2]) + 1; - target[tp] = iv / 256; tp++; - target[tp] = iv % 256; tp++; - concat(binary, " "); - if (debug) printf("[%d %d %d] ", x12_buffer[0], x12_buffer[1], x12_buffer[2]); - - x12_buffer[0] = x12_buffer[3]; - x12_buffer[1] = x12_buffer[4]; - x12_buffer[2] = x12_buffer[5]; - x12_buffer[3] = 0; - x12_buffer[4] = 0; - x12_buffer[5] = 0; - x12_p -= 3; - } - sp++; - } - } - - /* step (f) EDIFACT encodation */ - if(current_mode == DM_EDIFACT) { - int value = 0; - - next_mode = DM_EDIFACT; - if(edifact_p == 3) { - next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); - } - - if(next_mode != DM_EDIFACT) { - edifact_buffer[edifact_p] = 31; edifact_p++; - next_mode = DM_ASCII; - } else { - if((source[sp] >= '@') && (source[sp] <= '^')) { value = source[sp] - '@'; } - if((source[sp] >= ' ') && (source[sp] <= '?')) { value = source[sp]; } - - edifact_buffer[edifact_p] = value; edifact_p++; - sp++; - } - - if(edifact_p >= 4) { - target[tp] = (edifact_buffer[0] << 2) + ((edifact_buffer[1] & 0x30) >> 4); tp++; - target[tp] = ((edifact_buffer[1] & 0x0f) << 4) + ((edifact_buffer[2] & 0x3c) >> 2); tp++; - target[tp] = ((edifact_buffer[2] & 0x03) << 6) + edifact_buffer[3]; tp++; - concat(binary, " "); - if (debug) printf("[%d %d %d %d] ", edifact_buffer[0], edifact_buffer[1], edifact_buffer[2], edifact_buffer[3]); - - edifact_buffer[0] = edifact_buffer[4]; - edifact_buffer[1] = edifact_buffer[5]; - edifact_buffer[2] = edifact_buffer[6]; - edifact_buffer[3] = edifact_buffer[7]; - edifact_buffer[4] = 0; - edifact_buffer[5] = 0; - edifact_buffer[6] = 0; - edifact_buffer[7] = 0; - edifact_p -= 4; - } - } - - /* step (g) Base 256 encodation */ - if(current_mode == DM_BASE256) { - next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); - - if(next_mode == DM_BASE256) { - target[tp] = source[sp]; - if(debug) printf("B%02X ", target[tp]); - tp++; - sp++; - concat(binary, "b"); - } else { - next_mode = DM_ASCII; - if(debug) printf("ASC "); - } - } - - if(tp > 1558) { - return 0; - } - - } /* while */ - - /* Empty buffers */ - if(c40_p == 2) { - target[tp] = 254; tp++; /* unlatch */ - target[tp] = source[inputlen - 2] + 1; tp++; - target[tp] = source[inputlen - 1] + 1; tp++; - concat(binary, " "); - if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1); - current_mode = DM_ASCII; - } - if(c40_p == 1) { - target[tp] = 254; tp++; /* unlatch */ - target[tp] = source[inputlen - 1] + 1; tp++; - concat(binary, " "); - if(debug) printf("ASC A%02X ", target[tp - 1] - 1); - current_mode = DM_ASCII; - } - - if(text_p == 2) { - target[tp] = 254; tp++; /* unlatch */ - target[tp] = source[inputlen - 2] + 1; tp++; - target[tp] = source[inputlen - 1] + 1; tp++; - concat(binary, " "); - if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1); - current_mode = DM_ASCII; - } - if(text_p == 1) { - target[tp] = 254; tp++; /* unlatch */ - target[tp] = source[inputlen - 1] + 1; tp++; - concat(binary, " "); - if(debug) printf("ASC A%02X ", target[tp - 1] - 1); - current_mode = DM_ASCII; - } - - if(x12_p == 2) { - target[tp] = 254; tp++; /* unlatch */ - target[tp] = source[inputlen - 2] + 1; tp++; - target[tp] = source[inputlen - 1] + 1; tp++; - concat(binary, " "); - if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1); - current_mode = DM_ASCII; - } - if(x12_p == 1) { - target[tp] = 254; tp++; /* unlatch */ - target[tp] = source[inputlen - 1] + 1; tp++; - concat(binary, " "); - if(debug) printf("ASC A%02X ", target[tp - 1] - 1); - current_mode = DM_ASCII; - } - - /* Add length and randomising algorithm to b256 */ - i = 0; - while (i < tp) { - if(binary[i] == 'b') { - if((i == 0) || ((i != 0) && (binary[i - 1] != 'b'))) { - /* start of binary data */ - int binary_count; /* length of b256 data */ - - for(binary_count = 0; binary[binary_count + i] == 'b'; binary_count++); - - if(binary_count <= 249) { - dminsert(binary, i, 'b'); - insert_value(target, i, tp, binary_count); tp++; - } else { - dminsert(binary, i, 'b'); - dminsert(binary, i + 1, 'b'); - insert_value(target, i, tp, (binary_count / 250) + 249); tp++; - insert_value(target, i + 1, tp, binary_count % 250); tp++; - } - } - } - i++; - } - - for(i = 0; i < tp; i++) { - if(binary[i] == 'b') { - int prn, temp; - - prn = ((149 * (i + 1)) % 255) + 1; - temp = target[i] + prn; - if (temp <= 255) { target[i] = temp; } else { target[i] = temp - 256; } - } - } - - if(debug) { - printf("\n\n"); - for(i = 0; i < tp; i++){ - printf("%02X ", target[i]); - } - printf("\n"); - } - - *(last_mode) = current_mode; - return tp; -} - -void add_tail(unsigned char target[], int tp, int tail_length, int last_mode) -{ - /* adds unlatch and pad bits */ - int i, prn, temp; - - switch(last_mode) { - case DM_C40: - case DM_TEXT: - case DM_X12: - target[tp] = 254; tp++; /* Unlatch */ - tail_length--; - } - - for(i = tail_length; i > 0; i--) { - if(i == tail_length) { - target[tp] = 129; tp++; /* Pad */ - } else { - prn = ((149 * (tp + 1)) % 253) + 1; - temp = 129 + prn; - if(temp <= 254) { - target[tp] = temp; tp++; - } else { - target[tp] = temp - 254; tp++; - } - } - } -} - -int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int inputlen, i, skew = 0; - unsigned char binary[2200]; - int binlen; - int symbolsize, optionsize, calcsize; - int taillength, error_number = 0; - int H, W, FH, FW, datablock, bytes, rsblock; - int last_mode; - unsigned char *grid = 0; - inputlen = length; - - binlen = dm200encode(symbol, source, binary, &last_mode, length); - - if(binlen == 0) { - strcpy(symbol->errtxt, "Data too long to fit in symbol"); - return ERROR_TOO_LONG; - } - - if((symbol->option_2 >= 1) && (symbol->option_2 <= 30)) { - optionsize = intsymbol[symbol->option_2 - 1]; - } else { - optionsize = -1; - } - - calcsize = 29; - for(i = 29; i > -1; i--) { - if(matrixbytes[i] >= binlen) { - calcsize = i; - } - } - - if(symbol->option_3 == DM_SQUARE) { - /* Force to use square symbol */ - switch(calcsize) { - case 2: - case 4: - case 6: - case 9: - case 11: - case 14: - calcsize++; - } - } - - symbolsize = optionsize; - if(calcsize > optionsize) { - symbolsize = calcsize; - if(optionsize != -1) { - /* flag an error */ - error_number = WARN_INVALID_OPTION; - strcpy(symbol->errtxt, "Data does not fit in selected symbol size"); - } - } - - H = matrixH[symbolsize]; - W = matrixW[symbolsize]; - FH = matrixFH[symbolsize]; - FW = matrixFW[symbolsize]; - bytes = matrixbytes[symbolsize]; - datablock = matrixdatablock[symbolsize]; - rsblock = matrixrsblock[symbolsize]; - - taillength = bytes - binlen; - - if(taillength != 0) { - add_tail(binary, binlen, taillength, last_mode); - } - - // ecc code - if(symbolsize == 29) { skew = 1; } - ecc200(binary, bytes, datablock, rsblock, skew); - { // placement - int x, y, NC, NR, *places; - NC = W - 2 * (W / FW); - NR = H - 2 * (H / FH); - places = (int*)malloc(NC * NR * sizeof(int)); - ecc200placement(places, NR, NC); - grid = (unsigned char*)malloc(W * H); - memset(grid, 0, W * H); - for (y = 0; y < H; y += FH) { - for (x = 0; x < W; x++) - grid[y * W + x] = 1; - for (x = 0; x < W; x += 2) - grid[(y + FH - 1) * W + x] = 1; - } - for (x = 0; x < W; x += FW) { - for (y = 0; y < H; y++) - grid[y * W + x] = 1; - for (y = 0; y < H; y += 2) - grid[y * W + x + FW - 1] = 1; - } - for (y = 0; y < NR; y++) { - for (x = 0; x < NC; x++) { - int v = places[(NR - y - 1) * NC + x]; - //fprintf (stderr, "%4d", v); - if (v == 1 || (v > 7 && (binary[(v >> 3) - 1] & (1 << (v & 7))))) - grid[(1 + y + 2 * (y / (FH - 2))) * W + 1 + x + 2 * (x / (FW - 2))] = 1; - } - //fprintf (stderr, "\n"); - } - for(y = H - 1; y >= 0; y--) { - int x; - for(x = 0; x < W; x++) { - if(grid[W * y + x]) { - set_module(symbol, (H - y) - 1, x); - } - } - symbol->row_height[(H - y) - 1] = 1; - } - free(grid); - free(places); - } - - symbol->rows = H; - symbol->width = W; - - return error_number; -} - -int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int error_number; - - if(symbol->option_1 <= 1) { - /* ECC 200 */ - error_number = data_matrix_200(symbol, source, length); - } else { - /* ECC 000 - 140 */ - strcpy(symbol->errtxt, "Older Data Matrix standards are no longer supported"); - error_number = ERROR_INVALID_OPTION; - } - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/dmatrix.h b/3rdparty/zint-2.4.4/backend/dmatrix.h deleted file mode 100644 index 79d1143..0000000 --- a/3rdparty/zint-2.4.4/backend/dmatrix.h +++ /dev/null @@ -1,101 +0,0 @@ -/* dmatrix.h - Handles Data Matrix ECC 200 */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "common.h" - -#ifndef __IEC16022ECC200_H -#define __IEC16022ECC200_H -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define MAXBARCODE 3116 - -#define DM_ASCII 1 -#define DM_C40 2 -#define DM_TEXT 3 -#define DM_X12 4 -#define DM_EDIFACT 5 -#define DM_BASE256 6 - -static int c40_shift[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - -static int c40_value[] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, - 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, - 15,16,17,18,19,20,21,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39, - 22,23,24,25,26,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; - -static int text_shift[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 }; - -static int text_value[] = { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, - 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, - 15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, - 22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 }; - -static int intsymbol[] = { - 0,1,3,5,7,8,10,12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,2,4,6,9,11,14 }; - -static int matrixH[] = { - 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 32, 36, 40, 44, 48, - 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 }; - -static int matrixW[] = { - 10, 12, 18, 14, 32, 16, 26, 18, 20, 36, 22, 36, 24, 26, 48, 32, 36, 40, 44, - 48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 }; - -static int matrixFH[] = { - 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 16, 18, 20, 22, 24, - 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 }; - -static int matrixFW[] = { - 10, 12, 18, 14, 16, 16, 26, 18, 20, 18, 22, 18, 24, 26, 24, 16, 18, 20, 22, - 24, 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 }; - -static int matrixbytes[] = { - 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, - 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558 }; - -static int matrixdatablock[] = { - 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, - 174, 102, 140, 92, 114, 144, 174, 136, 175, 163, 156 }; - -static int matrixrsblock[] = { - 5, 7, 7, 10, 11, 12, 14, 14, 18, 18, 20, 24, 24, 28, 28, 36, 42, 48, 56, 68, - 42, 56, 36, 48, 56, 68, 56, 68, 62, 62 }; - -#endif /* __IEC16022ECC200_H */ diff --git a/3rdparty/zint-2.4.4/backend/font.h b/3rdparty/zint-2.4.4/backend/font.h deleted file mode 100644 index 2c32b5e..0000000 --- a/3rdparty/zint-2.4.4/backend/font.h +++ /dev/null @@ -1,1691 +0,0 @@ -/* font.h - Font for PNG images */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* This file contains the pixel-by-pixel representation of the "Misc Fixed" font - at 10 point size processed by the Gimp */ - -static int ascii_font[9310] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0, - 0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1, - 0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0, - 1,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0, - 0,0,1,0,0,0,0,1,1,1,1,0,0,1,1,1, - 1,1,1,0,0,0,0,0,1,0,0,1,1,1,1,1, - 1,0,0,0,1,1,1,0,0,1,1,1,1,1,1,0, - 0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0, - 0,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1, - 1,1,0,0,1,1,1,1,0,0,0,1,1,1,1,1, - 1,0,1,1,1,1,1,1,0,0,1,1,1,1,0,0, - 1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,0, - 0,1,1,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1, - 0,0,1,1,1,1,0,0,1,1,1,1,1,0,0,0, - 1,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1, - 1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0, - 1,0,0,0,0,1,0,0,1,0,0,0,1,0,1,1, - 1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,1, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,1,1,1,1,0,0,1,0,0,1,0, - 1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0, - 0,1,1,0,0,0,1,0,0,0,0,1,0,0,0,0, - 0,0,1,0,0,0,0,1,1,0,0,1,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,1,0,0,0,0,1,0,0,1,0,0,0,1,0,0, - 1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0, - 0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0, - 0,0,0,1,1,0,0,1,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0, - 1,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0, - 0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,1, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1, - 0,1,0,0,1,0,0,1,0,1,0,1,0,0,1,1, - 0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0, - 0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0, - 1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0, - 0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,1,0,0,0,0,1,0,1,0,0,1,1,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0, - 0,0,0,1,1,0,0,1,1,0,1,1,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0, - 0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0, - 0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,1,0,1,0,0,1,0,1,0,0,1,1,1,0, - 0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1, - 0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, - 1,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1, - 0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0, - 1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1, - 0,0,0,1,1,1,1,1,1,0,0,0,0,1,0,0, - 0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,0,0,1,0,1,1,0,1,0,1,1,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0, - 0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,0,0,1,0,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,0,1,0,0,1,1,1,1, - 0,0,0,0,1,0,0,0,0,0,1,1,1,0,1,0, - 1,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0, - 0,0,1,1,0,1,0,0,0,1,0,0,0,0,0,1, - 0,0,0,0,1,1,0,1,0,0,1,0,1,1,1,0, - 0,0,1,1,1,1,0,0,1,0,1,1,1,0,0,0, - 1,1,1,0,1,0,1,0,1,1,1,0,0,0,1,1, - 1,1,0,0,1,1,1,1,1,0,0,1,0,0,0,0, - 1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,1,1, - 1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, - 1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1, - 1,1,0,0,0,1,0,0,1,0,0,1,0,0,0,0, - 1,0,1,0,1,1,1,0,0,0,0,0,1,0,0,0, - 0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, - 0,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1, - 0,0,0,0,1,0,1,1,1,1,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,0, - 0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0, - 1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,0, - 0,0,0,1,0,1,1,0,1,0,1,0,1,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,1, - 0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0, - 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, - 0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,1,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0, - 1,0,1,1,1,1,1,0,0,1,0,0,0,1,0,0, - 1,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1, - 0,1,0,0,0,0,1,0,1,1,0,0,0,1,0,1, - 0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,0, - 0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0, - 1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0, - 0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0, - 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0, - 1,0,1,1,0,0,0,1,0,0,0,0,1,0,0,0, - 0,1,0,0,1,0,0,0,1,1,1,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1, - 1,1,1,1,1,0,1,0,0,0,1,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,1,1,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,0,0,1,0,0,0,0,1,0,1,0,0,1,0,1, - 0,1,0,0,0,0,1,0,1,1,1,1,1,0,0,1, - 0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0, - 1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0, - 0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0, - 0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0, - 1,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0, - 0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0, - 0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,1,0,0,0,0,1,0,1,0,0,0,1,1,1, - 0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, - 1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0, - 0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0, - 0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1, - 1,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0, - 0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,1,0,0,1,0,0,0,1,0,1,0,1,0, - 0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,1, - 1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,1,1,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1, - 1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0, - 1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0, - 0,0,1,1,0,0,0,1,0,0,0,0,1,0,0,0, - 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,1,0,0,1,0,0,1,0,1,0,0,1,1,0,0, - 1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1, - 0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,1,1,1,1,1,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0, - 0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0, - 0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1, - 0,0,1,0,1,0,1,0,0,0,1,0,0,1,0,0, - 0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,0,1,1,0,0,0,0,1,0,1,0,1,0, - 0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0, - 1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0, - 0,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0, - 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,0, - 1,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0, - 0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0, - 0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0, - 1,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0, - 1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0, - 0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,1,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0, - 0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0, - 0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1, - 0,0,0,1,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 1,0,0,0,1,1,0,0,0,0,1,0,1,0,1,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,1,1,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0, - 1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1, - 0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,1,0,0,0,1,0,1, - 0,0,0,1,1,0,1,0,0,0,0,0,0,1,0,0, - 0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1, - 1,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0, - 1,0,0,0,0,1,0,0,1,1,1,0,1,0,0,1, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,1,0,0,0,1,1,1,1,0,0,1,0,0,1,1, - 0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, - 0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0, - 1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,1, - 1,1,0,0,0,0,0,0,1,0,0,0,1,1,1,1, - 0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0, - 0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0, - 0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,1, - 0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,1, - 1,1,0,0,1,1,1,1,0,0,0,1,1,1,1,1, - 1,0,1,0,0,0,0,0,0,0,1,1,1,0,1,0, - 1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1, - 1,1,0,0,0,1,0,0,0,0,1,0,1,1,1,1, - 1,1,0,1,0,0,0,0,1,0,1,0,0,0,0,1, - 0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0, - 1,1,1,1,0,0,1,0,0,0,0,1,0,0,1,1, - 1,1,0,0,0,0,0,1,0,0,0,0,1,1,1,1, - 0,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,1,1, - 1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,0,1,0,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,0,1,0,0,1,1,1,1, - 0,0,0,0,1,0,0,0,0,1,0,1,1,1,0,0, - 1,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1, - 0,0,0,1,0,1,0,0,0,0,1,0,0,1,1,1, - 1,1,0,0,1,0,0,0,1,0,1,0,0,0,0,1, - 0,0,1,1,1,1,0,0,1,0,1,1,1,0,0,0, - 1,1,1,0,1,0,1,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,0, - 1,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0, - 1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1, - 1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0, - 0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, - 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1, - 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0 -}; - -static int ascii_ext_font[9310] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,0,0,0,1,1,0,0,0,0,1,1, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0, - 1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0, - 0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, - 0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0, - 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0, - 0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1, - 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0, - 1,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1, - 0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,1, - 0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,1, - 0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0, - 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0, - 0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,1,1,1,1,1,0,0,1,0,0,1,0,0,0, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0, - 0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0, - 1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1, - 0,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,1, - 0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0, - 1,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1, - 0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1, - 0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0, - 0,1,0,1,1,0,0,0,1,0,0,0,1,0,0,1, - 0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0, - 0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,1, - 1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0, - 0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0, - 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1, - 1,1,1,1,0,1,1,1,1,1,1,0,0,1,1,1, - 1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1, - 0,0,1,1,1,1,1,0,0,1,0,0,0,1,0,1, - 1,0,0,0,1,0,0,1,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1, - 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0, - 1,0,0,0,1,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0, - 0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0, - 1,1,0,0,0,1,0,0,1,0,0,0,0,1,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1, - 0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,1, - 0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,1, - 0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,1, - 0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0, - 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1, - 0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0, - 0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0, - 1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, - 0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0, - 1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0, - 0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1, - 0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1, - 1,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0, - 1,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,1,0,0,0,1,0,1,1,1,1,1,0, - 0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,1, - 0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0, - 0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,1, - 0,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 1,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0, - 1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1, - 0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1, - 1,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1, - 0,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0, - 1,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1, - 0,0,0,1,1,1,1,1,0,0,1,1,1,1,0,0, - 0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1, - 1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,1, - 0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0, - 0,0,0,1,1,0,0,0,0,0,1,1,1,1,0,1, - 0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1, - 0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0, - 0,1,1,1,1,0,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,1,0,0,0,0,1,0,1,0,1,1,1,0, - 0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1, - 0,0,0,0,0,1,0,0,1,0,0,0,1,1,1,1, - 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0, - 1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,1,1,0,1,0,0, - 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,1,1,1,1,1,0,1,0,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,1,1,1,1,0,0,1,1, - 0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0, - 1,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1, - 0,0,1,1,1,0,0,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1, - 1,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0, - 1,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,1,0,0,0,0,1,0,1,1,0,0,0,1, - 0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,1, - 1,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0, - 0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0, - 0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, - 0,0,0,0,1,1,1,1,0,0,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,1, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 1,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1, - 1,1,1,0,0,0,0,1,0,1,0,0,0,0,1,0, - 0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,1, - 0,0,0,1,0,0,0,0,1,1,1,1,1,1,0,1, - 1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1, - 1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1, - 1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0, - 1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1, - 1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1, - 0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1, - 0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,0, - 0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0, - 1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,1, - 1,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0, - 1,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,1, - 0,0,1,0,0,0,1,0,0, - 0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1, - 1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0, - 0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1, - 1,1,1,1,0,1,0,1,0,0,0,0,0,1,1,1, - 1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0, - 1,1,0,0,0,1,1,0,1,0,0,1,0,0,1,1, - 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1, - 0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0, - 1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1, - 0,0,1,0,0,0,1,0,0,1,1,0,0,1,0,0, - 1,1,0,0,1,0,0,1,1,0,0,1,0,0,1,1, - 0,0,1,0,0,1,1,0,0,1,0,0,1,1,0,0, - 1,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0, - 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1, - 1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0, - 1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1, - 0,0,1,0,0,1,0,0,0, - 0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0, - 0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1, - 0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,1, - 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1, - 0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,0,1,0,0,0,1,1,1,1,1,0, - 0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,1,1,1,1,1,1,0, - 1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1, - 0,0,0,1,0,1,0,0,0, - 0,0,1,0,0,0,1,0,1,0,0,1,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1, - 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1, - 1,1,0,1,0,0,0,1,0,0,1,0,0,1,1,1, - 0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1, - 0,0,0,1,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,1,0,0,0,1,0, - 1,1,0,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0, - 0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,0,1,0,1,0,0,0,1,1,0,1, - 0,0,0,1,1,0,1,0,0,0,1,1,0,1,0,0, - 0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,1, - 1,0,1,0,0,1,0,0,1,1,0,0,0,0,1,0, - 1,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0, - 0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0, - 1,1,0,0,0,1,0,1,0,0,0,1,1,0,1,0, - 0,0,1,1,0,1,0,0,0,1,1,0,1,0,0,0, - 1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1, - 0,0,0,1,1,1,0,0,0, - 0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,1, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0, - 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, - 0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, - 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,1,0,1,0,0,1,1,1,0,0,0,0,0,0,1, - 0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1, - 0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0, - 0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0, - 1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,0, - 1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1, - 1,1,1,1,0,1,1,1,1,1,1,0,0,1,1,1, - 1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1, - 0,0,1,1,1,1,1,0,0,1,1,1,1,0,0,1, - 0,0,0,1,1,0,0,1,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1, - 0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,1, - 0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1, - 1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1, - 1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0, - 0,1,1,1,1,1,0,0,0,1,1,1,0,1,0,0, - 1,1,1,0,1,0,0,1,1,1,0,1,0,0,1,1, - 1,0,1,0,0,1,1,1,0,1,0,0,1,1,1,0, - 1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,0, - 0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,1, - 1,1,1,0,0,0,1,1,1,1,0,0,0,1,1,1, - 1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,1, - 0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,1, - 0,0,0,0,1,0,0,1,1,1,1,0,0,0,1,1, - 1,1,0,0,0,1,1,1,1,0,0,0,1,1,1,1, - 0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0, - 0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,1, - 1,1,0,1,0,0,1,1,1,0,1,0,0,1,1,1, - 0,1,0,0,0,0,1,0,0,0,1,0,1,1,1,0, - 0,0,0,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0, - 0,1,0,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0, - 0,0,1,1,0,0,0,0,0 -}; - -static int small_font[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,0,1,0,0,0,1,1,0,0,1,1,1,1,0,0, - 0,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1, - 1,1,0,0,1,1,0,0,0,1,1,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0, - 0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,1, - 1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,1, - 1,0,0,1,0,0,1,0,0,1,1,1,0,0,0,0, - 1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1, - 0,1,0,0,1,0,0,1,1,0,0,1,1,1,0,0, - 0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0, - 1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,0, - 0,1,0,1,0,0,1,0,0,1,0,1,0,1,1,1, - 1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1, - 0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0, - 1,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0, - 0,0,1,0,1,0,0,0,0,0,0, - 0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0, - 1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0, - 1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0, - 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0, - 0,1,1,0,0,1,0,0,1,0,0,0,0,1,0,0, - 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0, - 0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,1, - 0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,0,0,1,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0, - 0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0, - 1,0,1,0,1,0,0,1,0,0,0,0,1,1,1,1, - 0,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0, - 0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0, - 0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0, - 1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1, - 0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0, - 0,1,0,1,0,0,0,0,0,0,0, - 0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1, - 0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0, - 1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0, - 0,0,1,0,0,0,0,0,1,0,0,1,1,0,0,1, - 0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0, - 1,0,0,0,1,1,0,0,1,0,0,1,0,0,1,1, - 0,0,0,1,1,0,0,0,0,1,0,0,1,1,1,1, - 0,0,0,1,0,0,0,0,0,1,0,1,0,1,1,0, - 1,0,0,1,0,1,1,1,0,0,1,0,0,0,0,1, - 0,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0, - 0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0, - 1,0,1,1,0,0,0,1,0,0,0,0,1,1,1,1, - 0,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0, - 0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0, - 0,1,0,0,1,1,0,0,0,1,0,1,0,0,0,1, - 0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,1,1,0,1,1,1,0,0,0,1,1,0,0,0, - 1,1,1,0,0,1,1,0,0,0,1,0,0,0,0,1, - 1,1,0,1,1,1,0,0,0,1,1,0,0,0,0,0, - 1,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0, - 0,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0, - 0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,1, - 1,1,0,0,1,0,0,1,0,0,1,0,1,0,1,0, - 0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1, - 1,0,0,1,1,0,0,0,0,1,0,0,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0, - 1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1, - 1,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0, - 0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1, - 1,1,1,0,0,0,0,1,0,1,0,0,1,0,0,0, - 1,0,0,1,0,0,1,0,0,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,1,0,0,1,0,1,1,0, - 1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1, - 0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0, - 1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0, - 1,0,1,1,0,0,0,1,0,0,0,0,1,0,0,1, - 0,1,0,1,1,0,1,0,0,1,0,1,1,1,0,0, - 1,0,0,1,0,1,1,1,0,0,0,0,1,0,0,0, - 0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,1, - 1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0, - 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, - 0,0,1,0,1,0,1,1,0,1,1,1,0,0,1,0, - 0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0, - 1,0,1,1,0,0,0,0,0,1,0,0,1,1,1,1, - 0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,1,0,0,0,0, - 1,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0, - 0,1,0,0,1,1,0,0,1,0,0,1,0,0,0,1, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0, - 0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0, - 0,0,1,1,0,0,1,0,0,0,0,0,1,0,1,0, - 0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0, - 0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1, - 0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,1, - 0,0,0,1,1,0,0,0,0,1,0,0,1,1,1,1, - 0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0, - 0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0, - 1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1, - 0,1,0,1,1,0,1,0,0,1,0,1,0,0,0,0, - 1,1,0,1,0,1,0,1,0,0,1,0,0,1,0,0, - 0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,1, - 1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,1,1,0,1,0,0,1,0,1,0,0,0,0,1, - 0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,1, - 1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0, - 1,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1, - 0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,0,0,0,0,1,1,0,0, - 1,0,0,0,1,0,0,1,0,0,1,0,1,0,1,1, - 1,1,0,0,1,1,0,0,0,1,0,1,0,0,1,0, - 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0, - 1,1,1,0,0,0,0,1,0,0,1,0,1,0,0,0, - 0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0, - 1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0, - 0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0, - 0,1,1,1,0,1,1,1,1,0,0,1,1,0,0,0, - 0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1, - 0,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1, - 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0, - 0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0, - 1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,1, - 1,1,0,0,1,1,1,1,0,1,0,0,0,0,0,1, - 1,1,0,1,0,0,1,0,0,1,1,1,0,0,1,1, - 0,0,1,0,0,1,0,1,1,1,1,0,1,0,0,1, - 0,1,0,0,1,0,0,1,1,0,0,1,0,0,0,0, - 0,1,1,0,0,1,0,0,1,0,0,1,1,0,0,0, - 0,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0, - 0,1,0,1,0,0,1,0,0,0,1,0,0,1,1,1, - 1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1, - 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0, - 0,1,0,1,0,1,1,1,0,0,0,1,1,0,0,0, - 1,1,1,0,0,1,1,0,0,0,1,0,0,0,1,0, - 0,0,0,1,0,0,1,0,0,1,1,1,0,0,1,0, - 1,0,1,0,0,1,0,0,1,1,1,0,1,0,0,1, - 0,1,0,0,1,0,0,1,1,0,0,1,1,1,0,0, - 0,1,1,1,0,1,0,0,0,0,1,1,1,0,0,0, - 0,1,1,0,0,1,1,1,0,0,0,1,0,0,1,1, - 1,1,0,1,0,0,1,0,0,0,1,0,0,1,1,1, - 1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, - 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0 -}; - -static int small_font_extended[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, - 1,1,0,0,1,0,1,0,0,1,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,1,0,1,1,1,1,0,0,0,1,0,0, - 0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0, - 0,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0, - 0,1,1,0,0,0,0,0,1,0,0,0,1,1,0,0, - 0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1, - 0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1, - 1,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1, - 1,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1, - 0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0, - 1,0,1,1,0,0,1,1,0,0,0,1,1,0,0,0, - 1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0, - 0,0,0,0,1,1,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1, - 0,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0, - 0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0, - 1,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0, - 0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0, - 0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0, - 0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0, - 1,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1, - 0,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0, - 0,0,0,0,0,0,0,1,0,1,0, - 0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1, - 0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1, - 0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,0, - 0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0, - 1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,1, - 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0, - 0,1,1,0,0,0,0,0,0,0,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0, - 1,1,0,0,0,1,1,0,0,1,0,1,0,0,1,0, - 0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,0, - 0,0,0,1,0,1,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1, - 0,1,1,1,0,0,1,0,0,1,0,0,0,1,0,0, - 0,1,0,0,0,0,1,0,1,0,1,0,1,0,0,0, - 0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0, - 0,0,1,0,1,0,0,0,0,0,0,0,0,1,1,0, - 1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0, - 0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1, - 1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,1,1,1,0,0,1,0,0,0,0, - 1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1, - 1,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1, - 0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, - 0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,0, - 1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0, - 0,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1, - 1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0, - 0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0, - 0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0, - 0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1, - 0,0,1,1,1,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0, - 1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0, - 0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1, - 0,1,0,0,1,0,1,0,1,0,0,0,1,1,1,0, - 0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0, - 1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0, - 1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1, - 0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0, - 0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0, - 1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0, - 1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0, - 0,0,0,0,1,1,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1, - 0,1,1,1,0,0,1,0,0,1,0, - 0,0,1,0,0,1,0,1,0,0,1,1,1,0,0,0, - 1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,1, - 0,1,0,0,0,0,0,0,1,1,0,0,1,0,0,0, - 0,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0, - 0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0, - 0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1, - 1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0, - 0,0,0,1,0,0,1,1,0,0,1,0,1,0,1,1, - 0,1,1,0,1,0,0,1,0,0,0,1,1,1,1,0, - 1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1, - 1,1,1,0,1,1,1,1,0,1,1,1,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0, - 1,0,1,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1, - 1,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0, - 0,1,1,1,0,0,1,0,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1, - 0,0,0,1,0,1,1,0,1,0,1,1,0,1,0,1, - 1,0,1,0,1,1,0,0,0,1,0,0,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1, - 1,1,0,1,0,1,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1, - 0,1,0,0,1,0,1,0,0,1,0, - 0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0, - 1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,0, - 1,1,0,0,0,0,0,0,1,0,1,0,1,0,0,0, - 0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0, - 0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,1, - 0,0,0,1,1,0,0,1,0,1,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0, - 0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0, - 0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0, - 1,0,1,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1, - 1,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0, - 0,1,0,0,0,0,1,0,0,1,0,1,0,1,1,0, - 1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1, - 0,1,1,0,1,0,1,1,0,1,0,1,0,0,0,1, - 0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0, - 0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0, - 0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0, - 0,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1, - 0,1,0,0,1,0,0,1,0,1,0, - 0,0,1,0,0,0,1,1,1,0,1,0,1,1,0,1, - 0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0, - 0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,1,1,0,0,0,1,0,1,0,0,0, - 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0, - 0,0,1,1,1,0,0,0,1,0,0,1,0,0,1,0, - 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1, - 0,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1, - 1,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1, - 1,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1, - 0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0, - 1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0, - 1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0, - 0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1, - 0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,0, - 0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,0, - 0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0, - 1,0,1,0,0,1,0,1,0,0,1,1,1,0,0,0, - 1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1, - 0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1, - 0,0,1,1,1,0,0,1,1,1,0,0,1,1,0,0, - 1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0, - 1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1, - 1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1, - 1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,0, - 0,1,1,1,0,0,0,0,1,0,0, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,1,0,0,0,0,0,1,0,0,0 -}; diff --git a/3rdparty/zint-2.4.4/backend/gb2312.h b/3rdparty/zint-2.4.4/backend/gb2312.h deleted file mode 100644 index eca1c50..0000000 --- a/3rdparty/zint-2.4.4/backend/gb2312.h +++ /dev/null @@ -1,7467 +0,0 @@ -/* gb2312.h - Unicode to GB 2312-1980 lookup table - - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -unsigned long int gb2312_lookup[] = { - 0x00A4, 0xA1E8, - 0x00A7, 0xA1EC, - 0x00A8, 0xA1A7, - 0x00B0, 0xA1E3, - 0x00B1, 0xA1C0, - 0x00B7, 0xA1A4, - 0x00D7, 0xA1C1, - 0x00E0, 0xA8A4, - 0x00E1, 0xA8A2, - 0x00E8, 0xA8A8, - 0x00E9, 0xA8A6, - 0x00EA, 0xA8BA, - 0x00EC, 0xA8AC, - 0x00ED, 0xA8AA, - 0x00F2, 0xA8B0, - 0x00F3, 0xA8AE, - 0x00F7, 0xA1C2, - 0x00F9, 0xA8B4, - 0x00FA, 0xA8B2, - 0x00FC, 0xA8B9, - 0x0101, 0xA8A1, - 0x0113, 0xA8A5, - 0x011B, 0xA8A7, - 0x012B, 0xA8A9, - 0x014D, 0xA8AD, - 0x016B, 0xA8B1, - 0x01CE, 0xA8A3, - 0x01D0, 0xA8AB, - 0x01D2, 0xA8AF, - 0x01D4, 0xA8B3, - 0x01D6, 0xA8B5, - 0x01D8, 0xA8B6, - 0x01DA, 0xA8B7, - 0x01DC, 0xA8B8, - 0x02C7, 0xA1A6, - 0x02C9, 0xA1A5, - 0x0391, 0xA6A1, - 0x0392, 0xA6A2, - 0x0393, 0xA6A3, - 0x0394, 0xA6A4, - 0x0395, 0xA6A5, - 0x0396, 0xA6A6, - 0x0397, 0xA6A7, - 0x0398, 0xA6A8, - 0x0399, 0xA6A9, - 0x039A, 0xA6AA, - 0x039B, 0xA6AB, - 0x039C, 0xA6AC, - 0x039D, 0xA6AD, - 0x039E, 0xA6AE, - 0x039F, 0xA6AF, - 0x03A0, 0xA6B0, - 0x03A1, 0xA6B1, - 0x03A3, 0xA6B2, - 0x03A4, 0xA6B3, - 0x03A5, 0xA6B4, - 0x03A6, 0xA6B5, - 0x03A7, 0xA6B6, - 0x03A8, 0xA6B7, - 0x03A9, 0xA6B8, - 0x03B1, 0xA6C1, - 0x03B2, 0xA6C2, - 0x03B3, 0xA6C3, - 0x03B4, 0xA6C4, - 0x03B5, 0xA6C5, - 0x03B6, 0xA6C6, - 0x03B7, 0xA6C7, - 0x03B8, 0xA6C8, - 0x03B9, 0xA6C9, - 0x03BA, 0xA6CA, - 0x03BB, 0xA6CB, - 0x03BC, 0xA6CC, - 0x03BD, 0xA6CD, - 0x03BE, 0xA6CE, - 0x03BF, 0xA6CF, - 0x03C0, 0xA6D0, - 0x03C1, 0xA6D1, - 0x03C3, 0xA6D2, - 0x03C4, 0xA6D3, - 0x03C5, 0xA6D4, - 0x03C6, 0xA6D5, - 0x03C7, 0xA6D6, - 0x03C8, 0xA6D7, - 0x03C9, 0xA6D8, - 0x0401, 0xA7A7, - 0x0410, 0xA7A1, - 0x0411, 0xA7A2, - 0x0412, 0xA7A3, - 0x0413, 0xA7A4, - 0x0414, 0xA7A5, - 0x0415, 0xA7A6, - 0x0416, 0xA7A8, - 0x0417, 0xA7A9, - 0x0418, 0xA7AA, - 0x0419, 0xA7AB, - 0x041A, 0xA7AC, - 0x041B, 0xA7AD, - 0x041C, 0xA7AE, - 0x041D, 0xA7AF, - 0x041E, 0xA7B0, - 0x041F, 0xA7B1, - 0x0420, 0xA7B2, - 0x0421, 0xA7B3, - 0x0422, 0xA7B4, - 0x0423, 0xA7B5, - 0x0424, 0xA7B6, - 0x0425, 0xA7B7, - 0x0426, 0xA7B8, - 0x0427, 0xA7B9, - 0x0428, 0xA7BA, - 0x0429, 0xA7BB, - 0x042A, 0xA7BC, - 0x042B, 0xA7BD, - 0x042C, 0xA7BE, - 0x042D, 0xA7BF, - 0x042E, 0xA7C0, - 0x042F, 0xA7C1, - 0x0430, 0xA7D1, - 0x0431, 0xA7D2, - 0x0432, 0xA7D3, - 0x0433, 0xA7D4, - 0x0434, 0xA7D5, - 0x0435, 0xA7D6, - 0x0436, 0xA7D8, - 0x0437, 0xA7D9, - 0x0438, 0xA7DA, - 0x0439, 0xA7DB, - 0x043A, 0xA7DC, - 0x043B, 0xA7DD, - 0x043C, 0xA7DE, - 0x043D, 0xA7DF, - 0x043E, 0xA7E0, - 0x043F, 0xA7E1, - 0x0440, 0xA7E2, - 0x0441, 0xA7E3, - 0x0442, 0xA7E4, - 0x0443, 0xA7E5, - 0x0444, 0xA7E6, - 0x0445, 0xA7E7, - 0x0446, 0xA7E8, - 0x0447, 0xA7E9, - 0x0448, 0xA7EA, - 0x0449, 0xA7EB, - 0x044A, 0xA7EC, - 0x044B, 0xA7ED, - 0x044C, 0xA7EE, - 0x044D, 0xA7EF, - 0x044E, 0xA7F0, - 0x044F, 0xA7F1, - 0x0451, 0xA7D7, - 0x2014, 0xA1AA, - 0x2016, 0xA1AC, - 0x2018, 0xA1AE, - 0x2019, 0xA1AF, - 0x201C, 0xA1B0, - 0x201D, 0xA1B1, - 0x2026, 0xA1AD, - 0x2030, 0xA1EB, - 0x2032, 0xA1E4, - 0x2033, 0xA1E5, - 0x203B, 0xA1F9, - 0x2103, 0xA1E6, - 0x2116, 0xA1ED, - 0x2160, 0xA2F1, - 0x2161, 0xA2F2, - 0x2162, 0xA2F3, - 0x2163, 0xA2F4, - 0x2164, 0xA2F5, - 0x2165, 0xA2F6, - 0x2166, 0xA2F7, - 0x2167, 0xA2F8, - 0x2168, 0xA2F9, - 0x2169, 0xA2FA, - 0x216A, 0xA2FB, - 0x216B, 0xA2FC, - 0x2190, 0xA1FB, - 0x2191, 0xA1FC, - 0x2192, 0xA1FA, - 0x2193, 0xA1FD, - 0x2208, 0xA1CA, - 0x220F, 0xA1C7, - 0x2211, 0xA1C6, - 0x221A, 0xA1CC, - 0x221D, 0xA1D8, - 0x221E, 0xA1DE, - 0x2220, 0xA1CF, - 0x2225, 0xA1CE, - 0x2227, 0xA1C4, - 0x2228, 0xA1C5, - 0x2229, 0xA1C9, - 0x222A, 0xA1C8, - 0x222B, 0xA1D2, - 0x222E, 0xA1D3, - 0x2234, 0xA1E0, - 0x2235, 0xA1DF, - 0x2236, 0xA1C3, - 0x2237, 0xA1CB, - 0x223D, 0xA1D7, - 0x2248, 0xA1D6, - 0x224C, 0xA1D5, - 0x2260, 0xA1D9, - 0x2261, 0xA1D4, - 0x2264, 0xA1DC, - 0x2265, 0xA1DD, - 0x226E, 0xA1DA, - 0x226F, 0xA1DB, - 0x2299, 0xA1D1, - 0x22A5, 0xA1CD, - 0x2312, 0xA1D0, - 0x2460, 0xA2D9, - 0x2461, 0xA2DA, - 0x2462, 0xA2DB, - 0x2463, 0xA2DC, - 0x2464, 0xA2DD, - 0x2465, 0xA2DE, - 0x2466, 0xA2DF, - 0x2467, 0xA2E0, - 0x2468, 0xA2E1, - 0x2469, 0xA2E2, - 0x2474, 0xA2C5, - 0x2475, 0xA2C6, - 0x2476, 0xA2C7, - 0x2477, 0xA2C8, - 0x2478, 0xA2C9, - 0x2479, 0xA2CA, - 0x247A, 0xA2CB, - 0x247B, 0xA2CC, - 0x247C, 0xA2CD, - 0x247D, 0xA2CE, - 0x247E, 0xA2CF, - 0x247F, 0xA2D0, - 0x2480, 0xA2D1, - 0x2481, 0xA2D2, - 0x2482, 0xA2D3, - 0x2483, 0xA2D4, - 0x2484, 0xA2D5, - 0x2485, 0xA2D6, - 0x2486, 0xA2D7, - 0x2487, 0xA2D8, - 0x2488, 0xA2B1, - 0x2489, 0xA2B2, - 0x248A, 0xA2B3, - 0x248B, 0xA2B4, - 0x248C, 0xA2B5, - 0x248D, 0xA2B6, - 0x248E, 0xA2B7, - 0x248F, 0xA2B8, - 0x2490, 0xA2B9, - 0x2491, 0xA2BA, - 0x2492, 0xA2BB, - 0x2493, 0xA2BC, - 0x2494, 0xA2BD, - 0x2495, 0xA2BE, - 0x2496, 0xA2BF, - 0x2497, 0xA2C0, - 0x2498, 0xA2C1, - 0x2499, 0xA2C2, - 0x249A, 0xA2C3, - 0x249B, 0xA2C4, - 0x2500, 0xA9A4, - 0x2501, 0xA9A5, - 0x2502, 0xA9A6, - 0x2503, 0xA9A7, - 0x2504, 0xA9A8, - 0x2505, 0xA9A9, - 0x2506, 0xA9AA, - 0x2507, 0xA9AB, - 0x2508, 0xA9AC, - 0x2509, 0xA9AD, - 0x250A, 0xA9AE, - 0x250B, 0xA9AF, - 0x250C, 0xA9B0, - 0x250D, 0xA9B1, - 0x250E, 0xA9B2, - 0x250F, 0xA9B3, - 0x2510, 0xA9B4, - 0x2511, 0xA9B5, - 0x2512, 0xA9B6, - 0x2513, 0xA9B7, - 0x2514, 0xA9B8, - 0x2515, 0xA9B9, - 0x2516, 0xA9BA, - 0x2517, 0xA9BB, - 0x2518, 0xA9BC, - 0x2519, 0xA9BD, - 0x251A, 0xA9BE, - 0x251B, 0xA9BF, - 0x251C, 0xA9C0, - 0x251D, 0xA9C1, - 0x251E, 0xA9C2, - 0x251F, 0xA9C3, - 0x2520, 0xA9C4, - 0x2521, 0xA9C5, - 0x2522, 0xA9C6, - 0x2523, 0xA9C7, - 0x2524, 0xA9C8, - 0x2525, 0xA9C9, - 0x2526, 0xA9CA, - 0x2527, 0xA9CB, - 0x2528, 0xA9CC, - 0x2529, 0xA9CD, - 0x252A, 0xA9CE, - 0x252B, 0xA9CF, - 0x252C, 0xA9D0, - 0x252D, 0xA9D1, - 0x252E, 0xA9D2, - 0x252F, 0xA9D3, - 0x2530, 0xA9D4, - 0x2531, 0xA9D5, - 0x2532, 0xA9D6, - 0x2533, 0xA9D7, - 0x2534, 0xA9D8, - 0x2535, 0xA9D9, - 0x2536, 0xA9DA, - 0x2537, 0xA9DB, - 0x2538, 0xA9DC, - 0x2539, 0xA9DD, - 0x253A, 0xA9DE, - 0x253B, 0xA9DF, - 0x253C, 0xA9E0, - 0x253D, 0xA9E1, - 0x253E, 0xA9E2, - 0x253F, 0xA9E3, - 0x2540, 0xA9E4, - 0x2541, 0xA9E5, - 0x2542, 0xA9E6, - 0x2543, 0xA9E7, - 0x2544, 0xA9E8, - 0x2545, 0xA9E9, - 0x2546, 0xA9EA, - 0x2547, 0xA9EB, - 0x2548, 0xA9EC, - 0x2549, 0xA9ED, - 0x254A, 0xA9EE, - 0x254B, 0xA9EF, - 0x25A0, 0xA1F6, - 0x25A1, 0xA1F5, - 0x25B2, 0xA1F8, - 0x25B3, 0xA1F7, - 0x25C6, 0xA1F4, - 0x25C7, 0xA1F3, - 0x25CB, 0xA1F0, - 0x25CE, 0xA1F2, - 0x25CF, 0xA1F1, - 0x2605, 0xA1EF, - 0x2606, 0xA1EE, - 0x2640, 0xA1E2, - 0x2642, 0xA1E1, - 0x3000, 0xA1A1, - 0x3001, 0xA1A2, - 0x3002, 0xA1A3, - 0x3003, 0xA1A8, - 0x3005, 0xA1A9, - 0x3008, 0xA1B4, - 0x3009, 0xA1B5, - 0x300A, 0xA1B6, - 0x300B, 0xA1B7, - 0x300C, 0xA1B8, - 0x300D, 0xA1B9, - 0x300E, 0xA1BA, - 0x300F, 0xA1BB, - 0x3010, 0xA1BE, - 0x3011, 0xA1BF, - 0x3013, 0xA1FE, - 0x3014, 0xA1B2, - 0x3015, 0xA1B3, - 0x3016, 0xA1BC, - 0x3017, 0xA1BD, - 0x3041, 0xA4A1, - 0x3042, 0xA4A2, - 0x3043, 0xA4A3, - 0x3044, 0xA4A4, - 0x3045, 0xA4A5, - 0x3046, 0xA4A6, - 0x3047, 0xA4A7, - 0x3048, 0xA4A8, - 0x3049, 0xA4A9, - 0x304A, 0xA4AA, - 0x304B, 0xA4AB, - 0x304C, 0xA4AC, - 0x304D, 0xA4AD, - 0x304E, 0xA4AE, - 0x304F, 0xA4AF, - 0x3050, 0xA4B0, - 0x3051, 0xA4B1, - 0x3052, 0xA4B2, - 0x3053, 0xA4B3, - 0x3054, 0xA4B4, - 0x3055, 0xA4B5, - 0x3056, 0xA4B6, - 0x3057, 0xA4B7, - 0x3058, 0xA4B8, - 0x3059, 0xA4B9, - 0x305A, 0xA4BA, - 0x305B, 0xA4BB, - 0x305C, 0xA4BC, - 0x305D, 0xA4BD, - 0x305E, 0xA4BE, - 0x305F, 0xA4BF, - 0x3060, 0xA4C0, - 0x3061, 0xA4C1, - 0x3062, 0xA4C2, - 0x3063, 0xA4C3, - 0x3064, 0xA4C4, - 0x3065, 0xA4C5, - 0x3066, 0xA4C6, - 0x3067, 0xA4C7, - 0x3068, 0xA4C8, - 0x3069, 0xA4C9, - 0x306A, 0xA4CA, - 0x306B, 0xA4CB, - 0x306C, 0xA4CC, - 0x306D, 0xA4CD, - 0x306E, 0xA4CE, - 0x306F, 0xA4CF, - 0x3070, 0xA4D0, - 0x3071, 0xA4D1, - 0x3072, 0xA4D2, - 0x3073, 0xA4D3, - 0x3074, 0xA4D4, - 0x3075, 0xA4D5, - 0x3076, 0xA4D6, - 0x3077, 0xA4D7, - 0x3078, 0xA4D8, - 0x3079, 0xA4D9, - 0x307A, 0xA4DA, - 0x307B, 0xA4DB, - 0x307C, 0xA4DC, - 0x307D, 0xA4DD, - 0x307E, 0xA4DE, - 0x307F, 0xA4DF, - 0x3080, 0xA4E0, - 0x3081, 0xA4E1, - 0x3082, 0xA4E2, - 0x3083, 0xA4E3, - 0x3084, 0xA4E4, - 0x3085, 0xA4E5, - 0x3086, 0xA4E6, - 0x3087, 0xA4E7, - 0x3088, 0xA4E8, - 0x3089, 0xA4E9, - 0x308A, 0xA4EA, - 0x308B, 0xA4EB, - 0x308C, 0xA4EC, - 0x308D, 0xA4ED, - 0x308E, 0xA4EE, - 0x308F, 0xA4EF, - 0x3090, 0xA4F0, - 0x3091, 0xA4F1, - 0x3092, 0xA4F2, - 0x3093, 0xA4F3, - 0x30A1, 0xA5A1, - 0x30A2, 0xA5A2, - 0x30A3, 0xA5A3, - 0x30A4, 0xA5A4, - 0x30A5, 0xA5A5, - 0x30A6, 0xA5A6, - 0x30A7, 0xA5A7, - 0x30A8, 0xA5A8, - 0x30A9, 0xA5A9, - 0x30AA, 0xA5AA, - 0x30AB, 0xA5AB, - 0x30AC, 0xA5AC, - 0x30AD, 0xA5AD, - 0x30AE, 0xA5AE, - 0x30AF, 0xA5AF, - 0x30B0, 0xA5B0, - 0x30B1, 0xA5B1, - 0x30B2, 0xA5B2, - 0x30B3, 0xA5B3, - 0x30B4, 0xA5B4, - 0x30B5, 0xA5B5, - 0x30B6, 0xA5B6, - 0x30B7, 0xA5B7, - 0x30B8, 0xA5B8, - 0x30B9, 0xA5B9, - 0x30BA, 0xA5BA, - 0x30BB, 0xA5BB, - 0x30BC, 0xA5BC, - 0x30BD, 0xA5BD, - 0x30BE, 0xA5BE, - 0x30BF, 0xA5BF, - 0x30C0, 0xA5C0, - 0x30C1, 0xA5C1, - 0x30C2, 0xA5C2, - 0x30C3, 0xA5C3, - 0x30C4, 0xA5C4, - 0x30C5, 0xA5C5, - 0x30C6, 0xA5C6, - 0x30C7, 0xA5C7, - 0x30C8, 0xA5C8, - 0x30C9, 0xA5C9, - 0x30CA, 0xA5CA, - 0x30CB, 0xA5CB, - 0x30CC, 0xA5CC, - 0x30CD, 0xA5CD, - 0x30CE, 0xA5CE, - 0x30CF, 0xA5CF, - 0x30D0, 0xA5D0, - 0x30D1, 0xA5D1, - 0x30D2, 0xA5D2, - 0x30D3, 0xA5D3, - 0x30D4, 0xA5D4, - 0x30D5, 0xA5D5, - 0x30D6, 0xA5D6, - 0x30D7, 0xA5D7, - 0x30D8, 0xA5D8, - 0x30D9, 0xA5D9, - 0x30DA, 0xA5DA, - 0x30DB, 0xA5DB, - 0x30DC, 0xA5DC, - 0x30DD, 0xA5DD, - 0x30DE, 0xA5DE, - 0x30DF, 0xA5DF, - 0x30E0, 0xA5E0, - 0x30E1, 0xA5E1, - 0x30E2, 0xA5E2, - 0x30E3, 0xA5E3, - 0x30E4, 0xA5E4, - 0x30E5, 0xA5E5, - 0x30E6, 0xA5E6, - 0x30E7, 0xA5E7, - 0x30E8, 0xA5E8, - 0x30E9, 0xA5E9, - 0x30EA, 0xA5EA, - 0x30EB, 0xA5EB, - 0x30EC, 0xA5EC, - 0x30ED, 0xA5ED, - 0x30EE, 0xA5EE, - 0x30EF, 0xA5EF, - 0x30F0, 0xA5F0, - 0x30F1, 0xA5F1, - 0x30F2, 0xA5F2, - 0x30F3, 0xA5F3, - 0x30F4, 0xA5F4, - 0x30F5, 0xA5F5, - 0x30F6, 0xA5F6, - 0x3105, 0xA8C5, - 0x3106, 0xA8C6, - 0x3107, 0xA8C7, - 0x3108, 0xA8C8, - 0x3109, 0xA8C9, - 0x310A, 0xA8CA, - 0x310B, 0xA8CB, - 0x310C, 0xA8CC, - 0x310D, 0xA8CD, - 0x310E, 0xA8CE, - 0x310F, 0xA8CF, - 0x3110, 0xA8D0, - 0x3111, 0xA8D1, - 0x3112, 0xA8D2, - 0x3113, 0xA8D3, - 0x3114, 0xA8D4, - 0x3115, 0xA8D5, - 0x3116, 0xA8D6, - 0x3117, 0xA8D7, - 0x3118, 0xA8D8, - 0x3119, 0xA8D9, - 0x311A, 0xA8DA, - 0x311B, 0xA8DB, - 0x311C, 0xA8DC, - 0x311D, 0xA8DD, - 0x311E, 0xA8DE, - 0x311F, 0xA8DF, - 0x3120, 0xA8E0, - 0x3121, 0xA8E1, - 0x3122, 0xA8E2, - 0x3123, 0xA8E3, - 0x3124, 0xA8E4, - 0x3125, 0xA8E5, - 0x3126, 0xA8E6, - 0x3127, 0xA8E7, - 0x3128, 0xA8E8, - 0x3129, 0xA8E9, - 0x3220, 0xA2E5, - 0x3221, 0xA2E6, - 0x3222, 0xA2E7, - 0x3223, 0xA2E8, - 0x3224, 0xA2E9, - 0x3225, 0xA2EA, - 0x3226, 0xA2EB, - 0x3227, 0xA2EC, - 0x3228, 0xA2ED, - 0x3229, 0xA2EE, - 0x4E00, 0xD2BB, - 0x4E01, 0xB6A1, - 0x4E03, 0xC6DF, - 0x4E07, 0xCDF2, - 0x4E08, 0xD5C9, - 0x4E09, 0xC8FD, - 0x4E0A, 0xC9CF, - 0x4E0B, 0xCFC2, - 0x4E0C, 0xD8A2, - 0x4E0D, 0xB2BB, - 0x4E0E, 0xD3EB, - 0x4E10, 0xD8A4, - 0x4E11, 0xB3F3, - 0x4E13, 0xD7A8, - 0x4E14, 0xC7D2, - 0x4E15, 0xD8A7, - 0x4E16, 0xCAC0, - 0x4E18, 0xC7F0, - 0x4E19, 0xB1FB, - 0x4E1A, 0xD2B5, - 0x4E1B, 0xB4D4, - 0x4E1C, 0xB6AB, - 0x4E1D, 0xCBBF, - 0x4E1E, 0xD8A9, - 0x4E22, 0xB6AA, - 0x4E24, 0xC1BD, - 0x4E25, 0xD1CF, - 0x4E27, 0xC9A5, - 0x4E28, 0xD8AD, - 0x4E2A, 0xB8F6, - 0x4E2B, 0xD1BE, - 0x4E2C, 0xE3DC, - 0x4E2D, 0xD6D0, - 0x4E30, 0xB7E1, - 0x4E32, 0xB4AE, - 0x4E34, 0xC1D9, - 0x4E36, 0xD8BC, - 0x4E38, 0xCDE8, - 0x4E39, 0xB5A4, - 0x4E3A, 0xCEAA, - 0x4E3B, 0xD6F7, - 0x4E3D, 0xC0F6, - 0x4E3E, 0xBED9, - 0x4E3F, 0xD8AF, - 0x4E43, 0xC4CB, - 0x4E45, 0xBEC3, - 0x4E47, 0xD8B1, - 0x4E48, 0xC3B4, - 0x4E49, 0xD2E5, - 0x4E4B, 0xD6AE, - 0x4E4C, 0xCEDA, - 0x4E4D, 0xD5A7, - 0x4E4E, 0xBAF5, - 0x4E4F, 0xB7A6, - 0x4E50, 0xC0D6, - 0x4E52, 0xC6B9, - 0x4E53, 0xC5D2, - 0x4E54, 0xC7C7, - 0x4E56, 0xB9D4, - 0x4E58, 0xB3CB, - 0x4E59, 0xD2D2, - 0x4E5C, 0xD8BF, - 0x4E5D, 0xBEC5, - 0x4E5E, 0xC6F2, - 0x4E5F, 0xD2B2, - 0x4E60, 0xCFB0, - 0x4E61, 0xCFE7, - 0x4E66, 0xCAE9, - 0x4E69, 0xD8C0, - 0x4E70, 0xC2F2, - 0x4E71, 0xC2D2, - 0x4E73, 0xC8E9, - 0x4E7E, 0xC7AC, - 0x4E86, 0xC1CB, - 0x4E88, 0xD3E8, - 0x4E89, 0xD5F9, - 0x4E8B, 0xCAC2, - 0x4E8C, 0xB6FE, - 0x4E8D, 0xD8A1, - 0x4E8E, 0xD3DA, - 0x4E8F, 0xBFF7, - 0x4E91, 0xD4C6, - 0x4E92, 0xBBA5, - 0x4E93, 0xD8C1, - 0x4E94, 0xCEE5, - 0x4E95, 0xBEAE, - 0x4E98, 0xD8A8, - 0x4E9A, 0xD1C7, - 0x4E9B, 0xD0A9, - 0x4E9F, 0xD8BD, - 0x4EA0, 0xD9EF, - 0x4EA1, 0xCDF6, - 0x4EA2, 0xBFBA, - 0x4EA4, 0xBDBB, - 0x4EA5, 0xBAA5, - 0x4EA6, 0xD2E0, - 0x4EA7, 0xB2FA, - 0x4EA8, 0xBAE0, - 0x4EA9, 0xC4B6, - 0x4EAB, 0xCFED, - 0x4EAC, 0xBEA9, - 0x4EAD, 0xCDA4, - 0x4EAE, 0xC1C1, - 0x4EB2, 0xC7D7, - 0x4EB3, 0xD9F1, - 0x4EB5, 0xD9F4, - 0x4EBA, 0xC8CB, - 0x4EBB, 0xD8E9, - 0x4EBF, 0xD2DA, - 0x4EC0, 0xCAB2, - 0x4EC1, 0xC8CA, - 0x4EC2, 0xD8EC, - 0x4EC3, 0xD8EA, - 0x4EC4, 0xD8C6, - 0x4EC5, 0xBDF6, - 0x4EC6, 0xC6CD, - 0x4EC7, 0xB3F0, - 0x4EC9, 0xD8EB, - 0x4ECA, 0xBDF1, - 0x4ECB, 0xBDE9, - 0x4ECD, 0xC8D4, - 0x4ECE, 0xB4D3, - 0x4ED1, 0xC2D8, - 0x4ED3, 0xB2D6, - 0x4ED4, 0xD7D0, - 0x4ED5, 0xCACB, - 0x4ED6, 0xCBFB, - 0x4ED7, 0xD5CC, - 0x4ED8, 0xB8B6, - 0x4ED9, 0xCFC9, - 0x4EDD, 0xD9DA, - 0x4EDE, 0xD8F0, - 0x4EDF, 0xC7AA, - 0x4EE1, 0xD8EE, - 0x4EE3, 0xB4FA, - 0x4EE4, 0xC1EE, - 0x4EE5, 0xD2D4, - 0x4EE8, 0xD8ED, - 0x4EEA, 0xD2C7, - 0x4EEB, 0xD8EF, - 0x4EEC, 0xC3C7, - 0x4EF0, 0xD1F6, - 0x4EF2, 0xD6D9, - 0x4EF3, 0xD8F2, - 0x4EF5, 0xD8F5, - 0x4EF6, 0xBCFE, - 0x4EF7, 0xBCDB, - 0x4EFB, 0xC8CE, - 0x4EFD, 0xB7DD, - 0x4EFF, 0xB7C2, - 0x4F01, 0xC6F3, - 0x4F09, 0xD8F8, - 0x4F0A, 0xD2C1, - 0x4F0D, 0xCEE9, - 0x4F0E, 0xBCBF, - 0x4F0F, 0xB7FC, - 0x4F10, 0xB7A5, - 0x4F11, 0xD0DD, - 0x4F17, 0xD6DA, - 0x4F18, 0xD3C5, - 0x4F19, 0xBBEF, - 0x4F1A, 0xBBE1, - 0x4F1B, 0xD8F1, - 0x4F1E, 0xC9A1, - 0x4F1F, 0xCEB0, - 0x4F20, 0xB4AB, - 0x4F22, 0xD8F3, - 0x4F24, 0xC9CB, - 0x4F25, 0xD8F6, - 0x4F26, 0xC2D7, - 0x4F27, 0xD8F7, - 0x4F2A, 0xCEB1, - 0x4F2B, 0xD8F9, - 0x4F2F, 0xB2AE, - 0x4F30, 0xB9C0, - 0x4F32, 0xD9A3, - 0x4F34, 0xB0E9, - 0x4F36, 0xC1E6, - 0x4F38, 0xC9EC, - 0x4F3A, 0xCBC5, - 0x4F3C, 0xCBC6, - 0x4F3D, 0xD9A4, - 0x4F43, 0xB5E8, - 0x4F46, 0xB5AB, - 0x4F4D, 0xCEBB, - 0x4F4E, 0xB5CD, - 0x4F4F, 0xD7A1, - 0x4F50, 0xD7F4, - 0x4F51, 0xD3D3, - 0x4F53, 0xCCE5, - 0x4F55, 0xBACE, - 0x4F57, 0xD9A2, - 0x4F58, 0xD9DC, - 0x4F59, 0xD3E0, - 0x4F5A, 0xD8FD, - 0x4F5B, 0xB7F0, - 0x4F5C, 0xD7F7, - 0x4F5D, 0xD8FE, - 0x4F5E, 0xD8FA, - 0x4F5F, 0xD9A1, - 0x4F60, 0xC4E3, - 0x4F63, 0xD3B6, - 0x4F64, 0xD8F4, - 0x4F65, 0xD9DD, - 0x4F67, 0xD8FB, - 0x4F69, 0xC5E5, - 0x4F6C, 0xC0D0, - 0x4F6F, 0xD1F0, - 0x4F70, 0xB0DB, - 0x4F73, 0xBCD1, - 0x4F74, 0xD9A6, - 0x4F76, 0xD9A5, - 0x4F7B, 0xD9AC, - 0x4F7C, 0xD9AE, - 0x4F7E, 0xD9AB, - 0x4F7F, 0xCAB9, - 0x4F83, 0xD9A9, - 0x4F84, 0xD6B6, - 0x4F88, 0xB3DE, - 0x4F89, 0xD9A8, - 0x4F8B, 0xC0FD, - 0x4F8D, 0xCACC, - 0x4F8F, 0xD9AA, - 0x4F91, 0xD9A7, - 0x4F94, 0xD9B0, - 0x4F97, 0xB6B1, - 0x4F9B, 0xB9A9, - 0x4F9D, 0xD2C0, - 0x4FA0, 0xCFC0, - 0x4FA3, 0xC2C2, - 0x4FA5, 0xBDC4, - 0x4FA6, 0xD5EC, - 0x4FA7, 0xB2E0, - 0x4FA8, 0xC7C8, - 0x4FA9, 0xBFEB, - 0x4FAA, 0xD9AD, - 0x4FAC, 0xD9AF, - 0x4FAE, 0xCEEA, - 0x4FAF, 0xBAEE, - 0x4FB5, 0xC7D6, - 0x4FBF, 0xB1E3, - 0x4FC3, 0xB4D9, - 0x4FC4, 0xB6ED, - 0x4FC5, 0xD9B4, - 0x4FCA, 0xBFA1, - 0x4FCE, 0xD9DE, - 0x4FCF, 0xC7CE, - 0x4FD0, 0xC0FE, - 0x4FD1, 0xD9B8, - 0x4FD7, 0xCBD7, - 0x4FD8, 0xB7FD, - 0x4FDA, 0xD9B5, - 0x4FDC, 0xD9B7, - 0x4FDD, 0xB1A3, - 0x4FDE, 0xD3E1, - 0x4FDF, 0xD9B9, - 0x4FE1, 0xD0C5, - 0x4FE3, 0xD9B6, - 0x4FE6, 0xD9B1, - 0x4FE8, 0xD9B2, - 0x4FE9, 0xC1A9, - 0x4FEA, 0xD9B3, - 0x4FED, 0xBCF3, - 0x4FEE, 0xD0DE, - 0x4FEF, 0xB8A9, - 0x4FF1, 0xBEE3, - 0x4FF3, 0xD9BD, - 0x4FF8, 0xD9BA, - 0x4FFA, 0xB0B3, - 0x4FFE, 0xD9C2, - 0x500C, 0xD9C4, - 0x500D, 0xB1B6, - 0x500F, 0xD9BF, - 0x5012, 0xB5B9, - 0x5014, 0xBEF3, - 0x5018, 0xCCC8, - 0x5019, 0xBAF2, - 0x501A, 0xD2D0, - 0x501C, 0xD9C3, - 0x501F, 0xBDE8, - 0x5021, 0xB3AB, - 0x5025, 0xD9C5, - 0x5026, 0xBEEB, - 0x5028, 0xD9C6, - 0x5029, 0xD9BB, - 0x502A, 0xC4DF, - 0x502C, 0xD9BE, - 0x502D, 0xD9C1, - 0x502E, 0xD9C0, - 0x503A, 0xD5AE, - 0x503C, 0xD6B5, - 0x503E, 0xC7E3, - 0x5043, 0xD9C8, - 0x5047, 0xBCD9, - 0x5048, 0xD9CA, - 0x504C, 0xD9BC, - 0x504E, 0xD9CB, - 0x504F, 0xC6AB, - 0x5055, 0xD9C9, - 0x505A, 0xD7F6, - 0x505C, 0xCDA3, - 0x5065, 0xBDA1, - 0x506C, 0xD9CC, - 0x5076, 0xC5BC, - 0x5077, 0xCDB5, - 0x507B, 0xD9CD, - 0x507E, 0xD9C7, - 0x507F, 0xB3A5, - 0x5080, 0xBFFE, - 0x5085, 0xB8B5, - 0x5088, 0xC0FC, - 0x508D, 0xB0F8, - 0x50A3, 0xB4F6, - 0x50A5, 0xD9CE, - 0x50A7, 0xD9CF, - 0x50A8, 0xB4A2, - 0x50A9, 0xD9D0, - 0x50AC, 0xB4DF, - 0x50B2, 0xB0C1, - 0x50BA, 0xD9D1, - 0x50BB, 0xC9B5, - 0x50CF, 0xCFF1, - 0x50D6, 0xD9D2, - 0x50DA, 0xC1C5, - 0x50E6, 0xD9D6, - 0x50E7, 0xC9AE, - 0x50EC, 0xD9D5, - 0x50ED, 0xD9D4, - 0x50EE, 0xD9D7, - 0x50F3, 0xCBDB, - 0x50F5, 0xBDA9, - 0x50FB, 0xC6A7, - 0x5106, 0xD9D3, - 0x5107, 0xD9D8, - 0x510B, 0xD9D9, - 0x5112, 0xC8E5, - 0x5121, 0xC0DC, - 0x513F, 0xB6F9, - 0x5140, 0xD8A3, - 0x5141, 0xD4CA, - 0x5143, 0xD4AA, - 0x5144, 0xD0D6, - 0x5145, 0xB3E4, - 0x5146, 0xD5D7, - 0x5148, 0xCFC8, - 0x5149, 0xB9E2, - 0x514B, 0xBFCB, - 0x514D, 0xC3E2, - 0x5151, 0xB6D2, - 0x5154, 0xCDC3, - 0x5155, 0xD9EE, - 0x5156, 0xD9F0, - 0x515A, 0xB5B3, - 0x515C, 0xB6B5, - 0x5162, 0xBEA4, - 0x5165, 0xC8EB, - 0x5168, 0xC8AB, - 0x516B, 0xB0CB, - 0x516C, 0xB9AB, - 0x516D, 0xC1F9, - 0x516E, 0xD9E2, - 0x5170, 0xC0BC, - 0x5171, 0xB9B2, - 0x5173, 0xB9D8, - 0x5174, 0xD0CB, - 0x5175, 0xB1F8, - 0x5176, 0xC6E4, - 0x5177, 0xBEDF, - 0x5178, 0xB5E4, - 0x5179, 0xD7C8, - 0x517B, 0xD1F8, - 0x517C, 0xBCE6, - 0x517D, 0xCADE, - 0x5180, 0xBCBD, - 0x5181, 0xD9E6, - 0x5182, 0xD8E7, - 0x5185, 0xC4DA, - 0x5188, 0xB8D4, - 0x5189, 0xC8BD, - 0x518C, 0xB2E1, - 0x518D, 0xD4D9, - 0x5192, 0xC3B0, - 0x5195, 0xC3E1, - 0x5196, 0xDAA2, - 0x5197, 0xC8DF, - 0x5199, 0xD0B4, - 0x519B, 0xBEFC, - 0x519C, 0xC5A9, - 0x51A0, 0xB9DA, - 0x51A2, 0xDAA3, - 0x51A4, 0xD4A9, - 0x51A5, 0xDAA4, - 0x51AB, 0xD9FB, - 0x51AC, 0xB6AC, - 0x51AF, 0xB7EB, - 0x51B0, 0xB1F9, - 0x51B1, 0xD9FC, - 0x51B2, 0xB3E5, - 0x51B3, 0xBEF6, - 0x51B5, 0xBFF6, - 0x51B6, 0xD2B1, - 0x51B7, 0xC0E4, - 0x51BB, 0xB6B3, - 0x51BC, 0xD9FE, - 0x51BD, 0xD9FD, - 0x51C0, 0xBEBB, - 0x51C4, 0xC6E0, - 0x51C6, 0xD7BC, - 0x51C7, 0xDAA1, - 0x51C9, 0xC1B9, - 0x51CB, 0xB5F2, - 0x51CC, 0xC1E8, - 0x51CF, 0xBCF5, - 0x51D1, 0xB4D5, - 0x51DB, 0xC1DD, - 0x51DD, 0xC4FD, - 0x51E0, 0xBCB8, - 0x51E1, 0xB7B2, - 0x51E4, 0xB7EF, - 0x51EB, 0xD9EC, - 0x51ED, 0xC6BE, - 0x51EF, 0xBFAD, - 0x51F0, 0xBBCB, - 0x51F3, 0xB5CA, - 0x51F5, 0xDBC9, - 0x51F6, 0xD0D7, - 0x51F8, 0xCDB9, - 0x51F9, 0xB0BC, - 0x51FA, 0xB3F6, - 0x51FB, 0xBBF7, - 0x51FC, 0xDBCA, - 0x51FD, 0xBAAF, - 0x51FF, 0xD4E4, - 0x5200, 0xB5B6, - 0x5201, 0xB5F3, - 0x5202, 0xD8D6, - 0x5203, 0xC8D0, - 0x5206, 0xB7D6, - 0x5207, 0xC7D0, - 0x5208, 0xD8D7, - 0x520A, 0xBFAF, - 0x520D, 0xDBBB, - 0x520E, 0xD8D8, - 0x5211, 0xD0CC, - 0x5212, 0xBBAE, - 0x5216, 0xEBBE, - 0x5217, 0xC1D0, - 0x5218, 0xC1F5, - 0x5219, 0xD4F2, - 0x521A, 0xB8D5, - 0x521B, 0xB4B4, - 0x521D, 0xB3F5, - 0x5220, 0xC9BE, - 0x5224, 0xC5D0, - 0x5228, 0xC5D9, - 0x5229, 0xC0FB, - 0x522B, 0xB1F0, - 0x522D, 0xD8D9, - 0x522E, 0xB9CE, - 0x5230, 0xB5BD, - 0x5233, 0xD8DA, - 0x5236, 0xD6C6, - 0x5237, 0xCBA2, - 0x5238, 0xC8AF, - 0x5239, 0xC9B2, - 0x523A, 0xB4CC, - 0x523B, 0xBFCC, - 0x523D, 0xB9F4, - 0x523F, 0xD8DB, - 0x5240, 0xD8DC, - 0x5241, 0xB6E7, - 0x5242, 0xBCC1, - 0x5243, 0xCCEA, - 0x524A, 0xCFF7, - 0x524C, 0xD8DD, - 0x524D, 0xC7B0, - 0x5250, 0xB9D0, - 0x5251, 0xBDA3, - 0x5254, 0xCCDE, - 0x5256, 0xC6CA, - 0x525C, 0xD8E0, - 0x525E, 0xD8DE, - 0x5261, 0xD8DF, - 0x5265, 0xB0FE, - 0x5267, 0xBEE7, - 0x5269, 0xCAA3, - 0x526A, 0xBCF4, - 0x526F, 0xB8B1, - 0x5272, 0xB8EE, - 0x527D, 0xD8E2, - 0x527F, 0xBDCB, - 0x5281, 0xD8E4, - 0x5282, 0xD8E3, - 0x5288, 0xC5FC, - 0x5290, 0xD8E5, - 0x5293, 0xD8E6, - 0x529B, 0xC1A6, - 0x529D, 0xC8B0, - 0x529E, 0xB0EC, - 0x529F, 0xB9A6, - 0x52A0, 0xBCD3, - 0x52A1, 0xCEF1, - 0x52A2, 0xDBBD, - 0x52A3, 0xC1D3, - 0x52A8, 0xB6AF, - 0x52A9, 0xD6FA, - 0x52AA, 0xC5AC, - 0x52AB, 0xBDD9, - 0x52AC, 0xDBBE, - 0x52AD, 0xDBBF, - 0x52B1, 0xC0F8, - 0x52B2, 0xBEA2, - 0x52B3, 0xC0CD, - 0x52BE, 0xDBC0, - 0x52BF, 0xCAC6, - 0x52C3, 0xB2AA, - 0x52C7, 0xD3C2, - 0x52C9, 0xC3E3, - 0x52CB, 0xD1AB, - 0x52D0, 0xDBC2, - 0x52D2, 0xC0D5, - 0x52D6, 0xDBC3, - 0x52D8, 0xBFB1, - 0x52DF, 0xC4BC, - 0x52E4, 0xC7DA, - 0x52F0, 0xDBC4, - 0x52F9, 0xD9E8, - 0x52FA, 0xC9D7, - 0x52FE, 0xB9B4, - 0x52FF, 0xCEF0, - 0x5300, 0xD4C8, - 0x5305, 0xB0FC, - 0x5306, 0xB4D2, - 0x5308, 0xD0D9, - 0x530D, 0xD9E9, - 0x530F, 0xDECB, - 0x5310, 0xD9EB, - 0x5315, 0xD8B0, - 0x5316, 0xBBAF, - 0x5317, 0xB1B1, - 0x5319, 0xB3D7, - 0x531A, 0xD8CE, - 0x531D, 0xD4D1, - 0x5320, 0xBDB3, - 0x5321, 0xBFEF, - 0x5323, 0xCFBB, - 0x5326, 0xD8D0, - 0x532A, 0xB7CB, - 0x532E, 0xD8D1, - 0x5339, 0xC6A5, - 0x533A, 0xC7F8, - 0x533B, 0xD2BD, - 0x533E, 0xD8D2, - 0x533F, 0xC4E4, - 0x5341, 0xCAAE, - 0x5343, 0xC7A7, - 0x5345, 0xD8A6, - 0x5347, 0xC9FD, - 0x5348, 0xCEE7, - 0x5349, 0xBBDC, - 0x534A, 0xB0EB, - 0x534E, 0xBBAA, - 0x534F, 0xD0AD, - 0x5351, 0xB1B0, - 0x5352, 0xD7E4, - 0x5353, 0xD7BF, - 0x5355, 0xB5A5, - 0x5356, 0xC2F4, - 0x5357, 0xC4CF, - 0x535A, 0xB2A9, - 0x535C, 0xB2B7, - 0x535E, 0xB1E5, - 0x535F, 0xDFB2, - 0x5360, 0xD5BC, - 0x5361, 0xBFA8, - 0x5362, 0xC2AC, - 0x5363, 0xD8D5, - 0x5364, 0xC2B1, - 0x5366, 0xD8D4, - 0x5367, 0xCED4, - 0x5369, 0xDAE0, - 0x536B, 0xCEC0, - 0x536E, 0xD8B4, - 0x536F, 0xC3AE, - 0x5370, 0xD3A1, - 0x5371, 0xCEA3, - 0x5373, 0xBCB4, - 0x5374, 0xC8B4, - 0x5375, 0xC2D1, - 0x5377, 0xBEED, - 0x5378, 0xD0B6, - 0x537A, 0xDAE1, - 0x537F, 0xC7E4, - 0x5382, 0xB3A7, - 0x5384, 0xB6F2, - 0x5385, 0xCCFC, - 0x5386, 0xC0FA, - 0x5389, 0xC0F7, - 0x538B, 0xD1B9, - 0x538C, 0xD1E1, - 0x538D, 0xD8C7, - 0x5395, 0xB2DE, - 0x5398, 0xC0E5, - 0x539A, 0xBAF1, - 0x539D, 0xD8C8, - 0x539F, 0xD4AD, - 0x53A2, 0xCFE1, - 0x53A3, 0xD8C9, - 0x53A5, 0xD8CA, - 0x53A6, 0xCFC3, - 0x53A8, 0xB3F8, - 0x53A9, 0xBEC7, - 0x53AE, 0xD8CB, - 0x53B6, 0xDBCC, - 0x53BB, 0xC8A5, - 0x53BF, 0xCFD8, - 0x53C1, 0xC8FE, - 0x53C2, 0xB2CE, - 0x53C8, 0xD3D6, - 0x53C9, 0xB2E6, - 0x53CA, 0xBCB0, - 0x53CB, 0xD3D1, - 0x53CC, 0xCBAB, - 0x53CD, 0xB7B4, - 0x53D1, 0xB7A2, - 0x53D4, 0xCAE5, - 0x53D6, 0xC8A1, - 0x53D7, 0xCADC, - 0x53D8, 0xB1E4, - 0x53D9, 0xD0F0, - 0x53DB, 0xC5D1, - 0x53DF, 0xDBC5, - 0x53E0, 0xB5FE, - 0x53E3, 0xBFDA, - 0x53E4, 0xB9C5, - 0x53E5, 0xBEE4, - 0x53E6, 0xC1ED, - 0x53E8, 0xDFB6, - 0x53E9, 0xDFB5, - 0x53EA, 0xD6BB, - 0x53EB, 0xBDD0, - 0x53EC, 0xD5D9, - 0x53ED, 0xB0C8, - 0x53EE, 0xB6A3, - 0x53EF, 0xBFC9, - 0x53F0, 0xCCA8, - 0x53F1, 0xDFB3, - 0x53F2, 0xCAB7, - 0x53F3, 0xD3D2, - 0x53F5, 0xD8CF, - 0x53F6, 0xD2B6, - 0x53F7, 0xBAC5, - 0x53F8, 0xCBBE, - 0x53F9, 0xCCBE, - 0x53FB, 0xDFB7, - 0x53FC, 0xB5F0, - 0x53FD, 0xDFB4, - 0x5401, 0xD3F5, - 0x5403, 0xB3D4, - 0x5404, 0xB8F7, - 0x5406, 0xDFBA, - 0x5408, 0xBACF, - 0x5409, 0xBCAA, - 0x540A, 0xB5F5, - 0x540C, 0xCDAC, - 0x540D, 0xC3FB, - 0x540E, 0xBAF3, - 0x540F, 0xC0F4, - 0x5410, 0xCDC2, - 0x5411, 0xCFF2, - 0x5412, 0xDFB8, - 0x5413, 0xCFC5, - 0x5415, 0xC2C0, - 0x5416, 0xDFB9, - 0x5417, 0xC2F0, - 0x541B, 0xBEFD, - 0x541D, 0xC1DF, - 0x541E, 0xCDCC, - 0x541F, 0xD2F7, - 0x5420, 0xB7CD, - 0x5421, 0xDFC1, - 0x5423, 0xDFC4, - 0x5426, 0xB7F1, - 0x5427, 0xB0C9, - 0x5428, 0xB6D6, - 0x5429, 0xB7D4, - 0x542B, 0xBAAC, - 0x542C, 0xCCFD, - 0x542D, 0xBFD4, - 0x542E, 0xCBB1, - 0x542F, 0xC6F4, - 0x5431, 0xD6A8, - 0x5432, 0xDFC5, - 0x5434, 0xCEE2, - 0x5435, 0xB3B3, - 0x5438, 0xCEFC, - 0x5439, 0xB4B5, - 0x543B, 0xCEC7, - 0x543C, 0xBAF0, - 0x543E, 0xCEE1, - 0x5440, 0xD1BD, - 0x5443, 0xDFC0, - 0x5446, 0xB4F4, - 0x5448, 0xB3CA, - 0x544A, 0xB8E6, - 0x544B, 0xDFBB, - 0x5450, 0xC4C5, - 0x5452, 0xDFBC, - 0x5453, 0xDFBD, - 0x5454, 0xDFBE, - 0x5455, 0xC5BB, - 0x5456, 0xDFBF, - 0x5457, 0xDFC2, - 0x5458, 0xD4B1, - 0x5459, 0xDFC3, - 0x545B, 0xC7BA, - 0x545C, 0xCED8, - 0x5462, 0xC4D8, - 0x5464, 0xDFCA, - 0x5466, 0xDFCF, - 0x5468, 0xD6DC, - 0x5471, 0xDFC9, - 0x5472, 0xDFDA, - 0x5473, 0xCEB6, - 0x5475, 0xBAC7, - 0x5476, 0xDFCE, - 0x5477, 0xDFC8, - 0x5478, 0xC5DE, - 0x547B, 0xC9EB, - 0x547C, 0xBAF4, - 0x547D, 0xC3FC, - 0x5480, 0xBED7, - 0x5482, 0xDFC6, - 0x5484, 0xDFCD, - 0x5486, 0xC5D8, - 0x548B, 0xD5A6, - 0x548C, 0xBACD, - 0x548E, 0xBECC, - 0x548F, 0xD3BD, - 0x5490, 0xB8C0, - 0x5492, 0xD6E4, - 0x5494, 0xDFC7, - 0x5495, 0xB9BE, - 0x5496, 0xBFA7, - 0x5499, 0xC1FC, - 0x549A, 0xDFCB, - 0x549B, 0xDFCC, - 0x549D, 0xDFD0, - 0x54A3, 0xDFDB, - 0x54A4, 0xDFE5, - 0x54A6, 0xDFD7, - 0x54A7, 0xDFD6, - 0x54A8, 0xD7C9, - 0x54A9, 0xDFE3, - 0x54AA, 0xDFE4, - 0x54AB, 0xE5EB, - 0x54AC, 0xD2A7, - 0x54AD, 0xDFD2, - 0x54AF, 0xBFA9, - 0x54B1, 0xD4DB, - 0x54B3, 0xBFC8, - 0x54B4, 0xDFD4, - 0x54B8, 0xCFCC, - 0x54BB, 0xDFDD, - 0x54BD, 0xD1CA, - 0x54BF, 0xDFDE, - 0x54C0, 0xB0A7, - 0x54C1, 0xC6B7, - 0x54C2, 0xDFD3, - 0x54C4, 0xBAE5, - 0x54C6, 0xB6DF, - 0x54C7, 0xCDDB, - 0x54C8, 0xB9FE, - 0x54C9, 0xD4D5, - 0x54CC, 0xDFDF, - 0x54CD, 0xCFEC, - 0x54CE, 0xB0A5, - 0x54CF, 0xDFE7, - 0x54D0, 0xDFD1, - 0x54D1, 0xD1C6, - 0x54D2, 0xDFD5, - 0x54D3, 0xDFD8, - 0x54D4, 0xDFD9, - 0x54D5, 0xDFDC, - 0x54D7, 0xBBA9, - 0x54D9, 0xDFE0, - 0x54DA, 0xDFE1, - 0x54DC, 0xDFE2, - 0x54DD, 0xDFE6, - 0x54DE, 0xDFE8, - 0x54DF, 0xD3B4, - 0x54E5, 0xB8E7, - 0x54E6, 0xC5B6, - 0x54E7, 0xDFEA, - 0x54E8, 0xC9DA, - 0x54E9, 0xC1A8, - 0x54EA, 0xC4C4, - 0x54ED, 0xBFDE, - 0x54EE, 0xCFF8, - 0x54F2, 0xD5DC, - 0x54F3, 0xDFEE, - 0x54FA, 0xB2B8, - 0x54FC, 0xBADF, - 0x54FD, 0xDFEC, - 0x54FF, 0xDBC1, - 0x5501, 0xD1E4, - 0x5506, 0xCBF4, - 0x5507, 0xB4BD, - 0x5509, 0xB0A6, - 0x550F, 0xDFF1, - 0x5510, 0xCCC6, - 0x5511, 0xDFF2, - 0x5514, 0xDFED, - 0x551B, 0xDFE9, - 0x5520, 0xDFEB, - 0x5522, 0xDFEF, - 0x5523, 0xDFF0, - 0x5524, 0xBBBD, - 0x5527, 0xDFF3, - 0x552A, 0xDFF4, - 0x552C, 0xBBA3, - 0x552E, 0xCADB, - 0x552F, 0xCEA8, - 0x5530, 0xE0A7, - 0x5531, 0xB3AA, - 0x5533, 0xE0A6, - 0x5537, 0xE0A1, - 0x553C, 0xDFFE, - 0x553E, 0xCDD9, - 0x553F, 0xDFFC, - 0x5541, 0xDFFA, - 0x5543, 0xBFD0, - 0x5544, 0xD7C4, - 0x5546, 0xC9CC, - 0x5549, 0xDFF8, - 0x554A, 0xB0A1, - 0x5550, 0xDFFD, - 0x5555, 0xDFFB, - 0x5556, 0xE0A2, - 0x555C, 0xE0A8, - 0x5561, 0xB7C8, - 0x5564, 0xC6A1, - 0x5565, 0xC9B6, - 0x5566, 0xC0B2, - 0x5567, 0xDFF5, - 0x556A, 0xC5BE, - 0x556C, 0xD8C4, - 0x556D, 0xDFF9, - 0x556E, 0xC4F6, - 0x5575, 0xE0A3, - 0x5576, 0xE0A4, - 0x5577, 0xE0A5, - 0x5578, 0xD0A5, - 0x557B, 0xE0B4, - 0x557C, 0xCCE4, - 0x557E, 0xE0B1, - 0x5580, 0xBFA6, - 0x5581, 0xE0AF, - 0x5582, 0xCEB9, - 0x5583, 0xE0AB, - 0x5584, 0xC9C6, - 0x5587, 0xC0AE, - 0x5588, 0xE0AE, - 0x5589, 0xBAED, - 0x558A, 0xBAB0, - 0x558B, 0xE0A9, - 0x558F, 0xDFF6, - 0x5591, 0xE0B3, - 0x5594, 0xE0B8, - 0x5598, 0xB4AD, - 0x5599, 0xE0B9, - 0x559C, 0xCFB2, - 0x559D, 0xBAC8, - 0x559F, 0xE0B0, - 0x55A7, 0xD0FA, - 0x55B1, 0xE0AC, - 0x55B3, 0xD4FB, - 0x55B5, 0xDFF7, - 0x55B7, 0xC5E7, - 0x55B9, 0xE0AD, - 0x55BB, 0xD3F7, - 0x55BD, 0xE0B6, - 0x55BE, 0xE0B7, - 0x55C4, 0xE0C4, - 0x55C5, 0xD0E1, - 0x55C9, 0xE0BC, - 0x55CC, 0xE0C9, - 0x55CD, 0xE0CA, - 0x55D1, 0xE0BE, - 0x55D2, 0xE0AA, - 0x55D3, 0xC9A4, - 0x55D4, 0xE0C1, - 0x55D6, 0xE0B2, - 0x55DC, 0xCAC8, - 0x55DD, 0xE0C3, - 0x55DF, 0xE0B5, - 0x55E1, 0xCECB, - 0x55E3, 0xCBC3, - 0x55E4, 0xE0CD, - 0x55E5, 0xE0C6, - 0x55E6, 0xE0C2, - 0x55E8, 0xE0CB, - 0x55EA, 0xE0BA, - 0x55EB, 0xE0BF, - 0x55EC, 0xE0C0, - 0x55EF, 0xE0C5, - 0x55F2, 0xE0C7, - 0x55F3, 0xE0C8, - 0x55F5, 0xE0CC, - 0x55F7, 0xE0BB, - 0x55FD, 0xCBD4, - 0x55FE, 0xE0D5, - 0x5600, 0xE0D6, - 0x5601, 0xE0D2, - 0x5608, 0xE0D0, - 0x5609, 0xBCCE, - 0x560C, 0xE0D1, - 0x560E, 0xB8C2, - 0x560F, 0xD8C5, - 0x5618, 0xD0EA, - 0x561B, 0xC2EF, - 0x561E, 0xE0CF, - 0x561F, 0xE0BD, - 0x5623, 0xE0D4, - 0x5624, 0xE0D3, - 0x5627, 0xE0D7, - 0x562C, 0xE0DC, - 0x562D, 0xE0D8, - 0x5631, 0xD6F6, - 0x5632, 0xB3B0, - 0x5634, 0xD7EC, - 0x5636, 0xCBBB, - 0x5639, 0xE0DA, - 0x563B, 0xCEFB, - 0x563F, 0xBAD9, - 0x564C, 0xE0E1, - 0x564D, 0xE0DD, - 0x564E, 0xD2AD, - 0x5654, 0xE0E2, - 0x5657, 0xE0DB, - 0x5658, 0xE0D9, - 0x5659, 0xE0DF, - 0x565C, 0xE0E0, - 0x5662, 0xE0DE, - 0x5664, 0xE0E4, - 0x5668, 0xC6F7, - 0x5669, 0xD8AC, - 0x566A, 0xD4EB, - 0x566B, 0xE0E6, - 0x566C, 0xCAC9, - 0x5671, 0xE0E5, - 0x5676, 0xB8C1, - 0x567B, 0xE0E7, - 0x567C, 0xE0E8, - 0x5685, 0xE0E9, - 0x5686, 0xE0E3, - 0x568E, 0xBABF, - 0x568F, 0xCCE7, - 0x5693, 0xE0EA, - 0x56A3, 0xCFF9, - 0x56AF, 0xE0EB, - 0x56B7, 0xC8C2, - 0x56BC, 0xBDC0, - 0x56CA, 0xC4D2, - 0x56D4, 0xE0EC, - 0x56D7, 0xE0ED, - 0x56DA, 0xC7F4, - 0x56DB, 0xCBC4, - 0x56DD, 0xE0EE, - 0x56DE, 0xBBD8, - 0x56DF, 0xD8B6, - 0x56E0, 0xD2F2, - 0x56E1, 0xE0EF, - 0x56E2, 0xCDC5, - 0x56E4, 0xB6DA, - 0x56EB, 0xE0F1, - 0x56ED, 0xD4B0, - 0x56F0, 0xC0A7, - 0x56F1, 0xB4D1, - 0x56F4, 0xCEA7, - 0x56F5, 0xE0F0, - 0x56F9, 0xE0F2, - 0x56FA, 0xB9CC, - 0x56FD, 0xB9FA, - 0x56FE, 0xCDBC, - 0x56FF, 0xE0F3, - 0x5703, 0xC6D4, - 0x5704, 0xE0F4, - 0x5706, 0xD4B2, - 0x5708, 0xC8A6, - 0x5709, 0xE0F6, - 0x570A, 0xE0F5, - 0x571C, 0xE0F7, - 0x571F, 0xCDC1, - 0x5723, 0xCAA5, - 0x5728, 0xD4DA, - 0x5729, 0xDBD7, - 0x572A, 0xDBD9, - 0x572C, 0xDBD8, - 0x572D, 0xB9E7, - 0x572E, 0xDBDC, - 0x572F, 0xDBDD, - 0x5730, 0xB5D8, - 0x5733, 0xDBDA, - 0x5739, 0xDBDB, - 0x573A, 0xB3A1, - 0x573B, 0xDBDF, - 0x573E, 0xBBF8, - 0x5740, 0xD6B7, - 0x5742, 0xDBE0, - 0x5747, 0xBEF9, - 0x574A, 0xB7BB, - 0x574C, 0xDBD0, - 0x574D, 0xCCAE, - 0x574E, 0xBFB2, - 0x574F, 0xBBB5, - 0x5750, 0xD7F8, - 0x5751, 0xBFD3, - 0x5757, 0xBFE9, - 0x575A, 0xBCE1, - 0x575B, 0xCCB3, - 0x575C, 0xDBDE, - 0x575D, 0xB0D3, - 0x575E, 0xCEEB, - 0x575F, 0xB7D8, - 0x5760, 0xD7B9, - 0x5761, 0xC6C2, - 0x5764, 0xC0A4, - 0x5766, 0xCCB9, - 0x5768, 0xDBE7, - 0x5769, 0xDBE1, - 0x576A, 0xC6BA, - 0x576B, 0xDBE3, - 0x576D, 0xDBE8, - 0x576F, 0xC5F7, - 0x5773, 0xDBEA, - 0x5776, 0xDBE9, - 0x5777, 0xBFC0, - 0x577B, 0xDBE6, - 0x577C, 0xDBE5, - 0x5782, 0xB4B9, - 0x5783, 0xC0AC, - 0x5784, 0xC2A2, - 0x5785, 0xDBE2, - 0x5786, 0xDBE4, - 0x578B, 0xD0CD, - 0x578C, 0xDBED, - 0x5792, 0xC0DD, - 0x5793, 0xDBF2, - 0x579B, 0xB6E2, - 0x57A0, 0xDBF3, - 0x57A1, 0xDBD2, - 0x57A2, 0xB9B8, - 0x57A3, 0xD4AB, - 0x57A4, 0xDBEC, - 0x57A6, 0xBFD1, - 0x57A7, 0xDBF0, - 0x57A9, 0xDBD1, - 0x57AB, 0xB5E6, - 0x57AD, 0xDBEB, - 0x57AE, 0xBFE5, - 0x57B2, 0xDBEE, - 0x57B4, 0xDBF1, - 0x57B8, 0xDBF9, - 0x57C2, 0xB9A1, - 0x57C3, 0xB0A3, - 0x57CB, 0xC2F1, - 0x57CE, 0xB3C7, - 0x57CF, 0xDBEF, - 0x57D2, 0xDBF8, - 0x57D4, 0xC6D2, - 0x57D5, 0xDBF4, - 0x57D8, 0xDBF5, - 0x57D9, 0xDBF7, - 0x57DA, 0xDBF6, - 0x57DD, 0xDBFE, - 0x57DF, 0xD3F2, - 0x57E0, 0xB2BA, - 0x57E4, 0xDBFD, - 0x57ED, 0xDCA4, - 0x57EF, 0xDBFB, - 0x57F4, 0xDBFA, - 0x57F8, 0xDBFC, - 0x57F9, 0xC5E0, - 0x57FA, 0xBBF9, - 0x57FD, 0xDCA3, - 0x5800, 0xDCA5, - 0x5802, 0xCCC3, - 0x5806, 0xB6D1, - 0x5807, 0xDDC0, - 0x580B, 0xDCA1, - 0x580D, 0xDCA2, - 0x5811, 0xC7B5, - 0x5815, 0xB6E9, - 0x5819, 0xDCA7, - 0x581E, 0xDCA6, - 0x5820, 0xDCA9, - 0x5821, 0xB1A4, - 0x5824, 0xB5CC, - 0x582A, 0xBFB0, - 0x5830, 0xD1DF, - 0x5835, 0xB6C2, - 0x5844, 0xDCA8, - 0x584C, 0xCBFA, - 0x584D, 0xEBF3, - 0x5851, 0xCBDC, - 0x5854, 0xCBFE, - 0x5858, 0xCCC1, - 0x585E, 0xC8FB, - 0x5865, 0xDCAA, - 0x586B, 0xCCEE, - 0x586C, 0xDCAB, - 0x587E, 0xDBD3, - 0x5880, 0xDCAF, - 0x5881, 0xDCAC, - 0x5883, 0xBEB3, - 0x5885, 0xCAFB, - 0x5889, 0xDCAD, - 0x5892, 0xC9CA, - 0x5893, 0xC4B9, - 0x5899, 0xC7BD, - 0x589A, 0xDCAE, - 0x589E, 0xD4F6, - 0x589F, 0xD0E6, - 0x58A8, 0xC4AB, - 0x58A9, 0xB6D5, - 0x58BC, 0xDBD4, - 0x58C1, 0xB1DA, - 0x58C5, 0xDBD5, - 0x58D1, 0xDBD6, - 0x58D5, 0xBABE, - 0x58E4, 0xC8C0, - 0x58EB, 0xCABF, - 0x58EC, 0xC8C9, - 0x58EE, 0xD7B3, - 0x58F0, 0xC9F9, - 0x58F3, 0xBFC7, - 0x58F6, 0xBAF8, - 0x58F9, 0xD2BC, - 0x5902, 0xE2BA, - 0x5904, 0xB4A6, - 0x5907, 0xB1B8, - 0x590D, 0xB8B4, - 0x590F, 0xCFC4, - 0x5914, 0xD9E7, - 0x5915, 0xCFA6, - 0x5916, 0xCDE2, - 0x5919, 0xD9ED, - 0x591A, 0xB6E0, - 0x591C, 0xD2B9, - 0x591F, 0xB9BB, - 0x5924, 0xE2B9, - 0x5925, 0xE2B7, - 0x5927, 0xB4F3, - 0x5929, 0xCCEC, - 0x592A, 0xCCAB, - 0x592B, 0xB7F2, - 0x592D, 0xD8B2, - 0x592E, 0xD1EB, - 0x592F, 0xBABB, - 0x5931, 0xCAA7, - 0x5934, 0xCDB7, - 0x5937, 0xD2C4, - 0x5938, 0xBFE4, - 0x5939, 0xBCD0, - 0x593A, 0xB6E1, - 0x593C, 0xDEC5, - 0x5941, 0xDEC6, - 0x5942, 0xDBBC, - 0x5944, 0xD1D9, - 0x5947, 0xC6E6, - 0x5948, 0xC4CE, - 0x5949, 0xB7EE, - 0x594B, 0xB7DC, - 0x594E, 0xBFFC, - 0x594F, 0xD7E0, - 0x5951, 0xC6F5, - 0x5954, 0xB1BC, - 0x5955, 0xDEC8, - 0x5956, 0xBDB1, - 0x5957, 0xCCD7, - 0x5958, 0xDECA, - 0x595A, 0xDEC9, - 0x5960, 0xB5EC, - 0x5962, 0xC9DD, - 0x5965, 0xB0C2, - 0x5973, 0xC5AE, - 0x5974, 0xC5AB, - 0x5976, 0xC4CC, - 0x5978, 0xBCE9, - 0x5979, 0xCBFD, - 0x597D, 0xBAC3, - 0x5981, 0xE5F9, - 0x5982, 0xC8E7, - 0x5983, 0xE5FA, - 0x5984, 0xCDFD, - 0x5986, 0xD7B1, - 0x5987, 0xB8BE, - 0x5988, 0xC2E8, - 0x598A, 0xC8D1, - 0x598D, 0xE5FB, - 0x5992, 0xB6CA, - 0x5993, 0xBCCB, - 0x5996, 0xD1FD, - 0x5997, 0xE6A1, - 0x5999, 0xC3EE, - 0x599E, 0xE6A4, - 0x59A3, 0xE5FE, - 0x59A4, 0xE6A5, - 0x59A5, 0xCDD7, - 0x59A8, 0xB7C1, - 0x59A9, 0xE5FC, - 0x59AA, 0xE5FD, - 0x59AB, 0xE6A3, - 0x59AE, 0xC4DD, - 0x59AF, 0xE6A8, - 0x59B2, 0xE6A7, - 0x59B9, 0xC3C3, - 0x59BB, 0xC6DE, - 0x59BE, 0xE6AA, - 0x59C6, 0xC4B7, - 0x59CA, 0xE6A2, - 0x59CB, 0xCABC, - 0x59D0, 0xBDE3, - 0x59D1, 0xB9C3, - 0x59D2, 0xE6A6, - 0x59D3, 0xD0D5, - 0x59D4, 0xCEAF, - 0x59D7, 0xE6A9, - 0x59D8, 0xE6B0, - 0x59DA, 0xD2A6, - 0x59DC, 0xBDAA, - 0x59DD, 0xE6AD, - 0x59E3, 0xE6AF, - 0x59E5, 0xC0D1, - 0x59E8, 0xD2CC, - 0x59EC, 0xBCA7, - 0x59F9, 0xE6B1, - 0x59FB, 0xD2F6, - 0x59FF, 0xD7CB, - 0x5A01, 0xCDFE, - 0x5A03, 0xCDDE, - 0x5A04, 0xC2A6, - 0x5A05, 0xE6AB, - 0x5A06, 0xE6AC, - 0x5A07, 0xBDBF, - 0x5A08, 0xE6AE, - 0x5A09, 0xE6B3, - 0x5A0C, 0xE6B2, - 0x5A11, 0xE6B6, - 0x5A13, 0xE6B8, - 0x5A18, 0xC4EF, - 0x5A1C, 0xC4C8, - 0x5A1F, 0xBEEA, - 0x5A20, 0xC9EF, - 0x5A23, 0xE6B7, - 0x5A25, 0xB6F0, - 0x5A29, 0xC3E4, - 0x5A31, 0xD3E9, - 0x5A32, 0xE6B4, - 0x5A34, 0xE6B5, - 0x5A36, 0xC8A2, - 0x5A3C, 0xE6BD, - 0x5A40, 0xE6B9, - 0x5A46, 0xC6C5, - 0x5A49, 0xCDF1, - 0x5A4A, 0xE6BB, - 0x5A55, 0xE6BC, - 0x5A5A, 0xBBE9, - 0x5A62, 0xE6BE, - 0x5A67, 0xE6BA, - 0x5A6A, 0xC0B7, - 0x5A74, 0xD3A4, - 0x5A75, 0xE6BF, - 0x5A76, 0xC9F4, - 0x5A77, 0xE6C3, - 0x5A7A, 0xE6C4, - 0x5A7F, 0xD0F6, - 0x5A92, 0xC3BD, - 0x5A9A, 0xC3C4, - 0x5A9B, 0xE6C2, - 0x5AAA, 0xE6C1, - 0x5AB2, 0xE6C7, - 0x5AB3, 0xCFB1, - 0x5AB5, 0xEBF4, - 0x5AB8, 0xE6CA, - 0x5ABE, 0xE6C5, - 0x5AC1, 0xBCDE, - 0x5AC2, 0xC9A9, - 0x5AC9, 0xBCB5, - 0x5ACC, 0xCFD3, - 0x5AD2, 0xE6C8, - 0x5AD4, 0xE6C9, - 0x5AD6, 0xE6CE, - 0x5AD8, 0xE6D0, - 0x5ADC, 0xE6D1, - 0x5AE0, 0xE6CB, - 0x5AE1, 0xB5D5, - 0x5AE3, 0xE6CC, - 0x5AE6, 0xE6CF, - 0x5AE9, 0xC4DB, - 0x5AEB, 0xE6C6, - 0x5AF1, 0xE6CD, - 0x5B09, 0xE6D2, - 0x5B16, 0xE6D4, - 0x5B17, 0xE6D3, - 0x5B32, 0xE6D5, - 0x5B34, 0xD9F8, - 0x5B37, 0xE6D6, - 0x5B40, 0xE6D7, - 0x5B50, 0xD7D3, - 0x5B51, 0xE6DD, - 0x5B53, 0xE6DE, - 0x5B54, 0xBFD7, - 0x5B55, 0xD4D0, - 0x5B57, 0xD7D6, - 0x5B58, 0xB4E6, - 0x5B59, 0xCBEF, - 0x5B5A, 0xE6DA, - 0x5B5B, 0xD8C3, - 0x5B5C, 0xD7CE, - 0x5B5D, 0xD0A2, - 0x5B5F, 0xC3CF, - 0x5B62, 0xE6DF, - 0x5B63, 0xBCBE, - 0x5B64, 0xB9C2, - 0x5B65, 0xE6DB, - 0x5B66, 0xD1A7, - 0x5B69, 0xBAA2, - 0x5B6A, 0xC2CF, - 0x5B6C, 0xD8AB, - 0x5B70, 0xCAEB, - 0x5B71, 0xE5EE, - 0x5B73, 0xE6DC, - 0x5B75, 0xB7F5, - 0x5B7A, 0xC8E6, - 0x5B7D, 0xC4F5, - 0x5B80, 0xE5B2, - 0x5B81, 0xC4FE, - 0x5B83, 0xCBFC, - 0x5B84, 0xE5B3, - 0x5B85, 0xD5AC, - 0x5B87, 0xD3EE, - 0x5B88, 0xCAD8, - 0x5B89, 0xB0B2, - 0x5B8B, 0xCBCE, - 0x5B8C, 0xCDEA, - 0x5B8F, 0xBAEA, - 0x5B93, 0xE5B5, - 0x5B95, 0xE5B4, - 0x5B97, 0xD7DA, - 0x5B98, 0xB9D9, - 0x5B99, 0xD6E6, - 0x5B9A, 0xB6A8, - 0x5B9B, 0xCDF0, - 0x5B9C, 0xD2CB, - 0x5B9D, 0xB1A6, - 0x5B9E, 0xCAB5, - 0x5BA0, 0xB3E8, - 0x5BA1, 0xC9F3, - 0x5BA2, 0xBFCD, - 0x5BA3, 0xD0FB, - 0x5BA4, 0xCAD2, - 0x5BA5, 0xE5B6, - 0x5BA6, 0xBBC2, - 0x5BAA, 0xCFDC, - 0x5BAB, 0xB9AC, - 0x5BB0, 0xD4D7, - 0x5BB3, 0xBAA6, - 0x5BB4, 0xD1E7, - 0x5BB5, 0xCFFC, - 0x5BB6, 0xBCD2, - 0x5BB8, 0xE5B7, - 0x5BB9, 0xC8DD, - 0x5BBD, 0xBFED, - 0x5BBE, 0xB1F6, - 0x5BBF, 0xCBDE, - 0x5BC2, 0xBCC5, - 0x5BC4, 0xBCC4, - 0x5BC5, 0xD2FA, - 0x5BC6, 0xC3DC, - 0x5BC7, 0xBFDC, - 0x5BCC, 0xB8BB, - 0x5BD0, 0xC3C2, - 0x5BD2, 0xBAAE, - 0x5BD3, 0xD4A2, - 0x5BDD, 0xC7DE, - 0x5BDE, 0xC4AF, - 0x5BDF, 0xB2EC, - 0x5BE1, 0xB9D1, - 0x5BE4, 0xE5BB, - 0x5BE5, 0xC1C8, - 0x5BE8, 0xD5AF, - 0x5BEE, 0xE5BC, - 0x5BF0, 0xE5BE, - 0x5BF8, 0xB4E7, - 0x5BF9, 0xB6D4, - 0x5BFA, 0xCBC2, - 0x5BFB, 0xD1B0, - 0x5BFC, 0xB5BC, - 0x5BFF, 0xCAD9, - 0x5C01, 0xB7E2, - 0x5C04, 0xC9E4, - 0x5C06, 0xBDAB, - 0x5C09, 0xCEBE, - 0x5C0A, 0xD7F0, - 0x5C0F, 0xD0A1, - 0x5C11, 0xC9D9, - 0x5C14, 0xB6FB, - 0x5C15, 0xE6D8, - 0x5C16, 0xBCE2, - 0x5C18, 0xB3BE, - 0x5C1A, 0xC9D0, - 0x5C1C, 0xE6D9, - 0x5C1D, 0xB3A2, - 0x5C22, 0xDECC, - 0x5C24, 0xD3C8, - 0x5C25, 0xDECD, - 0x5C27, 0xD2A2, - 0x5C2C, 0xDECE, - 0x5C31, 0xBECD, - 0x5C34, 0xDECF, - 0x5C38, 0xCAAC, - 0x5C39, 0xD2FC, - 0x5C3A, 0xB3DF, - 0x5C3B, 0xE5EA, - 0x5C3C, 0xC4E1, - 0x5C3D, 0xBEA1, - 0x5C3E, 0xCEB2, - 0x5C3F, 0xC4F2, - 0x5C40, 0xBED6, - 0x5C41, 0xC6A8, - 0x5C42, 0xB2E3, - 0x5C45, 0xBED3, - 0x5C48, 0xC7FC, - 0x5C49, 0xCCEB, - 0x5C4A, 0xBDEC, - 0x5C4B, 0xCEDD, - 0x5C4E, 0xCABA, - 0x5C4F, 0xC6C1, - 0x5C50, 0xE5EC, - 0x5C51, 0xD0BC, - 0x5C55, 0xD5B9, - 0x5C59, 0xE5ED, - 0x5C5E, 0xCAF4, - 0x5C60, 0xCDC0, - 0x5C61, 0xC2C5, - 0x5C63, 0xE5EF, - 0x5C65, 0xC2C4, - 0x5C66, 0xE5F0, - 0x5C6E, 0xE5F8, - 0x5C6F, 0xCDCD, - 0x5C71, 0xC9BD, - 0x5C79, 0xD2D9, - 0x5C7A, 0xE1A8, - 0x5C7F, 0xD3EC, - 0x5C81, 0xCBEA, - 0x5C82, 0xC6F1, - 0x5C88, 0xE1AC, - 0x5C8C, 0xE1A7, - 0x5C8D, 0xE1A9, - 0x5C90, 0xE1AA, - 0x5C91, 0xE1AF, - 0x5C94, 0xB2ED, - 0x5C96, 0xE1AB, - 0x5C97, 0xB8DA, - 0x5C98, 0xE1AD, - 0x5C99, 0xE1AE, - 0x5C9A, 0xE1B0, - 0x5C9B, 0xB5BA, - 0x5C9C, 0xE1B1, - 0x5CA2, 0xE1B3, - 0x5CA3, 0xE1B8, - 0x5CA9, 0xD1D2, - 0x5CAB, 0xE1B6, - 0x5CAC, 0xE1B5, - 0x5CAD, 0xC1EB, - 0x5CB1, 0xE1B7, - 0x5CB3, 0xD4C0, - 0x5CB5, 0xE1B2, - 0x5CB7, 0xE1BA, - 0x5CB8, 0xB0B6, - 0x5CBD, 0xE1B4, - 0x5CBF, 0xBFF9, - 0x5CC1, 0xE1B9, - 0x5CC4, 0xE1BB, - 0x5CCB, 0xE1BE, - 0x5CD2, 0xE1BC, - 0x5CD9, 0xD6C5, - 0x5CE1, 0xCFBF, - 0x5CE4, 0xE1BD, - 0x5CE5, 0xE1BF, - 0x5CE6, 0xC2CD, - 0x5CE8, 0xB6EB, - 0x5CEA, 0xD3F8, - 0x5CED, 0xC7CD, - 0x5CF0, 0xB7E5, - 0x5CFB, 0xBEFE, - 0x5D02, 0xE1C0, - 0x5D03, 0xE1C1, - 0x5D06, 0xE1C7, - 0x5D07, 0xB3E7, - 0x5D0E, 0xC6E9, - 0x5D14, 0xB4DE, - 0x5D16, 0xD1C2, - 0x5D1B, 0xE1C8, - 0x5D1E, 0xE1C6, - 0x5D24, 0xE1C5, - 0x5D26, 0xE1C3, - 0x5D27, 0xE1C2, - 0x5D29, 0xB1C0, - 0x5D2D, 0xD5B8, - 0x5D2E, 0xE1C4, - 0x5D34, 0xE1CB, - 0x5D3D, 0xE1CC, - 0x5D3E, 0xE1CA, - 0x5D47, 0xEFFA, - 0x5D4A, 0xE1D3, - 0x5D4B, 0xE1D2, - 0x5D4C, 0xC7B6, - 0x5D58, 0xE1C9, - 0x5D5B, 0xE1CE, - 0x5D5D, 0xE1D0, - 0x5D69, 0xE1D4, - 0x5D6B, 0xE1D1, - 0x5D6C, 0xE1CD, - 0x5D6F, 0xE1CF, - 0x5D74, 0xE1D5, - 0x5D82, 0xE1D6, - 0x5D99, 0xE1D7, - 0x5D9D, 0xE1D8, - 0x5DB7, 0xE1DA, - 0x5DC5, 0xE1DB, - 0x5DCD, 0xCEA1, - 0x5DDB, 0xE7DD, - 0x5DDD, 0xB4A8, - 0x5DDE, 0xD6DD, - 0x5DE1, 0xD1B2, - 0x5DE2, 0xB3B2, - 0x5DE5, 0xB9A4, - 0x5DE6, 0xD7F3, - 0x5DE7, 0xC7C9, - 0x5DE8, 0xBEDE, - 0x5DE9, 0xB9AE, - 0x5DEB, 0xCED7, - 0x5DEE, 0xB2EE, - 0x5DEF, 0xDBCF, - 0x5DF1, 0xBCBA, - 0x5DF2, 0xD2D1, - 0x5DF3, 0xCBC8, - 0x5DF4, 0xB0CD, - 0x5DF7, 0xCFEF, - 0x5DFD, 0xD9E3, - 0x5DFE, 0xBDED, - 0x5E01, 0xB1D2, - 0x5E02, 0xCAD0, - 0x5E03, 0xB2BC, - 0x5E05, 0xCBA7, - 0x5E06, 0xB7AB, - 0x5E08, 0xCAA6, - 0x5E0C, 0xCFA3, - 0x5E0F, 0xE0F8, - 0x5E10, 0xD5CA, - 0x5E11, 0xE0FB, - 0x5E14, 0xE0FA, - 0x5E15, 0xC5C1, - 0x5E16, 0xCCFB, - 0x5E18, 0xC1B1, - 0x5E19, 0xE0F9, - 0x5E1A, 0xD6E3, - 0x5E1B, 0xB2AF, - 0x5E1C, 0xD6C4, - 0x5E1D, 0xB5DB, - 0x5E26, 0xB4F8, - 0x5E27, 0xD6A1, - 0x5E2D, 0xCFAF, - 0x5E2E, 0xB0EF, - 0x5E31, 0xE0FC, - 0x5E37, 0xE1A1, - 0x5E38, 0xB3A3, - 0x5E3B, 0xE0FD, - 0x5E3C, 0xE0FE, - 0x5E3D, 0xC3B1, - 0x5E42, 0xC3DD, - 0x5E44, 0xE1A2, - 0x5E45, 0xB7F9, - 0x5E4C, 0xBBCF, - 0x5E54, 0xE1A3, - 0x5E55, 0xC4BB, - 0x5E5B, 0xE1A4, - 0x5E5E, 0xE1A5, - 0x5E61, 0xE1A6, - 0x5E62, 0xB4B1, - 0x5E72, 0xB8C9, - 0x5E73, 0xC6BD, - 0x5E74, 0xC4EA, - 0x5E76, 0xB2A2, - 0x5E78, 0xD0D2, - 0x5E7A, 0xE7DB, - 0x5E7B, 0xBBC3, - 0x5E7C, 0xD3D7, - 0x5E7D, 0xD3C4, - 0x5E7F, 0xB9E3, - 0x5E80, 0xE2CF, - 0x5E84, 0xD7AF, - 0x5E86, 0xC7EC, - 0x5E87, 0xB1D3, - 0x5E8A, 0xB4B2, - 0x5E8B, 0xE2D1, - 0x5E8F, 0xD0F2, - 0x5E90, 0xC2AE, - 0x5E91, 0xE2D0, - 0x5E93, 0xBFE2, - 0x5E94, 0xD3A6, - 0x5E95, 0xB5D7, - 0x5E96, 0xE2D2, - 0x5E97, 0xB5EA, - 0x5E99, 0xC3ED, - 0x5E9A, 0xB8FD, - 0x5E9C, 0xB8AE, - 0x5E9E, 0xC5D3, - 0x5E9F, 0xB7CF, - 0x5EA0, 0xE2D4, - 0x5EA5, 0xE2D3, - 0x5EA6, 0xB6C8, - 0x5EA7, 0xD7F9, - 0x5EAD, 0xCDA5, - 0x5EB3, 0xE2D8, - 0x5EB5, 0xE2D6, - 0x5EB6, 0xCAFC, - 0x5EB7, 0xBFB5, - 0x5EB8, 0xD3B9, - 0x5EB9, 0xE2D5, - 0x5EBE, 0xE2D7, - 0x5EC9, 0xC1AE, - 0x5ECA, 0xC0C8, - 0x5ED1, 0xE2DB, - 0x5ED2, 0xE2DA, - 0x5ED3, 0xC0AA, - 0x5ED6, 0xC1CE, - 0x5EDB, 0xE2DC, - 0x5EE8, 0xE2DD, - 0x5EEA, 0xE2DE, - 0x5EF4, 0xDBC8, - 0x5EF6, 0xD1D3, - 0x5EF7, 0xCDA2, - 0x5EFA, 0xBDA8, - 0x5EFE, 0xDEC3, - 0x5EFF, 0xD8A5, - 0x5F00, 0xBFAA, - 0x5F01, 0xDBCD, - 0x5F02, 0xD2EC, - 0x5F03, 0xC6FA, - 0x5F04, 0xC5AA, - 0x5F08, 0xDEC4, - 0x5F0A, 0xB1D7, - 0x5F0B, 0xDFAE, - 0x5F0F, 0xCABD, - 0x5F11, 0xDFB1, - 0x5F13, 0xB9AD, - 0x5F15, 0xD2FD, - 0x5F17, 0xB8A5, - 0x5F18, 0xBAEB, - 0x5F1B, 0xB3DA, - 0x5F1F, 0xB5DC, - 0x5F20, 0xD5C5, - 0x5F25, 0xC3D6, - 0x5F26, 0xCFD2, - 0x5F27, 0xBBA1, - 0x5F29, 0xE5F3, - 0x5F2A, 0xE5F2, - 0x5F2D, 0xE5F4, - 0x5F2F, 0xCDE4, - 0x5F31, 0xC8F5, - 0x5F39, 0xB5AF, - 0x5F3A, 0xC7BF, - 0x5F3C, 0xE5F6, - 0x5F40, 0xECB0, - 0x5F50, 0xE5E6, - 0x5F52, 0xB9E9, - 0x5F53, 0xB5B1, - 0x5F55, 0xC2BC, - 0x5F56, 0xE5E8, - 0x5F57, 0xE5E7, - 0x5F58, 0xE5E9, - 0x5F5D, 0xD2CD, - 0x5F61, 0xE1EA, - 0x5F62, 0xD0CE, - 0x5F64, 0xCDAE, - 0x5F66, 0xD1E5, - 0x5F69, 0xB2CA, - 0x5F6A, 0xB1EB, - 0x5F6C, 0xB1F2, - 0x5F6D, 0xC5ED, - 0x5F70, 0xD5C3, - 0x5F71, 0xD3B0, - 0x5F73, 0xE1DC, - 0x5F77, 0xE1DD, - 0x5F79, 0xD2DB, - 0x5F7B, 0xB3B9, - 0x5F7C, 0xB1CB, - 0x5F80, 0xCDF9, - 0x5F81, 0xD5F7, - 0x5F82, 0xE1DE, - 0x5F84, 0xBEB6, - 0x5F85, 0xB4FD, - 0x5F87, 0xE1DF, - 0x5F88, 0xBADC, - 0x5F89, 0xE1E0, - 0x5F8A, 0xBBB2, - 0x5F8B, 0xC2C9, - 0x5F8C, 0xE1E1, - 0x5F90, 0xD0EC, - 0x5F92, 0xCDBD, - 0x5F95, 0xE1E2, - 0x5F97, 0xB5C3, - 0x5F98, 0xC5C7, - 0x5F99, 0xE1E3, - 0x5F9C, 0xE1E4, - 0x5FA1, 0xD3F9, - 0x5FA8, 0xE1E5, - 0x5FAA, 0xD1AD, - 0x5FAD, 0xE1E6, - 0x5FAE, 0xCEA2, - 0x5FB5, 0xE1E7, - 0x5FB7, 0xB5C2, - 0x5FBC, 0xE1E8, - 0x5FBD, 0xBBD5, - 0x5FC3, 0xD0C4, - 0x5FC4, 0xE2E0, - 0x5FC5, 0xB1D8, - 0x5FC6, 0xD2E4, - 0x5FC9, 0xE2E1, - 0x5FCC, 0xBCC9, - 0x5FCD, 0xC8CC, - 0x5FCF, 0xE2E3, - 0x5FD0, 0xECFE, - 0x5FD1, 0xECFD, - 0x5FD2, 0xDFAF, - 0x5FD6, 0xE2E2, - 0x5FD7, 0xD6BE, - 0x5FD8, 0xCDFC, - 0x5FD9, 0xC3A6, - 0x5FDD, 0xE3C3, - 0x5FE0, 0xD6D2, - 0x5FE1, 0xE2E7, - 0x5FE4, 0xE2E8, - 0x5FE7, 0xD3C7, - 0x5FEA, 0xE2EC, - 0x5FEB, 0xBFEC, - 0x5FED, 0xE2ED, - 0x5FEE, 0xE2E5, - 0x5FF1, 0xB3C0, - 0x5FF5, 0xC4EE, - 0x5FF8, 0xE2EE, - 0x5FFB, 0xD0C3, - 0x5FFD, 0xBAF6, - 0x5FFE, 0xE2E9, - 0x5FFF, 0xB7DE, - 0x6000, 0xBBB3, - 0x6001, 0xCCAC, - 0x6002, 0xCBCB, - 0x6003, 0xE2E4, - 0x6004, 0xE2E6, - 0x6005, 0xE2EA, - 0x6006, 0xE2EB, - 0x600A, 0xE2F7, - 0x600D, 0xE2F4, - 0x600E, 0xD4F5, - 0x600F, 0xE2F3, - 0x6012, 0xC5AD, - 0x6014, 0xD5FA, - 0x6015, 0xC5C2, - 0x6016, 0xB2C0, - 0x6019, 0xE2EF, - 0x601B, 0xE2F2, - 0x601C, 0xC1AF, - 0x601D, 0xCBBC, - 0x6020, 0xB5A1, - 0x6021, 0xE2F9, - 0x6025, 0xBCB1, - 0x6026, 0xE2F1, - 0x6027, 0xD0D4, - 0x6028, 0xD4B9, - 0x6029, 0xE2F5, - 0x602A, 0xB9D6, - 0x602B, 0xE2F6, - 0x602F, 0xC7D3, - 0x6035, 0xE2F0, - 0x603B, 0xD7DC, - 0x603C, 0xEDA1, - 0x603F, 0xE2F8, - 0x6041, 0xEDA5, - 0x6042, 0xE2FE, - 0x6043, 0xCAD1, - 0x604B, 0xC1B5, - 0x604D, 0xBBD0, - 0x6050, 0xBFD6, - 0x6052, 0xBAE3, - 0x6055, 0xCBA1, - 0x6059, 0xEDA6, - 0x605A, 0xEDA3, - 0x605D, 0xEDA2, - 0x6062, 0xBBD6, - 0x6063, 0xEDA7, - 0x6064, 0xD0F4, - 0x6067, 0xEDA4, - 0x6068, 0xBADE, - 0x6069, 0xB6F7, - 0x606A, 0xE3A1, - 0x606B, 0xB6B2, - 0x606C, 0xCCF1, - 0x606D, 0xB9A7, - 0x606F, 0xCFA2, - 0x6070, 0xC7A1, - 0x6073, 0xBFD2, - 0x6076, 0xB6F1, - 0x6078, 0xE2FA, - 0x6079, 0xE2FB, - 0x607A, 0xE2FD, - 0x607B, 0xE2FC, - 0x607C, 0xC4D5, - 0x607D, 0xE3A2, - 0x607F, 0xD3C1, - 0x6083, 0xE3A7, - 0x6084, 0xC7C4, - 0x6089, 0xCFA4, - 0x608C, 0xE3A9, - 0x608D, 0xBAB7, - 0x6092, 0xE3A8, - 0x6094, 0xBBDA, - 0x6096, 0xE3A3, - 0x609A, 0xE3A4, - 0x609B, 0xE3AA, - 0x609D, 0xE3A6, - 0x609F, 0xCEF2, - 0x60A0, 0xD3C6, - 0x60A3, 0xBBBC, - 0x60A6, 0xD4C3, - 0x60A8, 0xC4FA, - 0x60AB, 0xEDA8, - 0x60AC, 0xD0FC, - 0x60AD, 0xE3A5, - 0x60AF, 0xC3F5, - 0x60B1, 0xE3AD, - 0x60B2, 0xB1AF, - 0x60B4, 0xE3B2, - 0x60B8, 0xBCC2, - 0x60BB, 0xE3AC, - 0x60BC, 0xB5BF, - 0x60C5, 0xC7E9, - 0x60C6, 0xE3B0, - 0x60CA, 0xBEAA, - 0x60CB, 0xCDEF, - 0x60D1, 0xBBF3, - 0x60D5, 0xCCE8, - 0x60D8, 0xE3AF, - 0x60DA, 0xE3B1, - 0x60DC, 0xCFA7, - 0x60DD, 0xE3AE, - 0x60DF, 0xCEA9, - 0x60E0, 0xBBDD, - 0x60E6, 0xB5EB, - 0x60E7, 0xBEE5, - 0x60E8, 0xB2D2, - 0x60E9, 0xB3CD, - 0x60EB, 0xB1B9, - 0x60EC, 0xE3AB, - 0x60ED, 0xB2D1, - 0x60EE, 0xB5AC, - 0x60EF, 0xB9DF, - 0x60F0, 0xB6E8, - 0x60F3, 0xCFEB, - 0x60F4, 0xE3B7, - 0x60F6, 0xBBCC, - 0x60F9, 0xC8C7, - 0x60FA, 0xD0CA, - 0x6100, 0xE3B8, - 0x6101, 0xB3EE, - 0x6106, 0xEDA9, - 0x6108, 0xD3FA, - 0x6109, 0xD3E4, - 0x610D, 0xEDAA, - 0x610E, 0xE3B9, - 0x610F, 0xD2E2, - 0x6115, 0xE3B5, - 0x611A, 0xD3DE, - 0x611F, 0xB8D0, - 0x6120, 0xE3B3, - 0x6123, 0xE3B6, - 0x6124, 0xB7DF, - 0x6126, 0xE3B4, - 0x6127, 0xC0A2, - 0x612B, 0xE3BA, - 0x613F, 0xD4B8, - 0x6148, 0xB4C8, - 0x614A, 0xE3BB, - 0x614C, 0xBBC5, - 0x614E, 0xC9F7, - 0x6151, 0xC9E5, - 0x6155, 0xC4BD, - 0x615D, 0xEDAB, - 0x6162, 0xC2FD, - 0x6167, 0xBBDB, - 0x6168, 0xBFAE, - 0x6170, 0xCEBF, - 0x6175, 0xE3BC, - 0x6177, 0xBFB6, - 0x618B, 0xB1EF, - 0x618E, 0xD4F7, - 0x6194, 0xE3BE, - 0x619D, 0xEDAD, - 0x61A7, 0xE3BF, - 0x61A8, 0xBAA9, - 0x61A9, 0xEDAC, - 0x61AC, 0xE3BD, - 0x61B7, 0xE3C0, - 0x61BE, 0xBAB6, - 0x61C2, 0xB6AE, - 0x61C8, 0xD0B8, - 0x61CA, 0xB0C3, - 0x61CB, 0xEDAE, - 0x61D1, 0xEDAF, - 0x61D2, 0xC0C1, - 0x61D4, 0xE3C1, - 0x61E6, 0xC5B3, - 0x61F5, 0xE3C2, - 0x61FF, 0xDCB2, - 0x6206, 0xEDB0, - 0x6208, 0xB8EA, - 0x620A, 0xCEEC, - 0x620B, 0xEAA7, - 0x620C, 0xD0E7, - 0x620D, 0xCAF9, - 0x620E, 0xC8D6, - 0x620F, 0xCFB7, - 0x6210, 0xB3C9, - 0x6211, 0xCED2, - 0x6212, 0xBDE4, - 0x6215, 0xE3DE, - 0x6216, 0xBBF2, - 0x6217, 0xEAA8, - 0x6218, 0xD5BD, - 0x621A, 0xC6DD, - 0x621B, 0xEAA9, - 0x621F, 0xEAAA, - 0x6221, 0xEAAC, - 0x6222, 0xEAAB, - 0x6224, 0xEAAE, - 0x6225, 0xEAAD, - 0x622A, 0xBDD8, - 0x622C, 0xEAAF, - 0x622E, 0xC2BE, - 0x6233, 0xB4C1, - 0x6234, 0xB4F7, - 0x6237, 0xBBA7, - 0x623D, 0xECE6, - 0x623E, 0xECE5, - 0x623F, 0xB7BF, - 0x6240, 0xCBF9, - 0x6241, 0xB1E2, - 0x6243, 0xECE7, - 0x6247, 0xC9C8, - 0x6248, 0xECE8, - 0x6249, 0xECE9, - 0x624B, 0xCAD6, - 0x624C, 0xDED0, - 0x624D, 0xB2C5, - 0x624E, 0xD4FA, - 0x6251, 0xC6CB, - 0x6252, 0xB0C7, - 0x6253, 0xB4F2, - 0x6254, 0xC8D3, - 0x6258, 0xCDD0, - 0x625B, 0xBFB8, - 0x6263, 0xBFDB, - 0x6266, 0xC7A4, - 0x6267, 0xD6B4, - 0x6269, 0xC0A9, - 0x626A, 0xDED1, - 0x626B, 0xC9A8, - 0x626C, 0xD1EF, - 0x626D, 0xC5A4, - 0x626E, 0xB0E7, - 0x626F, 0xB3B6, - 0x6270, 0xC8C5, - 0x6273, 0xB0E2, - 0x6276, 0xB7F6, - 0x6279, 0xC5FA, - 0x627C, 0xB6F3, - 0x627E, 0xD5D2, - 0x627F, 0xB3D0, - 0x6280, 0xBCBC, - 0x6284, 0xB3AD, - 0x6289, 0xBEF1, - 0x628A, 0xB0D1, - 0x6291, 0xD2D6, - 0x6292, 0xCAE3, - 0x6293, 0xD7A5, - 0x6295, 0xCDB6, - 0x6296, 0xB6B6, - 0x6297, 0xBFB9, - 0x6298, 0xD5DB, - 0x629A, 0xB8A7, - 0x629B, 0xC5D7, - 0x629F, 0xDED2, - 0x62A0, 0xBFD9, - 0x62A1, 0xC2D5, - 0x62A2, 0xC7C0, - 0x62A4, 0xBBA4, - 0x62A5, 0xB1A8, - 0x62A8, 0xC5EA, - 0x62AB, 0xC5FB, - 0x62AC, 0xCCA7, - 0x62B1, 0xB1A7, - 0x62B5, 0xB5D6, - 0x62B9, 0xC4A8, - 0x62BB, 0xDED3, - 0x62BC, 0xD1BA, - 0x62BD, 0xB3E9, - 0x62BF, 0xC3F2, - 0x62C2, 0xB7F7, - 0x62C4, 0xD6F4, - 0x62C5, 0xB5A3, - 0x62C6, 0xB2F0, - 0x62C7, 0xC4B4, - 0x62C8, 0xC4E9, - 0x62C9, 0xC0AD, - 0x62CA, 0xDED4, - 0x62CC, 0xB0E8, - 0x62CD, 0xC5C4, - 0x62CE, 0xC1E0, - 0x62D0, 0xB9D5, - 0x62D2, 0xBEDC, - 0x62D3, 0xCDD8, - 0x62D4, 0xB0CE, - 0x62D6, 0xCDCF, - 0x62D7, 0xDED6, - 0x62D8, 0xBED0, - 0x62D9, 0xD7BE, - 0x62DA, 0xDED5, - 0x62DB, 0xD5D0, - 0x62DC, 0xB0DD, - 0x62DF, 0xC4E2, - 0x62E2, 0xC2A3, - 0x62E3, 0xBCF0, - 0x62E5, 0xD3B5, - 0x62E6, 0xC0B9, - 0x62E7, 0xC5A1, - 0x62E8, 0xB2A6, - 0x62E9, 0xD4F1, - 0x62EC, 0xC0A8, - 0x62ED, 0xCAC3, - 0x62EE, 0xDED7, - 0x62EF, 0xD5FC, - 0x62F1, 0xB9B0, - 0x62F3, 0xC8AD, - 0x62F4, 0xCBA9, - 0x62F6, 0xDED9, - 0x62F7, 0xBFBD, - 0x62FC, 0xC6B4, - 0x62FD, 0xD7A7, - 0x62FE, 0xCAB0, - 0x62FF, 0xC4C3, - 0x6301, 0xB3D6, - 0x6302, 0xB9D2, - 0x6307, 0xD6B8, - 0x6308, 0xEAFC, - 0x6309, 0xB0B4, - 0x630E, 0xBFE6, - 0x6311, 0xCCF4, - 0x6316, 0xCDDA, - 0x631A, 0xD6BF, - 0x631B, 0xC2CE, - 0x631D, 0xCECE, - 0x631E, 0xCCA2, - 0x631F, 0xD0AE, - 0x6320, 0xC4D3, - 0x6321, 0xB5B2, - 0x6322, 0xDED8, - 0x6323, 0xD5F5, - 0x6324, 0xBCB7, - 0x6325, 0xBBD3, - 0x6328, 0xB0A4, - 0x632A, 0xC5B2, - 0x632B, 0xB4EC, - 0x632F, 0xD5F1, - 0x6332, 0xEAFD, - 0x6339, 0xDEDA, - 0x633A, 0xCDA6, - 0x633D, 0xCDEC, - 0x6342, 0xCEE6, - 0x6343, 0xDEDC, - 0x6345, 0xCDB1, - 0x6346, 0xC0A6, - 0x6349, 0xD7BD, - 0x634B, 0xDEDB, - 0x634C, 0xB0C6, - 0x634D, 0xBAB4, - 0x634E, 0xC9D3, - 0x634F, 0xC4F3, - 0x6350, 0xBEE8, - 0x6355, 0xB2B6, - 0x635E, 0xC0CC, - 0x635F, 0xCBF0, - 0x6361, 0xBCF1, - 0x6362, 0xBBBB, - 0x6363, 0xB5B7, - 0x6367, 0xC5F5, - 0x6369, 0xDEE6, - 0x636D, 0xDEE3, - 0x636E, 0xBEDD, - 0x6371, 0xDEDF, - 0x6376, 0xB4B7, - 0x6377, 0xBDDD, - 0x637A, 0xDEE0, - 0x637B, 0xC4ED, - 0x6380, 0xCFC6, - 0x6382, 0xB5E0, - 0x6387, 0xB6DE, - 0x6388, 0xCADA, - 0x6389, 0xB5F4, - 0x638A, 0xDEE5, - 0x638C, 0xD5C6, - 0x638E, 0xDEE1, - 0x638F, 0xCCCD, - 0x6390, 0xC6FE, - 0x6392, 0xC5C5, - 0x6396, 0xD2B4, - 0x6398, 0xBEF2, - 0x63A0, 0xC2D3, - 0x63A2, 0xCCBD, - 0x63A3, 0xB3B8, - 0x63A5, 0xBDD3, - 0x63A7, 0xBFD8, - 0x63A8, 0xCDC6, - 0x63A9, 0xD1DA, - 0x63AA, 0xB4EB, - 0x63AC, 0xDEE4, - 0x63AD, 0xDEDD, - 0x63AE, 0xDEE7, - 0x63B0, 0xEAFE, - 0x63B3, 0xC2B0, - 0x63B4, 0xDEE2, - 0x63B7, 0xD6C0, - 0x63B8, 0xB5A7, - 0x63BA, 0xB2F4, - 0x63BC, 0xDEE8, - 0x63BE, 0xDEF2, - 0x63C4, 0xDEED, - 0x63C6, 0xDEF1, - 0x63C9, 0xC8E0, - 0x63CD, 0xD7E1, - 0x63CE, 0xDEEF, - 0x63CF, 0xC3E8, - 0x63D0, 0xCCE1, - 0x63D2, 0xB2E5, - 0x63D6, 0xD2BE, - 0x63DE, 0xDEEE, - 0x63E0, 0xDEEB, - 0x63E1, 0xCED5, - 0x63E3, 0xB4A7, - 0x63E9, 0xBFAB, - 0x63EA, 0xBEBE, - 0x63ED, 0xBDD2, - 0x63F2, 0xDEE9, - 0x63F4, 0xD4AE, - 0x63F6, 0xDEDE, - 0x63F8, 0xDEEA, - 0x63FD, 0xC0BF, - 0x63FF, 0xDEEC, - 0x6400, 0xB2F3, - 0x6401, 0xB8E9, - 0x6402, 0xC2A7, - 0x6405, 0xBDC1, - 0x640B, 0xDEF5, - 0x640C, 0xDEF8, - 0x640F, 0xB2AB, - 0x6410, 0xB4A4, - 0x6413, 0xB4EA, - 0x6414, 0xC9A6, - 0x641B, 0xDEF6, - 0x641C, 0xCBD1, - 0x641E, 0xB8E3, - 0x6420, 0xDEF7, - 0x6421, 0xDEFA, - 0x6426, 0xDEF9, - 0x642A, 0xCCC2, - 0x642C, 0xB0E1, - 0x642D, 0xB4EE, - 0x6434, 0xE5BA, - 0x643A, 0xD0AF, - 0x643D, 0xB2EB, - 0x643F, 0xEBA1, - 0x6441, 0xDEF4, - 0x6444, 0xC9E3, - 0x6445, 0xDEF3, - 0x6446, 0xB0DA, - 0x6447, 0xD2A1, - 0x6448, 0xB1F7, - 0x644A, 0xCCAF, - 0x6452, 0xDEF0, - 0x6454, 0xCBA4, - 0x6458, 0xD5AA, - 0x645E, 0xDEFB, - 0x6467, 0xB4DD, - 0x6469, 0xC4A6, - 0x646D, 0xDEFD, - 0x6478, 0xC3FE, - 0x6479, 0xC4A1, - 0x647A, 0xDFA1, - 0x6482, 0xC1CC, - 0x6484, 0xDEFC, - 0x6485, 0xBEEF, - 0x6487, 0xC6B2, - 0x6491, 0xB3C5, - 0x6492, 0xC8F6, - 0x6495, 0xCBBA, - 0x6496, 0xDEFE, - 0x6499, 0xDFA4, - 0x649E, 0xD7B2, - 0x64A4, 0xB3B7, - 0x64A9, 0xC1C3, - 0x64AC, 0xC7CB, - 0x64AD, 0xB2A5, - 0x64AE, 0xB4E9, - 0x64B0, 0xD7AB, - 0x64B5, 0xC4EC, - 0x64B7, 0xDFA2, - 0x64B8, 0xDFA3, - 0x64BA, 0xDFA5, - 0x64BC, 0xBAB3, - 0x64C0, 0xDFA6, - 0x64C2, 0xC0DE, - 0x64C5, 0xC9C3, - 0x64CD, 0xB2D9, - 0x64CE, 0xC7E6, - 0x64D0, 0xDFA7, - 0x64D2, 0xC7DC, - 0x64D7, 0xDFA8, - 0x64D8, 0xEBA2, - 0x64DE, 0xCBD3, - 0x64E2, 0xDFAA, - 0x64E4, 0xDFA9, - 0x64E6, 0xB2C1, - 0x6500, 0xC5CA, - 0x6509, 0xDFAB, - 0x6512, 0xD4DC, - 0x6518, 0xC8C1, - 0x6525, 0xDFAC, - 0x652B, 0xBEF0, - 0x652E, 0xDFAD, - 0x652F, 0xD6A7, - 0x6534, 0xEAB7, - 0x6535, 0xEBB6, - 0x6536, 0xCAD5, - 0x6538, 0xD8FC, - 0x6539, 0xB8C4, - 0x653B, 0xB9A5, - 0x653E, 0xB7C5, - 0x653F, 0xD5FE, - 0x6545, 0xB9CA, - 0x6548, 0xD0A7, - 0x6549, 0xF4CD, - 0x654C, 0xB5D0, - 0x654F, 0xC3F4, - 0x6551, 0xBEC8, - 0x6555, 0xEBB7, - 0x6556, 0xB0BD, - 0x6559, 0xBDCC, - 0x655B, 0xC1B2, - 0x655D, 0xB1D6, - 0x655E, 0xB3A8, - 0x6562, 0xB8D2, - 0x6563, 0xC9A2, - 0x6566, 0xB6D8, - 0x656B, 0xEBB8, - 0x656C, 0xBEB4, - 0x6570, 0xCAFD, - 0x6572, 0xC7C3, - 0x6574, 0xD5FB, - 0x6577, 0xB7F3, - 0x6587, 0xCEC4, - 0x658B, 0xD5AB, - 0x658C, 0xB1F3, - 0x6590, 0xECB3, - 0x6591, 0xB0DF, - 0x6593, 0xECB5, - 0x6597, 0xB6B7, - 0x6599, 0xC1CF, - 0x659B, 0xF5FA, - 0x659C, 0xD0B1, - 0x659F, 0xD5E5, - 0x65A1, 0xCED3, - 0x65A4, 0xBDEF, - 0x65A5, 0xB3E2, - 0x65A7, 0xB8AB, - 0x65A9, 0xD5B6, - 0x65AB, 0xEDBD, - 0x65AD, 0xB6CF, - 0x65AF, 0xCBB9, - 0x65B0, 0xD0C2, - 0x65B9, 0xB7BD, - 0x65BC, 0xECB6, - 0x65BD, 0xCAA9, - 0x65C1, 0xC5D4, - 0x65C3, 0xECB9, - 0x65C4, 0xECB8, - 0x65C5, 0xC2C3, - 0x65C6, 0xECB7, - 0x65CB, 0xD0FD, - 0x65CC, 0xECBA, - 0x65CE, 0xECBB, - 0x65CF, 0xD7E5, - 0x65D2, 0xECBC, - 0x65D6, 0xECBD, - 0x65D7, 0xC6EC, - 0x65E0, 0xCEDE, - 0x65E2, 0xBCC8, - 0x65E5, 0xC8D5, - 0x65E6, 0xB5A9, - 0x65E7, 0xBEC9, - 0x65E8, 0xD6BC, - 0x65E9, 0xD4E7, - 0x65EC, 0xD1AE, - 0x65ED, 0xD0F1, - 0x65EE, 0xEAB8, - 0x65EF, 0xEAB9, - 0x65F0, 0xEABA, - 0x65F1, 0xBAB5, - 0x65F6, 0xCAB1, - 0x65F7, 0xBFF5, - 0x65FA, 0xCDFA, - 0x6600, 0xEAC0, - 0x6602, 0xB0BA, - 0x6603, 0xEABE, - 0x6606, 0xC0A5, - 0x660A, 0xEABB, - 0x660C, 0xB2FD, - 0x660E, 0xC3F7, - 0x660F, 0xBBE8, - 0x6613, 0xD2D7, - 0x6614, 0xCEF4, - 0x6615, 0xEABF, - 0x6619, 0xEABC, - 0x661D, 0xEAC3, - 0x661F, 0xD0C7, - 0x6620, 0xD3B3, - 0x6625, 0xB4BA, - 0x6627, 0xC3C1, - 0x6628, 0xD7F2, - 0x662D, 0xD5D1, - 0x662F, 0xCAC7, - 0x6631, 0xEAC5, - 0x6634, 0xEAC4, - 0x6635, 0xEAC7, - 0x6636, 0xEAC6, - 0x663C, 0xD6E7, - 0x663E, 0xCFD4, - 0x6641, 0xEACB, - 0x6643, 0xBBCE, - 0x664B, 0xBDFA, - 0x664C, 0xC9CE, - 0x664F, 0xEACC, - 0x6652, 0xC9B9, - 0x6653, 0xCFFE, - 0x6654, 0xEACA, - 0x6655, 0xD4CE, - 0x6656, 0xEACD, - 0x6657, 0xEACF, - 0x665A, 0xCDED, - 0x665F, 0xEAC9, - 0x6661, 0xEACE, - 0x6664, 0xCEEE, - 0x6666, 0xBBDE, - 0x6668, 0xB3BF, - 0x666E, 0xC6D5, - 0x666F, 0xBEB0, - 0x6670, 0xCEFA, - 0x6674, 0xC7E7, - 0x6676, 0xBEA7, - 0x6677, 0xEAD0, - 0x667A, 0xD6C7, - 0x667E, 0xC1C0, - 0x6682, 0xD4DD, - 0x6684, 0xEAD1, - 0x6687, 0xCFBE, - 0x668C, 0xEAD2, - 0x6691, 0xCAEE, - 0x6696, 0xC5AF, - 0x6697, 0xB0B5, - 0x669D, 0xEAD4, - 0x66A7, 0xEAD3, - 0x66A8, 0xF4DF, - 0x66AE, 0xC4BA, - 0x66B4, 0xB1A9, - 0x66B9, 0xE5DF, - 0x66BE, 0xEAD5, - 0x66D9, 0xCAEF, - 0x66DB, 0xEAD6, - 0x66DC, 0xEAD7, - 0x66DD, 0xC6D8, - 0x66E6, 0xEAD8, - 0x66E9, 0xEAD9, - 0x66F0, 0xD4BB, - 0x66F2, 0xC7FA, - 0x66F3, 0xD2B7, - 0x66F4, 0xB8FC, - 0x66F7, 0xEAC2, - 0x66F9, 0xB2DC, - 0x66FC, 0xC2FC, - 0x66FE, 0xD4F8, - 0x66FF, 0xCCE6, - 0x6700, 0xD7EE, - 0x6708, 0xD4C2, - 0x6709, 0xD3D0, - 0x670A, 0xEBC3, - 0x670B, 0xC5F3, - 0x670D, 0xB7FE, - 0x6710, 0xEBD4, - 0x6714, 0xCBB7, - 0x6715, 0xEBDE, - 0x6717, 0xC0CA, - 0x671B, 0xCDFB, - 0x671D, 0xB3AF, - 0x671F, 0xC6DA, - 0x6726, 0xEBFC, - 0x6728, 0xC4BE, - 0x672A, 0xCEB4, - 0x672B, 0xC4A9, - 0x672C, 0xB1BE, - 0x672D, 0xD4FD, - 0x672F, 0xCAF5, - 0x6731, 0xD6EC, - 0x6734, 0xC6D3, - 0x6735, 0xB6E4, - 0x673A, 0xBBFA, - 0x673D, 0xD0E0, - 0x6740, 0xC9B1, - 0x6742, 0xD4D3, - 0x6743, 0xC8A8, - 0x6746, 0xB8CB, - 0x6748, 0xE8BE, - 0x6749, 0xC9BC, - 0x674C, 0xE8BB, - 0x674E, 0xC0EE, - 0x674F, 0xD0D3, - 0x6750, 0xB2C4, - 0x6751, 0xB4E5, - 0x6753, 0xE8BC, - 0x6756, 0xD5C8, - 0x675C, 0xB6C5, - 0x675E, 0xE8BD, - 0x675F, 0xCAF8, - 0x6760, 0xB8DC, - 0x6761, 0xCCF5, - 0x6765, 0xC0B4, - 0x6768, 0xD1EE, - 0x6769, 0xE8BF, - 0x676A, 0xE8C2, - 0x676D, 0xBABC, - 0x676F, 0xB1AD, - 0x6770, 0xBDDC, - 0x6772, 0xEABD, - 0x6773, 0xE8C3, - 0x6775, 0xE8C6, - 0x6777, 0xE8CB, - 0x677C, 0xE8CC, - 0x677E, 0xCBC9, - 0x677F, 0xB0E5, - 0x6781, 0xBCAB, - 0x6784, 0xB9B9, - 0x6787, 0xE8C1, - 0x6789, 0xCDF7, - 0x678B, 0xE8CA, - 0x6790, 0xCEF6, - 0x6795, 0xD5ED, - 0x6797, 0xC1D6, - 0x6798, 0xE8C4, - 0x679A, 0xC3B6, - 0x679C, 0xB9FB, - 0x679D, 0xD6A6, - 0x679E, 0xE8C8, - 0x67A2, 0xCAE0, - 0x67A3, 0xD4E6, - 0x67A5, 0xE8C0, - 0x67A7, 0xE8C5, - 0x67A8, 0xE8C7, - 0x67AA, 0xC7B9, - 0x67AB, 0xB7E3, - 0x67AD, 0xE8C9, - 0x67AF, 0xBFDD, - 0x67B0, 0xE8D2, - 0x67B3, 0xE8D7, - 0x67B5, 0xE8D5, - 0x67B6, 0xBCDC, - 0x67B7, 0xBCCF, - 0x67B8, 0xE8DB, - 0x67C1, 0xE8DE, - 0x67C3, 0xE8DA, - 0x67C4, 0xB1FA, - 0x67CF, 0xB0D8, - 0x67D0, 0xC4B3, - 0x67D1, 0xB8CC, - 0x67D2, 0xC6E2, - 0x67D3, 0xC8BE, - 0x67D4, 0xC8E1, - 0x67D8, 0xE8CF, - 0x67D9, 0xE8D4, - 0x67DA, 0xE8D6, - 0x67DC, 0xB9F1, - 0x67DD, 0xE8D8, - 0x67DE, 0xD7F5, - 0x67E0, 0xC4FB, - 0x67E2, 0xE8DC, - 0x67E5, 0xB2E9, - 0x67E9, 0xE8D1, - 0x67EC, 0xBCED, - 0x67EF, 0xBFC2, - 0x67F0, 0xE8CD, - 0x67F1, 0xD6F9, - 0x67F3, 0xC1F8, - 0x67F4, 0xB2F1, - 0x67FD, 0xE8DF, - 0x67FF, 0xCAC1, - 0x6800, 0xE8D9, - 0x6805, 0xD5A4, - 0x6807, 0xB1EA, - 0x6808, 0xD5BB, - 0x6809, 0xE8CE, - 0x680A, 0xE8D0, - 0x680B, 0xB6B0, - 0x680C, 0xE8D3, - 0x680E, 0xE8DD, - 0x680F, 0xC0B8, - 0x6811, 0xCAF7, - 0x6813, 0xCBA8, - 0x6816, 0xC6DC, - 0x6817, 0xC0F5, - 0x681D, 0xE8E9, - 0x6821, 0xD0A3, - 0x6829, 0xE8F2, - 0x682A, 0xD6EA, - 0x6832, 0xE8E0, - 0x6833, 0xE8E1, - 0x6837, 0xD1F9, - 0x6838, 0xBACB, - 0x6839, 0xB8F9, - 0x683C, 0xB8F1, - 0x683D, 0xD4D4, - 0x683E, 0xE8EF, - 0x6840, 0xE8EE, - 0x6841, 0xE8EC, - 0x6842, 0xB9F0, - 0x6843, 0xCCD2, - 0x6844, 0xE8E6, - 0x6845, 0xCEA6, - 0x6846, 0xBFF2, - 0x6848, 0xB0B8, - 0x6849, 0xE8F1, - 0x684A, 0xE8F0, - 0x684C, 0xD7C0, - 0x684E, 0xE8E4, - 0x6850, 0xCDA9, - 0x6851, 0xC9A3, - 0x6853, 0xBBB8, - 0x6854, 0xBDDB, - 0x6855, 0xE8EA, - 0x6860, 0xE8E2, - 0x6861, 0xE8E3, - 0x6862, 0xE8E5, - 0x6863, 0xB5B5, - 0x6864, 0xE8E7, - 0x6865, 0xC7C5, - 0x6866, 0xE8EB, - 0x6867, 0xE8ED, - 0x6868, 0xBDB0, - 0x6869, 0xD7AE, - 0x686B, 0xE8F8, - 0x6874, 0xE8F5, - 0x6876, 0xCDB0, - 0x6877, 0xE8F6, - 0x6881, 0xC1BA, - 0x6883, 0xE8E8, - 0x6885, 0xC3B7, - 0x6886, 0xB0F0, - 0x688F, 0xE8F4, - 0x6893, 0xE8F7, - 0x6897, 0xB9A3, - 0x68A2, 0xC9D2, - 0x68A6, 0xC3CE, - 0x68A7, 0xCEE0, - 0x68A8, 0xC0E6, - 0x68AD, 0xCBF3, - 0x68AF, 0xCCDD, - 0x68B0, 0xD0B5, - 0x68B3, 0xCAE1, - 0x68B5, 0xE8F3, - 0x68C0, 0xBCEC, - 0x68C2, 0xE8F9, - 0x68C9, 0xC3DE, - 0x68CB, 0xC6E5, - 0x68CD, 0xB9F7, - 0x68D2, 0xB0F4, - 0x68D5, 0xD7D8, - 0x68D8, 0xBCAC, - 0x68DA, 0xC5EF, - 0x68E0, 0xCCC4, - 0x68E3, 0xE9A6, - 0x68EE, 0xC9AD, - 0x68F0, 0xE9A2, - 0x68F1, 0xC0E2, - 0x68F5, 0xBFC3, - 0x68F9, 0xE8FE, - 0x68FA, 0xB9D7, - 0x68FC, 0xE8FB, - 0x6901, 0xE9A4, - 0x6905, 0xD2CE, - 0x690B, 0xE9A3, - 0x690D, 0xD6B2, - 0x690E, 0xD7B5, - 0x6910, 0xE9A7, - 0x6912, 0xBDB7, - 0x691F, 0xE8FC, - 0x6920, 0xE8FD, - 0x6924, 0xE9A1, - 0x692D, 0xCDD6, - 0x6930, 0xD2AC, - 0x6934, 0xE9B2, - 0x6939, 0xE9A9, - 0x693D, 0xB4AA, - 0x693F, 0xB4BB, - 0x6942, 0xE9AB, - 0x6954, 0xD0A8, - 0x6957, 0xE9A5, - 0x695A, 0xB3FE, - 0x695D, 0xE9AC, - 0x695E, 0xC0E3, - 0x6960, 0xE9AA, - 0x6963, 0xE9B9, - 0x6966, 0xE9B8, - 0x696B, 0xE9AE, - 0x696E, 0xE8FA, - 0x6971, 0xE9A8, - 0x6977, 0xBFAC, - 0x6978, 0xE9B1, - 0x6979, 0xE9BA, - 0x697C, 0xC2A5, - 0x6980, 0xE9AF, - 0x6982, 0xB8C5, - 0x6984, 0xE9AD, - 0x6986, 0xD3DC, - 0x6987, 0xE9B4, - 0x6988, 0xE9B5, - 0x6989, 0xE9B7, - 0x698D, 0xE9C7, - 0x6994, 0xC0C6, - 0x6995, 0xE9C5, - 0x6998, 0xE9B0, - 0x699B, 0xE9BB, - 0x699C, 0xB0F1, - 0x69A7, 0xE9BC, - 0x69A8, 0xD5A5, - 0x69AB, 0xE9BE, - 0x69AD, 0xE9BF, - 0x69B1, 0xE9C1, - 0x69B4, 0xC1F1, - 0x69B7, 0xC8B6, - 0x69BB, 0xE9BD, - 0x69C1, 0xE9C2, - 0x69CA, 0xE9C3, - 0x69CC, 0xE9B3, - 0x69CE, 0xE9B6, - 0x69D0, 0xBBB1, - 0x69D4, 0xE9C0, - 0x69DB, 0xBCF7, - 0x69DF, 0xE9C4, - 0x69E0, 0xE9C6, - 0x69ED, 0xE9CA, - 0x69F2, 0xE9CE, - 0x69FD, 0xB2DB, - 0x69FF, 0xE9C8, - 0x6A0A, 0xB7AE, - 0x6A17, 0xE9CB, - 0x6A18, 0xE9CC, - 0x6A1F, 0xD5C1, - 0x6A21, 0xC4A3, - 0x6A28, 0xE9D8, - 0x6A2A, 0xBAE1, - 0x6A2F, 0xE9C9, - 0x6A31, 0xD3A3, - 0x6A35, 0xE9D4, - 0x6A3D, 0xE9D7, - 0x6A3E, 0xE9D0, - 0x6A44, 0xE9CF, - 0x6A47, 0xC7C1, - 0x6A50, 0xE9D2, - 0x6A58, 0xE9D9, - 0x6A59, 0xB3C8, - 0x6A5B, 0xE9D3, - 0x6A61, 0xCFF0, - 0x6A65, 0xE9CD, - 0x6A71, 0xB3F7, - 0x6A79, 0xE9D6, - 0x6A7C, 0xE9DA, - 0x6A80, 0xCCB4, - 0x6A84, 0xCFAD, - 0x6A8E, 0xE9D5, - 0x6A90, 0xE9DC, - 0x6A91, 0xE9DB, - 0x6A97, 0xE9DE, - 0x6AA0, 0xE9D1, - 0x6AA9, 0xE9DD, - 0x6AAB, 0xE9DF, - 0x6AAC, 0xC3CA, - 0x6B20, 0xC7B7, - 0x6B21, 0xB4CE, - 0x6B22, 0xBBB6, - 0x6B23, 0xD0C0, - 0x6B24, 0xECA3, - 0x6B27, 0xC5B7, - 0x6B32, 0xD3FB, - 0x6B37, 0xECA4, - 0x6B39, 0xECA5, - 0x6B3A, 0xC6DB, - 0x6B3E, 0xBFEE, - 0x6B43, 0xECA6, - 0x6B46, 0xECA7, - 0x6B47, 0xD0AA, - 0x6B49, 0xC7B8, - 0x6B4C, 0xB8E8, - 0x6B59, 0xECA8, - 0x6B62, 0xD6B9, - 0x6B63, 0xD5FD, - 0x6B64, 0xB4CB, - 0x6B65, 0xB2BD, - 0x6B66, 0xCEE4, - 0x6B67, 0xC6E7, - 0x6B6A, 0xCDE1, - 0x6B79, 0xB4F5, - 0x6B7B, 0xCBC0, - 0x6B7C, 0xBCDF, - 0x6B81, 0xE9E2, - 0x6B82, 0xE9E3, - 0x6B83, 0xD1EA, - 0x6B84, 0xE9E5, - 0x6B86, 0xB4F9, - 0x6B87, 0xE9E4, - 0x6B89, 0xD1B3, - 0x6B8A, 0xCAE2, - 0x6B8B, 0xB2D0, - 0x6B8D, 0xE9E8, - 0x6B92, 0xE9E6, - 0x6B93, 0xE9E7, - 0x6B96, 0xD6B3, - 0x6B9A, 0xE9E9, - 0x6B9B, 0xE9EA, - 0x6BA1, 0xE9EB, - 0x6BAA, 0xE9EC, - 0x6BB3, 0xECAF, - 0x6BB4, 0xC5B9, - 0x6BB5, 0xB6CE, - 0x6BB7, 0xD2F3, - 0x6BBF, 0xB5EE, - 0x6BC1, 0xBBD9, - 0x6BC2, 0xECB1, - 0x6BC5, 0xD2E3, - 0x6BCB, 0xCEE3, - 0x6BCD, 0xC4B8, - 0x6BCF, 0xC3BF, - 0x6BD2, 0xB6BE, - 0x6BD3, 0xD8B9, - 0x6BD4, 0xB1C8, - 0x6BD5, 0xB1CF, - 0x6BD6, 0xB1D1, - 0x6BD7, 0xC5FE, - 0x6BD9, 0xB1D0, - 0x6BDB, 0xC3AB, - 0x6BE1, 0xD5B1, - 0x6BEA, 0xEBA4, - 0x6BEB, 0xBAC1, - 0x6BEF, 0xCCBA, - 0x6BF3, 0xEBA5, - 0x6BF5, 0xEBA7, - 0x6BF9, 0xEBA8, - 0x6BFD, 0xEBA6, - 0x6C05, 0xEBA9, - 0x6C06, 0xEBAB, - 0x6C07, 0xEBAA, - 0x6C0D, 0xEBAC, - 0x6C0F, 0xCACF, - 0x6C10, 0xD8B5, - 0x6C11, 0xC3F1, - 0x6C13, 0xC3A5, - 0x6C14, 0xC6F8, - 0x6C15, 0xEBAD, - 0x6C16, 0xC4CA, - 0x6C18, 0xEBAE, - 0x6C19, 0xEBAF, - 0x6C1A, 0xEBB0, - 0x6C1B, 0xB7D5, - 0x6C1F, 0xB7FA, - 0x6C21, 0xEBB1, - 0x6C22, 0xC7E2, - 0x6C24, 0xEBB3, - 0x6C26, 0xBAA4, - 0x6C27, 0xD1F5, - 0x6C28, 0xB0B1, - 0x6C29, 0xEBB2, - 0x6C2A, 0xEBB4, - 0x6C2E, 0xB5AA, - 0x6C2F, 0xC2C8, - 0x6C30, 0xC7E8, - 0x6C32, 0xEBB5, - 0x6C34, 0xCBAE, - 0x6C35, 0xE3DF, - 0x6C38, 0xD3C0, - 0x6C3D, 0xD9DB, - 0x6C40, 0xCDA1, - 0x6C41, 0xD6AD, - 0x6C42, 0xC7F3, - 0x6C46, 0xD9E0, - 0x6C47, 0xBBE3, - 0x6C49, 0xBABA, - 0x6C4A, 0xE3E2, - 0x6C50, 0xCFAB, - 0x6C54, 0xE3E0, - 0x6C55, 0xC9C7, - 0x6C57, 0xBAB9, - 0x6C5B, 0xD1B4, - 0x6C5C, 0xE3E1, - 0x6C5D, 0xC8EA, - 0x6C5E, 0xB9AF, - 0x6C5F, 0xBDAD, - 0x6C60, 0xB3D8, - 0x6C61, 0xCEDB, - 0x6C64, 0xCCC0, - 0x6C68, 0xE3E8, - 0x6C69, 0xE3E9, - 0x6C6A, 0xCDF4, - 0x6C70, 0xCCAD, - 0x6C72, 0xBCB3, - 0x6C74, 0xE3EA, - 0x6C76, 0xE3EB, - 0x6C79, 0xD0DA, - 0x6C7D, 0xC6FB, - 0x6C7E, 0xB7DA, - 0x6C81, 0xC7DF, - 0x6C82, 0xD2CA, - 0x6C83, 0xCED6, - 0x6C85, 0xE3E4, - 0x6C86, 0xE3EC, - 0x6C88, 0xC9F2, - 0x6C89, 0xB3C1, - 0x6C8C, 0xE3E7, - 0x6C8F, 0xC6E3, - 0x6C90, 0xE3E5, - 0x6C93, 0xEDB3, - 0x6C94, 0xE3E6, - 0x6C99, 0xC9B3, - 0x6C9B, 0xC5E6, - 0x6C9F, 0xB9B5, - 0x6CA1, 0xC3BB, - 0x6CA3, 0xE3E3, - 0x6CA4, 0xC5BD, - 0x6CA5, 0xC1A4, - 0x6CA6, 0xC2D9, - 0x6CA7, 0xB2D7, - 0x6CA9, 0xE3ED, - 0x6CAA, 0xBBA6, - 0x6CAB, 0xC4AD, - 0x6CAD, 0xE3F0, - 0x6CAE, 0xBEDA, - 0x6CB1, 0xE3FB, - 0x6CB2, 0xE3F5, - 0x6CB3, 0xBAD3, - 0x6CB8, 0xB7D0, - 0x6CB9, 0xD3CD, - 0x6CBB, 0xD6CE, - 0x6CBC, 0xD5D3, - 0x6CBD, 0xB9C1, - 0x6CBE, 0xD5B4, - 0x6CBF, 0xD1D8, - 0x6CC4, 0xD0B9, - 0x6CC5, 0xC7F6, - 0x6CC9, 0xC8AA, - 0x6CCA, 0xB2B4, - 0x6CCC, 0xC3DA, - 0x6CD0, 0xE3EE, - 0x6CD3, 0xE3FC, - 0x6CD4, 0xE3EF, - 0x6CD5, 0xB7A8, - 0x6CD6, 0xE3F7, - 0x6CD7, 0xE3F4, - 0x6CDB, 0xB7BA, - 0x6CDE, 0xC5A2, - 0x6CE0, 0xE3F6, - 0x6CE1, 0xC5DD, - 0x6CE2, 0xB2A8, - 0x6CE3, 0xC6FC, - 0x6CE5, 0xC4E0, - 0x6CE8, 0xD7A2, - 0x6CEA, 0xC0E1, - 0x6CEB, 0xE3F9, - 0x6CEE, 0xE3FA, - 0x6CEF, 0xE3FD, - 0x6CF0, 0xCCA9, - 0x6CF1, 0xE3F3, - 0x6CF3, 0xD3BE, - 0x6CF5, 0xB1C3, - 0x6CF6, 0xEDB4, - 0x6CF7, 0xE3F1, - 0x6CF8, 0xE3F2, - 0x6CFA, 0xE3F8, - 0x6CFB, 0xD0BA, - 0x6CFC, 0xC6C3, - 0x6CFD, 0xD4F3, - 0x6CFE, 0xE3FE, - 0x6D01, 0xBDE0, - 0x6D04, 0xE4A7, - 0x6D07, 0xE4A6, - 0x6D0B, 0xD1F3, - 0x6D0C, 0xE4A3, - 0x6D0E, 0xE4A9, - 0x6D12, 0xC8F7, - 0x6D17, 0xCFB4, - 0x6D19, 0xE4A8, - 0x6D1A, 0xE4AE, - 0x6D1B, 0xC2E5, - 0x6D1E, 0xB6B4, - 0x6D25, 0xBDF2, - 0x6D27, 0xE4A2, - 0x6D2A, 0xBAE9, - 0x6D2B, 0xE4AA, - 0x6D2E, 0xE4AC, - 0x6D31, 0xB6FD, - 0x6D32, 0xD6DE, - 0x6D33, 0xE4B2, - 0x6D35, 0xE4AD, - 0x6D39, 0xE4A1, - 0x6D3B, 0xBBEE, - 0x6D3C, 0xCDDD, - 0x6D3D, 0xC7A2, - 0x6D3E, 0xC5C9, - 0x6D41, 0xC1F7, - 0x6D43, 0xE4A4, - 0x6D45, 0xC7B3, - 0x6D46, 0xBDAC, - 0x6D47, 0xBDBD, - 0x6D48, 0xE4A5, - 0x6D4A, 0xD7C7, - 0x6D4B, 0xB2E2, - 0x6D4D, 0xE4AB, - 0x6D4E, 0xBCC3, - 0x6D4F, 0xE4AF, - 0x6D51, 0xBBEB, - 0x6D52, 0xE4B0, - 0x6D53, 0xC5A8, - 0x6D54, 0xE4B1, - 0x6D59, 0xD5E3, - 0x6D5A, 0xBFA3, - 0x6D5C, 0xE4BA, - 0x6D5E, 0xE4B7, - 0x6D60, 0xE4BB, - 0x6D63, 0xE4BD, - 0x6D66, 0xC6D6, - 0x6D69, 0xBAC6, - 0x6D6A, 0xC0CB, - 0x6D6E, 0xB8A1, - 0x6D6F, 0xE4B4, - 0x6D74, 0xD4A1, - 0x6D77, 0xBAA3, - 0x6D78, 0xBDFE, - 0x6D7C, 0xE4BC, - 0x6D82, 0xCDBF, - 0x6D85, 0xC4F9, - 0x6D88, 0xCFFB, - 0x6D89, 0xC9E6, - 0x6D8C, 0xD3BF, - 0x6D8E, 0xCFD1, - 0x6D91, 0xE4B3, - 0x6D93, 0xE4B8, - 0x6D94, 0xE4B9, - 0x6D95, 0xCCE9, - 0x6D9B, 0xCCCE, - 0x6D9D, 0xC0D4, - 0x6D9E, 0xE4B5, - 0x6D9F, 0xC1B0, - 0x6DA0, 0xE4B6, - 0x6DA1, 0xCED0, - 0x6DA3, 0xBBC1, - 0x6DA4, 0xB5D3, - 0x6DA6, 0xC8F3, - 0x6DA7, 0xBDA7, - 0x6DA8, 0xD5C7, - 0x6DA9, 0xC9AC, - 0x6DAA, 0xB8A2, - 0x6DAB, 0xE4CA, - 0x6DAE, 0xE4CC, - 0x6DAF, 0xD1C4, - 0x6DB2, 0xD2BA, - 0x6DB5, 0xBAAD, - 0x6DB8, 0xBAD4, - 0x6DBF, 0xE4C3, - 0x6DC0, 0xB5ED, - 0x6DC4, 0xD7CD, - 0x6DC5, 0xE4C0, - 0x6DC6, 0xCFFD, - 0x6DC7, 0xE4BF, - 0x6DCB, 0xC1DC, - 0x6DCC, 0xCCCA, - 0x6DD1, 0xCAE7, - 0x6DD6, 0xC4D7, - 0x6DD8, 0xCCD4, - 0x6DD9, 0xE4C8, - 0x6DDD, 0xE4C7, - 0x6DDE, 0xE4C1, - 0x6DE0, 0xE4C4, - 0x6DE1, 0xB5AD, - 0x6DE4, 0xD3D9, - 0x6DE6, 0xE4C6, - 0x6DEB, 0xD2F9, - 0x6DEC, 0xB4E3, - 0x6DEE, 0xBBB4, - 0x6DF1, 0xC9EE, - 0x6DF3, 0xB4BE, - 0x6DF7, 0xBBEC, - 0x6DF9, 0xD1CD, - 0x6DFB, 0xCCED, - 0x6DFC, 0xEDB5, - 0x6E05, 0xC7E5, - 0x6E0A, 0xD4A8, - 0x6E0C, 0xE4CB, - 0x6E0D, 0xD7D5, - 0x6E0E, 0xE4C2, - 0x6E10, 0xBDA5, - 0x6E11, 0xE4C5, - 0x6E14, 0xD3E6, - 0x6E16, 0xE4C9, - 0x6E17, 0xC9F8, - 0x6E1A, 0xE4BE, - 0x6E1D, 0xD3E5, - 0x6E20, 0xC7FE, - 0x6E21, 0xB6C9, - 0x6E23, 0xD4FC, - 0x6E24, 0xB2B3, - 0x6E25, 0xE4D7, - 0x6E29, 0xCEC2, - 0x6E2B, 0xE4CD, - 0x6E2D, 0xCEBC, - 0x6E2F, 0xB8DB, - 0x6E32, 0xE4D6, - 0x6E34, 0xBFCA, - 0x6E38, 0xD3CE, - 0x6E3A, 0xC3EC, - 0x6E43, 0xC5C8, - 0x6E44, 0xE4D8, - 0x6E4D, 0xCDC4, - 0x6E4E, 0xE4CF, - 0x6E53, 0xE4D4, - 0x6E54, 0xE4D5, - 0x6E56, 0xBAFE, - 0x6E58, 0xCFE6, - 0x6E5B, 0xD5BF, - 0x6E5F, 0xE4D2, - 0x6E6B, 0xE4D0, - 0x6E6E, 0xE4CE, - 0x6E7E, 0xCDE5, - 0x6E7F, 0xCAAA, - 0x6E83, 0xC0A3, - 0x6E85, 0xBDA6, - 0x6E86, 0xE4D3, - 0x6E89, 0xB8C8, - 0x6E8F, 0xE4E7, - 0x6E90, 0xD4B4, - 0x6E98, 0xE4DB, - 0x6E9C, 0xC1EF, - 0x6E9F, 0xE4E9, - 0x6EA2, 0xD2E7, - 0x6EA5, 0xE4DF, - 0x6EA7, 0xE4E0, - 0x6EAA, 0xCFAA, - 0x6EAF, 0xCBDD, - 0x6EB1, 0xE4DA, - 0x6EB2, 0xE4D1, - 0x6EB4, 0xE4E5, - 0x6EB6, 0xC8DC, - 0x6EB7, 0xE4E3, - 0x6EBA, 0xC4E7, - 0x6EBB, 0xE4E2, - 0x6EBD, 0xE4E1, - 0x6EC1, 0xB3FC, - 0x6EC2, 0xE4E8, - 0x6EC7, 0xB5E1, - 0x6ECB, 0xD7CC, - 0x6ECF, 0xE4E6, - 0x6ED1, 0xBBAC, - 0x6ED3, 0xD7D2, - 0x6ED4, 0xCCCF, - 0x6ED5, 0xEBF8, - 0x6ED7, 0xE4E4, - 0x6EDA, 0xB9F6, - 0x6EDE, 0xD6CD, - 0x6EDF, 0xE4D9, - 0x6EE0, 0xE4DC, - 0x6EE1, 0xC2FA, - 0x6EE2, 0xE4DE, - 0x6EE4, 0xC2CB, - 0x6EE5, 0xC0C4, - 0x6EE6, 0xC2D0, - 0x6EE8, 0xB1F5, - 0x6EE9, 0xCCB2, - 0x6EF4, 0xB5CE, - 0x6EF9, 0xE4EF, - 0x6F02, 0xC6AF, - 0x6F06, 0xC6E1, - 0x6F09, 0xE4F5, - 0x6F0F, 0xC2A9, - 0x6F13, 0xC0EC, - 0x6F14, 0xD1DD, - 0x6F15, 0xE4EE, - 0x6F20, 0xC4AE, - 0x6F24, 0xE4ED, - 0x6F29, 0xE4F6, - 0x6F2A, 0xE4F4, - 0x6F2B, 0xC2FE, - 0x6F2D, 0xE4DD, - 0x6F2F, 0xE4F0, - 0x6F31, 0xCAFE, - 0x6F33, 0xD5C4, - 0x6F36, 0xE4F1, - 0x6F3E, 0xD1FA, - 0x6F46, 0xE4EB, - 0x6F47, 0xE4EC, - 0x6F4B, 0xE4F2, - 0x6F4D, 0xCEAB, - 0x6F58, 0xC5CB, - 0x6F5C, 0xC7B1, - 0x6F5E, 0xC2BA, - 0x6F62, 0xE4EA, - 0x6F66, 0xC1CA, - 0x6F6D, 0xCCB6, - 0x6F6E, 0xB3B1, - 0x6F72, 0xE4FB, - 0x6F74, 0xE4F3, - 0x6F78, 0xE4FA, - 0x6F7A, 0xE4FD, - 0x6F7C, 0xE4FC, - 0x6F84, 0xB3CE, - 0x6F88, 0xB3BA, - 0x6F89, 0xE4F7, - 0x6F8C, 0xE4F9, - 0x6F8D, 0xE4F8, - 0x6F8E, 0xC5EC, - 0x6F9C, 0xC0BD, - 0x6FA1, 0xD4E8, - 0x6FA7, 0xE5A2, - 0x6FB3, 0xB0C4, - 0x6FB6, 0xE5A4, - 0x6FB9, 0xE5A3, - 0x6FC0, 0xBCA4, - 0x6FC2, 0xE5A5, - 0x6FC9, 0xE5A1, - 0x6FD1, 0xE4FE, - 0x6FD2, 0xB1F4, - 0x6FDE, 0xE5A8, - 0x6FE0, 0xE5A9, - 0x6FE1, 0xE5A6, - 0x6FEE, 0xE5A7, - 0x6FEF, 0xE5AA, - 0x7011, 0xC6D9, - 0x701A, 0xE5AB, - 0x701B, 0xE5AD, - 0x7023, 0xE5AC, - 0x7035, 0xE5AF, - 0x7039, 0xE5AE, - 0x704C, 0xB9E0, - 0x704F, 0xE5B0, - 0x705E, 0xE5B1, - 0x706B, 0xBBF0, - 0x706C, 0xECE1, - 0x706D, 0xC3F0, - 0x706F, 0xB5C6, - 0x7070, 0xBBD2, - 0x7075, 0xC1E9, - 0x7076, 0xD4EE, - 0x7078, 0xBEC4, - 0x707C, 0xD7C6, - 0x707E, 0xD4D6, - 0x707F, 0xB2D3, - 0x7080, 0xECBE, - 0x7085, 0xEAC1, - 0x7089, 0xC2AF, - 0x708A, 0xB4B6, - 0x708E, 0xD1D7, - 0x7092, 0xB3B4, - 0x7094, 0xC8B2, - 0x7095, 0xBFBB, - 0x7096, 0xECC0, - 0x7099, 0xD6CB, - 0x709C, 0xECBF, - 0x709D, 0xECC1, - 0x70AB, 0xECC5, - 0x70AC, 0xBEE6, - 0x70AD, 0xCCBF, - 0x70AE, 0xC5DA, - 0x70AF, 0xBEBC, - 0x70B1, 0xECC6, - 0x70B3, 0xB1FE, - 0x70B7, 0xECC4, - 0x70B8, 0xD5A8, - 0x70B9, 0xB5E3, - 0x70BB, 0xECC2, - 0x70BC, 0xC1B6, - 0x70BD, 0xB3E3, - 0x70C0, 0xECC3, - 0x70C1, 0xCBB8, - 0x70C2, 0xC0C3, - 0x70C3, 0xCCFE, - 0x70C8, 0xC1D2, - 0x70CA, 0xECC8, - 0x70D8, 0xBAE6, - 0x70D9, 0xC0D3, - 0x70DB, 0xD6F2, - 0x70DF, 0xD1CC, - 0x70E4, 0xBFBE, - 0x70E6, 0xB7B3, - 0x70E7, 0xC9D5, - 0x70E8, 0xECC7, - 0x70E9, 0xBBE2, - 0x70EB, 0xCCCC, - 0x70EC, 0xBDFD, - 0x70ED, 0xC8C8, - 0x70EF, 0xCFA9, - 0x70F7, 0xCDE9, - 0x70F9, 0xC5EB, - 0x70FD, 0xB7E9, - 0x7109, 0xD1C9, - 0x710A, 0xBAB8, - 0x7110, 0xECC9, - 0x7113, 0xECCA, - 0x7115, 0xBBC0, - 0x7116, 0xECCB, - 0x7118, 0xECE2, - 0x7119, 0xB1BA, - 0x711A, 0xB7D9, - 0x7126, 0xBDB9, - 0x712F, 0xECCC, - 0x7130, 0xD1E6, - 0x7131, 0xECCD, - 0x7136, 0xC8BB, - 0x7145, 0xECD1, - 0x714A, 0xECD3, - 0x714C, 0xBBCD, - 0x714E, 0xBCE5, - 0x715C, 0xECCF, - 0x715E, 0xC9B7, - 0x7164, 0xC3BA, - 0x7166, 0xECE3, - 0x7167, 0xD5D5, - 0x7168, 0xECD0, - 0x716E, 0xD6F3, - 0x7172, 0xECD2, - 0x7173, 0xECCE, - 0x7178, 0xECD4, - 0x717A, 0xECD5, - 0x717D, 0xC9BF, - 0x7184, 0xCFA8, - 0x718A, 0xD0DC, - 0x718F, 0xD1AC, - 0x7194, 0xC8DB, - 0x7198, 0xECD6, - 0x7199, 0xCEF5, - 0x719F, 0xCAEC, - 0x71A0, 0xECDA, - 0x71A8, 0xECD9, - 0x71AC, 0xB0BE, - 0x71B3, 0xECD7, - 0x71B5, 0xECD8, - 0x71B9, 0xECE4, - 0x71C3, 0xC8BC, - 0x71CE, 0xC1C7, - 0x71D4, 0xECDC, - 0x71D5, 0xD1E0, - 0x71E0, 0xECDB, - 0x71E5, 0xD4EF, - 0x71E7, 0xECDD, - 0x71EE, 0xDBC6, - 0x71F9, 0xECDE, - 0x7206, 0xB1AC, - 0x721D, 0xECDF, - 0x7228, 0xECE0, - 0x722A, 0xD7A6, - 0x722C, 0xC5C0, - 0x7230, 0xEBBC, - 0x7231, 0xB0AE, - 0x7235, 0xBEF4, - 0x7236, 0xB8B8, - 0x7237, 0xD2AF, - 0x7238, 0xB0D6, - 0x7239, 0xB5F9, - 0x723B, 0xD8B3, - 0x723D, 0xCBAC, - 0x723F, 0xE3DD, - 0x7247, 0xC6AC, - 0x7248, 0xB0E6, - 0x724C, 0xC5C6, - 0x724D, 0xEBB9, - 0x7252, 0xEBBA, - 0x7256, 0xEBBB, - 0x7259, 0xD1C0, - 0x725B, 0xC5A3, - 0x725D, 0xEAF2, - 0x725F, 0xC4B2, - 0x7261, 0xC4B5, - 0x7262, 0xC0CE, - 0x7266, 0xEAF3, - 0x7267, 0xC4C1, - 0x7269, 0xCEEF, - 0x726E, 0xEAF0, - 0x726F, 0xEAF4, - 0x7272, 0xC9FC, - 0x7275, 0xC7A3, - 0x7279, 0xCCD8, - 0x727A, 0xCEFE, - 0x727E, 0xEAF5, - 0x727F, 0xEAF6, - 0x7280, 0xCFAC, - 0x7281, 0xC0E7, - 0x7284, 0xEAF7, - 0x728A, 0xB6BF, - 0x728B, 0xEAF8, - 0x728D, 0xEAF9, - 0x728F, 0xEAFA, - 0x7292, 0xEAFB, - 0x729F, 0xEAF1, - 0x72AC, 0xC8AE, - 0x72AD, 0xE1EB, - 0x72AF, 0xB7B8, - 0x72B0, 0xE1EC, - 0x72B4, 0xE1ED, - 0x72B6, 0xD7B4, - 0x72B7, 0xE1EE, - 0x72B8, 0xE1EF, - 0x72B9, 0xD3CC, - 0x72C1, 0xE1F1, - 0x72C2, 0xBFF1, - 0x72C3, 0xE1F0, - 0x72C4, 0xB5D2, - 0x72C8, 0xB1B7, - 0x72CD, 0xE1F3, - 0x72CE, 0xE1F2, - 0x72D0, 0xBAFC, - 0x72D2, 0xE1F4, - 0x72D7, 0xB9B7, - 0x72D9, 0xBED1, - 0x72DE, 0xC4FC, - 0x72E0, 0xBADD, - 0x72E1, 0xBDC6, - 0x72E8, 0xE1F5, - 0x72E9, 0xE1F7, - 0x72EC, 0xB6C0, - 0x72ED, 0xCFC1, - 0x72EE, 0xCAA8, - 0x72EF, 0xE1F6, - 0x72F0, 0xD5F8, - 0x72F1, 0xD3FC, - 0x72F2, 0xE1F8, - 0x72F3, 0xE1FC, - 0x72F4, 0xE1F9, - 0x72F7, 0xE1FA, - 0x72F8, 0xC0EA, - 0x72FA, 0xE1FE, - 0x72FB, 0xE2A1, - 0x72FC, 0xC0C7, - 0x7301, 0xE1FB, - 0x7303, 0xE1FD, - 0x730A, 0xE2A5, - 0x730E, 0xC1D4, - 0x7313, 0xE2A3, - 0x7315, 0xE2A8, - 0x7316, 0xB2FE, - 0x7317, 0xE2A2, - 0x731B, 0xC3CD, - 0x731C, 0xB2C2, - 0x731D, 0xE2A7, - 0x731E, 0xE2A6, - 0x7321, 0xE2A4, - 0x7322, 0xE2A9, - 0x7325, 0xE2AB, - 0x7329, 0xD0C9, - 0x732A, 0xD6ED, - 0x732B, 0xC3A8, - 0x732C, 0xE2AC, - 0x732E, 0xCFD7, - 0x7331, 0xE2AE, - 0x7334, 0xBAEF, - 0x7337, 0xE9E0, - 0x7338, 0xE2AD, - 0x7339, 0xE2AA, - 0x733E, 0xBBAB, - 0x733F, 0xD4B3, - 0x734D, 0xE2B0, - 0x7350, 0xE2AF, - 0x7352, 0xE9E1, - 0x7357, 0xE2B1, - 0x7360, 0xE2B2, - 0x736C, 0xE2B3, - 0x736D, 0xCCA1, - 0x736F, 0xE2B4, - 0x737E, 0xE2B5, - 0x7384, 0xD0FE, - 0x7387, 0xC2CA, - 0x7389, 0xD3F1, - 0x738B, 0xCDF5, - 0x738E, 0xE7E0, - 0x7391, 0xE7E1, - 0x7396, 0xBEC1, - 0x739B, 0xC2EA, - 0x739F, 0xE7E4, - 0x73A2, 0xE7E3, - 0x73A9, 0xCDE6, - 0x73AB, 0xC3B5, - 0x73AE, 0xE7E2, - 0x73AF, 0xBBB7, - 0x73B0, 0xCFD6, - 0x73B2, 0xC1E1, - 0x73B3, 0xE7E9, - 0x73B7, 0xE7E8, - 0x73BA, 0xE7F4, - 0x73BB, 0xB2A3, - 0x73C0, 0xE7EA, - 0x73C2, 0xE7E6, - 0x73C8, 0xE7EC, - 0x73C9, 0xE7EB, - 0x73CA, 0xC9BA, - 0x73CD, 0xD5E4, - 0x73CF, 0xE7E5, - 0x73D0, 0xB7A9, - 0x73D1, 0xE7E7, - 0x73D9, 0xE7EE, - 0x73DE, 0xE7F3, - 0x73E0, 0xD6E9, - 0x73E5, 0xE7ED, - 0x73E7, 0xE7F2, - 0x73E9, 0xE7F1, - 0x73ED, 0xB0E0, - 0x73F2, 0xE7F5, - 0x7403, 0xC7F2, - 0x7405, 0xC0C5, - 0x7406, 0xC0ED, - 0x7409, 0xC1F0, - 0x740A, 0xE7F0, - 0x740F, 0xE7F6, - 0x7410, 0xCBF6, - 0x741A, 0xE8A2, - 0x741B, 0xE8A1, - 0x7422, 0xD7C1, - 0x7425, 0xE7FA, - 0x7426, 0xE7F9, - 0x7428, 0xE7FB, - 0x742A, 0xE7F7, - 0x742C, 0xE7FE, - 0x742E, 0xE7FD, - 0x7430, 0xE7FC, - 0x7433, 0xC1D5, - 0x7434, 0xC7D9, - 0x7435, 0xC5FD, - 0x7436, 0xC5C3, - 0x743C, 0xC7ED, - 0x7441, 0xE8A3, - 0x7455, 0xE8A6, - 0x7457, 0xE8A5, - 0x7459, 0xE8A7, - 0x745A, 0xBAF7, - 0x745B, 0xE7F8, - 0x745C, 0xE8A4, - 0x745E, 0xC8F0, - 0x745F, 0xC9AA, - 0x746D, 0xE8A9, - 0x7470, 0xB9E5, - 0x7476, 0xD1FE, - 0x7477, 0xE8A8, - 0x747E, 0xE8AA, - 0x7480, 0xE8AD, - 0x7481, 0xE8AE, - 0x7483, 0xC1A7, - 0x7487, 0xE8AF, - 0x748B, 0xE8B0, - 0x748E, 0xE8AC, - 0x7490, 0xE8B4, - 0x749C, 0xE8AB, - 0x749E, 0xE8B1, - 0x74A7, 0xE8B5, - 0x74A8, 0xE8B2, - 0x74A9, 0xE8B3, - 0x74BA, 0xE8B7, - 0x74D2, 0xE8B6, - 0x74DC, 0xB9CF, - 0x74DE, 0xF0AC, - 0x74E0, 0xF0AD, - 0x74E2, 0xC6B0, - 0x74E3, 0xB0EA, - 0x74E4, 0xC8BF, - 0x74E6, 0xCDDF, - 0x74EE, 0xCECD, - 0x74EF, 0xEAB1, - 0x74F4, 0xEAB2, - 0x74F6, 0xC6BF, - 0x74F7, 0xB4C9, - 0x74FF, 0xEAB3, - 0x7504, 0xD5E7, - 0x750D, 0xDDF9, - 0x750F, 0xEAB4, - 0x7511, 0xEAB5, - 0x7513, 0xEAB6, - 0x7518, 0xB8CA, - 0x7519, 0xDFB0, - 0x751A, 0xC9F5, - 0x751C, 0xCCF0, - 0x751F, 0xC9FA, - 0x7525, 0xC9FB, - 0x7528, 0xD3C3, - 0x7529, 0xCBA6, - 0x752B, 0xB8A6, - 0x752C, 0xF0AE, - 0x752D, 0xB1C2, - 0x752F, 0xE5B8, - 0x7530, 0xCCEF, - 0x7531, 0xD3C9, - 0x7532, 0xBCD7, - 0x7533, 0xC9EA, - 0x7535, 0xB5E7, - 0x7537, 0xC4D0, - 0x7538, 0xB5E9, - 0x753A, 0xEEAE, - 0x753B, 0xBBAD, - 0x753E, 0xE7DE, - 0x7540, 0xEEAF, - 0x7545, 0xB3A9, - 0x7548, 0xEEB2, - 0x754B, 0xEEB1, - 0x754C, 0xBDE7, - 0x754E, 0xEEB0, - 0x754F, 0xCEB7, - 0x7554, 0xC5CF, - 0x7559, 0xC1F4, - 0x755A, 0xDBCE, - 0x755B, 0xEEB3, - 0x755C, 0xD0F3, - 0x7565, 0xC2D4, - 0x7566, 0xC6E8, - 0x756A, 0xB7AC, - 0x7572, 0xEEB4, - 0x7574, 0xB3EB, - 0x7578, 0xBBFB, - 0x7579, 0xEEB5, - 0x757F, 0xE7DC, - 0x7583, 0xEEB6, - 0x7586, 0xBDAE, - 0x758B, 0xF1E2, - 0x758F, 0xCAE8, - 0x7591, 0xD2C9, - 0x7592, 0xF0DA, - 0x7594, 0xF0DB, - 0x7596, 0xF0DC, - 0x7597, 0xC1C6, - 0x7599, 0xB8ED, - 0x759A, 0xBECE, - 0x759D, 0xF0DE, - 0x759F, 0xC5B1, - 0x75A0, 0xF0DD, - 0x75A1, 0xD1F1, - 0x75A3, 0xF0E0, - 0x75A4, 0xB0CC, - 0x75A5, 0xBDEA, - 0x75AB, 0xD2DF, - 0x75AC, 0xF0DF, - 0x75AE, 0xB4AF, - 0x75AF, 0xB7E8, - 0x75B0, 0xF0E6, - 0x75B1, 0xF0E5, - 0x75B2, 0xC6A3, - 0x75B3, 0xF0E1, - 0x75B4, 0xF0E2, - 0x75B5, 0xB4C3, - 0x75B8, 0xF0E3, - 0x75B9, 0xD5EE, - 0x75BC, 0xCCDB, - 0x75BD, 0xBED2, - 0x75BE, 0xBCB2, - 0x75C2, 0xF0E8, - 0x75C3, 0xF0E7, - 0x75C4, 0xF0E4, - 0x75C5, 0xB2A1, - 0x75C7, 0xD6A2, - 0x75C8, 0xD3B8, - 0x75C9, 0xBEB7, - 0x75CA, 0xC8AC, - 0x75CD, 0xF0EA, - 0x75D2, 0xD1F7, - 0x75D4, 0xD6CC, - 0x75D5, 0xBADB, - 0x75D6, 0xF0E9, - 0x75D8, 0xB6BB, - 0x75DB, 0xCDB4, - 0x75DE, 0xC6A6, - 0x75E2, 0xC1A1, - 0x75E3, 0xF0EB, - 0x75E4, 0xF0EE, - 0x75E6, 0xF0ED, - 0x75E7, 0xF0F0, - 0x75E8, 0xF0EC, - 0x75EA, 0xBBBE, - 0x75EB, 0xF0EF, - 0x75F0, 0xCCB5, - 0x75F1, 0xF0F2, - 0x75F4, 0xB3D5, - 0x75F9, 0xB1D4, - 0x75FC, 0xF0F3, - 0x75FF, 0xF0F4, - 0x7600, 0xF0F6, - 0x7601, 0xB4E1, - 0x7603, 0xF0F1, - 0x7605, 0xF0F7, - 0x760A, 0xF0FA, - 0x760C, 0xF0F8, - 0x7610, 0xF0F5, - 0x7615, 0xF0FD, - 0x7617, 0xF0F9, - 0x7618, 0xF0FC, - 0x7619, 0xF0FE, - 0x761B, 0xF1A1, - 0x761F, 0xCEC1, - 0x7620, 0xF1A4, - 0x7622, 0xF1A3, - 0x7624, 0xC1F6, - 0x7625, 0xF0FB, - 0x7626, 0xCADD, - 0x7629, 0xB4F1, - 0x762A, 0xB1F1, - 0x762B, 0xCCB1, - 0x762D, 0xF1A6, - 0x7630, 0xF1A7, - 0x7633, 0xF1AC, - 0x7634, 0xD5CE, - 0x7635, 0xF1A9, - 0x7638, 0xC8B3, - 0x763C, 0xF1A2, - 0x763E, 0xF1AB, - 0x763F, 0xF1A8, - 0x7640, 0xF1A5, - 0x7643, 0xF1AA, - 0x764C, 0xB0A9, - 0x764D, 0xF1AD, - 0x7654, 0xF1AF, - 0x7656, 0xF1B1, - 0x765C, 0xF1B0, - 0x765E, 0xF1AE, - 0x7663, 0xD1A2, - 0x766B, 0xF1B2, - 0x766F, 0xF1B3, - 0x7678, 0xB9EF, - 0x767B, 0xB5C7, - 0x767D, 0xB0D7, - 0x767E, 0xB0D9, - 0x7682, 0xD4ED, - 0x7684, 0xB5C4, - 0x7686, 0xBDD4, - 0x7687, 0xBBCA, - 0x7688, 0xF0A7, - 0x768B, 0xB8DE, - 0x768E, 0xF0A8, - 0x7691, 0xB0A8, - 0x7693, 0xF0A9, - 0x7696, 0xCDEE, - 0x7699, 0xF0AA, - 0x76A4, 0xF0AB, - 0x76AE, 0xC6A4, - 0x76B1, 0xD6E5, - 0x76B2, 0xF1E4, - 0x76B4, 0xF1E5, - 0x76BF, 0xC3F3, - 0x76C2, 0xD3DB, - 0x76C5, 0xD6D1, - 0x76C6, 0xC5E8, - 0x76C8, 0xD3AF, - 0x76CA, 0xD2E6, - 0x76CD, 0xEEC1, - 0x76CE, 0xB0BB, - 0x76CF, 0xD5B5, - 0x76D0, 0xD1CE, - 0x76D1, 0xBCE0, - 0x76D2, 0xBAD0, - 0x76D4, 0xBFF8, - 0x76D6, 0xB8C7, - 0x76D7, 0xB5C1, - 0x76D8, 0xC5CC, - 0x76DB, 0xCAA2, - 0x76DF, 0xC3CB, - 0x76E5, 0xEEC2, - 0x76EE, 0xC4BF, - 0x76EF, 0xB6A2, - 0x76F1, 0xEDEC, - 0x76F2, 0xC3A4, - 0x76F4, 0xD6B1, - 0x76F8, 0xCFE0, - 0x76F9, 0xEDEF, - 0x76FC, 0xC5CE, - 0x76FE, 0xB6DC, - 0x7701, 0xCAA1, - 0x7704, 0xEDED, - 0x7707, 0xEDF0, - 0x7708, 0xEDF1, - 0x7709, 0xC3BC, - 0x770B, 0xBFB4, - 0x770D, 0xEDEE, - 0x7719, 0xEDF4, - 0x771A, 0xEDF2, - 0x771F, 0xD5E6, - 0x7720, 0xC3DF, - 0x7722, 0xEDF3, - 0x7726, 0xEDF6, - 0x7728, 0xD5A3, - 0x7729, 0xD1A3, - 0x772D, 0xEDF5, - 0x772F, 0xC3D0, - 0x7735, 0xEDF7, - 0x7736, 0xBFF4, - 0x7737, 0xBEEC, - 0x7738, 0xEDF8, - 0x773A, 0xCCF7, - 0x773C, 0xD1DB, - 0x7740, 0xD7C5, - 0x7741, 0xD5F6, - 0x7743, 0xEDFC, - 0x7747, 0xEDFB, - 0x7750, 0xEDF9, - 0x7751, 0xEDFA, - 0x775A, 0xEDFD, - 0x775B, 0xBEA6, - 0x7761, 0xCBAF, - 0x7762, 0xEEA1, - 0x7763, 0xB6BD, - 0x7765, 0xEEA2, - 0x7766, 0xC4C0, - 0x7768, 0xEDFE, - 0x776B, 0xBDDE, - 0x776C, 0xB2C7, - 0x7779, 0xB6C3, - 0x777D, 0xEEA5, - 0x777E, 0xD8BA, - 0x777F, 0xEEA3, - 0x7780, 0xEEA6, - 0x7784, 0xC3E9, - 0x7785, 0xB3F2, - 0x778C, 0xEEA7, - 0x778D, 0xEEA4, - 0x778E, 0xCFB9, - 0x7791, 0xEEA8, - 0x7792, 0xC2F7, - 0x779F, 0xEEA9, - 0x77A0, 0xEEAA, - 0x77A2, 0xDEAB, - 0x77A5, 0xC6B3, - 0x77A7, 0xC7C6, - 0x77A9, 0xD6F5, - 0x77AA, 0xB5C9, - 0x77AC, 0xCBB2, - 0x77B0, 0xEEAB, - 0x77B3, 0xCDAB, - 0x77B5, 0xEEAC, - 0x77BB, 0xD5B0, - 0x77BD, 0xEEAD, - 0x77BF, 0xF6C4, - 0x77CD, 0xDBC7, - 0x77D7, 0xB4A3, - 0x77DB, 0xC3AC, - 0x77DC, 0xF1E6, - 0x77E2, 0xCAB8, - 0x77E3, 0xD2D3, - 0x77E5, 0xD6AA, - 0x77E7, 0xEFF2, - 0x77E9, 0xBED8, - 0x77EB, 0xBDC3, - 0x77EC, 0xEFF3, - 0x77ED, 0xB6CC, - 0x77EE, 0xB0AB, - 0x77F3, 0xCAAF, - 0x77F6, 0xEDB6, - 0x77F8, 0xEDB7, - 0x77FD, 0xCEF9, - 0x77FE, 0xB7AF, - 0x77FF, 0xBFF3, - 0x7800, 0xEDB8, - 0x7801, 0xC2EB, - 0x7802, 0xC9B0, - 0x7809, 0xEDB9, - 0x780C, 0xC6F6, - 0x780D, 0xBFB3, - 0x7811, 0xEDBC, - 0x7812, 0xC5F8, - 0x7814, 0xD1D0, - 0x7816, 0xD7A9, - 0x7817, 0xEDBA, - 0x7818, 0xEDBB, - 0x781A, 0xD1E2, - 0x781C, 0xEDBF, - 0x781D, 0xEDC0, - 0x781F, 0xEDC4, - 0x7823, 0xEDC8, - 0x7825, 0xEDC6, - 0x7826, 0xEDCE, - 0x7827, 0xD5E8, - 0x7829, 0xEDC9, - 0x782C, 0xEDC7, - 0x782D, 0xEDBE, - 0x7830, 0xC5E9, - 0x7834, 0xC6C6, - 0x7837, 0xC9E9, - 0x7838, 0xD4D2, - 0x7839, 0xEDC1, - 0x783A, 0xEDC2, - 0x783B, 0xEDC3, - 0x783C, 0xEDC5, - 0x783E, 0xC0F9, - 0x7840, 0xB4A1, - 0x7845, 0xB9E8, - 0x7847, 0xEDD0, - 0x784C, 0xEDD1, - 0x784E, 0xEDCA, - 0x7850, 0xEDCF, - 0x7852, 0xCEF8, - 0x7855, 0xCBB6, - 0x7856, 0xEDCC, - 0x7857, 0xEDCD, - 0x785D, 0xCFF5, - 0x786A, 0xEDD2, - 0x786B, 0xC1F2, - 0x786C, 0xD3B2, - 0x786D, 0xEDCB, - 0x786E, 0xC8B7, - 0x7877, 0xBCEF, - 0x787C, 0xC5F0, - 0x7887, 0xEDD6, - 0x7889, 0xB5EF, - 0x788C, 0xC2B5, - 0x788D, 0xB0AD, - 0x788E, 0xCBE9, - 0x7891, 0xB1AE, - 0x7893, 0xEDD4, - 0x7897, 0xCDEB, - 0x7898, 0xB5E2, - 0x789A, 0xEDD5, - 0x789B, 0xEDD3, - 0x789C, 0xEDD7, - 0x789F, 0xB5FA, - 0x78A1, 0xEDD8, - 0x78A3, 0xEDD9, - 0x78A5, 0xEDDC, - 0x78A7, 0xB1CC, - 0x78B0, 0xC5F6, - 0x78B1, 0xBCEE, - 0x78B2, 0xEDDA, - 0x78B3, 0xCCBC, - 0x78B4, 0xB2EA, - 0x78B9, 0xEDDB, - 0x78BE, 0xC4EB, - 0x78C1, 0xB4C5, - 0x78C5, 0xB0F5, - 0x78C9, 0xEDDF, - 0x78CA, 0xC0DA, - 0x78CB, 0xB4E8, - 0x78D0, 0xC5CD, - 0x78D4, 0xEDDD, - 0x78D5, 0xBFC4, - 0x78D9, 0xEDDE, - 0x78E8, 0xC4A5, - 0x78EC, 0xEDE0, - 0x78F2, 0xEDE1, - 0x78F4, 0xEDE3, - 0x78F7, 0xC1D7, - 0x78FA, 0xBBC7, - 0x7901, 0xBDB8, - 0x7905, 0xEDE2, - 0x7913, 0xEDE4, - 0x791E, 0xEDE6, - 0x7924, 0xEDE5, - 0x7934, 0xEDE7, - 0x793A, 0xCABE, - 0x793B, 0xECEA, - 0x793C, 0xC0F1, - 0x793E, 0xC9E7, - 0x7940, 0xECEB, - 0x7941, 0xC6EE, - 0x7946, 0xECEC, - 0x7948, 0xC6ED, - 0x7949, 0xECED, - 0x7953, 0xECF0, - 0x7956, 0xD7E6, - 0x7957, 0xECF3, - 0x795A, 0xECF1, - 0x795B, 0xECEE, - 0x795C, 0xECEF, - 0x795D, 0xD7A3, - 0x795E, 0xC9F1, - 0x795F, 0xCBEE, - 0x7960, 0xECF4, - 0x7962, 0xECF2, - 0x7965, 0xCFE9, - 0x7967, 0xECF6, - 0x7968, 0xC6B1, - 0x796D, 0xBCC0, - 0x796F, 0xECF5, - 0x7977, 0xB5BB, - 0x7978, 0xBBF6, - 0x797A, 0xECF7, - 0x7980, 0xD9F7, - 0x7981, 0xBDFB, - 0x7984, 0xC2BB, - 0x7985, 0xECF8, - 0x798A, 0xECF9, - 0x798F, 0xB8A3, - 0x799A, 0xECFA, - 0x79A7, 0xECFB, - 0x79B3, 0xECFC, - 0x79B9, 0xD3ED, - 0x79BA, 0xD8AE, - 0x79BB, 0xC0EB, - 0x79BD, 0xC7DD, - 0x79BE, 0xBACC, - 0x79C0, 0xD0E3, - 0x79C1, 0xCBBD, - 0x79C3, 0xCDBA, - 0x79C6, 0xB8D1, - 0x79C9, 0xB1FC, - 0x79CB, 0xC7EF, - 0x79CD, 0xD6D6, - 0x79D1, 0xBFC6, - 0x79D2, 0xC3EB, - 0x79D5, 0xEFF5, - 0x79D8, 0xC3D8, - 0x79DF, 0xD7E2, - 0x79E3, 0xEFF7, - 0x79E4, 0xB3D3, - 0x79E6, 0xC7D8, - 0x79E7, 0xD1ED, - 0x79E9, 0xD6C8, - 0x79EB, 0xEFF8, - 0x79ED, 0xEFF6, - 0x79EF, 0xBBFD, - 0x79F0, 0xB3C6, - 0x79F8, 0xBDD5, - 0x79FB, 0xD2C6, - 0x79FD, 0xBBE0, - 0x7A00, 0xCFA1, - 0x7A02, 0xEFFC, - 0x7A03, 0xEFFB, - 0x7A06, 0xEFF9, - 0x7A0B, 0xB3CC, - 0x7A0D, 0xC9D4, - 0x7A0E, 0xCBB0, - 0x7A14, 0xEFFE, - 0x7A17, 0xB0DE, - 0x7A1A, 0xD6C9, - 0x7A1E, 0xEFFD, - 0x7A20, 0xB3ED, - 0x7A23, 0xF6D5, - 0x7A33, 0xCEC8, - 0x7A37, 0xF0A2, - 0x7A39, 0xF0A1, - 0x7A3B, 0xB5BE, - 0x7A3C, 0xBCDA, - 0x7A3D, 0xBBFC, - 0x7A3F, 0xB8E5, - 0x7A46, 0xC4C2, - 0x7A51, 0xF0A3, - 0x7A57, 0xCBEB, - 0x7A70, 0xF0A6, - 0x7A74, 0xD1A8, - 0x7A76, 0xBEBF, - 0x7A77, 0xC7EE, - 0x7A78, 0xF1B6, - 0x7A79, 0xF1B7, - 0x7A7A, 0xBFD5, - 0x7A7F, 0xB4A9, - 0x7A80, 0xF1B8, - 0x7A81, 0xCDBB, - 0x7A83, 0xC7D4, - 0x7A84, 0xD5AD, - 0x7A86, 0xF1B9, - 0x7A88, 0xF1BA, - 0x7A8D, 0xC7CF, - 0x7A91, 0xD2A4, - 0x7A92, 0xD6CF, - 0x7A95, 0xF1BB, - 0x7A96, 0xBDD1, - 0x7A97, 0xB4B0, - 0x7A98, 0xBEBD, - 0x7A9C, 0xB4DC, - 0x7A9D, 0xCED1, - 0x7A9F, 0xBFDF, - 0x7AA0, 0xF1BD, - 0x7AA5, 0xBFFA, - 0x7AA6, 0xF1BC, - 0x7AA8, 0xF1BF, - 0x7AAC, 0xF1BE, - 0x7AAD, 0xF1C0, - 0x7AB3, 0xF1C1, - 0x7ABF, 0xC1FE, - 0x7ACB, 0xC1A2, - 0x7AD6, 0xCAFA, - 0x7AD9, 0xD5BE, - 0x7ADE, 0xBEBA, - 0x7ADF, 0xBEB9, - 0x7AE0, 0xD5C2, - 0x7AE3, 0xBFA2, - 0x7AE5, 0xCDAF, - 0x7AE6, 0xF1B5, - 0x7AED, 0xBDDF, - 0x7AEF, 0xB6CB, - 0x7AF9, 0xD6F1, - 0x7AFA, 0xF3C3, - 0x7AFD, 0xF3C4, - 0x7AFF, 0xB8CD, - 0x7B03, 0xF3C6, - 0x7B04, 0xF3C7, - 0x7B06, 0xB0CA, - 0x7B08, 0xF3C5, - 0x7B0A, 0xF3C9, - 0x7B0B, 0xCBF1, - 0x7B0F, 0xF3CB, - 0x7B11, 0xD0A6, - 0x7B14, 0xB1CA, - 0x7B15, 0xF3C8, - 0x7B19, 0xF3CF, - 0x7B1B, 0xB5D1, - 0x7B1E, 0xF3D7, - 0x7B20, 0xF3D2, - 0x7B24, 0xF3D4, - 0x7B25, 0xF3D3, - 0x7B26, 0xB7FB, - 0x7B28, 0xB1BF, - 0x7B2A, 0xF3CE, - 0x7B2B, 0xF3CA, - 0x7B2C, 0xB5DA, - 0x7B2E, 0xF3D0, - 0x7B31, 0xF3D1, - 0x7B33, 0xF3D5, - 0x7B38, 0xF3CD, - 0x7B3A, 0xBCE3, - 0x7B3C, 0xC1FD, - 0x7B3E, 0xF3D6, - 0x7B45, 0xF3DA, - 0x7B47, 0xF3CC, - 0x7B49, 0xB5C8, - 0x7B4B, 0xBDEE, - 0x7B4C, 0xF3DC, - 0x7B4F, 0xB7A4, - 0x7B50, 0xBFF0, - 0x7B51, 0xD6FE, - 0x7B52, 0xCDB2, - 0x7B54, 0xB4F0, - 0x7B56, 0xB2DF, - 0x7B58, 0xF3D8, - 0x7B5A, 0xF3D9, - 0x7B5B, 0xC9B8, - 0x7B5D, 0xF3DD, - 0x7B60, 0xF3DE, - 0x7B62, 0xF3E1, - 0x7B6E, 0xF3DF, - 0x7B71, 0xF3E3, - 0x7B72, 0xF3E2, - 0x7B75, 0xF3DB, - 0x7B77, 0xBFEA, - 0x7B79, 0xB3EF, - 0x7B7B, 0xF3E0, - 0x7B7E, 0xC7A9, - 0x7B80, 0xBCF2, - 0x7B85, 0xF3EB, - 0x7B8D, 0xB9BF, - 0x7B90, 0xF3E4, - 0x7B94, 0xB2AD, - 0x7B95, 0xBBFE, - 0x7B97, 0xCBE3, - 0x7B9C, 0xF3ED, - 0x7B9D, 0xF3E9, - 0x7BA1, 0xB9DC, - 0x7BA2, 0xF3EE, - 0x7BA6, 0xF3E5, - 0x7BA7, 0xF3E6, - 0x7BA8, 0xF3EA, - 0x7BA9, 0xC2E1, - 0x7BAA, 0xF3EC, - 0x7BAB, 0xF3EF, - 0x7BAC, 0xF3E8, - 0x7BAD, 0xBCFD, - 0x7BB1, 0xCFE4, - 0x7BB4, 0xF3F0, - 0x7BB8, 0xF3E7, - 0x7BC1, 0xF3F2, - 0x7BC6, 0xD7AD, - 0x7BC7, 0xC6AA, - 0x7BCC, 0xF3F3, - 0x7BD1, 0xF3F1, - 0x7BD3, 0xC2A8, - 0x7BD9, 0xB8DD, - 0x7BDA, 0xF3F5, - 0x7BDD, 0xF3F4, - 0x7BE1, 0xB4DB, - 0x7BE5, 0xF3F6, - 0x7BE6, 0xF3F7, - 0x7BEA, 0xF3F8, - 0x7BEE, 0xC0BA, - 0x7BF1, 0xC0E9, - 0x7BF7, 0xC5F1, - 0x7BFC, 0xF3FB, - 0x7BFE, 0xF3FA, - 0x7C07, 0xB4D8, - 0x7C0B, 0xF3FE, - 0x7C0C, 0xF3F9, - 0x7C0F, 0xF3FC, - 0x7C16, 0xF3FD, - 0x7C1F, 0xF4A1, - 0x7C26, 0xF4A3, - 0x7C27, 0xBBC9, - 0x7C2A, 0xF4A2, - 0x7C38, 0xF4A4, - 0x7C3F, 0xB2BE, - 0x7C40, 0xF4A6, - 0x7C41, 0xF4A5, - 0x7C4D, 0xBCAE, - 0x7C73, 0xC3D7, - 0x7C74, 0xD9E1, - 0x7C7B, 0xC0E0, - 0x7C7C, 0xF4CC, - 0x7C7D, 0xD7D1, - 0x7C89, 0xB7DB, - 0x7C91, 0xF4CE, - 0x7C92, 0xC1A3, - 0x7C95, 0xC6C9, - 0x7C97, 0xB4D6, - 0x7C98, 0xD5B3, - 0x7C9C, 0xF4D0, - 0x7C9D, 0xF4CF, - 0x7C9E, 0xF4D1, - 0x7C9F, 0xCBDA, - 0x7CA2, 0xF4D2, - 0x7CA4, 0xD4C1, - 0x7CA5, 0xD6E0, - 0x7CAA, 0xB7E0, - 0x7CAE, 0xC1B8, - 0x7CB1, 0xC1BB, - 0x7CB2, 0xF4D3, - 0x7CB3, 0xBEAC, - 0x7CB9, 0xB4E2, - 0x7CBC, 0xF4D4, - 0x7CBD, 0xF4D5, - 0x7CBE, 0xBEAB, - 0x7CC1, 0xF4D6, - 0x7CC5, 0xF4DB, - 0x7CC7, 0xF4D7, - 0x7CC8, 0xF4DA, - 0x7CCA, 0xBAFD, - 0x7CCC, 0xF4D8, - 0x7CCD, 0xF4D9, - 0x7CD5, 0xB8E2, - 0x7CD6, 0xCCC7, - 0x7CD7, 0xF4DC, - 0x7CD9, 0xB2DA, - 0x7CDC, 0xC3D3, - 0x7CDF, 0xD4E3, - 0x7CE0, 0xBFB7, - 0x7CE8, 0xF4DD, - 0x7CEF, 0xC5B4, - 0x7CF8, 0xF4E9, - 0x7CFB, 0xCFB5, - 0x7D0A, 0xCEC9, - 0x7D20, 0xCBD8, - 0x7D22, 0xCBF7, - 0x7D27, 0xBDF4, - 0x7D2B, 0xD7CF, - 0x7D2F, 0xC0DB, - 0x7D6E, 0xD0F5, - 0x7D77, 0xF4EA, - 0x7DA6, 0xF4EB, - 0x7DAE, 0xF4EC, - 0x7E3B, 0xF7E3, - 0x7E41, 0xB7B1, - 0x7E47, 0xF4ED, - 0x7E82, 0xD7EB, - 0x7E9B, 0xF4EE, - 0x7E9F, 0xE6F9, - 0x7EA0, 0xBEC0, - 0x7EA1, 0xE6FA, - 0x7EA2, 0xBAEC, - 0x7EA3, 0xE6FB, - 0x7EA4, 0xCFCB, - 0x7EA5, 0xE6FC, - 0x7EA6, 0xD4BC, - 0x7EA7, 0xBCB6, - 0x7EA8, 0xE6FD, - 0x7EA9, 0xE6FE, - 0x7EAA, 0xBCCD, - 0x7EAB, 0xC8D2, - 0x7EAC, 0xCEB3, - 0x7EAD, 0xE7A1, - 0x7EAF, 0xB4BF, - 0x7EB0, 0xE7A2, - 0x7EB1, 0xC9B4, - 0x7EB2, 0xB8D9, - 0x7EB3, 0xC4C9, - 0x7EB5, 0xD7DD, - 0x7EB6, 0xC2DA, - 0x7EB7, 0xB7D7, - 0x7EB8, 0xD6BD, - 0x7EB9, 0xCEC6, - 0x7EBA, 0xB7C4, - 0x7EBD, 0xC5A6, - 0x7EBE, 0xE7A3, - 0x7EBF, 0xCFDF, - 0x7EC0, 0xE7A4, - 0x7EC1, 0xE7A5, - 0x7EC2, 0xE7A6, - 0x7EC3, 0xC1B7, - 0x7EC4, 0xD7E9, - 0x7EC5, 0xC9F0, - 0x7EC6, 0xCFB8, - 0x7EC7, 0xD6AF, - 0x7EC8, 0xD6D5, - 0x7EC9, 0xE7A7, - 0x7ECA, 0xB0ED, - 0x7ECB, 0xE7A8, - 0x7ECC, 0xE7A9, - 0x7ECD, 0xC9DC, - 0x7ECE, 0xD2EF, - 0x7ECF, 0xBEAD, - 0x7ED0, 0xE7AA, - 0x7ED1, 0xB0F3, - 0x7ED2, 0xC8DE, - 0x7ED3, 0xBDE1, - 0x7ED4, 0xE7AB, - 0x7ED5, 0xC8C6, - 0x7ED7, 0xE7AC, - 0x7ED8, 0xBBE6, - 0x7ED9, 0xB8F8, - 0x7EDA, 0xD1A4, - 0x7EDB, 0xE7AD, - 0x7EDC, 0xC2E7, - 0x7EDD, 0xBEF8, - 0x7EDE, 0xBDCA, - 0x7EDF, 0xCDB3, - 0x7EE0, 0xE7AE, - 0x7EE1, 0xE7AF, - 0x7EE2, 0xBEEE, - 0x7EE3, 0xD0E5, - 0x7EE5, 0xCBE7, - 0x7EE6, 0xCCD0, - 0x7EE7, 0xBCCC, - 0x7EE8, 0xE7B0, - 0x7EE9, 0xBCA8, - 0x7EEA, 0xD0F7, - 0x7EEB, 0xE7B1, - 0x7EED, 0xD0F8, - 0x7EEE, 0xE7B2, - 0x7EEF, 0xE7B3, - 0x7EF0, 0xB4C2, - 0x7EF1, 0xE7B4, - 0x7EF2, 0xE7B5, - 0x7EF3, 0xC9FE, - 0x7EF4, 0xCEAC, - 0x7EF5, 0xC3E0, - 0x7EF6, 0xE7B7, - 0x7EF7, 0xB1C1, - 0x7EF8, 0xB3F1, - 0x7EFA, 0xE7B8, - 0x7EFB, 0xE7B9, - 0x7EFC, 0xD7DB, - 0x7EFD, 0xD5C0, - 0x7EFE, 0xE7BA, - 0x7EFF, 0xC2CC, - 0x7F00, 0xD7BA, - 0x7F01, 0xE7BB, - 0x7F02, 0xE7BC, - 0x7F03, 0xE7BD, - 0x7F04, 0xBCEA, - 0x7F05, 0xC3E5, - 0x7F06, 0xC0C2, - 0x7F07, 0xE7BE, - 0x7F08, 0xE7BF, - 0x7F09, 0xBCA9, - 0x7F0B, 0xE7C0, - 0x7F0C, 0xE7C1, - 0x7F0D, 0xE7B6, - 0x7F0E, 0xB6D0, - 0x7F0F, 0xE7C2, - 0x7F11, 0xE7C3, - 0x7F12, 0xE7C4, - 0x7F13, 0xBBBA, - 0x7F14, 0xB5DE, - 0x7F15, 0xC2C6, - 0x7F16, 0xB1E0, - 0x7F17, 0xE7C5, - 0x7F18, 0xD4B5, - 0x7F19, 0xE7C6, - 0x7F1A, 0xB8BF, - 0x7F1B, 0xE7C8, - 0x7F1C, 0xE7C7, - 0x7F1D, 0xB7EC, - 0x7F1F, 0xE7C9, - 0x7F20, 0xB2F8, - 0x7F21, 0xE7CA, - 0x7F22, 0xE7CB, - 0x7F23, 0xE7CC, - 0x7F24, 0xE7CD, - 0x7F25, 0xE7CE, - 0x7F26, 0xE7CF, - 0x7F27, 0xE7D0, - 0x7F28, 0xD3A7, - 0x7F29, 0xCBF5, - 0x7F2A, 0xE7D1, - 0x7F2B, 0xE7D2, - 0x7F2C, 0xE7D3, - 0x7F2D, 0xE7D4, - 0x7F2E, 0xC9C9, - 0x7F2F, 0xE7D5, - 0x7F30, 0xE7D6, - 0x7F31, 0xE7D7, - 0x7F32, 0xE7D8, - 0x7F33, 0xE7D9, - 0x7F34, 0xBDC9, - 0x7F35, 0xE7DA, - 0x7F36, 0xF3BE, - 0x7F38, 0xB8D7, - 0x7F3A, 0xC8B1, - 0x7F42, 0xF3BF, - 0x7F44, 0xF3C0, - 0x7F45, 0xF3C1, - 0x7F50, 0xB9DE, - 0x7F51, 0xCDF8, - 0x7F54, 0xD8E8, - 0x7F55, 0xBAB1, - 0x7F57, 0xC2DE, - 0x7F58, 0xEEB7, - 0x7F5A, 0xB7A3, - 0x7F5F, 0xEEB9, - 0x7F61, 0xEEB8, - 0x7F62, 0xB0D5, - 0x7F68, 0xEEBB, - 0x7F69, 0xD5D6, - 0x7F6A, 0xD7EF, - 0x7F6E, 0xD6C3, - 0x7F71, 0xEEBD, - 0x7F72, 0xCAF0, - 0x7F74, 0xEEBC, - 0x7F79, 0xEEBE, - 0x7F7E, 0xEEC0, - 0x7F81, 0xEEBF, - 0x7F8A, 0xD1F2, - 0x7F8C, 0xC7BC, - 0x7F8E, 0xC3C0, - 0x7F94, 0xB8E1, - 0x7F9A, 0xC1E7, - 0x7F9D, 0xF4C6, - 0x7F9E, 0xD0DF, - 0x7F9F, 0xF4C7, - 0x7FA1, 0xCFDB, - 0x7FA4, 0xC8BA, - 0x7FA7, 0xF4C8, - 0x7FAF, 0xF4C9, - 0x7FB0, 0xF4CA, - 0x7FB2, 0xF4CB, - 0x7FB8, 0xD9FA, - 0x7FB9, 0xB8FE, - 0x7FBC, 0xE5F1, - 0x7FBD, 0xD3F0, - 0x7FBF, 0xF4E0, - 0x7FC1, 0xCECC, - 0x7FC5, 0xB3E1, - 0x7FCA, 0xF1B4, - 0x7FCC, 0xD2EE, - 0x7FCE, 0xF4E1, - 0x7FD4, 0xCFE8, - 0x7FD5, 0xF4E2, - 0x7FD8, 0xC7CC, - 0x7FDF, 0xB5D4, - 0x7FE0, 0xB4E4, - 0x7FE1, 0xF4E4, - 0x7FE5, 0xF4E3, - 0x7FE6, 0xF4E5, - 0x7FE9, 0xF4E6, - 0x7FEE, 0xF4E7, - 0x7FF0, 0xBAB2, - 0x7FF1, 0xB0BF, - 0x7FF3, 0xF4E8, - 0x7FFB, 0xB7AD, - 0x7FFC, 0xD2ED, - 0x8000, 0xD2AB, - 0x8001, 0xC0CF, - 0x8003, 0xBFBC, - 0x8004, 0xEBA3, - 0x8005, 0xD5DF, - 0x8006, 0xEAC8, - 0x800B, 0xF1F3, - 0x800C, 0xB6F8, - 0x800D, 0xCBA3, - 0x8010, 0xC4CD, - 0x8012, 0xF1E7, - 0x8014, 0xF1E8, - 0x8015, 0xB8FB, - 0x8016, 0xF1E9, - 0x8017, 0xBAC4, - 0x8018, 0xD4C5, - 0x8019, 0xB0D2, - 0x801C, 0xF1EA, - 0x8020, 0xF1EB, - 0x8022, 0xF1EC, - 0x8025, 0xF1ED, - 0x8026, 0xF1EE, - 0x8027, 0xF1EF, - 0x8028, 0xF1F1, - 0x8029, 0xF1F0, - 0x802A, 0xC5D5, - 0x8031, 0xF1F2, - 0x8033, 0xB6FA, - 0x8035, 0xF1F4, - 0x8036, 0xD2AE, - 0x8037, 0xDEC7, - 0x8038, 0xCBCA, - 0x803B, 0xB3DC, - 0x803D, 0xB5A2, - 0x803F, 0xB9A2, - 0x8042, 0xC4F4, - 0x8043, 0xF1F5, - 0x8046, 0xF1F6, - 0x804A, 0xC1C4, - 0x804B, 0xC1FB, - 0x804C, 0xD6B0, - 0x804D, 0xF1F7, - 0x8052, 0xF1F8, - 0x8054, 0xC1AA, - 0x8058, 0xC6B8, - 0x805A, 0xBEDB, - 0x8069, 0xF1F9, - 0x806A, 0xB4CF, - 0x8071, 0xF1FA, - 0x807F, 0xEDB2, - 0x8080, 0xEDB1, - 0x8083, 0xCBE0, - 0x8084, 0xD2DE, - 0x8086, 0xCBC1, - 0x8087, 0xD5D8, - 0x8089, 0xC8E2, - 0x808B, 0xC0DF, - 0x808C, 0xBCA1, - 0x8093, 0xEBC1, - 0x8096, 0xD0A4, - 0x8098, 0xD6E2, - 0x809A, 0xB6C7, - 0x809B, 0xB8D8, - 0x809C, 0xEBC0, - 0x809D, 0xB8CE, - 0x809F, 0xEBBF, - 0x80A0, 0xB3A6, - 0x80A1, 0xB9C9, - 0x80A2, 0xD6AB, - 0x80A4, 0xB7F4, - 0x80A5, 0xB7CA, - 0x80A9, 0xBCE7, - 0x80AA, 0xB7BE, - 0x80AB, 0xEBC6, - 0x80AD, 0xEBC7, - 0x80AE, 0xB0B9, - 0x80AF, 0xBFCF, - 0x80B1, 0xEBC5, - 0x80B2, 0xD3FD, - 0x80B4, 0xEBC8, - 0x80B7, 0xEBC9, - 0x80BA, 0xB7CE, - 0x80BC, 0xEBC2, - 0x80BD, 0xEBC4, - 0x80BE, 0xC9F6, - 0x80BF, 0xD6D7, - 0x80C0, 0xD5CD, - 0x80C1, 0xD0B2, - 0x80C2, 0xEBCF, - 0x80C3, 0xCEB8, - 0x80C4, 0xEBD0, - 0x80C6, 0xB5A8, - 0x80CC, 0xB1B3, - 0x80CD, 0xEBD2, - 0x80CE, 0xCCA5, - 0x80D6, 0xC5D6, - 0x80D7, 0xEBD3, - 0x80D9, 0xEBD1, - 0x80DA, 0xC5DF, - 0x80DB, 0xEBCE, - 0x80DC, 0xCAA4, - 0x80DD, 0xEBD5, - 0x80DE, 0xB0FB, - 0x80E1, 0xBAFA, - 0x80E4, 0xD8B7, - 0x80E5, 0xF1E3, - 0x80E7, 0xEBCA, - 0x80E8, 0xEBCB, - 0x80E9, 0xEBCC, - 0x80EA, 0xEBCD, - 0x80EB, 0xEBD6, - 0x80EC, 0xE6C0, - 0x80ED, 0xEBD9, - 0x80EF, 0xBFE8, - 0x80F0, 0xD2C8, - 0x80F1, 0xEBD7, - 0x80F2, 0xEBDC, - 0x80F3, 0xB8EC, - 0x80F4, 0xEBD8, - 0x80F6, 0xBDBA, - 0x80F8, 0xD0D8, - 0x80FA, 0xB0B7, - 0x80FC, 0xEBDD, - 0x80FD, 0xC4DC, - 0x8102, 0xD6AC, - 0x8106, 0xB4E0, - 0x8109, 0xC2F6, - 0x810A, 0xBCB9, - 0x810D, 0xEBDA, - 0x810E, 0xEBDB, - 0x810F, 0xD4E0, - 0x8110, 0xC6EA, - 0x8111, 0xC4D4, - 0x8112, 0xEBDF, - 0x8113, 0xC5A7, - 0x8114, 0xD9F5, - 0x8116, 0xB2B1, - 0x8118, 0xEBE4, - 0x811A, 0xBDC5, - 0x811E, 0xEBE2, - 0x812C, 0xEBE3, - 0x812F, 0xB8AC, - 0x8131, 0xCDD1, - 0x8132, 0xEBE5, - 0x8136, 0xEBE1, - 0x8138, 0xC1B3, - 0x813E, 0xC6A2, - 0x8146, 0xCCF3, - 0x8148, 0xEBE6, - 0x814A, 0xC0B0, - 0x814B, 0xD2B8, - 0x814C, 0xEBE7, - 0x8150, 0xB8AF, - 0x8151, 0xB8AD, - 0x8153, 0xEBE8, - 0x8154, 0xC7BB, - 0x8155, 0xCDF3, - 0x8159, 0xEBEA, - 0x815A, 0xEBEB, - 0x8160, 0xEBED, - 0x8165, 0xD0C8, - 0x8167, 0xEBF2, - 0x8169, 0xEBEE, - 0x816D, 0xEBF1, - 0x816E, 0xC8F9, - 0x8170, 0xD1FC, - 0x8171, 0xEBEC, - 0x8174, 0xEBE9, - 0x8179, 0xB8B9, - 0x817A, 0xCFD9, - 0x817B, 0xC4E5, - 0x817C, 0xEBEF, - 0x817D, 0xEBF0, - 0x817E, 0xCCDA, - 0x817F, 0xCDC8, - 0x8180, 0xB0F2, - 0x8182, 0xEBF6, - 0x8188, 0xEBF5, - 0x818A, 0xB2B2, - 0x818F, 0xB8E0, - 0x8191, 0xEBF7, - 0x8198, 0xB1EC, - 0x819B, 0xCCC5, - 0x819C, 0xC4A4, - 0x819D, 0xCFA5, - 0x81A3, 0xEBF9, - 0x81A6, 0xECA2, - 0x81A8, 0xC5F2, - 0x81AA, 0xEBFA, - 0x81B3, 0xC9C5, - 0x81BA, 0xE2DF, - 0x81BB, 0xEBFE, - 0x81C0, 0xCDCE, - 0x81C1, 0xECA1, - 0x81C2, 0xB1DB, - 0x81C3, 0xD3B7, - 0x81C6, 0xD2DC, - 0x81CA, 0xEBFD, - 0x81CC, 0xEBFB, - 0x81E3, 0xB3BC, - 0x81E7, 0xEAB0, - 0x81EA, 0xD7D4, - 0x81EC, 0xF4AB, - 0x81ED, 0xB3F4, - 0x81F3, 0xD6C1, - 0x81F4, 0xD6C2, - 0x81FB, 0xD5E9, - 0x81FC, 0xBECA, - 0x81FE, 0xF4A7, - 0x8200, 0xD2A8, - 0x8201, 0xF4A8, - 0x8202, 0xF4A9, - 0x8204, 0xF4AA, - 0x8205, 0xBECB, - 0x8206, 0xD3DF, - 0x820C, 0xC9E0, - 0x820D, 0xC9E1, - 0x8210, 0xF3C2, - 0x8212, 0xCAE6, - 0x8214, 0xCCF2, - 0x821B, 0xE2B6, - 0x821C, 0xCBB4, - 0x821E, 0xCEE8, - 0x821F, 0xD6DB, - 0x8221, 0xF4AD, - 0x8222, 0xF4AE, - 0x8223, 0xF4AF, - 0x8228, 0xF4B2, - 0x822A, 0xBABD, - 0x822B, 0xF4B3, - 0x822C, 0xB0E3, - 0x822D, 0xF4B0, - 0x822F, 0xF4B1, - 0x8230, 0xBDA2, - 0x8231, 0xB2D5, - 0x8233, 0xF4B6, - 0x8234, 0xF4B7, - 0x8235, 0xB6E6, - 0x8236, 0xB2B0, - 0x8237, 0xCFCF, - 0x8238, 0xF4B4, - 0x8239, 0xB4AC, - 0x823B, 0xF4B5, - 0x823E, 0xF4B8, - 0x8244, 0xF4B9, - 0x8247, 0xCDA7, - 0x8249, 0xF4BA, - 0x824B, 0xF4BB, - 0x824F, 0xF4BC, - 0x8258, 0xCBD2, - 0x825A, 0xF4BD, - 0x825F, 0xF4BE, - 0x8268, 0xF4BF, - 0x826E, 0xF4DE, - 0x826F, 0xC1BC, - 0x8270, 0xBCE8, - 0x8272, 0xC9AB, - 0x8273, 0xD1DE, - 0x8274, 0xE5F5, - 0x8279, 0xDCB3, - 0x827A, 0xD2D5, - 0x827D, 0xDCB4, - 0x827E, 0xB0AC, - 0x827F, 0xDCB5, - 0x8282, 0xBDDA, - 0x8284, 0xDCB9, - 0x8288, 0xD8C2, - 0x828A, 0xDCB7, - 0x828B, 0xD3F3, - 0x828D, 0xC9D6, - 0x828E, 0xDCBA, - 0x828F, 0xDCB6, - 0x8291, 0xDCBB, - 0x8292, 0xC3A2, - 0x8297, 0xDCBC, - 0x8298, 0xDCC5, - 0x8299, 0xDCBD, - 0x829C, 0xCEDF, - 0x829D, 0xD6A5, - 0x829F, 0xDCCF, - 0x82A1, 0xDCCD, - 0x82A4, 0xDCD2, - 0x82A5, 0xBDE6, - 0x82A6, 0xC2AB, - 0x82A8, 0xDCB8, - 0x82A9, 0xDCCB, - 0x82AA, 0xDCCE, - 0x82AB, 0xDCBE, - 0x82AC, 0xB7D2, - 0x82AD, 0xB0C5, - 0x82AE, 0xDCC7, - 0x82AF, 0xD0BE, - 0x82B0, 0xDCC1, - 0x82B1, 0xBBA8, - 0x82B3, 0xB7BC, - 0x82B4, 0xDCCC, - 0x82B7, 0xDCC6, - 0x82B8, 0xDCBF, - 0x82B9, 0xC7DB, - 0x82BD, 0xD1BF, - 0x82BE, 0xDCC0, - 0x82C1, 0xDCCA, - 0x82C4, 0xDCD0, - 0x82C7, 0xCEAD, - 0x82C8, 0xDCC2, - 0x82CA, 0xDCC3, - 0x82CB, 0xDCC8, - 0x82CC, 0xDCC9, - 0x82CD, 0xB2D4, - 0x82CE, 0xDCD1, - 0x82CF, 0xCBD5, - 0x82D1, 0xD4B7, - 0x82D2, 0xDCDB, - 0x82D3, 0xDCDF, - 0x82D4, 0xCCA6, - 0x82D5, 0xDCE6, - 0x82D7, 0xC3E7, - 0x82D8, 0xDCDC, - 0x82DB, 0xBFC1, - 0x82DC, 0xDCD9, - 0x82DE, 0xB0FA, - 0x82DF, 0xB9B6, - 0x82E0, 0xDCE5, - 0x82E1, 0xDCD3, - 0x82E3, 0xDCC4, - 0x82E4, 0xDCD6, - 0x82E5, 0xC8F4, - 0x82E6, 0xBFE0, - 0x82EB, 0xC9BB, - 0x82EF, 0xB1BD, - 0x82F1, 0xD3A2, - 0x82F4, 0xDCDA, - 0x82F7, 0xDCD5, - 0x82F9, 0xC6BB, - 0x82FB, 0xDCDE, - 0x8301, 0xD7C2, - 0x8302, 0xC3AF, - 0x8303, 0xB7B6, - 0x8304, 0xC7D1, - 0x8305, 0xC3A9, - 0x8306, 0xDCE2, - 0x8307, 0xDCD8, - 0x8308, 0xDCEB, - 0x8309, 0xDCD4, - 0x830C, 0xDCDD, - 0x830E, 0xBEA5, - 0x830F, 0xDCD7, - 0x8311, 0xDCE0, - 0x8314, 0xDCE3, - 0x8315, 0xDCE4, - 0x8317, 0xDCF8, - 0x831A, 0xDCE1, - 0x831B, 0xDDA2, - 0x831C, 0xDCE7, - 0x8327, 0xBCEB, - 0x8328, 0xB4C4, - 0x832B, 0xC3A3, - 0x832C, 0xB2E7, - 0x832D, 0xDCFA, - 0x832F, 0xDCF2, - 0x8331, 0xDCEF, - 0x8333, 0xDCFC, - 0x8334, 0xDCEE, - 0x8335, 0xD2F0, - 0x8336, 0xB2E8, - 0x8338, 0xC8D7, - 0x8339, 0xC8E3, - 0x833A, 0xDCFB, - 0x833C, 0xDCED, - 0x8340, 0xDCF7, - 0x8343, 0xDCF5, - 0x8346, 0xBEA3, - 0x8347, 0xDCF4, - 0x8349, 0xB2DD, - 0x834F, 0xDCF3, - 0x8350, 0xBCF6, - 0x8351, 0xDCE8, - 0x8352, 0xBBC4, - 0x8354, 0xC0F3, - 0x835A, 0xBCD4, - 0x835B, 0xDCE9, - 0x835C, 0xDCEA, - 0x835E, 0xDCF1, - 0x835F, 0xDCF6, - 0x8360, 0xDCF9, - 0x8361, 0xB5B4, - 0x8363, 0xC8D9, - 0x8364, 0xBBE7, - 0x8365, 0xDCFE, - 0x8366, 0xDCFD, - 0x8367, 0xD3AB, - 0x8368, 0xDDA1, - 0x8369, 0xDDA3, - 0x836A, 0xDDA5, - 0x836B, 0xD2F1, - 0x836C, 0xDDA4, - 0x836D, 0xDDA6, - 0x836E, 0xDDA7, - 0x836F, 0xD2A9, - 0x8377, 0xBAC9, - 0x8378, 0xDDA9, - 0x837B, 0xDDB6, - 0x837C, 0xDDB1, - 0x837D, 0xDDB4, - 0x8385, 0xDDB0, - 0x8386, 0xC6CE, - 0x8389, 0xC0F2, - 0x838E, 0xC9AF, - 0x8392, 0xDCEC, - 0x8393, 0xDDAE, - 0x8398, 0xDDB7, - 0x839B, 0xDCF0, - 0x839C, 0xDDAF, - 0x839E, 0xDDB8, - 0x83A0, 0xDDAC, - 0x83A8, 0xDDB9, - 0x83A9, 0xDDB3, - 0x83AA, 0xDDAD, - 0x83AB, 0xC4AA, - 0x83B0, 0xDDA8, - 0x83B1, 0xC0B3, - 0x83B2, 0xC1AB, - 0x83B3, 0xDDAA, - 0x83B4, 0xDDAB, - 0x83B6, 0xDDB2, - 0x83B7, 0xBBF1, - 0x83B8, 0xDDB5, - 0x83B9, 0xD3A8, - 0x83BA, 0xDDBA, - 0x83BC, 0xDDBB, - 0x83BD, 0xC3A7, - 0x83C0, 0xDDD2, - 0x83C1, 0xDDBC, - 0x83C5, 0xDDD1, - 0x83C7, 0xB9BD, - 0x83CA, 0xBED5, - 0x83CC, 0xBEFA, - 0x83CF, 0xBACA, - 0x83D4, 0xDDCA, - 0x83D6, 0xDDC5, - 0x83D8, 0xDDBF, - 0x83DC, 0xB2CB, - 0x83DD, 0xDDC3, - 0x83DF, 0xDDCB, - 0x83E0, 0xB2A4, - 0x83E1, 0xDDD5, - 0x83E5, 0xDDBE, - 0x83E9, 0xC6D0, - 0x83EA, 0xDDD0, - 0x83F0, 0xDDD4, - 0x83F1, 0xC1E2, - 0x83F2, 0xB7C6, - 0x83F8, 0xDDCE, - 0x83F9, 0xDDCF, - 0x83FD, 0xDDC4, - 0x8401, 0xDDBD, - 0x8403, 0xDDCD, - 0x8404, 0xCCD1, - 0x8406, 0xDDC9, - 0x840B, 0xDDC2, - 0x840C, 0xC3C8, - 0x840D, 0xC6BC, - 0x840E, 0xCEAE, - 0x840F, 0xDDCC, - 0x8411, 0xDDC8, - 0x8418, 0xDDC1, - 0x841C, 0xDDC6, - 0x841D, 0xC2DC, - 0x8424, 0xD3A9, - 0x8425, 0xD3AA, - 0x8426, 0xDDD3, - 0x8427, 0xCFF4, - 0x8428, 0xC8F8, - 0x8431, 0xDDE6, - 0x8438, 0xDDC7, - 0x843C, 0xDDE0, - 0x843D, 0xC2E4, - 0x8446, 0xDDE1, - 0x8451, 0xDDD7, - 0x8457, 0xD6F8, - 0x8459, 0xDDD9, - 0x845A, 0xDDD8, - 0x845B, 0xB8F0, - 0x845C, 0xDDD6, - 0x8461, 0xC6CF, - 0x8463, 0xB6AD, - 0x8469, 0xDDE2, - 0x846B, 0xBAF9, - 0x846C, 0xD4E1, - 0x846D, 0xDDE7, - 0x8471, 0xB4D0, - 0x8473, 0xDDDA, - 0x8475, 0xBFFB, - 0x8476, 0xDDE3, - 0x8478, 0xDDDF, - 0x847A, 0xDDDD, - 0x8482, 0xB5D9, - 0x8487, 0xDDDB, - 0x8488, 0xDDDC, - 0x8489, 0xDDDE, - 0x848B, 0xBDAF, - 0x848C, 0xDDE4, - 0x848E, 0xDDE5, - 0x8497, 0xDDF5, - 0x8499, 0xC3C9, - 0x849C, 0xCBE2, - 0x84A1, 0xDDF2, - 0x84AF, 0xD8E1, - 0x84B2, 0xC6D1, - 0x84B4, 0xDDF4, - 0x84B8, 0xD5F4, - 0x84B9, 0xDDF3, - 0x84BA, 0xDDF0, - 0x84BD, 0xDDEC, - 0x84BF, 0xDDEF, - 0x84C1, 0xDDE8, - 0x84C4, 0xD0EE, - 0x84C9, 0xC8D8, - 0x84CA, 0xDDEE, - 0x84CD, 0xDDE9, - 0x84D0, 0xDDEA, - 0x84D1, 0xCBF2, - 0x84D3, 0xDDED, - 0x84D6, 0xB1CD, - 0x84DD, 0xC0B6, - 0x84DF, 0xBCBB, - 0x84E0, 0xDDF1, - 0x84E3, 0xDDF7, - 0x84E5, 0xDDF6, - 0x84E6, 0xDDEB, - 0x84EC, 0xC5EE, - 0x84F0, 0xDDFB, - 0x84FC, 0xDEA4, - 0x84FF, 0xDEA3, - 0x850C, 0xDDF8, - 0x8511, 0xC3EF, - 0x8513, 0xC2FB, - 0x8517, 0xD5E1, - 0x851A, 0xCEB5, - 0x851F, 0xDDFD, - 0x8521, 0xB2CC, - 0x852B, 0xC4E8, - 0x852C, 0xCADF, - 0x8537, 0xC7BE, - 0x8538, 0xDDFA, - 0x8539, 0xDDFC, - 0x853A, 0xDDFE, - 0x853B, 0xDEA2, - 0x853C, 0xB0AA, - 0x853D, 0xB1CE, - 0x8543, 0xDEAC, - 0x8548, 0xDEA6, - 0x8549, 0xBDB6, - 0x854A, 0xC8EF, - 0x8556, 0xDEA1, - 0x8559, 0xDEA5, - 0x855E, 0xDEA9, - 0x8564, 0xDEA8, - 0x8568, 0xDEA7, - 0x8572, 0xDEAD, - 0x8574, 0xD4CC, - 0x8579, 0xDEB3, - 0x857A, 0xDEAA, - 0x857B, 0xDEAE, - 0x857E, 0xC0D9, - 0x8584, 0xB1A1, - 0x8585, 0xDEB6, - 0x8587, 0xDEB1, - 0x858F, 0xDEB2, - 0x859B, 0xD1A6, - 0x859C, 0xDEB5, - 0x85A4, 0xDEAF, - 0x85A8, 0xDEB0, - 0x85AA, 0xD0BD, - 0x85AE, 0xDEB4, - 0x85AF, 0xCAED, - 0x85B0, 0xDEB9, - 0x85B7, 0xDEB8, - 0x85B9, 0xDEB7, - 0x85C1, 0xDEBB, - 0x85C9, 0xBDE5, - 0x85CF, 0xB2D8, - 0x85D0, 0xC3EA, - 0x85D3, 0xDEBA, - 0x85D5, 0xC5BA, - 0x85DC, 0xDEBC, - 0x85E4, 0xCCD9, - 0x85E9, 0xB7AA, - 0x85FB, 0xD4E5, - 0x85FF, 0xDEBD, - 0x8605, 0xDEBF, - 0x8611, 0xC4A2, - 0x8616, 0xDEC1, - 0x8627, 0xDEBE, - 0x8629, 0xDEC0, - 0x8638, 0xD5BA, - 0x863C, 0xDEC2, - 0x864D, 0xF2AE, - 0x864E, 0xBBA2, - 0x864F, 0xC2B2, - 0x8650, 0xC5B0, - 0x8651, 0xC2C7, - 0x8654, 0xF2AF, - 0x865A, 0xD0E9, - 0x865E, 0xD3DD, - 0x8662, 0xEBBD, - 0x866B, 0xB3E6, - 0x866C, 0xF2B0, - 0x866E, 0xF2B1, - 0x8671, 0xCAAD, - 0x8679, 0xBAE7, - 0x867A, 0xF2B3, - 0x867B, 0xF2B5, - 0x867C, 0xF2B4, - 0x867D, 0xCBE4, - 0x867E, 0xCFBA, - 0x867F, 0xF2B2, - 0x8680, 0xCAB4, - 0x8681, 0xD2CF, - 0x8682, 0xC2EC, - 0x868A, 0xCEC3, - 0x868B, 0xF2B8, - 0x868C, 0xB0F6, - 0x868D, 0xF2B7, - 0x8693, 0xF2BE, - 0x8695, 0xB2CF, - 0x869C, 0xD1C1, - 0x869D, 0xF2BA, - 0x86A3, 0xF2BC, - 0x86A4, 0xD4E9, - 0x86A7, 0xF2BB, - 0x86A8, 0xF2B6, - 0x86A9, 0xF2BF, - 0x86AA, 0xF2BD, - 0x86AC, 0xF2B9, - 0x86AF, 0xF2C7, - 0x86B0, 0xF2C4, - 0x86B1, 0xF2C6, - 0x86B4, 0xF2CA, - 0x86B5, 0xF2C2, - 0x86B6, 0xF2C0, - 0x86BA, 0xF2C5, - 0x86C0, 0xD6FB, - 0x86C4, 0xF2C1, - 0x86C6, 0xC7F9, - 0x86C7, 0xC9DF, - 0x86C9, 0xF2C8, - 0x86CA, 0xB9C6, - 0x86CB, 0xB5B0, - 0x86CE, 0xF2C3, - 0x86CF, 0xF2C9, - 0x86D0, 0xF2D0, - 0x86D1, 0xF2D6, - 0x86D4, 0xBBD7, - 0x86D8, 0xF2D5, - 0x86D9, 0xCDDC, - 0x86DB, 0xD6EB, - 0x86DE, 0xF2D2, - 0x86DF, 0xF2D4, - 0x86E4, 0xB8F2, - 0x86E9, 0xF2CB, - 0x86ED, 0xF2CE, - 0x86EE, 0xC2F9, - 0x86F0, 0xD5DD, - 0x86F1, 0xF2CC, - 0x86F2, 0xF2CD, - 0x86F3, 0xF2CF, - 0x86F4, 0xF2D3, - 0x86F8, 0xF2D9, - 0x86F9, 0xD3BC, - 0x86FE, 0xB6EA, - 0x8700, 0xCAF1, - 0x8702, 0xB7E4, - 0x8703, 0xF2D7, - 0x8707, 0xF2D8, - 0x8708, 0xF2DA, - 0x8709, 0xF2DD, - 0x870A, 0xF2DB, - 0x870D, 0xF2DC, - 0x8712, 0xD1D1, - 0x8713, 0xF2D1, - 0x8715, 0xCDC9, - 0x8717, 0xCECF, - 0x8718, 0xD6A9, - 0x871A, 0xF2E3, - 0x871C, 0xC3DB, - 0x871E, 0xF2E0, - 0x8721, 0xC0AF, - 0x8722, 0xF2EC, - 0x8723, 0xF2DE, - 0x8725, 0xF2E1, - 0x8729, 0xF2E8, - 0x872E, 0xF2E2, - 0x8731, 0xF2E7, - 0x8734, 0xF2E6, - 0x8737, 0xF2E9, - 0x873B, 0xF2DF, - 0x873E, 0xF2E4, - 0x873F, 0xF2EA, - 0x8747, 0xD3AC, - 0x8748, 0xF2E5, - 0x8749, 0xB2F5, - 0x874C, 0xF2F2, - 0x874E, 0xD0AB, - 0x8753, 0xF2F5, - 0x8757, 0xBBC8, - 0x8759, 0xF2F9, - 0x8760, 0xF2F0, - 0x8763, 0xF2F6, - 0x8764, 0xF2F8, - 0x8765, 0xF2FA, - 0x876E, 0xF2F3, - 0x8770, 0xF2F1, - 0x8774, 0xBAFB, - 0x8776, 0xB5FB, - 0x877B, 0xF2EF, - 0x877C, 0xF2F7, - 0x877D, 0xF2ED, - 0x877E, 0xF2EE, - 0x8782, 0xF2EB, - 0x8783, 0xF3A6, - 0x8785, 0xF3A3, - 0x8788, 0xF3A2, - 0x878B, 0xF2F4, - 0x878D, 0xC8DA, - 0x8793, 0xF2FB, - 0x8797, 0xF3A5, - 0x879F, 0xC3F8, - 0x87A8, 0xF2FD, - 0x87AB, 0xF3A7, - 0x87AC, 0xF3A9, - 0x87AD, 0xF3A4, - 0x87AF, 0xF2FC, - 0x87B3, 0xF3AB, - 0x87B5, 0xF3AA, - 0x87BA, 0xC2DD, - 0x87BD, 0xF3AE, - 0x87C0, 0xF3B0, - 0x87C6, 0xF3A1, - 0x87CA, 0xF3B1, - 0x87CB, 0xF3AC, - 0x87D1, 0xF3AF, - 0x87D2, 0xF2FE, - 0x87D3, 0xF3AD, - 0x87DB, 0xF3B2, - 0x87E0, 0xF3B4, - 0x87E5, 0xF3A8, - 0x87EA, 0xF3B3, - 0x87EE, 0xF3B5, - 0x87F9, 0xD0B7, - 0x87FE, 0xF3B8, - 0x8803, 0xD9F9, - 0x880A, 0xF3B9, - 0x8813, 0xF3B7, - 0x8815, 0xC8E4, - 0x8816, 0xF3B6, - 0x881B, 0xF3BA, - 0x8821, 0xF3BB, - 0x8822, 0xB4C0, - 0x8832, 0xEEC3, - 0x8839, 0xF3BC, - 0x883C, 0xF3BD, - 0x8840, 0xD1AA, - 0x8844, 0xF4AC, - 0x8845, 0xD0C6, - 0x884C, 0xD0D0, - 0x884D, 0xD1DC, - 0x8854, 0xCFCE, - 0x8857, 0xBDD6, - 0x8859, 0xD1C3, - 0x8861, 0xBAE2, - 0x8862, 0xE1E9, - 0x8863, 0xD2C2, - 0x8864, 0xF1C2, - 0x8865, 0xB2B9, - 0x8868, 0xB1ED, - 0x8869, 0xF1C3, - 0x886B, 0xC9C0, - 0x886C, 0xB3C4, - 0x886E, 0xD9F2, - 0x8870, 0xCBA5, - 0x8872, 0xF1C4, - 0x8877, 0xD6D4, - 0x887D, 0xF1C5, - 0x887E, 0xF4C0, - 0x887F, 0xF1C6, - 0x8881, 0xD4AC, - 0x8882, 0xF1C7, - 0x8884, 0xB0C0, - 0x8885, 0xF4C1, - 0x8888, 0xF4C2, - 0x888B, 0xB4FC, - 0x888D, 0xC5DB, - 0x8892, 0xCCBB, - 0x8896, 0xD0E4, - 0x889C, 0xCDE0, - 0x88A2, 0xF1C8, - 0x88A4, 0xD9F3, - 0x88AB, 0xB1BB, - 0x88AD, 0xCFAE, - 0x88B1, 0xB8A4, - 0x88B7, 0xF1CA, - 0x88BC, 0xF1CB, - 0x88C1, 0xB2C3, - 0x88C2, 0xC1D1, - 0x88C5, 0xD7B0, - 0x88C6, 0xF1C9, - 0x88C9, 0xF1CC, - 0x88CE, 0xF1CE, - 0x88D2, 0xD9F6, - 0x88D4, 0xD2E1, - 0x88D5, 0xD4A3, - 0x88D8, 0xF4C3, - 0x88D9, 0xC8B9, - 0x88DF, 0xF4C4, - 0x88E2, 0xF1CD, - 0x88E3, 0xF1CF, - 0x88E4, 0xBFE3, - 0x88E5, 0xF1D0, - 0x88E8, 0xF1D4, - 0x88F0, 0xF1D6, - 0x88F1, 0xF1D1, - 0x88F3, 0xC9D1, - 0x88F4, 0xC5E1, - 0x88F8, 0xC2E3, - 0x88F9, 0xB9FC, - 0x88FC, 0xF1D3, - 0x88FE, 0xF1D5, - 0x8902, 0xB9D3, - 0x890A, 0xF1DB, - 0x8910, 0xBAD6, - 0x8912, 0xB0FD, - 0x8913, 0xF1D9, - 0x8919, 0xF1D8, - 0x891A, 0xF1D2, - 0x891B, 0xF1DA, - 0x8921, 0xF1D7, - 0x8925, 0xC8EC, - 0x892A, 0xCDCA, - 0x892B, 0xF1DD, - 0x8930, 0xE5BD, - 0x8934, 0xF1DC, - 0x8936, 0xF1DE, - 0x8941, 0xF1DF, - 0x8944, 0xCFE5, - 0x895E, 0xF4C5, - 0x895F, 0xBDF3, - 0x8966, 0xF1E0, - 0x897B, 0xF1E1, - 0x897F, 0xCEF7, - 0x8981, 0xD2AA, - 0x8983, 0xF1FB, - 0x8986, 0xB8B2, - 0x89C1, 0xBCFB, - 0x89C2, 0xB9DB, - 0x89C4, 0xB9E6, - 0x89C5, 0xC3D9, - 0x89C6, 0xCAD3, - 0x89C7, 0xEAE8, - 0x89C8, 0xC0C0, - 0x89C9, 0xBEF5, - 0x89CA, 0xEAE9, - 0x89CB, 0xEAEA, - 0x89CC, 0xEAEB, - 0x89CE, 0xEAEC, - 0x89CF, 0xEAED, - 0x89D0, 0xEAEE, - 0x89D1, 0xEAEF, - 0x89D2, 0xBDC7, - 0x89D6, 0xF5FB, - 0x89DA, 0xF5FD, - 0x89DC, 0xF5FE, - 0x89DE, 0xF5FC, - 0x89E3, 0xBDE2, - 0x89E5, 0xF6A1, - 0x89E6, 0xB4A5, - 0x89EB, 0xF6A2, - 0x89EF, 0xF6A3, - 0x89F3, 0xECB2, - 0x8A00, 0xD1D4, - 0x8A07, 0xD9EA, - 0x8A3E, 0xF6A4, - 0x8A48, 0xEEBA, - 0x8A79, 0xD5B2, - 0x8A89, 0xD3FE, - 0x8A8A, 0xCCDC, - 0x8A93, 0xCAC4, - 0x8B07, 0xE5C0, - 0x8B26, 0xF6A5, - 0x8B66, 0xBEAF, - 0x8B6C, 0xC6A9, - 0x8BA0, 0xDAA5, - 0x8BA1, 0xBCC6, - 0x8BA2, 0xB6A9, - 0x8BA3, 0xB8BC, - 0x8BA4, 0xC8CF, - 0x8BA5, 0xBCA5, - 0x8BA6, 0xDAA6, - 0x8BA7, 0xDAA7, - 0x8BA8, 0xCCD6, - 0x8BA9, 0xC8C3, - 0x8BAA, 0xDAA8, - 0x8BAB, 0xC6FD, - 0x8BAD, 0xD1B5, - 0x8BAE, 0xD2E9, - 0x8BAF, 0xD1B6, - 0x8BB0, 0xBCC7, - 0x8BB2, 0xBDB2, - 0x8BB3, 0xBBE4, - 0x8BB4, 0xDAA9, - 0x8BB5, 0xDAAA, - 0x8BB6, 0xD1C8, - 0x8BB7, 0xDAAB, - 0x8BB8, 0xD0ED, - 0x8BB9, 0xB6EF, - 0x8BBA, 0xC2DB, - 0x8BBC, 0xCBCF, - 0x8BBD, 0xB7ED, - 0x8BBE, 0xC9E8, - 0x8BBF, 0xB7C3, - 0x8BC0, 0xBEF7, - 0x8BC1, 0xD6A4, - 0x8BC2, 0xDAAC, - 0x8BC3, 0xDAAD, - 0x8BC4, 0xC6C0, - 0x8BC5, 0xD7E7, - 0x8BC6, 0xCAB6, - 0x8BC8, 0xD5A9, - 0x8BC9, 0xCBDF, - 0x8BCA, 0xD5EF, - 0x8BCB, 0xDAAE, - 0x8BCC, 0xD6DF, - 0x8BCD, 0xB4CA, - 0x8BCE, 0xDAB0, - 0x8BCF, 0xDAAF, - 0x8BD1, 0xD2EB, - 0x8BD2, 0xDAB1, - 0x8BD3, 0xDAB2, - 0x8BD4, 0xDAB3, - 0x8BD5, 0xCAD4, - 0x8BD6, 0xDAB4, - 0x8BD7, 0xCAAB, - 0x8BD8, 0xDAB5, - 0x8BD9, 0xDAB6, - 0x8BDA, 0xB3CF, - 0x8BDB, 0xD6EF, - 0x8BDC, 0xDAB7, - 0x8BDD, 0xBBB0, - 0x8BDE, 0xB5AE, - 0x8BDF, 0xDAB8, - 0x8BE0, 0xDAB9, - 0x8BE1, 0xB9EE, - 0x8BE2, 0xD1AF, - 0x8BE3, 0xD2E8, - 0x8BE4, 0xDABA, - 0x8BE5, 0xB8C3, - 0x8BE6, 0xCFEA, - 0x8BE7, 0xB2EF, - 0x8BE8, 0xDABB, - 0x8BE9, 0xDABC, - 0x8BEB, 0xBDEB, - 0x8BEC, 0xCEDC, - 0x8BED, 0xD3EF, - 0x8BEE, 0xDABD, - 0x8BEF, 0xCEF3, - 0x8BF0, 0xDABE, - 0x8BF1, 0xD3D5, - 0x8BF2, 0xBBE5, - 0x8BF3, 0xDABF, - 0x8BF4, 0xCBB5, - 0x8BF5, 0xCBD0, - 0x8BF6, 0xDAC0, - 0x8BF7, 0xC7EB, - 0x8BF8, 0xD6EE, - 0x8BF9, 0xDAC1, - 0x8BFA, 0xC5B5, - 0x8BFB, 0xB6C1, - 0x8BFC, 0xDAC2, - 0x8BFD, 0xB7CC, - 0x8BFE, 0xBFCE, - 0x8BFF, 0xDAC3, - 0x8C00, 0xDAC4, - 0x8C01, 0xCBAD, - 0x8C02, 0xDAC5, - 0x8C03, 0xB5F7, - 0x8C04, 0xDAC6, - 0x8C05, 0xC1C2, - 0x8C06, 0xD7BB, - 0x8C07, 0xDAC7, - 0x8C08, 0xCCB8, - 0x8C0A, 0xD2EA, - 0x8C0B, 0xC4B1, - 0x8C0C, 0xDAC8, - 0x8C0D, 0xB5FD, - 0x8C0E, 0xBBD1, - 0x8C0F, 0xDAC9, - 0x8C10, 0xD0B3, - 0x8C11, 0xDACA, - 0x8C12, 0xDACB, - 0x8C13, 0xCEBD, - 0x8C14, 0xDACC, - 0x8C15, 0xDACD, - 0x8C16, 0xDACE, - 0x8C17, 0xB2F7, - 0x8C18, 0xDAD1, - 0x8C19, 0xDACF, - 0x8C1A, 0xD1E8, - 0x8C1B, 0xDAD0, - 0x8C1C, 0xC3D5, - 0x8C1D, 0xDAD2, - 0x8C1F, 0xDAD3, - 0x8C20, 0xDAD4, - 0x8C21, 0xDAD5, - 0x8C22, 0xD0BB, - 0x8C23, 0xD2A5, - 0x8C24, 0xB0F9, - 0x8C25, 0xDAD6, - 0x8C26, 0xC7AB, - 0x8C27, 0xDAD7, - 0x8C28, 0xBDF7, - 0x8C29, 0xC3A1, - 0x8C2A, 0xDAD8, - 0x8C2B, 0xDAD9, - 0x8C2C, 0xC3FD, - 0x8C2D, 0xCCB7, - 0x8C2E, 0xDADA, - 0x8C2F, 0xDADB, - 0x8C30, 0xC0BE, - 0x8C31, 0xC6D7, - 0x8C32, 0xDADC, - 0x8C33, 0xDADD, - 0x8C34, 0xC7B4, - 0x8C35, 0xDADE, - 0x8C36, 0xDADF, - 0x8C37, 0xB9C8, - 0x8C41, 0xBBED, - 0x8C46, 0xB6B9, - 0x8C47, 0xF4F8, - 0x8C49, 0xF4F9, - 0x8C4C, 0xCDE3, - 0x8C55, 0xF5B9, - 0x8C5A, 0xEBE0, - 0x8C61, 0xCFF3, - 0x8C62, 0xBBBF, - 0x8C6A, 0xBAC0, - 0x8C6B, 0xD4A5, - 0x8C73, 0xE1D9, - 0x8C78, 0xF5F4, - 0x8C79, 0xB1AA, - 0x8C7A, 0xB2F2, - 0x8C82, 0xF5F5, - 0x8C85, 0xF5F7, - 0x8C89, 0xBAD1, - 0x8C8A, 0xF5F6, - 0x8C8C, 0xC3B2, - 0x8C94, 0xF5F9, - 0x8C98, 0xF5F8, - 0x8D1D, 0xB1B4, - 0x8D1E, 0xD5EA, - 0x8D1F, 0xB8BA, - 0x8D21, 0xB9B1, - 0x8D22, 0xB2C6, - 0x8D23, 0xD4F0, - 0x8D24, 0xCFCD, - 0x8D25, 0xB0DC, - 0x8D26, 0xD5CB, - 0x8D27, 0xBBF5, - 0x8D28, 0xD6CA, - 0x8D29, 0xB7B7, - 0x8D2A, 0xCCB0, - 0x8D2B, 0xC6B6, - 0x8D2C, 0xB1E1, - 0x8D2D, 0xB9BA, - 0x8D2E, 0xD6FC, - 0x8D2F, 0xB9E1, - 0x8D30, 0xB7A1, - 0x8D31, 0xBCFA, - 0x8D32, 0xEADA, - 0x8D33, 0xEADB, - 0x8D34, 0xCCF9, - 0x8D35, 0xB9F3, - 0x8D36, 0xEADC, - 0x8D37, 0xB4FB, - 0x8D38, 0xC3B3, - 0x8D39, 0xB7D1, - 0x8D3A, 0xBAD8, - 0x8D3B, 0xEADD, - 0x8D3C, 0xD4F4, - 0x8D3D, 0xEADE, - 0x8D3E, 0xBCD6, - 0x8D3F, 0xBBDF, - 0x8D40, 0xEADF, - 0x8D41, 0xC1DE, - 0x8D42, 0xC2B8, - 0x8D43, 0xD4DF, - 0x8D44, 0xD7CA, - 0x8D45, 0xEAE0, - 0x8D46, 0xEAE1, - 0x8D47, 0xEAE4, - 0x8D48, 0xEAE2, - 0x8D49, 0xEAE3, - 0x8D4A, 0xC9DE, - 0x8D4B, 0xB8B3, - 0x8D4C, 0xB6C4, - 0x8D4D, 0xEAE5, - 0x8D4E, 0xCAEA, - 0x8D4F, 0xC9CD, - 0x8D50, 0xB4CD, - 0x8D53, 0xE2D9, - 0x8D54, 0xC5E2, - 0x8D55, 0xEAE6, - 0x8D56, 0xC0B5, - 0x8D58, 0xD7B8, - 0x8D59, 0xEAE7, - 0x8D5A, 0xD7AC, - 0x8D5B, 0xC8FC, - 0x8D5C, 0xD8D3, - 0x8D5D, 0xD8CD, - 0x8D5E, 0xD4DE, - 0x8D60, 0xD4F9, - 0x8D61, 0xC9C4, - 0x8D62, 0xD3AE, - 0x8D63, 0xB8D3, - 0x8D64, 0xB3E0, - 0x8D66, 0xC9E2, - 0x8D67, 0xF4F6, - 0x8D6B, 0xBAD5, - 0x8D6D, 0xF4F7, - 0x8D70, 0xD7DF, - 0x8D73, 0xF4F1, - 0x8D74, 0xB8B0, - 0x8D75, 0xD5D4, - 0x8D76, 0xB8CF, - 0x8D77, 0xC6F0, - 0x8D81, 0xB3C3, - 0x8D84, 0xF4F2, - 0x8D85, 0xB3AC, - 0x8D8A, 0xD4BD, - 0x8D8B, 0xC7F7, - 0x8D91, 0xF4F4, - 0x8D94, 0xF4F3, - 0x8D9F, 0xCCCB, - 0x8DA3, 0xC8A4, - 0x8DB1, 0xF4F5, - 0x8DB3, 0xD7E3, - 0x8DB4, 0xC5BF, - 0x8DB5, 0xF5C0, - 0x8DB8, 0xF5BB, - 0x8DBA, 0xF5C3, - 0x8DBC, 0xF5C2, - 0x8DBE, 0xD6BA, - 0x8DBF, 0xF5C1, - 0x8DC3, 0xD4BE, - 0x8DC4, 0xF5C4, - 0x8DC6, 0xF5CC, - 0x8DCB, 0xB0CF, - 0x8DCC, 0xB5F8, - 0x8DCE, 0xF5C9, - 0x8DCF, 0xF5CA, - 0x8DD1, 0xC5DC, - 0x8DD6, 0xF5C5, - 0x8DD7, 0xF5C6, - 0x8DDA, 0xF5C7, - 0x8DDB, 0xF5CB, - 0x8DDD, 0xBEE0, - 0x8DDE, 0xF5C8, - 0x8DDF, 0xB8FA, - 0x8DE3, 0xF5D0, - 0x8DE4, 0xF5D3, - 0x8DE8, 0xBFE7, - 0x8DEA, 0xB9F2, - 0x8DEB, 0xF5BC, - 0x8DEC, 0xF5CD, - 0x8DEF, 0xC2B7, - 0x8DF3, 0xCCF8, - 0x8DF5, 0xBCF9, - 0x8DF7, 0xF5CE, - 0x8DF8, 0xF5CF, - 0x8DF9, 0xF5D1, - 0x8DFA, 0xB6E5, - 0x8DFB, 0xF5D2, - 0x8DFD, 0xF5D5, - 0x8E05, 0xF5BD, - 0x8E09, 0xF5D4, - 0x8E0A, 0xD3BB, - 0x8E0C, 0xB3EC, - 0x8E0F, 0xCCA4, - 0x8E14, 0xF5D6, - 0x8E1D, 0xF5D7, - 0x8E1E, 0xBEE1, - 0x8E1F, 0xF5D8, - 0x8E22, 0xCCDF, - 0x8E23, 0xF5DB, - 0x8E29, 0xB2C8, - 0x8E2A, 0xD7D9, - 0x8E2C, 0xF5D9, - 0x8E2E, 0xF5DA, - 0x8E2F, 0xF5DC, - 0x8E31, 0xF5E2, - 0x8E35, 0xF5E0, - 0x8E39, 0xF5DF, - 0x8E3A, 0xF5DD, - 0x8E3D, 0xF5E1, - 0x8E40, 0xF5DE, - 0x8E41, 0xF5E4, - 0x8E42, 0xF5E5, - 0x8E44, 0xCCE3, - 0x8E47, 0xE5BF, - 0x8E48, 0xB5B8, - 0x8E49, 0xF5E3, - 0x8E4A, 0xF5E8, - 0x8E4B, 0xCCA3, - 0x8E51, 0xF5E6, - 0x8E52, 0xF5E7, - 0x8E59, 0xF5BE, - 0x8E66, 0xB1C4, - 0x8E69, 0xF5BF, - 0x8E6C, 0xB5C5, - 0x8E6D, 0xB2E4, - 0x8E6F, 0xF5EC, - 0x8E70, 0xF5E9, - 0x8E72, 0xB6D7, - 0x8E74, 0xF5ED, - 0x8E76, 0xF5EA, - 0x8E7C, 0xF5EB, - 0x8E7F, 0xB4DA, - 0x8E81, 0xD4EA, - 0x8E85, 0xF5EE, - 0x8E87, 0xB3F9, - 0x8E8F, 0xF5EF, - 0x8E90, 0xF5F1, - 0x8E94, 0xF5F0, - 0x8E9C, 0xF5F2, - 0x8E9E, 0xF5F3, - 0x8EAB, 0xC9ED, - 0x8EAC, 0xB9AA, - 0x8EAF, 0xC7FB, - 0x8EB2, 0xB6E3, - 0x8EBA, 0xCCC9, - 0x8ECE, 0xEAA6, - 0x8F66, 0xB3B5, - 0x8F67, 0xD4FE, - 0x8F68, 0xB9EC, - 0x8F69, 0xD0F9, - 0x8F6B, 0xE9ED, - 0x8F6C, 0xD7AA, - 0x8F6D, 0xE9EE, - 0x8F6E, 0xC2D6, - 0x8F6F, 0xC8ED, - 0x8F70, 0xBAE4, - 0x8F71, 0xE9EF, - 0x8F72, 0xE9F0, - 0x8F73, 0xE9F1, - 0x8F74, 0xD6E1, - 0x8F75, 0xE9F2, - 0x8F76, 0xE9F3, - 0x8F77, 0xE9F5, - 0x8F78, 0xE9F4, - 0x8F79, 0xE9F6, - 0x8F7A, 0xE9F7, - 0x8F7B, 0xC7E1, - 0x8F7C, 0xE9F8, - 0x8F7D, 0xD4D8, - 0x8F7E, 0xE9F9, - 0x8F7F, 0xBDCE, - 0x8F81, 0xE9FA, - 0x8F82, 0xE9FB, - 0x8F83, 0xBDCF, - 0x8F84, 0xE9FC, - 0x8F85, 0xB8A8, - 0x8F86, 0xC1BE, - 0x8F87, 0xE9FD, - 0x8F88, 0xB1B2, - 0x8F89, 0xBBD4, - 0x8F8A, 0xB9F5, - 0x8F8B, 0xE9FE, - 0x8F8D, 0xEAA1, - 0x8F8E, 0xEAA2, - 0x8F8F, 0xEAA3, - 0x8F90, 0xB7F8, - 0x8F91, 0xBCAD, - 0x8F93, 0xCAE4, - 0x8F94, 0xE0CE, - 0x8F95, 0xD4AF, - 0x8F96, 0xCFBD, - 0x8F97, 0xD5B7, - 0x8F98, 0xEAA4, - 0x8F99, 0xD5DE, - 0x8F9A, 0xEAA5, - 0x8F9B, 0xD0C1, - 0x8F9C, 0xB9BC, - 0x8F9E, 0xB4C7, - 0x8F9F, 0xB1D9, - 0x8FA3, 0xC0B1, - 0x8FA8, 0xB1E6, - 0x8FA9, 0xB1E7, - 0x8FAB, 0xB1E8, - 0x8FB0, 0xB3BD, - 0x8FB1, 0xC8E8, - 0x8FB6, 0xE5C1, - 0x8FB9, 0xB1DF, - 0x8FBD, 0xC1C9, - 0x8FBE, 0xB4EF, - 0x8FC1, 0xC7A8, - 0x8FC2, 0xD3D8, - 0x8FC4, 0xC6F9, - 0x8FC5, 0xD1B8, - 0x8FC7, 0xB9FD, - 0x8FC8, 0xC2F5, - 0x8FCE, 0xD3AD, - 0x8FD0, 0xD4CB, - 0x8FD1, 0xBDFC, - 0x8FD3, 0xE5C2, - 0x8FD4, 0xB7B5, - 0x8FD5, 0xE5C3, - 0x8FD8, 0xBBB9, - 0x8FD9, 0xD5E2, - 0x8FDB, 0xBDF8, - 0x8FDC, 0xD4B6, - 0x8FDD, 0xCEA5, - 0x8FDE, 0xC1AC, - 0x8FDF, 0xB3D9, - 0x8FE2, 0xCCF6, - 0x8FE4, 0xE5C6, - 0x8FE5, 0xE5C4, - 0x8FE6, 0xE5C8, - 0x8FE8, 0xE5CA, - 0x8FE9, 0xE5C7, - 0x8FEA, 0xB5CF, - 0x8FEB, 0xC6C8, - 0x8FED, 0xB5FC, - 0x8FEE, 0xE5C5, - 0x8FF0, 0xCAF6, - 0x8FF3, 0xE5C9, - 0x8FF7, 0xC3D4, - 0x8FF8, 0xB1C5, - 0x8FF9, 0xBCA3, - 0x8FFD, 0xD7B7, - 0x9000, 0xCDCB, - 0x9001, 0xCBCD, - 0x9002, 0xCACA, - 0x9003, 0xCCD3, - 0x9004, 0xE5CC, - 0x9005, 0xE5CB, - 0x9006, 0xC4E6, - 0x9009, 0xD1A1, - 0x900A, 0xD1B7, - 0x900B, 0xE5CD, - 0x900D, 0xE5D0, - 0x900F, 0xCDB8, - 0x9010, 0xD6F0, - 0x9011, 0xE5CF, - 0x9012, 0xB5DD, - 0x9014, 0xCDBE, - 0x9016, 0xE5D1, - 0x9017, 0xB6BA, - 0x901A, 0xCDA8, - 0x901B, 0xB9E4, - 0x901D, 0xCAC5, - 0x901E, 0xB3D1, - 0x901F, 0xCBD9, - 0x9020, 0xD4EC, - 0x9021, 0xE5D2, - 0x9022, 0xB7EA, - 0x9026, 0xE5CE, - 0x902D, 0xE5D5, - 0x902E, 0xB4FE, - 0x902F, 0xE5D6, - 0x9035, 0xE5D3, - 0x9036, 0xE5D4, - 0x9038, 0xD2DD, - 0x903B, 0xC2DF, - 0x903C, 0xB1C6, - 0x903E, 0xD3E2, - 0x9041, 0xB6DD, - 0x9042, 0xCBEC, - 0x9044, 0xE5D7, - 0x9047, 0xD3F6, - 0x904D, 0xB1E9, - 0x904F, 0xB6F4, - 0x9050, 0xE5DA, - 0x9051, 0xE5D8, - 0x9052, 0xE5D9, - 0x9053, 0xB5C0, - 0x9057, 0xD2C5, - 0x9058, 0xE5DC, - 0x905B, 0xE5DE, - 0x9062, 0xE5DD, - 0x9063, 0xC7B2, - 0x9065, 0xD2A3, - 0x9068, 0xE5DB, - 0x906D, 0xD4E2, - 0x906E, 0xD5DA, - 0x9074, 0xE5E0, - 0x9075, 0xD7F1, - 0x907D, 0xE5E1, - 0x907F, 0xB1DC, - 0x9080, 0xD1FB, - 0x9082, 0xE5E2, - 0x9083, 0xE5E4, - 0x9088, 0xE5E3, - 0x908B, 0xE5E5, - 0x9091, 0xD2D8, - 0x9093, 0xB5CB, - 0x9095, 0xE7DF, - 0x9097, 0xDAF5, - 0x9099, 0xDAF8, - 0x909B, 0xDAF6, - 0x909D, 0xDAF7, - 0x90A1, 0xDAFA, - 0x90A2, 0xD0CF, - 0x90A3, 0xC4C7, - 0x90A6, 0xB0EE, - 0x90AA, 0xD0B0, - 0x90AC, 0xDAF9, - 0x90AE, 0xD3CA, - 0x90AF, 0xBAAA, - 0x90B0, 0xDBA2, - 0x90B1, 0xC7F1, - 0x90B3, 0xDAFC, - 0x90B4, 0xDAFB, - 0x90B5, 0xC9DB, - 0x90B6, 0xDAFD, - 0x90B8, 0xDBA1, - 0x90B9, 0xD7DE, - 0x90BA, 0xDAFE, - 0x90BB, 0xC1DA, - 0x90BE, 0xDBA5, - 0x90C1, 0xD3F4, - 0x90C4, 0xDBA7, - 0x90C5, 0xDBA4, - 0x90C7, 0xDBA8, - 0x90CA, 0xBDBC, - 0x90CE, 0xC0C9, - 0x90CF, 0xDBA3, - 0x90D0, 0xDBA6, - 0x90D1, 0xD6A3, - 0x90D3, 0xDBA9, - 0x90D7, 0xDBAD, - 0x90DB, 0xDBAE, - 0x90DC, 0xDBAC, - 0x90DD, 0xBAC2, - 0x90E1, 0xBFA4, - 0x90E2, 0xDBAB, - 0x90E6, 0xDBAA, - 0x90E7, 0xD4C7, - 0x90E8, 0xB2BF, - 0x90EB, 0xDBAF, - 0x90ED, 0xB9F9, - 0x90EF, 0xDBB0, - 0x90F4, 0xB3BB, - 0x90F8, 0xB5A6, - 0x90FD, 0xB6BC, - 0x90FE, 0xDBB1, - 0x9102, 0xB6F5, - 0x9104, 0xDBB2, - 0x9119, 0xB1C9, - 0x911E, 0xDBB4, - 0x9122, 0xDBB3, - 0x9123, 0xDBB5, - 0x912F, 0xDBB7, - 0x9131, 0xDBB6, - 0x9139, 0xDBB8, - 0x9143, 0xDBB9, - 0x9146, 0xDBBA, - 0x9149, 0xD3CF, - 0x914A, 0xF4FA, - 0x914B, 0xC7F5, - 0x914C, 0xD7C3, - 0x914D, 0xC5E4, - 0x914E, 0xF4FC, - 0x914F, 0xF4FD, - 0x9150, 0xF4FB, - 0x9152, 0xBEC6, - 0x9157, 0xD0EF, - 0x915A, 0xB7D3, - 0x915D, 0xD4CD, - 0x915E, 0xCCAA, - 0x9161, 0xF5A2, - 0x9162, 0xF5A1, - 0x9163, 0xBAA8, - 0x9164, 0xF4FE, - 0x9165, 0xCBD6, - 0x9169, 0xF5A4, - 0x916A, 0xC0D2, - 0x916C, 0xB3EA, - 0x916E, 0xCDAA, - 0x916F, 0xF5A5, - 0x9170, 0xF5A3, - 0x9171, 0xBDB4, - 0x9172, 0xF5A8, - 0x9174, 0xF5A9, - 0x9175, 0xBDCD, - 0x9176, 0xC3B8, - 0x9177, 0xBFE1, - 0x9178, 0xCBE1, - 0x9179, 0xF5AA, - 0x917D, 0xF5A6, - 0x917E, 0xF5A7, - 0x917F, 0xC4F0, - 0x9185, 0xF5AC, - 0x9187, 0xB4BC, - 0x9189, 0xD7ED, - 0x918B, 0xB4D7, - 0x918C, 0xF5AB, - 0x918D, 0xF5AE, - 0x9190, 0xF5AD, - 0x9191, 0xF5AF, - 0x9192, 0xD0D1, - 0x919A, 0xC3D1, - 0x919B, 0xC8A9, - 0x91A2, 0xF5B0, - 0x91A3, 0xF5B1, - 0x91AA, 0xF5B2, - 0x91AD, 0xF5B3, - 0x91AE, 0xF5B4, - 0x91AF, 0xF5B5, - 0x91B4, 0xF5B7, - 0x91B5, 0xF5B6, - 0x91BA, 0xF5B8, - 0x91C7, 0xB2C9, - 0x91C9, 0xD3D4, - 0x91CA, 0xCACD, - 0x91CC, 0xC0EF, - 0x91CD, 0xD6D8, - 0x91CE, 0xD2B0, - 0x91CF, 0xC1BF, - 0x91D1, 0xBDF0, - 0x91DC, 0xB8AA, - 0x9274, 0xBCF8, - 0x928E, 0xF6C6, - 0x92AE, 0xF6C7, - 0x92C8, 0xF6C8, - 0x933E, 0xF6C9, - 0x936A, 0xF6CA, - 0x938F, 0xF6CC, - 0x93CA, 0xF6CB, - 0x93D6, 0xF7E9, - 0x943E, 0xF6CD, - 0x946B, 0xF6CE, - 0x9485, 0xEEC4, - 0x9486, 0xEEC5, - 0x9487, 0xEEC6, - 0x9488, 0xD5EB, - 0x9489, 0xB6A4, - 0x948A, 0xEEC8, - 0x948B, 0xEEC7, - 0x948C, 0xEEC9, - 0x948D, 0xEECA, - 0x948E, 0xC7A5, - 0x948F, 0xEECB, - 0x9490, 0xEECC, - 0x9492, 0xB7B0, - 0x9493, 0xB5F6, - 0x9494, 0xEECD, - 0x9495, 0xEECF, - 0x9497, 0xEECE, - 0x9499, 0xB8C6, - 0x949A, 0xEED0, - 0x949B, 0xEED1, - 0x949C, 0xEED2, - 0x949D, 0xB6DB, - 0x949E, 0xB3AE, - 0x949F, 0xD6D3, - 0x94A0, 0xC4C6, - 0x94A1, 0xB1B5, - 0x94A2, 0xB8D6, - 0x94A3, 0xEED3, - 0x94A4, 0xEED4, - 0x94A5, 0xD4BF, - 0x94A6, 0xC7D5, - 0x94A7, 0xBEFB, - 0x94A8, 0xCED9, - 0x94A9, 0xB9B3, - 0x94AA, 0xEED6, - 0x94AB, 0xEED5, - 0x94AC, 0xEED8, - 0x94AD, 0xEED7, - 0x94AE, 0xC5A5, - 0x94AF, 0xEED9, - 0x94B0, 0xEEDA, - 0x94B1, 0xC7AE, - 0x94B2, 0xEEDB, - 0x94B3, 0xC7AF, - 0x94B4, 0xEEDC, - 0x94B5, 0xB2A7, - 0x94B6, 0xEEDD, - 0x94B7, 0xEEDE, - 0x94B8, 0xEEDF, - 0x94B9, 0xEEE0, - 0x94BA, 0xEEE1, - 0x94BB, 0xD7EA, - 0x94BC, 0xEEE2, - 0x94BD, 0xEEE3, - 0x94BE, 0xBCD8, - 0x94BF, 0xEEE4, - 0x94C0, 0xD3CB, - 0x94C1, 0xCCFA, - 0x94C2, 0xB2AC, - 0x94C3, 0xC1E5, - 0x94C4, 0xEEE5, - 0x94C5, 0xC7A6, - 0x94C6, 0xC3AD, - 0x94C8, 0xEEE6, - 0x94C9, 0xEEE7, - 0x94CA, 0xEEE8, - 0x94CB, 0xEEE9, - 0x94CC, 0xEEEA, - 0x94CD, 0xEEEB, - 0x94CE, 0xEEEC, - 0x94D0, 0xEEED, - 0x94D1, 0xEEEE, - 0x94D2, 0xEEEF, - 0x94D5, 0xEEF0, - 0x94D6, 0xEEF1, - 0x94D7, 0xEEF2, - 0x94D8, 0xEEF4, - 0x94D9, 0xEEF3, - 0x94DB, 0xEEF5, - 0x94DC, 0xCDAD, - 0x94DD, 0xC2C1, - 0x94DE, 0xEEF6, - 0x94DF, 0xEEF7, - 0x94E0, 0xEEF8, - 0x94E1, 0xD5A1, - 0x94E2, 0xEEF9, - 0x94E3, 0xCFB3, - 0x94E4, 0xEEFA, - 0x94E5, 0xEEFB, - 0x94E7, 0xEEFC, - 0x94E8, 0xEEFD, - 0x94E9, 0xEFA1, - 0x94EA, 0xEEFE, - 0x94EB, 0xEFA2, - 0x94EC, 0xB8F5, - 0x94ED, 0xC3FA, - 0x94EE, 0xEFA3, - 0x94EF, 0xEFA4, - 0x94F0, 0xBDC2, - 0x94F1, 0xD2BF, - 0x94F2, 0xB2F9, - 0x94F3, 0xEFA5, - 0x94F4, 0xEFA6, - 0x94F5, 0xEFA7, - 0x94F6, 0xD2F8, - 0x94F7, 0xEFA8, - 0x94F8, 0xD6FD, - 0x94F9, 0xEFA9, - 0x94FA, 0xC6CC, - 0x94FC, 0xEFAA, - 0x94FD, 0xEFAB, - 0x94FE, 0xC1B4, - 0x94FF, 0xEFAC, - 0x9500, 0xCFFA, - 0x9501, 0xCBF8, - 0x9502, 0xEFAE, - 0x9503, 0xEFAD, - 0x9504, 0xB3FA, - 0x9505, 0xB9F8, - 0x9506, 0xEFAF, - 0x9507, 0xEFB0, - 0x9508, 0xD0E2, - 0x9509, 0xEFB1, - 0x950A, 0xEFB2, - 0x950B, 0xB7E6, - 0x950C, 0xD0BF, - 0x950D, 0xEFB3, - 0x950E, 0xEFB4, - 0x950F, 0xEFB5, - 0x9510, 0xC8F1, - 0x9511, 0xCCE0, - 0x9512, 0xEFB6, - 0x9513, 0xEFB7, - 0x9514, 0xEFB8, - 0x9515, 0xEFB9, - 0x9516, 0xEFBA, - 0x9517, 0xD5E0, - 0x9518, 0xEFBB, - 0x9519, 0xB4ED, - 0x951A, 0xC3AA, - 0x951B, 0xEFBC, - 0x951D, 0xEFBD, - 0x951E, 0xEFBE, - 0x951F, 0xEFBF, - 0x9521, 0xCEFD, - 0x9522, 0xEFC0, - 0x9523, 0xC2E0, - 0x9524, 0xB4B8, - 0x9525, 0xD7B6, - 0x9526, 0xBDF5, - 0x9528, 0xCFC7, - 0x9529, 0xEFC3, - 0x952A, 0xEFC1, - 0x952B, 0xEFC2, - 0x952C, 0xEFC4, - 0x952D, 0xB6A7, - 0x952E, 0xBCFC, - 0x952F, 0xBEE2, - 0x9530, 0xC3CC, - 0x9531, 0xEFC5, - 0x9532, 0xEFC6, - 0x9534, 0xEFC7, - 0x9535, 0xEFCF, - 0x9536, 0xEFC8, - 0x9537, 0xEFC9, - 0x9538, 0xEFCA, - 0x9539, 0xC7C2, - 0x953A, 0xEFF1, - 0x953B, 0xB6CD, - 0x953C, 0xEFCB, - 0x953E, 0xEFCC, - 0x953F, 0xEFCD, - 0x9540, 0xB6C6, - 0x9541, 0xC3BE, - 0x9542, 0xEFCE, - 0x9544, 0xEFD0, - 0x9545, 0xEFD1, - 0x9546, 0xEFD2, - 0x9547, 0xD5F2, - 0x9549, 0xEFD3, - 0x954A, 0xC4F7, - 0x954C, 0xEFD4, - 0x954D, 0xC4F8, - 0x954E, 0xEFD5, - 0x954F, 0xEFD6, - 0x9550, 0xB8E4, - 0x9551, 0xB0F7, - 0x9552, 0xEFD7, - 0x9553, 0xEFD8, - 0x9554, 0xEFD9, - 0x9556, 0xEFDA, - 0x9557, 0xEFDB, - 0x9558, 0xEFDC, - 0x9559, 0xEFDD, - 0x955B, 0xEFDE, - 0x955C, 0xBEB5, - 0x955D, 0xEFE1, - 0x955E, 0xEFDF, - 0x955F, 0xEFE0, - 0x9561, 0xEFE2, - 0x9562, 0xEFE3, - 0x9563, 0xC1CD, - 0x9564, 0xEFE4, - 0x9565, 0xEFE5, - 0x9566, 0xEFE6, - 0x9567, 0xEFE7, - 0x9568, 0xEFE8, - 0x9569, 0xEFE9, - 0x956A, 0xEFEA, - 0x956B, 0xEFEB, - 0x956C, 0xEFEC, - 0x956D, 0xC0D8, - 0x956F, 0xEFED, - 0x9570, 0xC1AD, - 0x9571, 0xEFEE, - 0x9572, 0xEFEF, - 0x9573, 0xEFF0, - 0x9576, 0xCFE2, - 0x957F, 0xB3A4, - 0x95E8, 0xC3C5, - 0x95E9, 0xE3C5, - 0x95EA, 0xC9C1, - 0x95EB, 0xE3C6, - 0x95ED, 0xB1D5, - 0x95EE, 0xCECA, - 0x95EF, 0xB4B3, - 0x95F0, 0xC8F2, - 0x95F1, 0xE3C7, - 0x95F2, 0xCFD0, - 0x95F3, 0xE3C8, - 0x95F4, 0xBCE4, - 0x95F5, 0xE3C9, - 0x95F6, 0xE3CA, - 0x95F7, 0xC3C6, - 0x95F8, 0xD5A2, - 0x95F9, 0xC4D6, - 0x95FA, 0xB9EB, - 0x95FB, 0xCEC5, - 0x95FC, 0xE3CB, - 0x95FD, 0xC3F6, - 0x95FE, 0xE3CC, - 0x9600, 0xB7A7, - 0x9601, 0xB8F3, - 0x9602, 0xBAD2, - 0x9603, 0xE3CD, - 0x9604, 0xE3CE, - 0x9605, 0xD4C4, - 0x9606, 0xE3CF, - 0x9608, 0xE3D0, - 0x9609, 0xD1CB, - 0x960A, 0xE3D1, - 0x960B, 0xE3D2, - 0x960C, 0xE3D3, - 0x960D, 0xE3D4, - 0x960E, 0xD1D6, - 0x960F, 0xE3D5, - 0x9610, 0xB2FB, - 0x9611, 0xC0BB, - 0x9612, 0xE3D6, - 0x9614, 0xC0AB, - 0x9615, 0xE3D7, - 0x9616, 0xE3D8, - 0x9617, 0xE3D9, - 0x9619, 0xE3DA, - 0x961A, 0xE3DB, - 0x961C, 0xB8B7, - 0x961D, 0xDAE2, - 0x961F, 0xB6D3, - 0x9621, 0xDAE4, - 0x9622, 0xDAE3, - 0x962A, 0xDAE6, - 0x962E, 0xC8EE, - 0x9631, 0xDAE5, - 0x9632, 0xB7C0, - 0x9633, 0xD1F4, - 0x9634, 0xD2F5, - 0x9635, 0xD5F3, - 0x9636, 0xBDD7, - 0x963B, 0xD7E8, - 0x963C, 0xDAE8, - 0x963D, 0xDAE7, - 0x963F, 0xB0A2, - 0x9640, 0xCDD3, - 0x9642, 0xDAE9, - 0x9644, 0xB8BD, - 0x9645, 0xBCCA, - 0x9646, 0xC2BD, - 0x9647, 0xC2A4, - 0x9648, 0xB3C2, - 0x9649, 0xDAEA, - 0x964B, 0xC2AA, - 0x964C, 0xC4B0, - 0x964D, 0xBDB5, - 0x9650, 0xCFDE, - 0x9654, 0xDAEB, - 0x9655, 0xC9C2, - 0x965B, 0xB1DD, - 0x965F, 0xDAEC, - 0x9661, 0xB6B8, - 0x9662, 0xD4BA, - 0x9664, 0xB3FD, - 0x9667, 0xDAED, - 0x9668, 0xD4C9, - 0x9669, 0xCFD5, - 0x966A, 0xC5E3, - 0x966C, 0xDAEE, - 0x9672, 0xDAEF, - 0x9674, 0xDAF0, - 0x9675, 0xC1EA, - 0x9676, 0xCCD5, - 0x9677, 0xCFDD, - 0x9685, 0xD3E7, - 0x9686, 0xC2A1, - 0x9688, 0xDAF1, - 0x968B, 0xCBE5, - 0x968D, 0xDAF2, - 0x968F, 0xCBE6, - 0x9690, 0xD2FE, - 0x9694, 0xB8F4, - 0x9697, 0xDAF3, - 0x9698, 0xB0AF, - 0x9699, 0xCFB6, - 0x969C, 0xD5CF, - 0x96A7, 0xCBED, - 0x96B0, 0xDAF4, - 0x96B3, 0xE3C4, - 0x96B6, 0xC1A5, - 0x96B9, 0xF6BF, - 0x96BC, 0xF6C0, - 0x96BD, 0xF6C1, - 0x96BE, 0xC4D1, - 0x96C0, 0xC8B8, - 0x96C1, 0xD1E3, - 0x96C4, 0xD0DB, - 0x96C5, 0xD1C5, - 0x96C6, 0xBCAF, - 0x96C7, 0xB9CD, - 0x96C9, 0xEFF4, - 0x96CC, 0xB4C6, - 0x96CD, 0xD3BA, - 0x96CE, 0xF6C2, - 0x96CF, 0xB3FB, - 0x96D2, 0xF6C3, - 0x96D5, 0xB5F1, - 0x96E0, 0xF6C5, - 0x96E8, 0xD3EA, - 0x96E9, 0xF6A7, - 0x96EA, 0xD1A9, - 0x96EF, 0xF6A9, - 0x96F3, 0xF6A8, - 0x96F6, 0xC1E3, - 0x96F7, 0xC0D7, - 0x96F9, 0xB1A2, - 0x96FE, 0xCEED, - 0x9700, 0xD0E8, - 0x9701, 0xF6AB, - 0x9704, 0xCFF6, - 0x9706, 0xF6AA, - 0x9707, 0xD5F0, - 0x9708, 0xF6AC, - 0x9709, 0xC3B9, - 0x970D, 0xBBF4, - 0x970E, 0xF6AE, - 0x970F, 0xF6AD, - 0x9713, 0xC4DE, - 0x9716, 0xC1D8, - 0x971C, 0xCBAA, - 0x971E, 0xCFBC, - 0x972A, 0xF6AF, - 0x972D, 0xF6B0, - 0x9730, 0xF6B1, - 0x9732, 0xC2B6, - 0x9738, 0xB0D4, - 0x9739, 0xC5F9, - 0x973E, 0xF6B2, - 0x9752, 0xC7E0, - 0x9753, 0xF6A6, - 0x9756, 0xBEB8, - 0x9759, 0xBEB2, - 0x975B, 0xB5E5, - 0x975E, 0xB7C7, - 0x9760, 0xBFBF, - 0x9761, 0xC3D2, - 0x9762, 0xC3E6, - 0x9765, 0xD8CC, - 0x9769, 0xB8EF, - 0x9773, 0xBDF9, - 0x9774, 0xD1A5, - 0x9776, 0xB0D0, - 0x977C, 0xF7B0, - 0x9785, 0xF7B1, - 0x978B, 0xD0AC, - 0x978D, 0xB0B0, - 0x9791, 0xF7B2, - 0x9792, 0xF7B3, - 0x9794, 0xF7B4, - 0x9798, 0xC7CA, - 0x97A0, 0xBECF, - 0x97A3, 0xF7B7, - 0x97AB, 0xF7B6, - 0x97AD, 0xB1DE, - 0x97AF, 0xF7B5, - 0x97B2, 0xF7B8, - 0x97B4, 0xF7B9, - 0x97E6, 0xCEA4, - 0x97E7, 0xC8CD, - 0x97E9, 0xBAAB, - 0x97EA, 0xE8B8, - 0x97EB, 0xE8B9, - 0x97EC, 0xE8BA, - 0x97ED, 0xBEC2, - 0x97F3, 0xD2F4, - 0x97F5, 0xD4CF, - 0x97F6, 0xC9D8, - 0x9875, 0xD2B3, - 0x9876, 0xB6A5, - 0x9877, 0xC7EA, - 0x9878, 0xF1FC, - 0x9879, 0xCFEE, - 0x987A, 0xCBB3, - 0x987B, 0xD0EB, - 0x987C, 0xE7EF, - 0x987D, 0xCDE7, - 0x987E, 0xB9CB, - 0x987F, 0xB6D9, - 0x9880, 0xF1FD, - 0x9881, 0xB0E4, - 0x9882, 0xCBCC, - 0x9883, 0xF1FE, - 0x9884, 0xD4A4, - 0x9885, 0xC2AD, - 0x9886, 0xC1EC, - 0x9887, 0xC6C4, - 0x9888, 0xBEB1, - 0x9889, 0xF2A1, - 0x988A, 0xBCD5, - 0x988C, 0xF2A2, - 0x988D, 0xF2A3, - 0x988F, 0xF2A4, - 0x9890, 0xD2C3, - 0x9891, 0xC6B5, - 0x9893, 0xCDC7, - 0x9894, 0xF2A5, - 0x9896, 0xD3B1, - 0x9897, 0xBFC5, - 0x9898, 0xCCE2, - 0x989A, 0xF2A6, - 0x989B, 0xF2A7, - 0x989C, 0xD1D5, - 0x989D, 0xB6EE, - 0x989E, 0xF2A8, - 0x989F, 0xF2A9, - 0x98A0, 0xB5DF, - 0x98A1, 0xF2AA, - 0x98A2, 0xF2AB, - 0x98A4, 0xB2FC, - 0x98A5, 0xF2AC, - 0x98A6, 0xF2AD, - 0x98A7, 0xC8A7, - 0x98CE, 0xB7E7, - 0x98D1, 0xECA9, - 0x98D2, 0xECAA, - 0x98D3, 0xECAB, - 0x98D5, 0xECAC, - 0x98D8, 0xC6AE, - 0x98D9, 0xECAD, - 0x98DA, 0xECAE, - 0x98DE, 0xB7C9, - 0x98DF, 0xCAB3, - 0x98E7, 0xE2B8, - 0x98E8, 0xF7CF, - 0x990D, 0xF7D0, - 0x9910, 0xB2CD, - 0x992E, 0xF7D1, - 0x9954, 0xF7D3, - 0x9955, 0xF7D2, - 0x9963, 0xE2BB, - 0x9965, 0xBCA2, - 0x9967, 0xE2BC, - 0x9968, 0xE2BD, - 0x9969, 0xE2BE, - 0x996A, 0xE2BF, - 0x996B, 0xE2C0, - 0x996C, 0xE2C1, - 0x996D, 0xB7B9, - 0x996E, 0xD2FB, - 0x996F, 0xBDA4, - 0x9970, 0xCACE, - 0x9971, 0xB1A5, - 0x9972, 0xCBC7, - 0x9974, 0xE2C2, - 0x9975, 0xB6FC, - 0x9976, 0xC8C4, - 0x9977, 0xE2C3, - 0x997A, 0xBDC8, - 0x997C, 0xB1FD, - 0x997D, 0xE2C4, - 0x997F, 0xB6F6, - 0x9980, 0xE2C5, - 0x9981, 0xC4D9, - 0x9984, 0xE2C6, - 0x9985, 0xCFDA, - 0x9986, 0xB9DD, - 0x9987, 0xE2C7, - 0x9988, 0xC0A1, - 0x998A, 0xE2C8, - 0x998B, 0xB2F6, - 0x998D, 0xE2C9, - 0x998F, 0xC1F3, - 0x9990, 0xE2CA, - 0x9991, 0xE2CB, - 0x9992, 0xC2F8, - 0x9993, 0xE2CC, - 0x9994, 0xE2CD, - 0x9995, 0xE2CE, - 0x9996, 0xCAD7, - 0x9997, 0xD8B8, - 0x9998, 0xD9E5, - 0x9999, 0xCFE3, - 0x99A5, 0xF0A5, - 0x99A8, 0xDCB0, - 0x9A6C, 0xC2ED, - 0x9A6D, 0xD4A6, - 0x9A6E, 0xCDD4, - 0x9A6F, 0xD1B1, - 0x9A70, 0xB3DB, - 0x9A71, 0xC7FD, - 0x9A73, 0xB2B5, - 0x9A74, 0xC2BF, - 0x9A75, 0xE6E0, - 0x9A76, 0xCABB, - 0x9A77, 0xE6E1, - 0x9A78, 0xE6E2, - 0x9A79, 0xBED4, - 0x9A7A, 0xE6E3, - 0x9A7B, 0xD7A4, - 0x9A7C, 0xCDD5, - 0x9A7D, 0xE6E5, - 0x9A7E, 0xBCDD, - 0x9A7F, 0xE6E4, - 0x9A80, 0xE6E6, - 0x9A81, 0xE6E7, - 0x9A82, 0xC2EE, - 0x9A84, 0xBDBE, - 0x9A85, 0xE6E8, - 0x9A86, 0xC2E6, - 0x9A87, 0xBAA7, - 0x9A88, 0xE6E9, - 0x9A8A, 0xE6EA, - 0x9A8B, 0xB3D2, - 0x9A8C, 0xD1E9, - 0x9A8F, 0xBFA5, - 0x9A90, 0xE6EB, - 0x9A91, 0xC6EF, - 0x9A92, 0xE6EC, - 0x9A93, 0xE6ED, - 0x9A96, 0xE6EE, - 0x9A97, 0xC6AD, - 0x9A98, 0xE6EF, - 0x9A9A, 0xC9A7, - 0x9A9B, 0xE6F0, - 0x9A9C, 0xE6F1, - 0x9A9D, 0xE6F2, - 0x9A9E, 0xE5B9, - 0x9A9F, 0xE6F3, - 0x9AA0, 0xE6F4, - 0x9AA1, 0xC2E2, - 0x9AA2, 0xE6F5, - 0x9AA3, 0xE6F6, - 0x9AA4, 0xD6E8, - 0x9AA5, 0xE6F7, - 0x9AA7, 0xE6F8, - 0x9AA8, 0xB9C7, - 0x9AB0, 0xF7BB, - 0x9AB1, 0xF7BA, - 0x9AB6, 0xF7BE, - 0x9AB7, 0xF7BC, - 0x9AB8, 0xBAA1, - 0x9ABA, 0xF7BF, - 0x9ABC, 0xF7C0, - 0x9AC0, 0xF7C2, - 0x9AC1, 0xF7C1, - 0x9AC2, 0xF7C4, - 0x9AC5, 0xF7C3, - 0x9ACB, 0xF7C5, - 0x9ACC, 0xF7C6, - 0x9AD1, 0xF7C7, - 0x9AD3, 0xCBE8, - 0x9AD8, 0xB8DF, - 0x9ADF, 0xF7D4, - 0x9AE1, 0xF7D5, - 0x9AE6, 0xF7D6, - 0x9AEB, 0xF7D8, - 0x9AED, 0xF7DA, - 0x9AEF, 0xF7D7, - 0x9AF9, 0xF7DB, - 0x9AFB, 0xF7D9, - 0x9B03, 0xD7D7, - 0x9B08, 0xF7DC, - 0x9B0F, 0xF7DD, - 0x9B13, 0xF7DE, - 0x9B1F, 0xF7DF, - 0x9B23, 0xF7E0, - 0x9B2F, 0xDBCB, - 0x9B32, 0xD8AA, - 0x9B3B, 0xE5F7, - 0x9B3C, 0xB9ED, - 0x9B41, 0xBFFD, - 0x9B42, 0xBBEA, - 0x9B43, 0xF7C9, - 0x9B44, 0xC6C7, - 0x9B45, 0xF7C8, - 0x9B47, 0xF7CA, - 0x9B48, 0xF7CC, - 0x9B49, 0xF7CB, - 0x9B4D, 0xF7CD, - 0x9B4F, 0xCEBA, - 0x9B51, 0xF7CE, - 0x9B54, 0xC4A7, - 0x9C7C, 0xD3E3, - 0x9C7F, 0xF6CF, - 0x9C81, 0xC2B3, - 0x9C82, 0xF6D0, - 0x9C85, 0xF6D1, - 0x9C86, 0xF6D2, - 0x9C87, 0xF6D3, - 0x9C88, 0xF6D4, - 0x9C8B, 0xF6D6, - 0x9C8D, 0xB1AB, - 0x9C8E, 0xF6D7, - 0x9C90, 0xF6D8, - 0x9C91, 0xF6D9, - 0x9C92, 0xF6DA, - 0x9C94, 0xF6DB, - 0x9C95, 0xF6DC, - 0x9C9A, 0xF6DD, - 0x9C9B, 0xF6DE, - 0x9C9C, 0xCFCA, - 0x9C9E, 0xF6DF, - 0x9C9F, 0xF6E0, - 0x9CA0, 0xF6E1, - 0x9CA1, 0xF6E2, - 0x9CA2, 0xF6E3, - 0x9CA3, 0xF6E4, - 0x9CA4, 0xC0F0, - 0x9CA5, 0xF6E5, - 0x9CA6, 0xF6E6, - 0x9CA7, 0xF6E7, - 0x9CA8, 0xF6E8, - 0x9CA9, 0xF6E9, - 0x9CAB, 0xF6EA, - 0x9CAD, 0xF6EB, - 0x9CAE, 0xF6EC, - 0x9CB0, 0xF6ED, - 0x9CB1, 0xF6EE, - 0x9CB2, 0xF6EF, - 0x9CB3, 0xF6F0, - 0x9CB4, 0xF6F1, - 0x9CB5, 0xF6F2, - 0x9CB6, 0xF6F3, - 0x9CB7, 0xF6F4, - 0x9CB8, 0xBEA8, - 0x9CBA, 0xF6F5, - 0x9CBB, 0xF6F6, - 0x9CBC, 0xF6F7, - 0x9CBD, 0xF6F8, - 0x9CC3, 0xC8FA, - 0x9CC4, 0xF6F9, - 0x9CC5, 0xF6FA, - 0x9CC6, 0xF6FB, - 0x9CC7, 0xF6FC, - 0x9CCA, 0xF6FD, - 0x9CCB, 0xF6FE, - 0x9CCC, 0xF7A1, - 0x9CCD, 0xF7A2, - 0x9CCE, 0xF7A3, - 0x9CCF, 0xF7A4, - 0x9CD0, 0xF7A5, - 0x9CD3, 0xF7A6, - 0x9CD4, 0xF7A7, - 0x9CD5, 0xF7A8, - 0x9CD6, 0xB1EE, - 0x9CD7, 0xF7A9, - 0x9CD8, 0xF7AA, - 0x9CD9, 0xF7AB, - 0x9CDC, 0xF7AC, - 0x9CDD, 0xF7AD, - 0x9CDE, 0xC1DB, - 0x9CDF, 0xF7AE, - 0x9CE2, 0xF7AF, - 0x9E1F, 0xC4F1, - 0x9E20, 0xF0AF, - 0x9E21, 0xBCA6, - 0x9E22, 0xF0B0, - 0x9E23, 0xC3F9, - 0x9E25, 0xC5B8, - 0x9E26, 0xD1BB, - 0x9E28, 0xF0B1, - 0x9E29, 0xF0B2, - 0x9E2A, 0xF0B3, - 0x9E2B, 0xF0B4, - 0x9E2C, 0xF0B5, - 0x9E2D, 0xD1BC, - 0x9E2F, 0xD1EC, - 0x9E31, 0xF0B7, - 0x9E32, 0xF0B6, - 0x9E33, 0xD4A7, - 0x9E35, 0xCDD2, - 0x9E36, 0xF0B8, - 0x9E37, 0xF0BA, - 0x9E38, 0xF0B9, - 0x9E39, 0xF0BB, - 0x9E3A, 0xF0BC, - 0x9E3D, 0xB8EB, - 0x9E3E, 0xF0BD, - 0x9E3F, 0xBAE8, - 0x9E41, 0xF0BE, - 0x9E42, 0xF0BF, - 0x9E43, 0xBEE9, - 0x9E44, 0xF0C0, - 0x9E45, 0xB6EC, - 0x9E46, 0xF0C1, - 0x9E47, 0xF0C2, - 0x9E48, 0xF0C3, - 0x9E49, 0xF0C4, - 0x9E4A, 0xC8B5, - 0x9E4B, 0xF0C5, - 0x9E4C, 0xF0C6, - 0x9E4E, 0xF0C7, - 0x9E4F, 0xC5F4, - 0x9E51, 0xF0C8, - 0x9E55, 0xF0C9, - 0x9E57, 0xF0CA, - 0x9E58, 0xF7BD, - 0x9E5A, 0xF0CB, - 0x9E5B, 0xF0CC, - 0x9E5C, 0xF0CD, - 0x9E5E, 0xF0CE, - 0x9E63, 0xF0CF, - 0x9E64, 0xBAD7, - 0x9E66, 0xF0D0, - 0x9E67, 0xF0D1, - 0x9E68, 0xF0D2, - 0x9E69, 0xF0D3, - 0x9E6A, 0xF0D4, - 0x9E6B, 0xF0D5, - 0x9E6C, 0xF0D6, - 0x9E6D, 0xF0D8, - 0x9E70, 0xD3A5, - 0x9E71, 0xF0D7, - 0x9E73, 0xF0D9, - 0x9E7E, 0xF5BA, - 0x9E7F, 0xC2B9, - 0x9E82, 0xF7E4, - 0x9E87, 0xF7E5, - 0x9E88, 0xF7E6, - 0x9E8B, 0xF7E7, - 0x9E92, 0xF7E8, - 0x9E93, 0xC2B4, - 0x9E9D, 0xF7EA, - 0x9E9F, 0xF7EB, - 0x9EA6, 0xC2F3, - 0x9EB4, 0xF4F0, - 0x9EB8, 0xF4EF, - 0x9EBB, 0xC2E9, - 0x9EBD, 0xF7E1, - 0x9EBE, 0xF7E2, - 0x9EC4, 0xBBC6, - 0x9EC9, 0xD9E4, - 0x9ECD, 0xCAF2, - 0x9ECE, 0xC0E8, - 0x9ECF, 0xF0A4, - 0x9ED1, 0xBADA, - 0x9ED4, 0xC7AD, - 0x9ED8, 0xC4AC, - 0x9EDB, 0xF7EC, - 0x9EDC, 0xF7ED, - 0x9EDD, 0xF7EE, - 0x9EDF, 0xF7F0, - 0x9EE0, 0xF7EF, - 0x9EE2, 0xF7F1, - 0x9EE5, 0xF7F4, - 0x9EE7, 0xF7F3, - 0x9EE9, 0xF7F2, - 0x9EEA, 0xF7F5, - 0x9EEF, 0xF7F6, - 0x9EF9, 0xEDE9, - 0x9EFB, 0xEDEA, - 0x9EFC, 0xEDEB, - 0x9EFE, 0xF6BC, - 0x9F0B, 0xF6BD, - 0x9F0D, 0xF6BE, - 0x9F0E, 0xB6A6, - 0x9F10, 0xD8BE, - 0x9F13, 0xB9C4, - 0x9F17, 0xD8BB, - 0x9F19, 0xDCB1, - 0x9F20, 0xCAF3, - 0x9F22, 0xF7F7, - 0x9F2C, 0xF7F8, - 0x9F2F, 0xF7F9, - 0x9F37, 0xF7FB, - 0x9F39, 0xF7FA, - 0x9F3B, 0xB1C7, - 0x9F3D, 0xF7FC, - 0x9F3E, 0xF7FD, - 0x9F44, 0xF7FE, - 0x9F50, 0xC6EB, - 0x9F51, 0xECB4, - 0x9F7F, 0xB3DD, - 0x9F80, 0xF6B3, - 0x9F83, 0xF6B4, - 0x9F84, 0xC1E4, - 0x9F85, 0xF6B5, - 0x9F86, 0xF6B6, - 0x9F87, 0xF6B7, - 0x9F88, 0xF6B8, - 0x9F89, 0xF6B9, - 0x9F8A, 0xF6BA, - 0x9F8B, 0xC8A3, - 0x9F8C, 0xF6BB, - 0x9F99, 0xC1FA, - 0x9F9A, 0xB9A8, - 0x9F9B, 0xEDE8, - 0x9F9F, 0xB9EA, - 0x9FA0, 0xD9DF, - 0xFF01, 0xA3A1, - 0xFF02, 0xA3A2, - 0xFF03, 0xA3A3, - 0xFF04, 0xA1E7, - 0xFF05, 0xA3A5, - 0xFF06, 0xA3A6, - 0xFF07, 0xA3A7, - 0xFF08, 0xA3A8, - 0xFF09, 0xA3A9, - 0xFF0A, 0xA3AA, - 0xFF0B, 0xA3AB, - 0xFF0C, 0xA3AC, - 0xFF0D, 0xA3AD, - 0xFF0E, 0xA3AE, - 0xFF0F, 0xA3AF, - 0xFF10, 0xA3B0, - 0xFF11, 0xA3B1, - 0xFF12, 0xA3B2, - 0xFF13, 0xA3B3, - 0xFF14, 0xA3B4, - 0xFF15, 0xA3B5, - 0xFF16, 0xA3B6, - 0xFF17, 0xA3B7, - 0xFF18, 0xA3B8, - 0xFF19, 0xA3B9, - 0xFF1A, 0xA3BA, - 0xFF1B, 0xA3BB, - 0xFF1C, 0xA3BC, - 0xFF1D, 0xA3BD, - 0xFF1E, 0xA3BE, - 0xFF1F, 0xA3BF, - 0xFF20, 0xA3C0, - 0xFF21, 0xA3C1, - 0xFF22, 0xA3C2, - 0xFF23, 0xA3C3, - 0xFF24, 0xA3C4, - 0xFF25, 0xA3C5, - 0xFF26, 0xA3C6, - 0xFF27, 0xA3C7, - 0xFF28, 0xA3C8, - 0xFF29, 0xA3C9, - 0xFF2A, 0xA3CA, - 0xFF2B, 0xA3CB, - 0xFF2C, 0xA3CC, - 0xFF2D, 0xA3CD, - 0xFF2E, 0xA3CE, - 0xFF2F, 0xA3CF, - 0xFF30, 0xA3D0, - 0xFF31, 0xA3D1, - 0xFF32, 0xA3D2, - 0xFF33, 0xA3D3, - 0xFF34, 0xA3D4, - 0xFF35, 0xA3D5, - 0xFF36, 0xA3D6, - 0xFF37, 0xA3D7, - 0xFF38, 0xA3D8, - 0xFF39, 0xA3D9, - 0xFF3A, 0xA3DA, - 0xFF3B, 0xA3DB, - 0xFF3C, 0xA3DC, - 0xFF3D, 0xA3DD, - 0xFF3E, 0xA3DE, - 0xFF3F, 0xA3DF, - 0xFF40, 0xA3E0, - 0xFF41, 0xA3E1, - 0xFF42, 0xA3E2, - 0xFF43, 0xA3E3, - 0xFF44, 0xA3E4, - 0xFF45, 0xA3E5, - 0xFF46, 0xA3E6, - 0xFF47, 0xA3E7, - 0xFF48, 0xA3E8, - 0xFF49, 0xA3E9, - 0xFF4A, 0xA3EA, - 0xFF4B, 0xA3EB, - 0xFF4C, 0xA3EC, - 0xFF4D, 0xA3ED, - 0xFF4E, 0xA3EE, - 0xFF4F, 0xA3EF, - 0xFF50, 0xA3F0, - 0xFF51, 0xA3F1, - 0xFF52, 0xA3F2, - 0xFF53, 0xA3F3, - 0xFF54, 0xA3F4, - 0xFF55, 0xA3F5, - 0xFF56, 0xA3F6, - 0xFF57, 0xA3F7, - 0xFF58, 0xA3F8, - 0xFF59, 0xA3F9, - 0xFF5A, 0xA3FA, - 0xFF5B, 0xA3FB, - 0xFF5C, 0xA3FC, - 0xFF5D, 0xA3FD, - 0xFF5E, 0xA1AB, - 0xFFE0, 0xA1E9, - 0xFFE1, 0xA1EA, - 0xFFE3, 0xA3FE, - 0xFFE5, 0xA3A4 -}; diff --git a/3rdparty/zint-2.4.4/backend/gridmtx.c b/3rdparty/zint-2.4.4/backend/gridmtx.c deleted file mode 100644 index 47f904d..0000000 --- a/3rdparty/zint-2.4.4/backend/gridmtx.c +++ /dev/null @@ -1,1090 +0,0 @@ -/* gridmtx.c - Grid Matrix - - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* This file impliments Grid Matrix as specified in - AIM Global Document Number AIMD014 Rev. 1.63 Revised 9 Dec 2008 */ - -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "reedsol.h" -#include "gridmtx.h" -#include "gb2312.h" - -int number_lat(int gbdata[], int length, int position) -{ - /* Attempt to calculate the 'cost' of using numeric mode from a given position in number of bits */ - /* Also ensures that numeric mode is not selected when it cannot be used: for example in - a string which has "2.2.0" (cannot have more than one non-numeric character for each - block of three numeric characters) */ - int sp; - int numb = 0, nonum = 0, done; - int tally = 0; - - sp = position; - - do { - done = 0; - - if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { numb++; done = 1; } - switch(gbdata[sp]) { - case ' ': - case '+': - case '-': - case '.': - case ',': - nonum++; - done = 1; - } - if((sp + 1) < length) { - if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { - nonum++; - done = 1; - sp++; - } - } - - if(done == 0) { - tally += 80; - } else { - if(numb == 3) { - if(nonum == 0) { - tally += 10; - } - if(nonum == 1) { - tally += 20; - } - if(nonum > 1) { - tally += 80; - } - numb = 0; - nonum = 0; - } - } - - sp++; - } while ((sp < length) && (sp <= (position + 8))); - - if(numb == 0) { - tally += 80; - } - - if(numb > 1) { - if(nonum == 0) { - tally += 10; - } - if(nonum == 1) { - tally += 20; - } - if(nonum > 1) { - tally += 80; - } - } - - return tally; -} - -int seek_forward(int gbdata[], int length, int position, int current_mode) -{ - /* In complete contrast to the method recommended in Annex D of the ANSI standard this - code uses a look-ahead test in the same manner as Data Matrix. This decision was made - because the "official" algorithm does not provide clear methods for dealing with all - possible combinations of input data */ - - int number_count, byte_count, mixed_count, upper_count, lower_count, chinese_count; - int sp, best_mode, done; - int best_count, last = -1; - int debug = 0; - - if(gbdata[position] > 0xff) { return GM_CHINESE; } - - switch(current_mode) { - case GM_CHINESE: - number_count = 13; - byte_count = 13; - mixed_count = 13; - upper_count = 13; - lower_count = 13; - chinese_count = 0; - break; - case GM_NUMBER: - number_count = 0; - byte_count = 10; - mixed_count = 10; - upper_count = 10; - lower_count = 10; - chinese_count = 10; - break; - case GM_LOWER: - number_count = 5; - byte_count = 7; - mixed_count = 7; - upper_count = 5; - lower_count = 0; - chinese_count = 5; - break; - case GM_UPPER: - number_count = 5; - byte_count = 7; - mixed_count = 7; - upper_count = 0; - lower_count = 5; - chinese_count = 5; - break; - case GM_MIXED: - number_count = 10; - byte_count = 10; - mixed_count = 0; - upper_count = 10; - lower_count = 10; - chinese_count = 10; - break; - case GM_BYTE: - number_count = 4; - byte_count = 0; - mixed_count = 4; - upper_count = 4; - lower_count = 4; - chinese_count = 4; - default: /* Start of symbol */ - number_count = 4; - byte_count = 4; - mixed_count = 4; - upper_count = 4; - lower_count = 4; - chinese_count = 4; - } - - for(sp = position; (sp < length) && (sp <= (position + 8)); sp++) { - - done = 0; - - if(gbdata[sp] >= 0xff) { - byte_count += 17; - mixed_count += 23; - upper_count += 18; - lower_count += 18; - chinese_count += 13; - done = 1; - } - - if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { - byte_count += 8; - mixed_count += 6; - upper_count += 10; - lower_count += 5; - chinese_count += 13; - done = 1; - } - - if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { - byte_count += 8; - mixed_count += 6; - upper_count += 5; - lower_count += 10; - chinese_count += 13; - done = 1; - } - - if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { - byte_count += 8; - mixed_count += 6; - upper_count += 8; - lower_count += 8; - chinese_count += 13; - done = 1; - } - - if(gbdata[sp] == ' ') { - byte_count += 8; - mixed_count += 6; - upper_count += 5; - lower_count += 5; - chinese_count += 13; - done = 1; - } - - if(done == 0) { - /* Control character */ - byte_count += 8; - mixed_count += 16; - upper_count += 13; - lower_count += 13; - chinese_count += 13; - } - - if(gbdata[sp] >= 0x7f) { - mixed_count += 20; - upper_count += 20; - lower_count += 20; - } - } - - /* Adjust for */ - for(sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { - if((gbdata[sp] == 0x13) && (gbdata[sp] == 0x10)) { - chinese_count -= 13; - } - } - - /* Adjust for double digits */ - for(sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { - if(sp != last) { - if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { - chinese_count -= 13; - last = sp + 1; - } - } - } - - /* Numeric mode is more complex */ - number_count += number_lat(gbdata, length, position); - - if(debug) { printf("C %d / B %d / M %d / U %d / L %d / N %d\n", chinese_count, byte_count, mixed_count, upper_count, lower_count, number_count); } - - best_count = chinese_count; - best_mode = GM_CHINESE; - - if(byte_count <= best_count) { - best_count = byte_count; - best_mode = GM_BYTE; - } - - if(mixed_count <= best_count) { - best_count = mixed_count; - best_mode = GM_MIXED; - } - - if(upper_count <= best_count) { - best_count = upper_count; - best_mode = GM_UPPER; - } - - if(lower_count <= best_count) { - best_count = lower_count; - best_mode = GM_LOWER; - } - - if(number_count <= best_count) { - best_count = number_count; - best_mode = GM_NUMBER; - } - - return best_mode; -} - -void add_byte_count(char binary[], int byte_count_posn, int byte_count) -{ - /* Add the length indicator for byte encoded blocks */ - if(byte_count & 0x100) { binary[byte_count_posn] = '0'; } else { binary[byte_count_posn] = '1'; } - if(byte_count & 0x80) { binary[byte_count_posn + 1] = '0'; } else { binary[byte_count_posn + 1] = '1'; } - if(byte_count & 0x40) { binary[byte_count_posn + 2] = '0'; } else { binary[byte_count_posn + 2] = '1'; } - if(byte_count & 0x20) { binary[byte_count_posn + 3] = '0'; } else { binary[byte_count_posn + 3] = '1'; } - if(byte_count & 0x10) { binary[byte_count_posn + 4] = '0'; } else { binary[byte_count_posn + 4] = '1'; } - if(byte_count & 0x08) { binary[byte_count_posn + 5] = '0'; } else { binary[byte_count_posn + 5] = '1'; } - if(byte_count & 0x04) { binary[byte_count_posn + 6] = '0'; } else { binary[byte_count_posn + 6] = '1'; } - if(byte_count & 0x02) { binary[byte_count_posn + 7] = '0'; } else { binary[byte_count_posn + 7] = '1'; } - if(byte_count & 0x01) { binary[byte_count_posn + 8] = '0'; } else { binary[byte_count_posn + 8] = '1'; } -} - -void add_shift_char(char binary[], int shifty) -{ - /* Add a control character to the data stream */ - int i, debug = 0; - int glyph = 0; - - for(i = 0; i < 64; i++) { - if(shift_set[i] == shifty) { - glyph = i; - } - } - - if(debug) { printf("SHIFT [%d] ", glyph); } - - if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } -} - -int gm_encode(int gbdata[], int length, char binary[], int reader) -{ - /* Create a binary stream representation of the input data. - 7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters, - Mixed numerals and latters, Control characters and 8-bit binary data */ - int sp, current_mode, next_mode, last_mode, glyph = 0; - int c1, c2, done; - int p = 0, ppos; - int numbuf[3], punt = 0; - int number_pad_posn, debug = 0; - int byte_count_posn = 0, byte_count = 0; - int shift, i; - - strcpy(binary, ""); - - sp = 0; - current_mode = 0; - last_mode = 0; - number_pad_posn = 0; - - if(reader) { - concat(binary, "1010"); /* FNC3 - Reader Initialisation */ - } - - do { - next_mode = seek_forward(gbdata, length, sp, current_mode); - - if(next_mode != current_mode) { - switch(current_mode) { - case 0: - switch(next_mode) { - case GM_CHINESE: concat(binary, "0001"); break; - case GM_NUMBER: concat(binary, "0010"); break; - case GM_LOWER: concat(binary, "0011"); break; - case GM_UPPER: concat(binary, "0100"); break; - case GM_MIXED: concat(binary, "0101"); break; - case GM_BYTE: concat(binary, "0111"); break; - } - break; - case GM_CHINESE: - switch(next_mode) { - case GM_NUMBER: concat(binary, "1111111100001"); break; // 8161 - case GM_LOWER: concat(binary, "1111111100010"); break; // 8162 - case GM_UPPER: concat(binary, "1111111100011"); break; // 8163 - case GM_MIXED: concat(binary, "1111111100100"); break; // 8164 - case GM_BYTE: concat(binary, "1111111100101"); break; // 8165 - } - break; - case GM_NUMBER: - /* add numeric block padding value */ - switch(p) { - case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits - case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit - case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits - } - switch(next_mode) { - case GM_CHINESE: concat(binary, "1111111011"); break; // 1019 - case GM_LOWER: concat(binary, "1111111100"); break; // 1020 - case GM_UPPER: concat(binary, "1111111101"); break; // 1021 - case GM_MIXED: concat(binary, "1111111110"); break; // 1022 - case GM_BYTE: concat(binary, "1111111111"); break; // 1023 - } - break; - case GM_LOWER: - case GM_UPPER: - switch(next_mode) { - case GM_CHINESE: concat(binary, "11100"); break; // 28 - case GM_NUMBER: concat(binary, "11101"); break; // 29 - case GM_LOWER: - case GM_UPPER: concat(binary, "11110"); break; // 30 - case GM_MIXED: concat(binary, "1111100"); break; // 124 - case GM_BYTE: concat(binary, "1111110"); break; // 126 - } - break; - case GM_MIXED: - switch(next_mode) { - case GM_CHINESE: concat(binary, "1111110001"); break; // 1009 - case GM_NUMBER: concat(binary, "1111110010"); break; // 1010 - case GM_LOWER: concat(binary, "1111110011"); break; // 1011 - case GM_UPPER: concat(binary, "1111110100"); break; // 1012 - case GM_BYTE: concat(binary, "1111110111"); break; // 1015 - } - break; - case GM_BYTE: - /* add byte block length indicator */ - add_byte_count(binary, byte_count_posn, byte_count); - byte_count = 0; - switch(next_mode) { - case GM_CHINESE: concat(binary, "0001"); break; // 1 - case GM_NUMBER: concat(binary, "0010"); break; // 2 - case GM_LOWER: concat(binary, "0011"); break; // 3 - case GM_UPPER: concat(binary, "0100"); break; // 4 - case GM_MIXED: concat(binary, "0101"); break; // 5 - } - break; - } - if(debug) { - switch(next_mode) { - case GM_CHINESE: printf("CHIN "); break; - case GM_NUMBER: printf("NUMB "); break; - case GM_LOWER: printf("LOWR "); break; - case GM_UPPER: printf("UPPR "); break; - case GM_MIXED: printf("MIXD "); break; - case GM_BYTE: printf("BYTE "); break; - } - } - } - last_mode = current_mode; - current_mode = next_mode; - - switch(current_mode) { - case GM_CHINESE: - done = 0; - if(gbdata[sp] > 0xff) { - /* GB2312 character */ - c1 = (gbdata[sp] & 0xff00) >> 8; - c2 = gbdata[sp] & 0xff; - - if((c1 >= 0xa0) && (c1 <= 0xa9)) { - glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0); - } - if((c1 >= 0xb0) && (c1 <= 0xf7)) { - glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2 - 0xa0); - } - done = 1; - } - if(!(done)) { - if(sp != (length - 1)) { - if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { - /* End of Line */ - glyph = 7776; - sp++; - } - done = 1; - } - } - if(!(done)) { - if(sp != (length - 1)) { - if(((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && - ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { - /* Two digits */ - glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0'); - sp++; - } - } - } - if(!(done)) { - /* Byte value */ - glyph = 7777 + gbdata[sp]; - } - - if(debug) { printf("[%d] ", glyph); } - - if(glyph & 0x1000) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x800) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x400) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - sp++; - break; - - case GM_NUMBER: - if(last_mode != current_mode) { - /* Reserve a space for numeric digit padding value (2 bits) */ - number_pad_posn = strlen(binary); - concat(binary, "XX"); - } - p = 0; - ppos = -1; - - /* Numeric compression can also include certain combinations of - non-numeric character */ - - numbuf[0] = '0'; - numbuf[1] = '0'; - numbuf[2] = '0'; - do { - if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { - numbuf[p] = gbdata[sp]; - sp++; - p++; - } - switch(gbdata[sp]) { - case ' ': - case '+': - case '-': - case '.': - case ',': - punt = gbdata[sp]; - sp++; - ppos = p; - break; - } - if(sp < (length - 1)) { - if((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { - /* */ - punt = gbdata[sp]; - sp += 2; - ppos = p; - } - } - } while ((p < 3) && (sp < length)); - - if(ppos != -1) { - switch(punt) { - case ' ': glyph = 0; break; - case '+': glyph = 3; break; - case '-': glyph = 6; break; - case '.': glyph = 9; break; - case ',': glyph = 12; break; - case 0x13: glyph = 15; break; - } - glyph += ppos; - glyph += 1000; - - if(debug) { printf("[%d] ", glyph); } - - if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - } - - glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0'); - if(debug) { printf("[%d] ", glyph); } - - if(glyph & 0x200) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x100) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - break; - - case GM_BYTE: - if(last_mode != current_mode) { - /* Reserve space for byte block length indicator (9 bits) */ - byte_count_posn = strlen(binary); - concat(binary, "LLLLLLLLL"); - } - if(byte_count == 512) { - /* Maximum byte block size is 512 bytes. If longer is needed then start a new block */ - add_byte_count(binary, byte_count_posn, byte_count); - concat(binary, "0111"); - byte_count_posn = strlen(binary); - concat(binary, "LLLLLLLLL"); - byte_count = 0; - } - - glyph = gbdata[sp]; - if(debug) { printf("[%d] ", glyph); } - if(glyph & 0x80) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x40) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - sp++; - byte_count++; - break; - - case GM_MIXED: - shift = 1; - if((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { shift = 0; } - if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; } - if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; } - if(gbdata[sp] == ' ') { shift = 0; } - - if(shift == 0) { - /* Mixed Mode character */ - glyph = posn(EUROPIUM, gbdata[sp]); - if(debug) { printf("[%d] ", glyph); } - - if(glyph & 0x20) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - } else { - /* Shift Mode character */ - concat(binary, "1111110110"); /* 1014 - shift indicator */ - add_shift_char(binary, gbdata[sp]); - } - - sp++; - break; - - case GM_UPPER: - shift = 1; - if((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { shift = 0; } - if(gbdata[sp] == ' ') { shift = 0; } - - if(shift == 0) { - /* Upper Case character */ - glyph = posn("ABCDEFGHIJKLMNOPQRSTUVWXYZ ", gbdata[sp]); - if(debug) { printf("[%d] ", glyph); } - - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - } else { - /* Shift Mode character */ - concat(binary, "1111101"); /* 127 - shift indicator */ - add_shift_char(binary, gbdata[sp]); - } - - sp++; - break; - - case GM_LOWER: - shift = 1; - if((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { shift = 0; } - if(gbdata[sp] == ' ') { shift = 0; } - - if(shift == 0) { - /* Lower Case character */ - glyph = posn("abcdefghijklmnopqrstuvwxyz ", gbdata[sp]); - if(debug) { printf("[%d] ", glyph); } - - if(glyph & 0x10) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x08) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x04) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x02) { concat(binary, "1"); } else { concat(binary, "0"); } - if(glyph & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } - } else { - /* Shift Mode character */ - concat(binary, "1111101"); /* 127 - shift indicator */ - add_shift_char(binary, gbdata[sp]); - } - - sp++; - break; - } - if(strlen(binary) > 9191) { - return ERROR_TOO_LONG; - } - - } while(sp < length); - - if(current_mode == GM_NUMBER) { - /* add numeric block padding value */ - switch(p) { - case 1: binary[number_pad_posn] = '1'; binary[number_pad_posn + 1] = '0'; break; // 2 pad digits - case 2: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '1'; break; // 1 pad digit - case 3: binary[number_pad_posn] = '0'; binary[number_pad_posn + 1] = '0'; break; // 0 pad digits - } - } - - if(current_mode == GM_BYTE) { - /* Add byte block length indicator */ - add_byte_count(binary, byte_count_posn, byte_count); - } - - /* Add "end of data" character */ - switch(current_mode) { - case GM_CHINESE: concat(binary, "1111111100000"); break; // 8160 - case GM_NUMBER: concat(binary, "1111111010"); break; // 1018 - case GM_LOWER: - case GM_UPPER: concat(binary, "11011"); break; // 27 - case GM_MIXED: concat(binary, "1111110000"); break; // 1008 - case GM_BYTE: concat(binary, "0000"); break; // 0 - } - - /* Add padding bits if required */ - p = 7 - (strlen(binary) % 7); - if(p == 7) { p = 0; } - for(i = 0; i < p; i++) { - concat(binary, "0"); - } - - if(strlen(binary) > 9191) { - return ERROR_TOO_LONG; - } - return 0; -} - -void gm_add_ecc(char binary[], int data_posn, int layers, int ecc_level, int word[]) -{ - int total_cw, data_cw, i, j, wp; - int n1, b1, n2, b2, e1, b3, e2; - int block_size, data_size, ecc_size, toggle; - int data[1320], block[130]; - unsigned char data_block[115], ecc_block[70]; - - total_cw = gm_total_cw[(layers - 1)]; - data_cw = gm_data_codewords[((layers - 1) * 5) + (ecc_level - 1)]; - - for(i = 0; i < 1320; i++) { - data[i] = 0; - } - - /* Convert from binary sream to 7-bit codewords */ - for(i = 0; i < data_posn; i++) { - if(binary[i * 7] == '1') { data[i] += 0x40; } - if(binary[(i * 7) + 1] == '1') { data[i] += 0x20; } - if(binary[(i * 7) + 2] == '1') { data[i] += 0x10; } - if(binary[(i * 7) + 3] == '1') { data[i] += 0x08; } - if(binary[(i * 7) + 4] == '1') { data[i] += 0x04; } - if(binary[(i * 7) + 5] == '1') { data[i] += 0x02; } - if(binary[(i * 7) + 6] == '1') { data[i] += 0x01; } - } - - /* Add padding codewords */ - data[data_posn] = 0x00; - for(i = (data_posn + 1); i < data_cw; i++) { - if(i & 1) { - data[i] = 0x7e; - toggle = 1; - } else { - data[i] = 0x00; - toggle = 0; - } - } - - /* Get block sizes */ - n1 = gm_n1[(layers - 1)]; - b1 = gm_b1[(layers - 1)]; - n2 = n1 - 1; - b2 = gm_b2[(layers - 1)]; - e1 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4)]; - b3 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 1]; - e2 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 2]; - - /* Split the data into blocks */ - wp = 0; - for(i = 0; i < (b1 + b2); i++) { - if(i < b1) { block_size = n1; } else { block_size = n2; } - if(i < b3) { ecc_size = e1; } else { ecc_size = e2; } - data_size = block_size - ecc_size; - - /* printf("block %d/%d: data %d / ecc %d\n", i + 1, (b1 + b2), data_size, ecc_size);*/ - - for(j = 0; j < data_size; j++) { - data_block[j] = data[wp]; - wp++; - } - - /* Calculate ECC data for this block */ - rs_init_gf(0x89); - rs_init_code(ecc_size, 1); - rs_encode(data_size, data_block, ecc_block); - rs_free(); - - /* Correct error correction data but in reverse order */ - for(j = 0; j < data_size; j++) { - block[j] = data_block[j]; - } - for(j = 0; j < ecc_size; j++) { - block[(j + data_size)] = ecc_block[ecc_size - j - 1]; - } - - for(j = 0; j < n2; j++) { - word[((b1 + b2) * j) + i] = block[j]; - } - if(block_size == n1) { - word[((b1 + b2) * (n1 - 1)) + i] = block[(n1 - 1)]; - } - } -} - -void place_macromodule(char grid[], int x, int y, int word1, int word2, int size) -{ - int i, j; - - i = (x * 6) + 1; - j = (y * 6) + 1; - - if(word2 & 0x40) { grid[(j * size) + i + 2] = '1'; } - if(word2 & 0x20) { grid[(j * size) + i + 3] = '1'; } - if(word2 & 0x10) { grid[((j + 1) * size) + i] = '1'; } - if(word2 & 0x08) { grid[((j + 1) * size) + i + 1] = '1'; } - if(word2 & 0x04) { grid[((j + 1) * size) + i + 2] = '1'; } - if(word2 & 0x02) { grid[((j + 1) * size) + i + 3] = '1'; } - if(word2 & 0x01) { grid[((j + 2) * size) + i] = '1'; } - if(word1 & 0x40) { grid[((j + 2) * size) + i + 1] = '1'; } - if(word1 & 0x20) { grid[((j + 2) * size) + i + 2] = '1'; } - if(word1 & 0x10) { grid[((j + 2) * size) + i + 3] = '1'; } - if(word1 & 0x08) { grid[((j + 3) * size) + i] = '1'; } - if(word1 & 0x04) { grid[((j + 3) * size) + i + 1] = '1'; } - if(word1 & 0x02) { grid[((j + 3) * size) + i + 2] = '1'; } - if(word1 & 0x01) { grid[((j + 3) * size) + i + 3] = '1'; } -} - -void place_data_in_grid(int word[], char grid[], int modules, int size) -{ - int x, y, macromodule, offset; - - offset = 13 - ((modules - 1) / 2); - for(y = 0; y < modules; y++) { - for(x = 0; x < modules; x++) { - macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)]; - place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size); - } - } -} - -void place_layer_id(char* grid, int size, int layers, int modules, int ecc_level) -{ - /* Place the layer ID into each macromodule */ - - int i, j, layer, start, stop; - -#ifndef _MSC_VER - int layerid[layers + 1]; - int id[modules * modules]; -#else - int* layerid = (int *)_alloca((layers + 1) * sizeof(int)); - int* id = (int *)_alloca((modules * modules) * sizeof(int)); -#endif - - /* Calculate Layer IDs */ - for(i = 0; i <= layers; i++) { - if(ecc_level == 1) { - layerid[i] = 3 - (i % 4); - } else { - layerid[i] = (i + 5 - ecc_level) % 4; - } - } - - for(i = 0; i < modules; i++) { - for(j = 0; j < modules; j++) { - id[(i * modules) + j] = 0; - } - } - - /* Calculate which value goes in each macromodule */ - start = modules / 2; - stop = modules / 2; - for(layer = 0; layer <= layers; layer++) { - for(i = start; i <= stop; i++) { - id[(start * modules) + i] = layerid[layer]; - id[(i * modules) + start] = layerid[layer]; - id[((modules - start - 1) * modules) + i] = layerid[layer]; - id[(i * modules) + (modules - start - 1)] = layerid[layer]; - } - start--; - stop++; - } - - /* Place the data in the grid */ - for(i = 0; i < modules; i++) { - for(j = 0; j < modules; j++) { - if(id[(i * modules) + j] & 0x02) { - grid[(((i * 6) + 1) * size) + (j * 6) + 1] = '1'; - } - if(id[(i * modules) + j] & 0x01) { - grid[(((i * 6) + 1) * size) + (j * 6) + 2] = '1'; - } - } - } -} - -int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int size, modules, dark, error_number; - int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level; - int x, y, i, j, glyph; - char binary[9300]; - int data_cw, input_latch = 0; - int word[1460], data_max, reader = 0; - -#ifndef _MSC_VER - int utfdata[length + 1]; - int gbdata[length + 1]; -#else - int* utfdata = (int *)_alloca((length + 1) * sizeof(int)); - int* gbdata = (int *)_alloca((length + 1) * sizeof(int)); - char* grid; -#endif - - for(i = 0; i < 1460; i++) { - word[i] = 0; - } - - switch(symbol->input_mode) { - case DATA_MODE: - for(i = 0; i < length; i++) { - gbdata[i] = (int)source[i]; - } - break; - default: - /* Convert Unicode input to GB-2312 */ - error_number = utf8toutf16(symbol, source, utfdata, &length); - if(error_number != 0) { return error_number; } - - for(i = 0; i < length; i++) { - if(utfdata[i] <= 0xff) { - gbdata[i] = utfdata[i]; - } else { - j = 0; - glyph = 0; - do { - if(gb2312_lookup[j * 2] == utfdata[i]) { - glyph = gb2312_lookup[(j * 2) + 1]; - } - j++; - } while ((j < 7445) && (glyph == 0)); - if(glyph == 0) { - strcpy(symbol->errtxt, "Invalid character in input data"); - return ERROR_INVALID_DATA1; - } - gbdata[i] = glyph; - } - } - break; - } - - if(symbol->output_options & READER_INIT) reader = 1; - - error_number = gm_encode(gbdata, length, binary, reader); - if(error_number != 0) { - strcpy(symbol->errtxt, "Input data too long"); - return error_number; - } - - /* Determine the size of the symbol */ - data_cw = strlen(binary) / 7; - - auto_layers = 13; - for(i = 12; i > 0; i--) { - if(gm_recommend_cw[(i - 1)] >= data_cw) { auto_layers = i; } - } - min_layers = 13; - for(i = 12; i > 0; i--) { - if(gm_max_cw[(i - 1)] >= data_cw) { min_layers = i; } - } - layers = auto_layers; - auto_ecc_level = 3; - if(layers == 1) { auto_ecc_level = 5; } - if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } - min_ecc_level = 1; - if(layers == 1) { min_ecc_level = 4; } - if((layers == 2) || (layers == 3)) { min_ecc_level = 2; } - ecc_level = auto_ecc_level; - - if((symbol->option_2 >= 1) && (symbol->option_2 <= 13)) { - input_latch = 1; - if(symbol->option_2 > min_layers) { - layers = symbol->option_2; - } else { - layers = min_layers; - } - } - - if(input_latch == 1) { - auto_ecc_level = 3; - if(layers == 1) { auto_ecc_level = 5; } - if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } - ecc_level = auto_ecc_level; - if(data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { - layers++; - } - } - - if(input_latch == 0) { - if((symbol->option_1 >= 1) && (symbol->option_1 <= 5)) { - if(symbol->option_1 > min_ecc_level) { - ecc_level = symbol->option_1; - } else { - ecc_level = min_ecc_level; - } - } - if(data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { - do { - layers++; - } while ((data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) && (layers <= 13)); - } - } - - data_max = 1313; - switch(ecc_level) { - case 2: data_max = 1167; break; - case 3: data_max = 1021; break; - case 4: data_max = 875; break; - case 5: data_max = 729; break; - } - - if(data_cw > data_max) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - - gm_add_ecc(binary, data_cw, layers, ecc_level, word); - size = 6 + (layers * 12); - modules = 1 + (layers * 2); - -#ifndef _MSC_VER - char grid[size * size]; -#else - grid = (char *)_alloca((size * size) * sizeof(char)); -#endif - - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - grid[(y * size) + x] = '0'; - } - } - - place_data_in_grid(word, grid, modules, size); - place_layer_id(grid, size, layers, modules, ecc_level); - - /* Add macromodule frames */ - for(x = 0; x < modules; x++) { - dark = 1 - (x & 1); - for(y = 0; y < modules; y++) { - if(dark == 1) { - for(i = 0; i < 5; i++) { - grid[((y * 6) * size) + (x * 6) + i] = '1'; - grid[(((y * 6) + 5) * size) + (x * 6) + i] = '1'; - grid[(((y * 6) + i) * size) + (x * 6)] = '1'; - grid[(((y * 6) + i) * size) + (x * 6) + 5] = '1'; - } - grid[(((y * 6) + 5) * size) + (x * 6) + 5] = '1'; - dark = 0; - } else { - dark = 1; - } - } - } - - /* Copy values to symbol */ - symbol->width = size; - symbol->rows = size; - - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - if(grid[(y * size) + x] == '1') { - set_module(symbol, y, x); - } - } - symbol->row_height[x] = 1; - } - - return 0; -} diff --git a/3rdparty/zint-2.4.4/backend/gridmtx.h b/3rdparty/zint-2.4.4/backend/gridmtx.h deleted file mode 100644 index ba684a1..0000000 --- a/3rdparty/zint-2.4.4/backend/gridmtx.h +++ /dev/null @@ -1,160 +0,0 @@ -/* gridmtx.h - definitions for Grid Matrix - - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define GM_NUMBER 1 -#define GM_LOWER 2 -#define GM_UPPER 3 -#define GM_MIXED 4 -#define GM_CONTROL 5 -#define GM_BYTE 6 -#define GM_CHINESE 7 - -#define EUROPIUM "0123456789ABCDEFGHIJKLMOPRSTUVWXYZabcdefghijklmnopqrstuvwxyz " - -static char shift_set[] = { - /* From Table 7 - Encoding of control characters */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* NULL -> SI */ - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* DLE -> US */ - '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', - ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' -}; - -static int gm_recommend_cw[] = { 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 }; -static int gm_max_cw[] = { 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313 }; -static int gm_total_cw[] = { 18, 50, 98, 162, 242, 338, 450, 578, 722, 882, 1058, 1250, 1458 }; - -static int gm_data_codewords[] = { - 0, 15, 13, 11, 9, - 45, 40, 35, 30, 25, - 89, 79, 69, 59, 49, - 146, 130, 114, 98, 81, - 218, 194, 170, 146, 121, - 305, 271, 237, 203, 169, - 405, 360, 315, 270, 225, - 521, 463, 405, 347, 289, - 650, 578, 506, 434, 361, - 794, 706, 618, 530, 441, - 953, 847, 741, 635, 529, - 1125, 1000, 875, 750, 625, - 1313, 1167, 1021, 875, 729 -}; - -static int gm_n1[] = { 18, 50, 98, 81, 121, 113, 113, 116, 121, 126, 118, 125, 122 }; -static int gm_b1[] = { 1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6 }; -static int gm_b2[] = { 0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6 }; - -static int gm_ebeb[] = { - /* E1 B3 E2 B4 */ - 0, 0, 0, 0, // version 1 - 3, 1, 0, 0, - 5, 1, 0, 0, - 7, 1, 0, 0, - 9, 1, 0, 0, - 5, 1, 0, 0, // version 2 - 10, 1, 0, 0, - 15, 1, 0, 0, - 20, 1, 0, 0, - 25, 1, 0, 0, - 9, 1, 0, 0, // version 3 - 19, 1, 0, 0, - 29, 1, 0, 0, - 39, 1, 0, 0, - 49, 1, 0, 0, - 8, 2, 0, 0, // version 4 - 16, 2, 0, 0, - 24, 2, 0, 0, - 32, 2, 0, 0, - 41, 1, 10, 1, - 12, 2, 0, 0, // version 5 - 24, 2, 0, 0, - 36, 2, 0, 0, - 48, 2, 0, 0, - 61, 1, 60, 1, - 11, 3, 0, 0, // version 6 - 23, 1, 22, 2, - 34, 2, 33, 1, - 45, 3, 0, 0, - 57, 1, 56, 2, - 12, 1, 11, 3, // version 7 - 23, 2, 22, 2, - 34, 3, 33, 1, - 45, 4, 0, 0, - 57, 1, 56, 3, - 12, 2, 11, 3, // version 8 - 23, 5, 0, 0, - 35, 3, 34, 2, - 47, 1, 46, 4, - 58, 4, 57, 1, - 12, 6, 0, 0, // version 9 - 24, 6, 0, 0, - 36, 6, 0, 0, - 48, 6, 0, 0, - 61, 1, 60, 5, - 13, 4, 12, 3, // version 10 - 26, 1, 25, 6, - 38, 5, 37, 2, - 51, 2, 50, 5, - 63, 7, 0, 0, - 12, 6, 11, 3, // version 11 - 24, 4, 23, 5, - 36, 2, 35, 7, - 47, 9, 0, 0, - 59, 7, 58, 2, - 13, 5, 12, 5, // version 12 - 25, 10, 0, 0, - 38, 5, 37, 5, - 50, 10, 0, 0, - 63, 5, 62, 5, - 13, 1, 12, 11, //version 13 - 25, 3, 24, 9, - 37, 5, 36, 7, - 49, 7, 48, 5, - 61, 9, 60, 3 -}; - -static int gm_macro_matrix[] = { - 728,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650, - 727,624,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,651, - 726,623,528,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,553,652, - 725,622,527,440,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,463,554,653, - 724,621,526,439,360,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,381,464,555,654, - 723,620,525,438,359,288,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,307,382,465,556,655, - 722,619,524,437,358,287,224,169,170,171,172,173,174,175,176,177,178,179,180,181,182,241,308,383,466,557,656, - 721,618,523,436,357,286,223,168,121,122,123,124,125,126,127,128,129,130,131,132,183,242,309,384,467,558,657, - 720,617,522,435,356,285,222,167,120,81,82,83,84,85,86,87,88,89,90,133,184,243,310,385,468,559,658, - 719,616,521,434,355,284,221,166,119,80,49,50,51,52,53,54,55,56,91,134,185,244,311,386,469,560,659, - 718,615,520,433,354,283,220,165,118,79,48,25,26,27,28,29,30,57,92,135,186,245,312,387,470,561,660, - 717,614,519,432,353,282,219,164,117,78,47,24,9,10,11,12,31,58,93,136,187,246,313,388,471,562,661, - 716,613,518,431,352,281,218,163,116,77,46,23,8,1,2,13,32,59,94,137,188,247,314,389,472,563,662, - 715,612,517,430,351,280,217,162,115,76,45,22,7,0,3,14,33,60,95,138,189,248,315,390,473,564,663, - 714,611,516,429,350,279,216,161,114,75,44,21,6,5,4,15,34,61,96,139,190,249,316,391,474,565,664, - 713,610,515,428,349,278,215,160,113,74,43,20,19,18,17,16,35,62,97,140,191,250,317,392,475,566,665, - 712,609,514,427,348,277,214,159,112,73,42,41,40,39,38,37,36,63,98,141,192,251,318,393,476,567,666, - 711,608,513,426,347,276,213,158,111,72,71,70,69,68,67,66,65,64,99,142,193,252,319,394,477,568,667, - 710,607,512,425,346,275,212,157,110,109,108,107,106,105,104,103,102,101,100,143,194,253,320,395,478,569,668, - 709,606,511,424,345,274,211,156,155,154,153,152,151,150,149,148,147,146,145,144,195,254,321,396,479,570,669, - 708,605,510,423,344,273,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,255,322,397,480,571,670, - 707,604,509,422,343,272,271,270,269,268,267,266,265,264,263,262,261,260,259,258,257,256,323,398,481,572,671, - 706,603,508,421,342,341,340,339,338,337,336,335,334,333,332,331,330,329,328,327,326,325,324,399,482,573,672, - 705,602,507,420,419,418,417,416,415,414,413,412,411,410,409,408,407,406,405,404,403,402,401,400,483,574,673, - 704,601,506,505,504,503,502,501,500,499,498,497,496,495,494,493,492,491,490,489,488,487,486,485,484,575,674, - 703,600,599,598,597,596,595,594,593,592,591,590,589,588,587,586,585,584,583,582,581,580,579,578,577,576,675, - 702,701,700,699,698,697,696,695,694,693,692,691,690,689,688,687,686,685,684,683,682,681,680,679,678,677,676, -}; diff --git a/3rdparty/zint-2.4.4/backend/gs1.c b/3rdparty/zint-2.4.4/backend/gs1.c deleted file mode 100644 index 45e14dd..0000000 --- a/3rdparty/zint-2.4.4/backend/gs1.c +++ /dev/null @@ -1,311 +0,0 @@ -/* gs1.c - Verifies GS1 data */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "gs1.h" - -/* This code does some checks on the integrity of GS1 data. It is not intended - to be bulletproof, nor does it report very accurately what problem was found - or where, but should prevent some of the more common encoding errors */ - -void itostr(char ai_string[], int ai_value) -{ - int thou, hund, ten, unit; - char temp[2]; - - strcpy(ai_string, "("); - thou = ai_value / 1000; - hund = (ai_value - (1000 * thou)) / 100; - ten = (ai_value - ((1000 * thou) + (100 * hund))) / 10; - unit = ai_value - ((1000 * thou) + (100 * hund) + (10 * ten)); - - temp[1] = '\0'; - if(ai_value >= 1000) { temp[0] = itoc(thou); concat(ai_string, temp); } - if(ai_value >= 100) { temp[0] = itoc(hund); concat(ai_string, temp); } - temp[0] = itoc(ten); - concat(ai_string, temp); - temp[0] = itoc(unit); - concat(ai_string, temp); - concat(ai_string, ")"); -} - -int gs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char reduced[]) -{ - int i, j, last_ai, ai_latch; - char ai_string[6]; - int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length; - int ai_value[100], ai_location[100], ai_count, data_location[100], data_length[100]; - int error_latch; - - /* Detect extended ASCII characters */ - for(i = 0; i < (int)src_len; i++) { - if(source[i] >=128) { - strcpy(symbol->errtxt, "Extended ASCII characters are not supported by GS1"); - return ERROR_INVALID_DATA1; - } - if(source[i] < 32) { - strcpy(symbol->errtxt, "Control characters are not supported by GS1"); - return ERROR_INVALID_DATA1; - } - } - - if(source[0] != '[') { - strcpy(symbol->errtxt, "Data does not start with an AI"); - return ERROR_INVALID_DATA1; - } - - /* Check the position of the brackets */ - bracket_level = 0; - max_bracket_level = 0; - ai_length = 0; - max_ai_length = 0; - min_ai_length = 5; - j = 0; - ai_latch = 0; - for(i = 0; i < (int)src_len; i++) { - ai_length += j; - if(((j == 1) && (source[i] != ']')) && ((source[i] < '0') || (source[i] > '9'))) { ai_latch = 1; } - if(source[i] == '[') { bracket_level++; j = 1; } - if(source[i] == ']') { - bracket_level--; - if(ai_length < min_ai_length) { min_ai_length = ai_length; } - j = 0; - ai_length = 0; - } - if(bracket_level > max_bracket_level) { max_bracket_level = bracket_level; } - if(ai_length > max_ai_length) { max_ai_length = ai_length; } - } - min_ai_length--; - - if(bracket_level != 0) { - /* Not all brackets are closed */ - strcpy(symbol->errtxt, "Malformed AI in input data (brackets don\'t match)"); - return ERROR_INVALID_DATA1; - } - - if(max_bracket_level > 1) { - /* Nested brackets */ - strcpy(symbol->errtxt, "Found nested brackets in input data"); - return ERROR_INVALID_DATA1; - } - - if(max_ai_length > 4) { - /* AI is too long */ - strcpy(symbol->errtxt, "Invalid AI in input data (AI too long)"); - return ERROR_INVALID_DATA1; - } - - if(min_ai_length <= 1) { - /* AI is too short */ - strcpy(symbol->errtxt, "Invalid AI in input data (AI too short)"); - return ERROR_INVALID_DATA1; - } - - if(ai_latch == 1) { - /* Non-numeric data in AI */ - strcpy(symbol->errtxt, "Invalid AI in input data (non-numeric characters in AI)"); - return ERROR_INVALID_DATA1; - } - - ai_count = 0; - for(i = 1; i < (int)src_len; i++) { - if(source[i - 1] == '[') { - ai_location[ai_count] = i; - j = 0; - do { - ai_string[j] = source[i + j]; - j++; - } while (ai_string[j - 1] != ']'); - ai_string[j - 1] = '\0'; - ai_value[ai_count] = atoi(ai_string); - ai_count++; - } - } - - for(i = 0; i < ai_count; i++) { - data_location[i] = ai_location[i] + 3; - if(ai_value[i] >= 100) { data_location[i]++; } - if(ai_value[i] >= 1000) { data_location[i]++; } - data_length[i] = 0; - do { - data_length[i]++; - } while ((source[data_location[i] + data_length[i] - 1] != '[') && (source[data_location[i] + data_length[i] - 1] != '\0')); - data_length[i]--; - } - - for(i = 0; i < ai_count; i++) { - if(data_length[i] == 0) { - /* No data for given AI */ - strcpy(symbol->errtxt, "Empty data field in input data"); - return ERROR_INVALID_DATA1; - } - } - - error_latch = 0; - strcpy(ai_string, ""); - for(i = 0; i < ai_count; i++) { - switch (ai_value[i]) { - case 0: if(data_length[i] != 18) { error_latch = 1; } break; - case 1: - case 2: - case 3: if(data_length[i] != 14) { error_latch = 1; } break; - case 4: if(data_length[i] != 16) { error_latch = 1; } break; - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: if(data_length[i] != 6) { error_latch = 1; } break; - case 20: if(data_length[i] != 2) { error_latch = 1; } break; - case 23: - case 24: - case 25: - case 39: - case 40: - case 41: - case 42: - case 70: - case 80: - case 81: error_latch = 2; break; - } - if( - ((ai_value[i] >= 100) && (ai_value[i] <= 179)) - || ((ai_value[i] >= 1000) && (ai_value[i] <= 1799)) - || ((ai_value[i] >= 200) && (ai_value[i] <= 229)) - || ((ai_value[i] >= 2000) && (ai_value[i] <= 2299)) - || ((ai_value[i] >= 300) && (ai_value[i] <= 309)) - || ((ai_value[i] >= 3000) && (ai_value[i] <= 3099)) - || ((ai_value[i] >= 31) && (ai_value[i] <= 36)) - || ((ai_value[i] >= 310) && (ai_value[i] <= 369)) - ) { - error_latch = 2; - } - if((ai_value[i] >= 3100) && (ai_value[i] <= 3699)) { - if(data_length[i] != 6) { - error_latch = 1; - } - } - if( - ((ai_value[i] >= 370) && (ai_value[i] <= 379)) - || ((ai_value[i] >= 3700) && (ai_value[i] <= 3799)) - ) { - error_latch = 2; - } - if((ai_value[i] >= 410) && (ai_value[i] <= 415)) { - if(data_length[i] != 13) { - error_latch = 1; - } - } - if( - ((ai_value[i] >= 4100) && (ai_value[i] <= 4199)) - || ((ai_value[i] >= 700) && (ai_value[i] <= 703)) - || ((ai_value[i] >= 800) && (ai_value[i] <= 810)) - || ((ai_value[i] >= 900) && (ai_value[i] <= 999)) - || ((ai_value[i] >= 9000) && (ai_value[i] <= 9999)) - ) { - error_latch = 2; - } - if((error_latch < 4) && (error_latch > 0)) { - /* error has just been detected: capture AI */ - itostr(ai_string, ai_value[i]); - error_latch += 4; - } - } - - if(error_latch == 5) { - strcpy(symbol->errtxt, "Invalid data length for AI "); - concat(symbol->errtxt, ai_string); - return ERROR_INVALID_DATA1; - } - - if(error_latch == 6) { - strcpy(symbol->errtxt, "Invalid AI value "); - concat(symbol->errtxt, ai_string); - return ERROR_INVALID_DATA1; - } - - /* Resolve AI data - put resulting string in 'reduced' */ - j = 0; - last_ai = 0; - ai_latch = 1; - for(i = 0; i < (int)src_len; i++) { - if((source[i] != '[') && (source[i] != ']')) { - reduced[j++] = source[i]; - } - if(source[i] == '[') { - /* Start of an AI string */ - if(ai_latch == 0) { - reduced[j++] = '['; - } - ai_string[0] = source[i + 1]; - ai_string[1] = source[i + 2]; - ai_string[2] = '\0'; - last_ai = atoi(ai_string); - ai_latch = 0; - /* The following values from "GS-1 General Specification version 8.0 issue 2, May 2008" - figure 5.4.8.2.1 - 1 "Element Strings with Pre-Defined Length Using Application Identifiers" */ - if( - ((last_ai >= 0) && (last_ai <= 4)) - || ((last_ai >= 11) && (last_ai <= 20)) - || (last_ai == 23) /* legacy support - see 5.3.8.2.2 */ - || ((last_ai >= 31) && (last_ai <= 36)) - || (last_ai == 41) - ) { - ai_latch = 1; - } - } - /* The ']' character is simply dropped from the input */ - } - reduced[j] = '\0'; - - /* the character '[' in the reduced string refers to the FNC1 character */ - return 0; -} - -int ugs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, unsigned char reduced[]) -{ - /* Only to keep the compiler happy */ -#ifndef _MSC_VER - char temp[src_len + 5]; -#else - char* temp = (char*)_alloca(src_len + 5); -#endif - int error_number; - - error_number = gs1_verify(symbol, source, src_len, temp); - if(error_number != 0) { return error_number; } - - if (strlen(temp) < src_len + 5) { - ustrcpy(reduced, (unsigned char*)temp); - return 0; - } - strcpy(symbol->errtxt, "ugs1_verify overflow"); - return ERROR_INVALID_DATA1; -} diff --git a/3rdparty/zint-2.4.4/backend/gs1.h b/3rdparty/zint-2.4.4/backend/gs1.h deleted file mode 100644 index 42b40df..0000000 --- a/3rdparty/zint-2.4.4/backend/gs1.h +++ /dev/null @@ -1,35 +0,0 @@ -/* gs1.h - Verifies GS1 data */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#ifndef __GS1_H -#define __GS1_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern int gs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char reduced[]); -extern int ugs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, unsigned char reduced[]); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __GS1_H */ \ No newline at end of file diff --git a/3rdparty/zint-2.4.4/backend/imail.c b/3rdparty/zint-2.4.4/backend/imail.c deleted file mode 100644 index 5094139..0000000 --- a/3rdparty/zint-2.4.4/backend/imail.c +++ /dev/null @@ -1,700 +0,0 @@ -/* imail.c - Handles Intelligent Mail (aka OneCode) for USPS */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence" - is Copyright (C) 2006 United States Postal Service */ - -static short int BCD[40] = { - 0, 0, 0, 0, - 1, 0, 0, 0, - 0, 1, 0, 0, - 1, 1, 0, 0, - 0, 0, 1, 0, - 1, 0, 1, 0, - 0, 1, 1, 0, - 1, 1, 1, 0, - 0, 0, 0, 1, - 1, 0, 0, 1 -}; - -#include -#include -#include -#include "common.h" -#include "large.h" - -#define SODIUM "0123456789-" - -/* The following lookup tables were generated using the code in Appendix C */ - -static unsigned short AppxD_I[1287] = { /* Appendix D Table 1 - 5 of 13 characters */ - 0x001F, 0x1F00, 0x002F, 0x1E80, 0x0037, 0x1D80, 0x003B, 0x1B80, 0x003D, 0x1780, - 0x003E, 0x0F80, 0x004F, 0x1E40, 0x0057, 0x1D40, 0x005B, 0x1B40, 0x005D, 0x1740, - 0x005E, 0x0F40, 0x0067, 0x1CC0, 0x006B, 0x1AC0, 0x006D, 0x16C0, 0x006E, 0x0EC0, - 0x0073, 0x19C0, 0x0075, 0x15C0, 0x0076, 0x0DC0, 0x0079, 0x13C0, 0x007A, 0x0BC0, - 0x007C, 0x07C0, 0x008F, 0x1E20, 0x0097, 0x1D20, 0x009B, 0x1B20, 0x009D, 0x1720, - 0x009E, 0x0F20, 0x00A7, 0x1CA0, 0x00AB, 0x1AA0, 0x00AD, 0x16A0, 0x00AE, 0x0EA0, - 0x00B3, 0x19A0, 0x00B5, 0x15A0, 0x00B6, 0x0DA0, 0x00B9, 0x13A0, 0x00BA, 0x0BA0, - 0x00BC, 0x07A0, 0x00C7, 0x1C60, 0x00CB, 0x1A60, 0x00CD, 0x1660, 0x00CE, 0x0E60, - 0x00D3, 0x1960, 0x00D5, 0x1560, 0x00D6, 0x0D60, 0x00D9, 0x1360, 0x00DA, 0x0B60, - 0x00DC, 0x0760, 0x00E3, 0x18E0, 0x00E5, 0x14E0, 0x00E6, 0x0CE0, 0x00E9, 0x12E0, - 0x00EA, 0x0AE0, 0x00EC, 0x06E0, 0x00F1, 0x11E0, 0x00F2, 0x09E0, 0x00F4, 0x05E0, - 0x00F8, 0x03E0, 0x010F, 0x1E10, 0x0117, 0x1D10, 0x011B, 0x1B10, 0x011D, 0x1710, - 0x011E, 0x0F10, 0x0127, 0x1C90, 0x012B, 0x1A90, 0x012D, 0x1690, 0x012E, 0x0E90, - 0x0133, 0x1990, 0x0135, 0x1590, 0x0136, 0x0D90, 0x0139, 0x1390, 0x013A, 0x0B90, - 0x013C, 0x0790, 0x0147, 0x1C50, 0x014B, 0x1A50, 0x014D, 0x1650, 0x014E, 0x0E50, - 0x0153, 0x1950, 0x0155, 0x1550, 0x0156, 0x0D50, 0x0159, 0x1350, 0x015A, 0x0B50, - 0x015C, 0x0750, 0x0163, 0x18D0, 0x0165, 0x14D0, 0x0166, 0x0CD0, 0x0169, 0x12D0, - 0x016A, 0x0AD0, 0x016C, 0x06D0, 0x0171, 0x11D0, 0x0172, 0x09D0, 0x0174, 0x05D0, - 0x0178, 0x03D0, 0x0187, 0x1C30, 0x018B, 0x1A30, 0x018D, 0x1630, 0x018E, 0x0E30, - 0x0193, 0x1930, 0x0195, 0x1530, 0x0196, 0x0D30, 0x0199, 0x1330, 0x019A, 0x0B30, - 0x019C, 0x0730, 0x01A3, 0x18B0, 0x01A5, 0x14B0, 0x01A6, 0x0CB0, 0x01A9, 0x12B0, - 0x01AA, 0x0AB0, 0x01AC, 0x06B0, 0x01B1, 0x11B0, 0x01B2, 0x09B0, 0x01B4, 0x05B0, - 0x01B8, 0x03B0, 0x01C3, 0x1870, 0x01C5, 0x1470, 0x01C6, 0x0C70, 0x01C9, 0x1270, - 0x01CA, 0x0A70, 0x01CC, 0x0670, 0x01D1, 0x1170, 0x01D2, 0x0970, 0x01D4, 0x0570, - 0x01D8, 0x0370, 0x01E1, 0x10F0, 0x01E2, 0x08F0, 0x01E4, 0x04F0, 0x01E8, 0x02F0, - 0x020F, 0x1E08, 0x0217, 0x1D08, 0x021B, 0x1B08, 0x021D, 0x1708, 0x021E, 0x0F08, - 0x0227, 0x1C88, 0x022B, 0x1A88, 0x022D, 0x1688, 0x022E, 0x0E88, 0x0233, 0x1988, - 0x0235, 0x1588, 0x0236, 0x0D88, 0x0239, 0x1388, 0x023A, 0x0B88, 0x023C, 0x0788, - 0x0247, 0x1C48, 0x024B, 0x1A48, 0x024D, 0x1648, 0x024E, 0x0E48, 0x0253, 0x1948, - 0x0255, 0x1548, 0x0256, 0x0D48, 0x0259, 0x1348, 0x025A, 0x0B48, 0x025C, 0x0748, - 0x0263, 0x18C8, 0x0265, 0x14C8, 0x0266, 0x0CC8, 0x0269, 0x12C8, 0x026A, 0x0AC8, - 0x026C, 0x06C8, 0x0271, 0x11C8, 0x0272, 0x09C8, 0x0274, 0x05C8, 0x0278, 0x03C8, - 0x0287, 0x1C28, 0x028B, 0x1A28, 0x028D, 0x1628, 0x028E, 0x0E28, 0x0293, 0x1928, - 0x0295, 0x1528, 0x0296, 0x0D28, 0x0299, 0x1328, 0x029A, 0x0B28, 0x029C, 0x0728, - 0x02A3, 0x18A8, 0x02A5, 0x14A8, 0x02A6, 0x0CA8, 0x02A9, 0x12A8, 0x02AA, 0x0AA8, - 0x02AC, 0x06A8, 0x02B1, 0x11A8, 0x02B2, 0x09A8, 0x02B4, 0x05A8, 0x02B8, 0x03A8, - 0x02C3, 0x1868, 0x02C5, 0x1468, 0x02C6, 0x0C68, 0x02C9, 0x1268, 0x02CA, 0x0A68, - 0x02CC, 0x0668, 0x02D1, 0x1168, 0x02D2, 0x0968, 0x02D4, 0x0568, 0x02D8, 0x0368, - 0x02E1, 0x10E8, 0x02E2, 0x08E8, 0x02E4, 0x04E8, 0x0307, 0x1C18, 0x030B, 0x1A18, - 0x030D, 0x1618, 0x030E, 0x0E18, 0x0313, 0x1918, 0x0315, 0x1518, 0x0316, 0x0D18, - 0x0319, 0x1318, 0x031A, 0x0B18, 0x031C, 0x0718, 0x0323, 0x1898, 0x0325, 0x1498, - 0x0326, 0x0C98, 0x0329, 0x1298, 0x032A, 0x0A98, 0x032C, 0x0698, 0x0331, 0x1198, - 0x0332, 0x0998, 0x0334, 0x0598, 0x0338, 0x0398, 0x0343, 0x1858, 0x0345, 0x1458, - 0x0346, 0x0C58, 0x0349, 0x1258, 0x034A, 0x0A58, 0x034C, 0x0658, 0x0351, 0x1158, - 0x0352, 0x0958, 0x0354, 0x0558, 0x0361, 0x10D8, 0x0362, 0x08D8, 0x0364, 0x04D8, - 0x0383, 0x1838, 0x0385, 0x1438, 0x0386, 0x0C38, 0x0389, 0x1238, 0x038A, 0x0A38, - 0x038C, 0x0638, 0x0391, 0x1138, 0x0392, 0x0938, 0x0394, 0x0538, 0x03A1, 0x10B8, - 0x03A2, 0x08B8, 0x03A4, 0x04B8, 0x03C1, 0x1078, 0x03C2, 0x0878, 0x03C4, 0x0478, - 0x040F, 0x1E04, 0x0417, 0x1D04, 0x041B, 0x1B04, 0x041D, 0x1704, 0x041E, 0x0F04, - 0x0427, 0x1C84, 0x042B, 0x1A84, 0x042D, 0x1684, 0x042E, 0x0E84, 0x0433, 0x1984, - 0x0435, 0x1584, 0x0436, 0x0D84, 0x0439, 0x1384, 0x043A, 0x0B84, 0x043C, 0x0784, - 0x0447, 0x1C44, 0x044B, 0x1A44, 0x044D, 0x1644, 0x044E, 0x0E44, 0x0453, 0x1944, - 0x0455, 0x1544, 0x0456, 0x0D44, 0x0459, 0x1344, 0x045A, 0x0B44, 0x045C, 0x0744, - 0x0463, 0x18C4, 0x0465, 0x14C4, 0x0466, 0x0CC4, 0x0469, 0x12C4, 0x046A, 0x0AC4, - 0x046C, 0x06C4, 0x0471, 0x11C4, 0x0472, 0x09C4, 0x0474, 0x05C4, 0x0487, 0x1C24, - 0x048B, 0x1A24, 0x048D, 0x1624, 0x048E, 0x0E24, 0x0493, 0x1924, 0x0495, 0x1524, - 0x0496, 0x0D24, 0x0499, 0x1324, 0x049A, 0x0B24, 0x049C, 0x0724, 0x04A3, 0x18A4, - 0x04A5, 0x14A4, 0x04A6, 0x0CA4, 0x04A9, 0x12A4, 0x04AA, 0x0AA4, 0x04AC, 0x06A4, - 0x04B1, 0x11A4, 0x04B2, 0x09A4, 0x04B4, 0x05A4, 0x04C3, 0x1864, 0x04C5, 0x1464, - 0x04C6, 0x0C64, 0x04C9, 0x1264, 0x04CA, 0x0A64, 0x04CC, 0x0664, 0x04D1, 0x1164, - 0x04D2, 0x0964, 0x04D4, 0x0564, 0x04E1, 0x10E4, 0x04E2, 0x08E4, 0x0507, 0x1C14, - 0x050B, 0x1A14, 0x050D, 0x1614, 0x050E, 0x0E14, 0x0513, 0x1914, 0x0515, 0x1514, - 0x0516, 0x0D14, 0x0519, 0x1314, 0x051A, 0x0B14, 0x051C, 0x0714, 0x0523, 0x1894, - 0x0525, 0x1494, 0x0526, 0x0C94, 0x0529, 0x1294, 0x052A, 0x0A94, 0x052C, 0x0694, - 0x0531, 0x1194, 0x0532, 0x0994, 0x0534, 0x0594, 0x0543, 0x1854, 0x0545, 0x1454, - 0x0546, 0x0C54, 0x0549, 0x1254, 0x054A, 0x0A54, 0x054C, 0x0654, 0x0551, 0x1154, - 0x0552, 0x0954, 0x0561, 0x10D4, 0x0562, 0x08D4, 0x0583, 0x1834, 0x0585, 0x1434, - 0x0586, 0x0C34, 0x0589, 0x1234, 0x058A, 0x0A34, 0x058C, 0x0634, 0x0591, 0x1134, - 0x0592, 0x0934, 0x05A1, 0x10B4, 0x05A2, 0x08B4, 0x05C1, 0x1074, 0x05C2, 0x0874, - 0x0607, 0x1C0C, 0x060B, 0x1A0C, 0x060D, 0x160C, 0x060E, 0x0E0C, 0x0613, 0x190C, - 0x0615, 0x150C, 0x0616, 0x0D0C, 0x0619, 0x130C, 0x061A, 0x0B0C, 0x061C, 0x070C, - 0x0623, 0x188C, 0x0625, 0x148C, 0x0626, 0x0C8C, 0x0629, 0x128C, 0x062A, 0x0A8C, - 0x062C, 0x068C, 0x0631, 0x118C, 0x0632, 0x098C, 0x0643, 0x184C, 0x0645, 0x144C, - 0x0646, 0x0C4C, 0x0649, 0x124C, 0x064A, 0x0A4C, 0x0651, 0x114C, 0x0652, 0x094C, - 0x0661, 0x10CC, 0x0662, 0x08CC, 0x0683, 0x182C, 0x0685, 0x142C, 0x0686, 0x0C2C, - 0x0689, 0x122C, 0x068A, 0x0A2C, 0x0691, 0x112C, 0x0692, 0x092C, 0x06A1, 0x10AC, - 0x06A2, 0x08AC, 0x06C1, 0x106C, 0x06C2, 0x086C, 0x0703, 0x181C, 0x0705, 0x141C, - 0x0706, 0x0C1C, 0x0709, 0x121C, 0x070A, 0x0A1C, 0x0711, 0x111C, 0x0712, 0x091C, - 0x0721, 0x109C, 0x0722, 0x089C, 0x0741, 0x105C, 0x0742, 0x085C, 0x0781, 0x103C, - 0x0782, 0x083C, 0x080F, 0x1E02, 0x0817, 0x1D02, 0x081B, 0x1B02, 0x081D, 0x1702, - 0x081E, 0x0F02, 0x0827, 0x1C82, 0x082B, 0x1A82, 0x082D, 0x1682, 0x082E, 0x0E82, - 0x0833, 0x1982, 0x0835, 0x1582, 0x0836, 0x0D82, 0x0839, 0x1382, 0x083A, 0x0B82, - 0x0847, 0x1C42, 0x084B, 0x1A42, 0x084D, 0x1642, 0x084E, 0x0E42, 0x0853, 0x1942, - 0x0855, 0x1542, 0x0856, 0x0D42, 0x0859, 0x1342, 0x085A, 0x0B42, 0x0863, 0x18C2, - 0x0865, 0x14C2, 0x0866, 0x0CC2, 0x0869, 0x12C2, 0x086A, 0x0AC2, 0x0871, 0x11C2, - 0x0872, 0x09C2, 0x0887, 0x1C22, 0x088B, 0x1A22, 0x088D, 0x1622, 0x088E, 0x0E22, - 0x0893, 0x1922, 0x0895, 0x1522, 0x0896, 0x0D22, 0x0899, 0x1322, 0x089A, 0x0B22, - 0x08A3, 0x18A2, 0x08A5, 0x14A2, 0x08A6, 0x0CA2, 0x08A9, 0x12A2, 0x08AA, 0x0AA2, - 0x08B1, 0x11A2, 0x08B2, 0x09A2, 0x08C3, 0x1862, 0x08C5, 0x1462, 0x08C6, 0x0C62, - 0x08C9, 0x1262, 0x08CA, 0x0A62, 0x08D1, 0x1162, 0x08D2, 0x0962, 0x08E1, 0x10E2, - 0x0907, 0x1C12, 0x090B, 0x1A12, 0x090D, 0x1612, 0x090E, 0x0E12, 0x0913, 0x1912, - 0x0915, 0x1512, 0x0916, 0x0D12, 0x0919, 0x1312, 0x091A, 0x0B12, 0x0923, 0x1892, - 0x0925, 0x1492, 0x0926, 0x0C92, 0x0929, 0x1292, 0x092A, 0x0A92, 0x0931, 0x1192, - 0x0932, 0x0992, 0x0943, 0x1852, 0x0945, 0x1452, 0x0946, 0x0C52, 0x0949, 0x1252, - 0x094A, 0x0A52, 0x0951, 0x1152, 0x0961, 0x10D2, 0x0983, 0x1832, 0x0985, 0x1432, - 0x0986, 0x0C32, 0x0989, 0x1232, 0x098A, 0x0A32, 0x0991, 0x1132, 0x09A1, 0x10B2, - 0x09C1, 0x1072, 0x0A07, 0x1C0A, 0x0A0B, 0x1A0A, 0x0A0D, 0x160A, 0x0A0E, 0x0E0A, - 0x0A13, 0x190A, 0x0A15, 0x150A, 0x0A16, 0x0D0A, 0x0A19, 0x130A, 0x0A1A, 0x0B0A, - 0x0A23, 0x188A, 0x0A25, 0x148A, 0x0A26, 0x0C8A, 0x0A29, 0x128A, 0x0A2A, 0x0A8A, - 0x0A31, 0x118A, 0x0A43, 0x184A, 0x0A45, 0x144A, 0x0A46, 0x0C4A, 0x0A49, 0x124A, - 0x0A51, 0x114A, 0x0A61, 0x10CA, 0x0A83, 0x182A, 0x0A85, 0x142A, 0x0A86, 0x0C2A, - 0x0A89, 0x122A, 0x0A91, 0x112A, 0x0AA1, 0x10AA, 0x0AC1, 0x106A, 0x0B03, 0x181A, - 0x0B05, 0x141A, 0x0B06, 0x0C1A, 0x0B09, 0x121A, 0x0B11, 0x111A, 0x0B21, 0x109A, - 0x0B41, 0x105A, 0x0B81, 0x103A, 0x0C07, 0x1C06, 0x0C0B, 0x1A06, 0x0C0D, 0x1606, - 0x0C0E, 0x0E06, 0x0C13, 0x1906, 0x0C15, 0x1506, 0x0C16, 0x0D06, 0x0C19, 0x1306, - 0x0C23, 0x1886, 0x0C25, 0x1486, 0x0C26, 0x0C86, 0x0C29, 0x1286, 0x0C31, 0x1186, - 0x0C43, 0x1846, 0x0C45, 0x1446, 0x0C49, 0x1246, 0x0C51, 0x1146, 0x0C61, 0x10C6, - 0x0C83, 0x1826, 0x0C85, 0x1426, 0x0C89, 0x1226, 0x0C91, 0x1126, 0x0CA1, 0x10A6, - 0x0CC1, 0x1066, 0x0D03, 0x1816, 0x0D05, 0x1416, 0x0D09, 0x1216, 0x0D11, 0x1116, - 0x0D21, 0x1096, 0x0D41, 0x1056, 0x0D81, 0x1036, 0x0E03, 0x180E, 0x0E05, 0x140E, - 0x0E09, 0x120E, 0x0E11, 0x110E, 0x0E21, 0x108E, 0x0E41, 0x104E, 0x0E81, 0x102E, - 0x0F01, 0x101E, 0x100F, 0x1E01, 0x1017, 0x1D01, 0x101B, 0x1B01, 0x101D, 0x1701, - 0x1027, 0x1C81, 0x102B, 0x1A81, 0x102D, 0x1681, 0x1033, 0x1981, 0x1035, 0x1581, - 0x1039, 0x1381, 0x1047, 0x1C41, 0x104B, 0x1A41, 0x104D, 0x1641, 0x1053, 0x1941, - 0x1055, 0x1541, 0x1059, 0x1341, 0x1063, 0x18C1, 0x1065, 0x14C1, 0x1069, 0x12C1, - 0x1071, 0x11C1, 0x1087, 0x1C21, 0x108B, 0x1A21, 0x108D, 0x1621, 0x1093, 0x1921, - 0x1095, 0x1521, 0x1099, 0x1321, 0x10A3, 0x18A1, 0x10A5, 0x14A1, 0x10A9, 0x12A1, - 0x10B1, 0x11A1, 0x10C3, 0x1861, 0x10C5, 0x1461, 0x10C9, 0x1261, 0x10D1, 0x1161, - 0x1107, 0x1C11, 0x110B, 0x1A11, 0x110D, 0x1611, 0x1113, 0x1911, 0x1115, 0x1511, - 0x1119, 0x1311, 0x1123, 0x1891, 0x1125, 0x1491, 0x1129, 0x1291, 0x1131, 0x1191, - 0x1143, 0x1851, 0x1145, 0x1451, 0x1149, 0x1251, 0x1183, 0x1831, 0x1185, 0x1431, - 0x1189, 0x1231, 0x1207, 0x1C09, 0x120B, 0x1A09, 0x120D, 0x1609, 0x1213, 0x1909, - 0x1215, 0x1509, 0x1219, 0x1309, 0x1223, 0x1889, 0x1225, 0x1489, 0x1229, 0x1289, - 0x1243, 0x1849, 0x1245, 0x1449, 0x1283, 0x1829, 0x1285, 0x1429, 0x1303, 0x1819, - 0x1305, 0x1419, 0x1407, 0x1C05, 0x140B, 0x1A05, 0x140D, 0x1605, 0x1413, 0x1905, - 0x1415, 0x1505, 0x1423, 0x1885, 0x1425, 0x1485, 0x1443, 0x1845, 0x1483, 0x1825, - 0x1503, 0x1815, 0x1603, 0x180D, 0x1807, 0x1C03, 0x180B, 0x1A03, 0x1813, 0x1903, - 0x1823, 0x1883, 0x1843, 0x1445, 0x1249, 0x1151, 0x10E1, 0x0C46, 0x0A4A, 0x0952, - 0x08E2, 0x064C, 0x0554, 0x04E4, 0x0358, 0x02E8, 0x01F0 }; - -static unsigned short AppxD_II[78] = { /* Appendix D Table II - 2 of 13 characters */ - 0x0003, 0x1800, 0x0005, 0x1400, 0x0006, 0x0C00, 0x0009, 0x1200, 0x000A, 0x0A00, - 0x000C, 0x0600, 0x0011, 0x1100, 0x0012, 0x0900, 0x0014, 0x0500, 0x0018, 0x0300, - 0x0021, 0x1080, 0x0022, 0x0880, 0x0024, 0x0480, 0x0028, 0x0280, 0x0030, 0x0180, - 0x0041, 0x1040, 0x0042, 0x0840, 0x0044, 0x0440, 0x0048, 0x0240, 0x0050, 0x0140, - 0x0060, 0x00C0, 0x0081, 0x1020, 0x0082, 0x0820, 0x0084, 0x0420, 0x0088, 0x0220, - 0x0090, 0x0120, 0x0101, 0x1010, 0x0102, 0x0810, 0x0104, 0x0410, 0x0108, 0x0210, - 0x0201, 0x1008, 0x0202, 0x0808, 0x0204, 0x0408, 0x0401, 0x1004, 0x0402, 0x0804, - 0x0801, 0x1002, 0x1001, 0x0802, 0x0404, 0x0208, 0x0110, 0x00A0 }; - -static int AppxD_IV[130] = { /* Appendix D Table IV - Bar-to-Character Mapping (reverse lookup) */ - 67, 6, 78, 16, 86, 95, 34, 40, 45, 113, 117, 121, 62, 87, 18, 104, 41, 76, 57, 119, 115, 72, 97, - 2, 127, 26, 105, 35, 122, 52, 114, 7, 24, 82, 68, 63, 94, 44, 77, 112, 70, 100, 39, 30, 107, - 15, 125, 85, 10, 65, 54, 88, 20, 106, 46, 66, 8, 116, 29, 61, 99, 80, 90, 37, 123, 51, 25, 84, - 129, 56, 4, 109, 96, 28, 36, 47, 11, 71, 33, 102, 21, 9, 17, 49, 124, 79, 64, 91, 42, 69, 53, - 60, 14, 1, 27, 103, 126, 75, 89, 50, 120, 19, 32, 110, 92, 111, 130, 59, 31, 12, 81, 43, 55, - 5, 74, 22, 101, 128, 58, 118, 48, 108, 38, 98, 93, 23, 83, 13, 73, 3 }; - -/*************************************************************************** - ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence - ** - ** Inputs: - ** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which - ** are right justified - ie: the leftmost 2 bits of the first byte do not - ** hold data and must be set to zero. - ** - ** Outputs: - ** return unsigned short - 11 bit Frame Check Sequence (right justified) -***************************************************************************/ -extern unsigned short - USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr ) - -{ - unsigned short GeneratorPolynomial = 0x0F35; - unsigned short FrameCheckSequence = 0x07FF; - unsigned short Data; - int ByteIndex, Bit; - - /* Do most significant byte skipping the 2 most significant bits */ - Data = *ByteArrayPtr << 5; - ByteArrayPtr++; - for ( Bit = 2; Bit < 8; Bit++ ) - { - if ( (FrameCheckSequence ^ Data) & 0x400 ) - FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; - else - FrameCheckSequence = (FrameCheckSequence << 1); - FrameCheckSequence &= 0x7FF; - Data <<= 1; - } - /* Do rest of the bytes */ - for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ ) - { - Data = *ByteArrayPtr << 3; - ByteArrayPtr++; - for ( Bit = 0; Bit < 8; Bit++ ) - { - if ( (FrameCheckSequence ^ Data) & 0x0400 ) { - FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; - } else { - FrameCheckSequence = (FrameCheckSequence << 1); - } - FrameCheckSequence &= 0x7FF; - Data <<= 1; - } - } - return FrameCheckSequence; -} - -void breakup(short int fcs_bit[], unsigned short usps_crc) -{ - int i; - - for(i = 0; i < 13; i++) { - fcs_bit[i] = 0; - } - - if(usps_crc >= 4096) { - fcs_bit[12] = 1; - usps_crc -= 4096; - } - if(usps_crc >= 2048) { - fcs_bit[11] = 1; - usps_crc -= 2048; - } - if(usps_crc >= 1024) { - fcs_bit[10] = 1; - usps_crc -= 1024; - } - if(usps_crc >= 512) { - fcs_bit[9] = 1; - usps_crc -= 512; - } - if(usps_crc >= 256) { - fcs_bit[8] = 1; - usps_crc -= 256; - } - if(usps_crc >= 128) { - fcs_bit[7] = 1; - usps_crc -= 128; - } - if(usps_crc >= 64) { - fcs_bit[6] = 1; - usps_crc -= 64; - } - if(usps_crc >= 32) { - fcs_bit[5] = 1; - usps_crc -= 32; - } - if(usps_crc >= 16) { - fcs_bit[4] = 1; - usps_crc -= 16; - } - if(usps_crc >= 8) { - fcs_bit[3] = 1; - usps_crc -= 8; - } - if(usps_crc >= 4) { - fcs_bit[2] = 1; - usps_crc -= 4; - } - if(usps_crc >= 2) { - fcs_bit[1] = 1; - usps_crc -= 2; - } - if(usps_crc == 1) { - fcs_bit[0] = 1; - } -} - -int imail(struct zint_symbol *symbol, unsigned char source[], int length) -{ - char data_pattern[200]; - int error_number; - int i, j, read; - char zip[35], tracker[35], zip_adder[11], temp[2]; - short int accum[112], x_reg[112], y_reg[112]; - unsigned char byte_array[13]; - unsigned short usps_crc; - int codeword[10]; - unsigned short characters[10]; - short int bit_pattern[13], bar_map[130]; - - error_number = 0; - - if(length > 32) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(SODIUM, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - strcpy(zip, ""); - strcpy(tracker, ""); - - /* separate the tracking code from the routing code */ - - read = 0; - j = 0; - for(i = 0; i < length; i++) { - if(source[i] == '-') { - tracker[read] = '\0'; - j = 1; - read = 0; - } else { - if(j == 0) { - /* reading tracker */ - tracker[read] = source[i]; - read++; - } else { - /* reading zip code */ - zip[read] = source[i]; - read++; - } - } - } - if(j == 0) { - tracker[read] = '\0'; - } else { - zip[read] = '\0'; - } - - if(strlen(tracker) != 20) { - strcpy(symbol->errtxt, "Invalid length tracking code"); - return ERROR_INVALID_DATA1; - } - if(strlen(zip) > 11) { - strcpy(symbol->errtxt, "Invalid ZIP code"); - return ERROR_INVALID_DATA1; - } - - /* *** Step 1 - Conversion of Data Fields into Binary Data *** */ - - /* Routing code first */ - - for(i = 0; i < 112; i++) { - accum[i] = 0; - } - - for(read = 0; read < strlen(zip); read++) { - - for(i = 0; i < 112; i++) { - x_reg[i] = accum[i]; - } - - for(i = 0; i < 9; i++) { - binary_add(accum, x_reg); - } - - x_reg[0] = BCD[ctoi(zip[read]) * 4]; - x_reg[1] = BCD[(ctoi(zip[read]) * 4) + 1]; - x_reg[2] = BCD[(ctoi(zip[read]) * 4) + 2]; - x_reg[3] = BCD[(ctoi(zip[read]) * 4) + 3]; - for(i = 4; i < 112; i++) { - x_reg[i] = 0; - } - - binary_add(accum, x_reg); - } - - /* add weight to routing code */ - - for(i = 0; i < 112; i++) { - x_reg[i] = accum[i]; - } - - if(strlen(zip) > 9) { - strcpy(zip_adder, "1000100001"); - } else { - if(strlen(zip) > 5) { - strcpy(zip_adder, "100001"); - } else { - if(strlen(zip) > 0) { - strcpy(zip_adder, "1"); - } else { - strcpy(zip_adder, "0"); - } - } - } - - for(i = 0; i < 112; i++) { - accum[i] = 0; - } - - for(read = 0; read < strlen(zip_adder); read++) { - - for(i = 0; i < 112; i++) { - y_reg[i] = accum[i]; - } - - for(i = 0; i < 9; i++) { - binary_add(accum, y_reg); - } - - y_reg[0] = BCD[ctoi(zip_adder[read]) * 4]; - y_reg[1] = BCD[(ctoi(zip_adder[read]) * 4) + 1]; - y_reg[2] = BCD[(ctoi(zip_adder[read]) * 4) + 2]; - y_reg[3] = BCD[(ctoi(zip_adder[read]) * 4) + 3]; - for(i = 4; i < 112; i++) { - y_reg[i] = 0; - } - - binary_add(accum, y_reg); - } - - binary_add(accum, x_reg); - - /* tracking code */ - - /* multiply by 10 */ - for(i = 0; i < 112; i++) { - y_reg[i] = accum[i]; - } - - for(i = 0; i < 9; i++) { - binary_add(accum, y_reg); - } - - /* add first digit of tracker */ - y_reg[0] = BCD[ctoi(tracker[0]) * 4]; - y_reg[1] = BCD[(ctoi(tracker[0]) * 4) + 1]; - y_reg[2] = BCD[(ctoi(tracker[0]) * 4) + 2]; - y_reg[3] = BCD[(ctoi(tracker[0]) * 4) + 3]; - for(i = 4; i < 112; i++) { - y_reg[i] = 0; - } - - binary_add(accum, y_reg); - - /* multiply by 5 */ - for(i = 0; i < 112; i++) { - y_reg[i] = accum[i]; - } - - for(i = 0; i < 4; i++) { - binary_add(accum, y_reg); - } - - /* add second digit */ - y_reg[0] = BCD[ctoi(tracker[1]) * 4]; - y_reg[1] = BCD[(ctoi(tracker[1]) * 4) + 1]; - y_reg[2] = BCD[(ctoi(tracker[1]) * 4) + 2]; - y_reg[3] = BCD[(ctoi(tracker[1]) * 4) + 3]; - for(i = 4; i < 112; i++) { - y_reg[i] = 0; - } - - binary_add(accum, y_reg); - - /* and then the rest */ - - for(read = 2; read < strlen(tracker); read++) { - - for(i = 0; i < 112; i++) { - y_reg[i] = accum[i]; - } - - for(i = 0; i < 9; i++) { - binary_add(accum, y_reg); - } - - y_reg[0] = BCD[ctoi(tracker[read]) * 4]; - y_reg[1] = BCD[(ctoi(tracker[read]) * 4) + 1]; - y_reg[2] = BCD[(ctoi(tracker[read]) * 4) + 2]; - y_reg[3] = BCD[(ctoi(tracker[read]) * 4) + 3]; - for(i = 4; i < 112; i++) { - y_reg[i] = 0; - } - - binary_add(accum, y_reg); - } - - /* printf("Binary data 1: "); - hex_dump(accum); */ - - /* *** Step 2 - Generation of 11-bit CRC on Binary Data *** */ - - accum[103] = 0; - accum[102] = 0; - - memset(byte_array, 0, 13); - for(j = 0; j < 13; j++) { - i = 96 - (8 * j); - byte_array[j] = 0; - byte_array[j] += accum[i]; - byte_array[j] += 2 * accum[i + 1]; - byte_array[j] += 4 * accum[i + 2]; - byte_array[j] += 8 * accum[i + 3]; - byte_array[j] += 16 * accum[i + 4]; - byte_array[j] += 32 * accum[i + 5]; - byte_array[j] += 64 * accum[i + 6]; - byte_array[j] += 128 * accum[i + 7]; - } - - usps_crc = USPS_MSB_Math_CRC11GenerateFrameCheckSequence(byte_array); - /* printf("FCS 2: %4.4X\n", usps_crc); */ - - /* *** Step 3 - Conversion from Binary Data to Codewords *** */ - - /* start with codeword J which is base 636 */ - for(i = 0; i < 112; i++) { - x_reg[i] = 0; - y_reg[i] = 0; - } - - x_reg[101] = 1; - x_reg[98] = 1; - x_reg[97] = 1; - x_reg[96] = 1; - x_reg[95] = 1; - x_reg[94] = 1; - - for(i = 92; i >= 0; i--) { - y_reg[i] = islarger(accum, x_reg); - if(y_reg[i] == 1) { - binary_subtract(accum, x_reg); - } - shiftdown(x_reg); - } - - codeword[9] = (accum[9] * 512) + (accum[8] * 256) + (accum[7] * 128) + (accum[6] * 64) + - (accum[5] * 32) + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) + - (accum[1] * 2) + accum[0]; - - /* then codewords I to B with base 1365 */ - - for(j = 8; j > 0; j--) { - for(i = 0; i < 112; i++) { - accum[i] = y_reg[i]; - y_reg[i] = 0; - x_reg[i] = 0; - } - x_reg[101] = 1; - x_reg[99] = 1; - x_reg[97] = 1; - x_reg[95] = 1; - x_reg[93] = 1; - x_reg[91] = 1; - for(i = 91; i >= 0; i--) { - y_reg[i] = islarger(accum, x_reg); - if(y_reg[i] == 1) { - binary_subtract(accum, x_reg); - } - shiftdown(x_reg); - } - - codeword[j] = (accum[10] * 1024) + (accum[9] * 512) + (accum[8] * 256) + - (accum[7] * 128) + (accum[6] * 64) + (accum[5] * 32) + - (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) + - (accum[1] * 2) + accum[0]; - } - - codeword[0] = (y_reg[10] * 1024) + (y_reg[9] * 512) + (y_reg[8] * 256) + - (y_reg[7] * 128) + (y_reg[6] * 64) + (y_reg[5] * 32) + - (y_reg[4] * 16) + (y_reg[3] * 8) + (y_reg[2] * 4) + - (y_reg[1] * 2) + y_reg[0]; - - for(i = 0; i < 8; i++) { - if(codeword[i] == 1365) { - codeword[i] = 0; - codeword[i + 1]++; - } - } - - /* printf("Codewords 3: "); - for(i = 0; i < 10; i++) { - printf("%d ", codeword[i]); - } - printf("\n"); */ - - /* *** Step 4 - Inserting Additional Information into Codewords *** */ - - codeword[9] = codeword[9] * 2; - - if(usps_crc >= 1024) { - codeword[0] += 659; - } - - /* printf("Codewords 4b: "); - for(i = 0; i < 10; i++) { - printf("%d ", codeword[i]); - } - printf("\n"); */ - - /* *** Step 5 - Conversion from Codewords to Characters *** */ - - for(i = 0; i < 10; i++) { - if(codeword[i] < 1287) { - characters[i] = AppxD_I[codeword[i]]; - } else { - characters[i] = AppxD_II[codeword[i] - 1287]; - } - } - - /* printf("Characters 5a: "); - for(i = 0; i < 10; i++) { - printf("%4.4X ", characters[i]); - } - printf("\n"); */ - - breakup(bit_pattern, usps_crc); - - for(i = 0; i < 10; i++) { - if(bit_pattern[i] == 1) { - characters[i] = 0x1FFF - characters[i]; - } - } - - /* printf("Characters 5b: "); - for(i = 0; i < 10; i++) { - printf("%4.4X ", characters[i]); - } - printf("\n"); */ - - /* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */ - - for(i = 0; i < 10; i++) { - breakup(bit_pattern, characters[i]); - for(j = 0; j < 13; j++) { - bar_map[AppxD_IV[(13 * i) + j] - 1] = bit_pattern[j]; - } - } - - strcpy(data_pattern, ""); - temp[1] = '\0'; - for(i = 0; i < 65; i++) { - j = 0; - if(bar_map[i] == 0) - j += 1; - if(bar_map[i + 65] == 0) - j += 2; - temp[0] = itoc(j); - concat(data_pattern, temp); - } - - /* Translate 4-state data pattern to symbol */ - read = 0; - for(i = 0; i < strlen(data_pattern); i++) - { - if((data_pattern[i] == '1') || (data_pattern[i] == '0')) - { - set_module(symbol, 0, read); - } - set_module(symbol, 1, read); - if((data_pattern[i] == '2') || (data_pattern[i] == '0')) - { - set_module(symbol, 2, read); - } - read += 2; - } - - symbol->row_height[0] = 3; - symbol->row_height[1] = 2; - symbol->row_height[2] = 3; - - symbol->rows = 3; - symbol->width = read - 1; - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/large.c b/3rdparty/zint-2.4.4/backend/large.c deleted file mode 100644 index e3f0453..0000000 --- a/3rdparty/zint-2.4.4/backend/large.c +++ /dev/null @@ -1,227 +0,0 @@ -/* large.c - Handles binary manipulation of large numbers */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include "common.h" -#include "large.h" - -static short int BCD[40] = { - 0, 0, 0, 0, - 1, 0, 0, 0, - 0, 1, 0, 0, - 1, 1, 0, 0, - 0, 0, 1, 0, - 1, 0, 1, 0, - 0, 1, 1, 0, - 1, 1, 1, 0, - 0, 0, 0, 1, - 1, 0, 0, 1 }; - -void binary_add(short int accumulator[], short int input_buffer[]) -{ /* Binary addition */ - int i, carry, done; - carry = 0; - - for(i = 0; i < 112; i++) { - done = 0; - if(((input_buffer[i] == 0) && (accumulator[i] == 0)) && ((carry == 0) && (done == 0))) { - accumulator[i] = 0; - carry = 0; - done = 1; - } - if(((input_buffer[i] == 0) && (accumulator[i] == 0)) && ((carry == 1) && (done == 0))) { - accumulator[i] = 1; - carry = 0; - done = 1; - } - if(((input_buffer[i] == 0) && (accumulator[i] == 1)) && ((carry == 0) && (done == 0))) { - accumulator[i] = 1; - carry = 0; - done = 1; - } - if(((input_buffer[i] == 0) && (accumulator[i] == 1)) && ((carry == 1) && (done == 0))) { - accumulator[i] = 0; - carry = 1; - done = 1; - } - if(((input_buffer[i] == 1) && (accumulator[i] == 0)) && ((carry == 0) && (done == 0))) { - accumulator[i] = 1; - carry = 0; - done = 1; - } - if(((input_buffer[i] == 1) && (accumulator[i] == 0)) && ((carry == 1) && (done == 0))) { - accumulator[i] = 0; - carry = 1; - done = 1; - } - if(((input_buffer[i] == 1) && (accumulator[i] == 1)) && ((carry == 0) && (done == 0))) { - accumulator[i] = 0; - carry = 1; - done = 1; - } - if(((input_buffer[i] == 1) && (accumulator[i] == 1)) && ((carry == 1) && (done == 0))) { - accumulator[i] = 1; - carry = 1; - done = 1; - } - } -} - -void binary_subtract(short int accumulator[], short int input_buffer[]) -{ /* 2's compliment subtraction */ - /* take input_buffer from accumulator and put answer in accumulator */ - int i; - short int sub_buffer[112]; - - for(i = 0; i < 112; i++) { - if(input_buffer[i] == 0) { - sub_buffer[i] = 1; - } else { - sub_buffer[i] = 0; - } - } - binary_add(accumulator, sub_buffer); - - sub_buffer[0] = 1; - - for(i = 1; i < 112; i++) { - sub_buffer[i] = 0; - } - binary_add(accumulator, sub_buffer); -} - -void shiftdown(short int buffer[]) -{ - int i; - - buffer[102] = 0; - buffer[103] = 0; - - for(i = 0; i < 102; i++) { - buffer[i] = buffer[i + 1]; - } -} - -void shiftup(short int buffer[]) -{ - int i; - - for(i = 102; i > 0; i--) { - buffer[i] = buffer[i - 1]; - } - - buffer[0] = 0; -} - -short int islarger(short int accum[], short int reg[]) -{ - /* Returns 1 if accum[] is larger than reg[], else 0 */ - int i, latch, larger; - latch = 0; - i = 103; - larger = 0; - - - do { - if((accum[i] == 1) && (reg[i] == 0)) { - latch = 1; - larger = 1; - } - if((accum[i] == 0) && (reg[i] == 1)) { - latch = 1; - } - i--; - } while ((latch == 0) && (i >= -1)); - - return larger; -} - -void binary_load(short int reg[], char data[], const unsigned int src_len) -{ - int read, i; - short int temp[112] = { 0 }; - - for(i = 0; i < 112; i++) { - reg[i] = 0; - } - - for(read = 0; read < (int)src_len; read++) { - - for(i = 0; i < 112; i++) { - temp[i] = reg[i]; - } - - for(i = 0; i < 9; i++) { - binary_add(reg, temp); - } - - temp[0] = BCD[ctoi(data[read]) * 4]; - temp[1] = BCD[(ctoi(data[read]) * 4) + 1]; - temp[2] = BCD[(ctoi(data[read]) * 4) + 2]; - temp[3] = BCD[(ctoi(data[read]) * 4) + 3]; - for(i = 4; i < 112; i++) { - temp[i] = 0; - } - - binary_add(reg, temp); - } -} - -void hex_dump(short int input_buffer[]) -{ - int i, digit, byte_space; - - byte_space = 1; - for(i = 100; i >= 0; i-=4) { - digit = 0; - digit += 1 * input_buffer[i]; - digit += 2 * input_buffer[i + 1]; - digit += 4 * input_buffer[i + 2]; - digit += 8 * input_buffer[i + 3]; - - switch(digit) { - case 0: printf("0"); break; - case 1: printf("1"); break; - case 2: printf("2"); break; - case 3: printf("3"); break; - case 4: printf("4"); break; - case 5: printf("5"); break; - case 6: printf("6"); break; - case 7: printf("7"); break; - case 8: printf("8"); break; - case 9: printf("9"); break; - case 10: printf("A"); break; - case 11: printf("B"); break; - case 12: printf("C"); break; - case 13: printf("D"); break; - case 14: printf("E"); break; - case 15: printf("F"); break; - } - if(byte_space == 1) { - byte_space = 0; - } else { - byte_space = 1; - printf(" "); - } - } - printf("\n"); -} diff --git a/3rdparty/zint-2.4.4/backend/large.h b/3rdparty/zint-2.4.4/backend/large.h deleted file mode 100644 index 72076b0..0000000 --- a/3rdparty/zint-2.4.4/backend/large.h +++ /dev/null @@ -1,40 +0,0 @@ -/* large.h - Handles binary manipulation of large numbers */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#ifndef __LARGE_H -#define __LARGE_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern void binary_load(short int reg[], char data[], const unsigned int src_len); -extern void binary_add(short int accumulator[], short int input_buffer[]); -extern void binary_subtract(short int accumulator[], short int input_buffer[]); -extern void shiftdown(short int buffer[]); -extern void shiftup(short int buffer[]); -extern short int islarger(short int accum[], short int reg[]); -extern void hex_dump(short int input_buffer[]); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __LARGE_H */ diff --git a/3rdparty/zint-2.4.4/backend/library.c b/3rdparty/zint-2.4.4/backend/library.c deleted file mode 100644 index f769a46..0000000 --- a/3rdparty/zint-2.4.4/backend/library.c +++ /dev/null @@ -1,908 +0,0 @@ -/* library.c - external functions of libzint - - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "gs1.h" - -#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" - -struct zint_symbol *ZBarcode_Create() -{ - struct zint_symbol *symbol; - int i; - - symbol = (struct zint_symbol*)malloc(sizeof(*symbol)); - if (!symbol) return NULL; - - memset(symbol, 0, sizeof(*symbol)); - symbol->symbology = BARCODE_CODE128; - symbol->height = 0; - symbol->whitespace_width = 0; - symbol->border_width = 0; - symbol->output_options = 0; - symbol->rows = 0; - symbol->width = 0; - strcpy(symbol->fgcolour, "000000"); - strcpy(symbol->bgcolour, "ffffff"); - strcpy(symbol->outfile, ""); - symbol->scale = 1.0; - symbol->option_1 = -1; - symbol->option_2 = 0; - symbol->option_3 = 928; // PDF_MAX - symbol->show_hrt = 1; // Show human readable text - symbol->input_mode = DATA_MODE; - strcpy(symbol->primary, ""); - memset(&(symbol->encoded_data[0][0]),0,sizeof(symbol->encoded_data)); - for(i = 0; i < 178; i++) { - symbol->row_height[i] = 0; - } - symbol->bitmap = NULL; - symbol->bitmap_width = 0; - symbol->bitmap_height = 0; - return symbol; -} - -void ZBarcode_Clear(struct zint_symbol *symbol) -{ - int i, j; - - for(i = 0; i < symbol->rows; i++) { - for(j = 0; j < symbol->width; j++) { - unset_module(symbol, i, j); - } - } - symbol->rows = 0; - symbol->width = 0; - symbol->text[0] = '\0'; - symbol->errtxt[0] = '\0'; - if (symbol->bitmap != NULL) - free(symbol->bitmap); - symbol->bitmap = NULL; - symbol->bitmap_width = 0; - symbol->bitmap_height = 0; -} - -void ZBarcode_Delete(struct zint_symbol *symbol) -{ - if (symbol->bitmap != NULL) - free(symbol->bitmap); - - // If there is a rendered version, ensure it's memory is released - if (symbol->rendered != NULL) { - struct zint_render_line *line, *l; - struct zint_render_string *string, *s; - - // Free lines - line = symbol->rendered->lines; - while(line) { - l = line; - line = line->next; - free(l); - } - // Free Strings - string = symbol->rendered->strings; - while (string) { - s = string; - string = string->next; - free(s->text); - free(s); - } - - // Free Render - free(symbol->rendered); - } - free(symbol); -} - -extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ -extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 3 from 9 (or Code 39) */ -extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ -extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */ -extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */ -extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */ -extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */ -extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */ -extern int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */ -extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */ -extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */ -extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ -extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ -extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ -extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */ -extern int ean_128(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-128 (GS1-128) */ -extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ -extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ -extern int telepen(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen ASCII */ -extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], int length); /* Telepen Numeric */ -extern int plessey(struct zint_symbol *symbol, unsigned char source[], int length); /* Plessey Code */ -extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */ -extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */ -extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */ -extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */ -extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */ -extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */ -extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */ -extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ -extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ -extern int code16k(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 16k */ -extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length); /* PDF417 */ -extern int dmatrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Data Matrix (IEC16022) */ -extern int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */ -extern int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length); /* Micro PDF417 */ -extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ -extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ -extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ -extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */ -extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ -extern int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ -extern int aztec(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Code */ -extern int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ -extern int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ -extern int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ -extern int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */ -extern int microqr(struct zint_symbol *symbol, unsigned char source[], int length); /* Micro QR Code */ -extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */ -extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */ -extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ -extern int code_49(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 49 */ -extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ -extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */ -extern int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length); /* Grid Matrix */ - -#ifndef NO_PNG -extern int png_handle(struct zint_symbol *symbol, int rotate_angle); -#endif - -extern int render_plot(struct zint_symbol *symbol, float width, float height); - -extern int bmp_handle(struct zint_symbol *symbol, int rotate_angle); -extern int ps_plot(struct zint_symbol *symbol); -extern int svg_plot(struct zint_symbol *symbol); - -void error_tag(char error_string[], int error_number) -{ - char error_buffer[100]; - - if(error_number != 0) { - strcpy(error_buffer, error_string); - - if(error_number > 4) { - strcpy(error_string, "error: "); - } else { - strcpy(error_string, "warning: "); - } - - concat(error_string, error_buffer); - } -} - -int dump_plot(struct zint_symbol *symbol) -{ - FILE *f; - int i, r; - - if(symbol->output_options & BARCODE_STDOUT) { - f = stdout; - } else { - f = fopen(symbol->outfile, "w"); - if(!f) { - strcpy(symbol->errtxt, "Could not open output file"); - return ERROR_FILE_ACCESS; - } - } - - fputs("[\n", f); - for (r = 0; r < symbol->rows; r++) { - fputs(" [ ", f); - for (i = 0; i < symbol->width; i++) { - fputs(module_is_set(symbol, r, i) ? "1 " : "0 ", f); - } - fputs("]\n", f); - } - fputs("]\n", f); - - fclose(f); - - return 0; -} - -int hibc(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int counter, error_number, i; - char to_process[40], temp[2], check_digit; - - if(length > 36) { - strcpy(symbol->errtxt, "Data too long for HIBC LIC"); - return ERROR_TOO_LONG; - } - to_upper(source); - error_number = is_sane(TECHNETIUM , source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - strcpy(to_process, "+"); - counter = 41; - for(i = 0; i < length; i++) { - counter += posn(TECHNETIUM, source[i]); - } - counter = counter % 43; - - if(counter < 10) { - check_digit = itoc(counter); - } else { - if(counter < 36) { - check_digit = (counter - 10) + 'A'; - } else { - switch(counter) { - case 36: check_digit = '-'; break; - case 37: check_digit = '.'; break; - case 38: check_digit = ' '; break; - case 39: check_digit = '$'; break; - case 40: check_digit = '/'; break; - case 41: check_digit = '+'; break; - case 42: check_digit = '%'; break; - default: check_digit = ' '; break; /* Keep compiler happy */ - } - } - } - - temp[0] = check_digit; - temp[1] = '\0'; - - concat(to_process, (char *)source); - concat(to_process, temp); - length = strlen(to_process); - - switch(symbol->symbology) { - case BARCODE_HIBC_128: - error_number = code_128(symbol, (unsigned char *)to_process, length); - ustrcpy(symbol->text, (unsigned char*)"*"); - uconcat(symbol->text, (unsigned char*)to_process); - uconcat(symbol->text, (unsigned char*)"*"); - break; - case BARCODE_HIBC_39: - symbol->option_2 = 0; - error_number = c39(symbol, (unsigned char *)to_process, length); - ustrcpy(symbol->text, (unsigned char*)"*"); - uconcat(symbol->text, (unsigned char*)to_process); - uconcat(symbol->text, (unsigned char*)"*"); - break; - case BARCODE_HIBC_DM: - error_number = dmatrix(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_QR: - error_number = qr_code(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_PDF: - error_number = pdf417enc(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_MICPDF: - error_number = micro_pdf417(symbol, (unsigned char *)to_process, length); - break; - case BARCODE_HIBC_AZTEC: - error_number = aztec(symbol, (unsigned char *)to_process, length); - break; - } - - return error_number; -} - -int gs1_compliant(int symbology) -{ - /* Returns 1 if symbology supports GS1 data */ - - int result = 0; - - switch(symbology) { - case BARCODE_EAN128: - case BARCODE_RSS_EXP: - case BARCODE_RSS_EXPSTACK: - case BARCODE_EANX_CC: - case BARCODE_EAN128_CC: - case BARCODE_RSS14_CC: - case BARCODE_RSS_LTD_CC: - case BARCODE_RSS_EXP_CC: - case BARCODE_UPCA_CC: - case BARCODE_UPCE_CC: - case BARCODE_RSS14STACK_CC: - case BARCODE_RSS14_OMNI_CC: - case BARCODE_RSS_EXPSTACK_CC: - case BARCODE_CODE16K: - case BARCODE_AZTEC: - case BARCODE_DATAMATRIX: - case BARCODE_CODEONE: - case BARCODE_CODE49: - case BARCODE_QRCODE: - result = 1; - break; - } - - return result; -} - -int ZBarcode_ValidID(int symbol_id) -{ - /* Checks whether a symbology is supported */ - - int result = 0; - - switch(symbol_id) { - case BARCODE_CODE11: - case BARCODE_C25MATRIX: - case BARCODE_C25INTER: - case BARCODE_C25IATA: - case BARCODE_C25LOGIC: - case BARCODE_C25IND: - case BARCODE_CODE39: - case BARCODE_EXCODE39: - case BARCODE_EANX: - case BARCODE_EAN128: - case BARCODE_CODABAR: - case BARCODE_CODE128: - case BARCODE_DPLEIT: - case BARCODE_DPIDENT: - case BARCODE_CODE16K: - case BARCODE_CODE49: - case BARCODE_CODE93: - case BARCODE_FLAT: - case BARCODE_RSS14: - case BARCODE_RSS_LTD: - case BARCODE_RSS_EXP: - case BARCODE_TELEPEN: - case BARCODE_UPCA: - case BARCODE_UPCE: - case BARCODE_POSTNET: - case BARCODE_MSI_PLESSEY: - case BARCODE_FIM: - case BARCODE_LOGMARS: - case BARCODE_PHARMA: - case BARCODE_PZN: - case BARCODE_PHARMA_TWO: - case BARCODE_PDF417: - case BARCODE_PDF417TRUNC: - case BARCODE_MAXICODE: - case BARCODE_QRCODE: - case BARCODE_CODE128B: - case BARCODE_AUSPOST: - case BARCODE_AUSREPLY: - case BARCODE_AUSROUTE: - case BARCODE_AUSREDIRECT: - case BARCODE_ISBNX: - case BARCODE_RM4SCC: - case BARCODE_DATAMATRIX: - case BARCODE_EAN14: - case BARCODE_NVE18: - case BARCODE_JAPANPOST: - case BARCODE_KOREAPOST: - case BARCODE_RSS14STACK: - case BARCODE_RSS14STACK_OMNI: - case BARCODE_RSS_EXPSTACK: - case BARCODE_PLANET: - case BARCODE_MICROPDF417: - case BARCODE_ONECODE: - case BARCODE_PLESSEY: - case BARCODE_TELEPEN_NUM: - case BARCODE_ITF14: - case BARCODE_KIX: - case BARCODE_AZTEC: - case BARCODE_DAFT: - case BARCODE_MICROQR: - case BARCODE_HIBC_128: - case BARCODE_HIBC_39: - case BARCODE_HIBC_DM: - case BARCODE_HIBC_QR: - case BARCODE_HIBC_PDF: - case BARCODE_HIBC_MICPDF: - case BARCODE_HIBC_AZTEC: - case BARCODE_AZRUNE: - case BARCODE_CODE32: - case BARCODE_EANX_CC: - case BARCODE_EAN128_CC: - case BARCODE_RSS14_CC: - case BARCODE_RSS_LTD_CC: - case BARCODE_RSS_EXP_CC: - case BARCODE_UPCA_CC: - case BARCODE_UPCE_CC: - case BARCODE_RSS14STACK_CC: - case BARCODE_RSS14_OMNI_CC: - case BARCODE_RSS_EXPSTACK_CC: - case BARCODE_CHANNEL: - case BARCODE_CODEONE: - case BARCODE_GRIDMATRIX: - result = 1; - break; - } - - return result; -} - -int extended_charset(struct zint_symbol *symbol, unsigned char *source, int length) -{ - int error_number = 0; - - /* These are the "elite" standards which can support multiple character sets */ - switch(symbol->symbology) { - case BARCODE_QRCODE: error_number = qr_code(symbol, source, length); break; - case BARCODE_MICROQR: error_number = microqr(symbol, source, length); break; - case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length); break; - } - - return error_number; -} - -int reduced_charset(struct zint_symbol *symbol, unsigned char *source, int length) -{ - /* These are the "norm" standards which only support Latin-1 at most */ - int error_number = 0; - -#ifndef _MSC_VER - unsigned char preprocessed[length + 1]; -#else - unsigned char* preprocessed = (unsigned char*)_alloca(length + 1); -#endif - - if(symbol->symbology == BARCODE_CODE16K) { - symbol->whitespace_width = 16; - symbol->border_width = 2; - symbol->output_options = BARCODE_BIND; - } - - if(symbol->symbology == BARCODE_ITF14) { - symbol->whitespace_width = 20; - symbol->border_width = 8; - symbol->output_options = BARCODE_BOX; - } - - switch(symbol->input_mode) { - case DATA_MODE: - case GS1_MODE: - memcpy(preprocessed, source, length); - preprocessed[length] = '\0'; - break; - case UNICODE_MODE: - error_number = latin1_process(symbol, source, preprocessed, &length); - if(error_number != 0) { return error_number; } - break; - } - - switch(symbol->symbology) { - case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, length); break; - case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, length); break; - case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, length); break; - case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, length); break; - case BARCODE_UPCA: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_UPCE: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_EANX: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, length); break; - case BARCODE_CODE39: error_number = c39(symbol, preprocessed, length); break; - case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, length); break; - case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, length); break; - case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, length); break; - case BARCODE_CODE93: error_number = c93(symbol, preprocessed, length); break; - case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, length); break; - case BARCODE_CODE128: error_number = code_128(symbol, preprocessed, length); break; - case BARCODE_CODE128B: error_number = code_128(symbol, preprocessed, length); break; - case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, length); break; - case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, length); break; - case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, length); break; - case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, length); break; - case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, length); break; - case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, length); break; - case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, length); break; - case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, length); break; - case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, length); break; - case BARCODE_FIM: error_number = fim(symbol, preprocessed, length); break; - case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, length); break; - case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, length); break; - case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, length); break; - case BARCODE_AUSPOST: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_AUSREPLY: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_AUSROUTE: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_AUSREDIRECT: error_number = australia_post(symbol, preprocessed, length); break; - case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, length); break; - case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, length); break; - case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, length); break; - case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, length); break; - case BARCODE_RSS14: error_number = rss14(symbol, preprocessed, length); break; - case BARCODE_RSS14STACK: error_number = rss14(symbol, preprocessed, length); break; - case BARCODE_RSS14STACK_OMNI: error_number = rss14(symbol, preprocessed, length); break; - case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, length); break; - case BARCODE_RSS_EXP: error_number = rssexpanded(symbol, preprocessed, length); break; - case BARCODE_RSS_EXPSTACK: error_number = rssexpanded(symbol, preprocessed, length); break; - case BARCODE_EANX_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_EAN128_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS14_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS_LTD_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS_EXP_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_UPCA_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_UPCE_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS14STACK_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS14_OMNI_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_RSS_EXPSTACK_CC: error_number = composite(symbol, preprocessed, length); break; - case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, length); break; - case BARCODE_CODE32: error_number = code32(symbol, preprocessed, length); break; - case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, length); break; - case BARCODE_EAN14: error_number = ean_14(symbol, preprocessed, length); break; - case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, length); break; - case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, length); break; - case BARCODE_HIBC_128: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_39: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_DM: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_QR: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_PDF: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_MICPDF: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_HIBC_AZTEC: error_number = hibc(symbol, preprocessed, length); break; - case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, length); break; - case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, length); break; - case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, length); break; - case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, length); break; - case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, length); break; - case BARCODE_PDF417: error_number = pdf417enc(symbol, preprocessed, length); break; - case BARCODE_PDF417TRUNC: error_number = pdf417enc(symbol, preprocessed, length); break; - case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, length); break; - case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, length); break; - case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, length); break; - } - - return error_number; -} - -int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source, int length) -{ -#ifdef _MSC_VER - unsigned char* local_source; -#endif - int error_number, error_buffer, i; - error_number = 0; - - if(length == 0) { - length = ustrlen(source); - } - if(length == 0) { - strcpy(symbol->errtxt, "No input data"); - error_tag(symbol->errtxt, ERROR_INVALID_DATA1); - return ERROR_INVALID_DATA1; - } - - if(strcmp(symbol->outfile, "") == 0) { - strcpy(symbol->outfile, "out.png"); - } -#ifndef _MSC_VER - unsigned char local_source[length + 1]; -#else - local_source = (unsigned char*)_alloca(length + 1); -#endif - - /* First check the symbology field */ - if(symbol->symbology < 1) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - - /* symbol->symbologys 1 to 86 are defined by tbarcode */ - if(symbol->symbology == 5) { symbol->symbology = BARCODE_C25MATRIX; } - if((symbol->symbology >= 10) && (symbol->symbology <= 12)) { symbol->symbology = BARCODE_EANX; } - if((symbol->symbology == 14) || (symbol->symbology == 15)) { symbol->symbology = BARCODE_EANX; } - if(symbol->symbology == 17) { symbol->symbology = BARCODE_UPCA; } - if(symbol->symbology == 19) { strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar"); symbol->symbology = BARCODE_CODABAR; error_number = WARN_INVALID_OPTION; } - if(symbol->symbology == 26) { symbol->symbology = BARCODE_UPCA; } - if(symbol->symbology == 27) { strcpy(symbol->errtxt, "UPCD1 not supported"); error_number = ERROR_INVALID_OPTION; } - if(symbol->symbology == 33) { symbol->symbology = BARCODE_EAN128; } - if((symbol->symbology == 35) || (symbol->symbology == 36)) { symbol->symbology = BARCODE_UPCA; } - if((symbol->symbology == 38) || (symbol->symbology == 39)) { symbol->symbology = BARCODE_UPCE; } - if((symbol->symbology >= 41) && (symbol->symbology <= 45)) { symbol->symbology = BARCODE_POSTNET; } - if(symbol->symbology == 46) { symbol->symbology = BARCODE_PLESSEY; } - if(symbol->symbology == 48) { symbol->symbology = BARCODE_NVE18; } - if(symbol->symbology == 54) { strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if((symbol->symbology == 59) || (symbol->symbology == 61)) { symbol->symbology = BARCODE_CODE128; } - if(symbol->symbology == 62) { symbol->symbology = BARCODE_CODE93; } - if((symbol->symbology == 64) || (symbol->symbology == 65)) { symbol->symbology = BARCODE_AUSPOST; } - if(symbol->symbology == 73) { strcpy(symbol->errtxt, "Codablock E not supported"); error_number = ERROR_INVALID_OPTION; } - if(symbol->symbology == 78) { symbol->symbology = BARCODE_RSS14; } - if(symbol->symbology == 83) { symbol->symbology = BARCODE_PLANET; } - if(symbol->symbology == 88) { symbol->symbology = BARCODE_EAN128; } - if(symbol->symbology == 91) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if((symbol->symbology >= 94) && (symbol->symbology <= 96)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if(symbol->symbology == 100) { symbol->symbology = BARCODE_HIBC_128; } - if(symbol->symbology == 101) { symbol->symbology = BARCODE_HIBC_39; } - if(symbol->symbology == 103) { symbol->symbology = BARCODE_HIBC_DM; } - if(symbol->symbology == 105) { symbol->symbology = BARCODE_HIBC_QR; } - if(symbol->symbology == 107) { symbol->symbology = BARCODE_HIBC_PDF; } - if(symbol->symbology == 109) { symbol->symbology = BARCODE_HIBC_MICPDF; } - if(symbol->symbology == 111) { symbol->symbology = BARCODE_HIBC_BLOCKF; } - if((symbol->symbology >= 113) && (symbol->symbology <= 127)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - /* Everything from 128 up is Zint-specific */ - if(symbol->symbology >= 143) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } - if((symbol->symbology == BARCODE_CODABLOCKF) || (symbol->symbology == BARCODE_HIBC_BLOCKF)) { strcpy(symbol->errtxt, "Codablock F not supported"); error_number = ERROR_INVALID_OPTION; } - - if(error_number > 4) { - error_tag(symbol->errtxt, error_number); - return error_number; - } else { - error_buffer = error_number; - } - - if((symbol->input_mode < 0) || (symbol->input_mode > 2)) { symbol->input_mode = DATA_MODE; } - - if(symbol->input_mode == GS1_MODE) { - for(i = 0; i < length; i++) { - if(source[i] == '\0') { - strcpy(symbol->errtxt, "NULL characters not permitted in GS1 mode"); - return ERROR_INVALID_DATA1; - } - } - if(gs1_compliant(symbol->symbology) == 1) { - error_number = ugs1_verify(symbol, source, length, local_source); - if(error_number != 0) { return error_number; } - length = ustrlen(local_source); - } else { - strcpy(symbol->errtxt, "Selected symbology does not support GS1 mode"); - return ERROR_INVALID_OPTION; - } - } else { - memcpy(local_source, source, length); - local_source[length] = '\0'; - } - - switch(symbol->symbology) { - case BARCODE_QRCODE: - case BARCODE_MICROQR: - case BARCODE_GRIDMATRIX: - error_number = extended_charset(symbol, local_source, length); - break; - default: - error_number = reduced_charset(symbol, local_source, length); - break; - } - - if((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) { - for(i = 0; i < length; i++) { - if(local_source[i] == '\0') { - symbol->text[i] = ' '; - } else { - symbol->text[i] = local_source[i]; - } - } - } - - if(error_number == 0) { - error_number = error_buffer; - } - error_tag(symbol->errtxt, error_number); - /*printf("%s\n",symbol->text);*/ - return error_number; -} - -int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) -{ - int error_number; - char output[4]; - - switch(rotate_angle) { - case 0: - case 90: - case 180: - case 270: - break; - default: - strcpy(symbol->errtxt, "Invalid rotation angle"); - return ERROR_INVALID_OPTION; - break; - } - - if(strlen(symbol->outfile) > 3) { - output[0] = symbol->outfile[strlen(symbol->outfile) - 3]; - output[1] = symbol->outfile[strlen(symbol->outfile) - 2]; - output[2] = symbol->outfile[strlen(symbol->outfile) - 1]; - output[3] = '\0'; - to_upper((unsigned char*)output); - -#ifndef NO_PNG - if(!(strcmp(output, "PNG"))) { - if(symbol->scale < 1.0) { symbol->text[0] = '\0'; } - error_number = png_handle(symbol, rotate_angle); - } else -#endif - if(!(strcmp(output, "TXT"))) { - error_number = dump_plot(symbol); - } else - if(!(strcmp(output, "EPS"))) { - error_number = ps_plot(symbol); - } else - if(!(strcmp(output, "SVG"))) { - error_number = svg_plot(symbol); - } else - { - strcpy(symbol->errtxt, "Unknown output format"); - error_tag(symbol->errtxt, ERROR_INVALID_OPTION); - return ERROR_INVALID_OPTION; - } - } else { - strcpy(symbol->errtxt, "Unknown output format"); - error_tag(symbol->errtxt, ERROR_INVALID_OPTION); - return ERROR_INVALID_OPTION; - } - - error_tag(symbol->errtxt, error_number); - return error_number; -} - -int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) -{ - int error_number; - - switch(rotate_angle) { - case 0: - case 90: - case 180: - case 270: - break; - default: - strcpy(symbol->errtxt, "Invalid rotation angle"); - return ERROR_INVALID_OPTION; - break; - } - - error_number = bmp_handle(symbol, rotate_angle); - error_tag(symbol->errtxt, error_number); - return error_number; -} - -int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) -{ - int error_number; - - error_number = 0; - - error_number = ZBarcode_Encode(symbol, input, length); - if(error_number != 0) { - return error_number; - } - - error_number = ZBarcode_Print(symbol, rotate_angle); - return error_number; -} - -int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) -{ - int error_number; - - error_number = 0; - - error_number = ZBarcode_Encode(symbol, input, length); - if(error_number != 0) { - return error_number; - } - - error_number = ZBarcode_Buffer(symbol, rotate_angle); - return error_number; -} - -int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) -{ - FILE *file; - unsigned char *buffer; - unsigned long fileLen; - unsigned int nRead = 0, n = 0; - int ret; - - if (!strcmp(filename, "-")) { - file = stdin; - fileLen = 7100; - } else { - file = fopen(filename, "rb"); - if (!file) { - strcpy(symbol->errtxt, "Unable to read input file"); - return ERROR_INVALID_DATA1; - } - - /* Get file length */ - fseek(file, 0, SEEK_END); - fileLen = ftell(file); - fseek(file, 0, SEEK_SET); - - if(fileLen > 7100) { - /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */ - strcpy(symbol->errtxt, "Input file too long"); - fclose(file); - return ERROR_INVALID_DATA1; - } - } - - /* Allocate memory */ - buffer = (unsigned char *)malloc(fileLen * sizeof(unsigned char)); - if(!buffer) { - strcpy(symbol->errtxt, "Internal memory error"); - fclose(file); - return ERROR_MEMORY; - } - - /* Read file contents into buffer */ - - do - { - n = fread(buffer + nRead, 1, fileLen - nRead, file); - if (ferror(file)) - { - strcpy(symbol->errtxt, strerror(errno)); - nRead = 0; - return ERROR_INVALID_DATA1; - } - nRead += n; - } while (!feof(file) && (0 < n) && (nRead < fileLen)); - - fclose(file); - ret = ZBarcode_Encode(symbol, buffer, nRead); - free(buffer); - return ret; -} - -int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) -{ - int error_number; - - error_number = 0; - - error_number = ZBarcode_Encode_File(symbol, filename); - if(error_number != 0) { - return error_number; - } - - return ZBarcode_Print(symbol, rotate_angle); -} - -int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle) -{ - int error_number; - - error_number = 0; - - error_number = ZBarcode_Encode_File(symbol, filename); - if(error_number != 0) { - return error_number; - } - - return ZBarcode_Buffer(symbol, rotate_angle); -} - -/* - * Rendering support, initially added by Sam Lown. - * - * Converts encoded data into an intermediate format to be interpreted - * in other applications using this library. - * - * If the width and height are not set to zero, the barcode will be resized to those - * dimensions. The symbol->scale and symbol->height values are totally ignored in this case. - * - */ -int ZBarcode_Render(struct zint_symbol *symbol, float width, float height) -{ - // Send the request to the render_plot method - return render_plot(symbol, width, height); -} diff --git a/3rdparty/zint-2.4.4/backend/maxicode.c b/3rdparty/zint-2.4.4/backend/maxicode.c deleted file mode 100644 index 53ce12e..0000000 --- a/3rdparty/zint-2.4.4/backend/maxicode.c +++ /dev/null @@ -1,709 +0,0 @@ -/* maxicode.c - Handles Maxicode */ - -/* - libzint - the open source barcode library - Copyright (C) 2010 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* Includes corrections thanks to Monica Swanson @ Source Technologies */ - -#include "common.h" -#include "maxicode.h" -#include "reedsol.h" -#include -#include -#ifdef __APPLE__ -#include -#else -#include -#endif - -int maxi_codeword[144]; - -void maxi_do_primary_check( ) -{ - /* Handles error correction of primary message */ - unsigned char data[15]; - unsigned char results[15]; - int j; - int datalen = 10; - int ecclen = 10; - - rs_init_gf(0x43); - rs_init_code(ecclen, 1); - - for(j = 0; j < datalen; j += 1) - data[j] = maxi_codeword[j]; - - rs_encode(datalen, data, results); - - for ( j = 0; j < ecclen; j += 1) - maxi_codeword[ datalen + j] = results[ecclen - 1 - j]; - rs_free(); -} - -void maxi_do_secondary_chk_odd( int ecclen ) -{ - /* Handles error correction of odd characters in secondary */ - unsigned char data[100]; - unsigned char results[30]; - int j; - int datalen = 68; - - rs_init_gf(0x43); - rs_init_code(ecclen, 1); - - if (ecclen == 20) - datalen = 84; - - for(j = 0; j < datalen; j += 1) - if (j & 1) // odd - data[(j-1)/2] = maxi_codeword[j + 20]; - - rs_encode(datalen/2, data, results); - - for ( j = 0; j < (ecclen); j += 1) - maxi_codeword[ datalen + (2 *j) + 1 + 20 ] = results[ecclen - 1 - j]; - rs_free(); -} - -void maxi_do_secondary_chk_even(int ecclen ) -{ - /* Handles error correction of even characters in secondary */ - unsigned char data[100]; - unsigned char results[30]; - int j; - int datalen = 68; - - if (ecclen == 20) - datalen = 84; - - rs_init_gf(0x43); - rs_init_code(ecclen, 1); - - for(j = 0; j < datalen + 1; j += 1) - if (!(j & 1)) // even - data[j/2] = maxi_codeword[j + 20]; - - rs_encode(datalen/2, data, results); - - for ( j = 0; j < (ecclen); j += 1) - maxi_codeword[ datalen + (2 *j) + 20] = results[ecclen - 1 - j]; - rs_free(); -} - -void maxi_bump(int set[], int character[], int bump_posn) -{ - /* Moves everything up so that a shift or latch can be inserted */ - int i; - - for(i = 143; i > bump_posn; i--) { - set[i] = set[i - 1]; - character[i] = character[i - 1]; - } -} - -int maxi_text_process(int mode, unsigned char source[], int length) -{ - /* Format text according to Appendix A */ - - /* This code doesn't make use of [Lock in C], [Lock in D] - and [Lock in E] and so is not always the most efficient at - compressing data, but should suffice for most applications */ - - int set[144], character[144], i, j, done, count, current_set; - - if(length > 138) { - return ERROR_TOO_LONG; - } - - for(i = 0; i < 144; i++) { - set[i] = -1; - character[i] = 0; - } - - for (i = 0; i < length; i++) { - /* Look up characters in table from Appendix A - this gives - value and code set for most characters */ - set[i] = maxiCodeSet[source[i]]; - character[i] = maxiSymbolChar[source[i]]; - } - - /* If a character can be represented in more than one code set, - pick which version to use */ - if(set[0] == 0) { - if(character[0] == 13) { - character[0] = 0; - } - set[0] = 1; - } - - for(i = 1; i < length; i++) { - if(set[i] == 0) { - done = 0; - /* Special character */ - if(character[i] == 13) { - /* Carriage Return */ - if(set[i - 1] == 5) { - character[i] = 13; - set[i] = 5; - } else { - if((i != length - 1) && (set[i + 1] == 5)) { - character[i] = 13; - set[i] = 5; - } else { - character[i] = 0; - set[i] = 1; - } - } - done = 1; - } - - if((character[i] == 28) && (done == 0)) { - /* FS */ - if(set[i - 1] == 5) { - character[i] = 32; - set[i] = 5; - } else { - set[i] = set[i - 1]; - } - done = 1; - } - - if((character[i] == 29) && (done == 0)) { - /* GS */ - if(set[i - 1] == 5) { - character[i] = 33; - set[i] = 5; - } else { - set[i] = set[i - 1]; - } - done = 1; - } - - if((character[i] == 30) && (done == 0)) { - /* RS */ - if(set[i - 1] == 5) { - character[i] = 34; - set[i] = 5; - } else { - set[i] = set[i - 1]; - } - done = 1; - } - - if((character[i] == 32) && (done == 0)) { - /* Space */ - if(set[i - 1] == 1) { - character[i] = 32; - set[i] = 1; - } - if(set[i - 1] == 2) { - character[i] = 47; - set[i] = 2; - } - if(set[i - 1] >= 3) { - if(i != length - 1) { - if(set[i + 1] == 1) { - character[i] = 32; - set[i] = 1; - } - if(set[i + 1] == 2) { - character[i] = 47; - set[i] = 2; - } - if(set[i + 1] >= 3) { - character[i] = 59; - set[i] = set[i - 1]; - } - } else { - character[i] = 59; - set[i] = set[i - 1]; - } - } - done = 1; - } - - if((character[i] == 44) && (done == 0)) { - /* Comma */ - if(set[i - 1] == 2) { - character[i] = 48; - set[i] = 2; - } else { - if((i != length - 1) && (set[i + 1] == 2)) { - character[i] = 48; - set[i] = 2; - } else { - set[i] = 1; - } - } - done = 1; - } - - if((character[i] == 46) && (done == 0)) { - /* Full Stop */ - if(set[i - 1] == 2) { - character[i] = 49; - set[i] = 2; - } else { - if((i != length - 1) && (set[i + 1] == 2)) { - character[i] = 49; - set[i] = 2; - } else { - set[i] = 1; - } - } - done = 1; - } - - if((character[i] == 47) && (done == 0)) { - /* Slash */ - if(set[i - 1] == 2) { - character[i] = 50; - set[i] = 2; - } else { - if((i != length - 1) && (set[i + 1] == 2)) { - character[i] = 50; - set[i] = 2; - } else { - set[i] = 1; - } - } - done = 1; - } - - if((character[i] == 58) && (done == 0)) { - /* Colon */ - if(set[i - 1] == 2) { - character[i] = 51; - set[i] = 2; - } else { - if((i != length - 1) && (set[i + 1] == 2)) { - character[i] = 51; - set[i] = 2; - } else { - set[i] = 1; - } - } - done = 1; - } - } - } - - for(i = length; i < 144; i++) { - /* Add the padding */ - if(set[length - 1] == 2) { - set[i] = 2; - } else { - set[i] = 1; - } - character[i] = 33; - } - - /* Find candidates for number compression */ - if((mode == 2) || (mode ==3)) { j = 0; } else { j = 9; } - /* Number compression not allowed in primary message */ - count = 0; - for(i = j; i < 143; i++) { - if((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) { - /* Character is a number */ - count++; - } else { - count = 0; - } - if(count == 9) { - /* Nine digits in a row can be compressed */ - set[i] = 6; - set[i - 1] = 6; - set[i - 2] = 6; - set[i - 3] = 6; - set[i - 4] = 6; - set[i - 5] = 6; - set[i - 6] = 6; - set[i - 7] = 6; - set[i - 8] = 6; - count = 0; - } - } - - /* Add shift and latch characters */ - current_set = 1; - i = 0; - do { - - if(set[i] != current_set) { - switch(set[i]) { - case 1: - if(set[i + 1] == 1) { - if(set[i + 2] == 1) { - if(set[i + 3] == 1) { - /* Latch A */ - maxi_bump(set, character, i); - character[i] = 63; - current_set = 1; - length++; - } else { - /* 3 Shift A */ - maxi_bump(set, character, i); - character[i] = 57; - length++; - i += 2; - } - } else { - /* 2 Shift A */ - maxi_bump(set, character, i); - character[i] = 56; - length++; - i++; - } - } else { - /* Shift A */ - maxi_bump(set, character, i); - character[i] = 59; - length++; - } - break; - case 2: - if(set[i + 1] == 2) { - /* Latch B */ - maxi_bump(set, character, i); - character[i] = 63; - current_set = 2; - length++; - } else { - /* Shift B */ - maxi_bump(set, character, i); - character[i] = 59; - length++; - } - break; - case 3: - /* Shift C */ - maxi_bump(set, character, i); - character[i] = 60; - length++; - break; - case 4: - /* Shift D */ - maxi_bump(set, character, i); - character[i] = 61; - length++; - break; - case 5: - /* Shift E */ - maxi_bump(set, character, i); - character[i] = 62; - length++; - break; - case 6: - /* Number Compressed */ - /* Do nothing */ - break; - } - i++; - } - i++; - } while(i < 145); - - /* Number compression has not been forgotten! - It's handled below */ - i = 0; - do { - if (set[i] == 6) { - /* Number compression */ - char substring[11]; - int value; - - for(j = 0; j < 10; j++) { - substring[j] = character[i + j]; - } - substring[10] = '\0'; - value = atoi(substring); - - character[i] = 31; /* NS */ - character[i + 1] = (value & 0x3f000000) >> 24; - character[i + 2] = (value & 0xfc0000) >> 18; - character[i + 3] = (value & 0x3f000) >> 12; - character[i + 4] = (value & 0xfc0) >> 6; - character[i + 5] = (value & 0x3f); - - i += 6; - for(j = i; j < 140; j++) { - set[j] = set[j + 3]; - character[j] = character[j + 3]; - } - length -= 3; - } else { - i++; - } - } while (i <= 143); - - if(((mode ==2) || (mode == 3)) && (length > 84)) { - return ERROR_TOO_LONG; - } - - if(((mode == 4) || (mode == 6)) && (length > 93)) { - return ERROR_TOO_LONG; - } - - if((mode == 5) && (length > 77)) { - return ERROR_TOO_LONG; - } - - - /* Copy the encoded text into the codeword array */ - if((mode == 2) || (mode == 3)) { - for(i = 0; i < 84; i++) { /* secondary only */ - maxi_codeword[i + 20] = character[i]; - } - } - - if((mode == 4) || (mode == 6)) { - for(i = 0; i < 9; i++) { /* primary */ - maxi_codeword[i + 1] = character[i]; - } - for(i = 0; i < 84; i++) { /* secondary */ - maxi_codeword[i + 20] = character[i + 9]; - } - } - - if(mode == 5) { - for(i = 0; i < 9; i++) { /* primary */ - maxi_codeword[i + 1] = character[i]; - } - for(i = 0; i < 68; i++) { /* secondary */ - maxi_codeword[i + 20] = character[i + 9]; - } - } - - return 0; -} - -void maxi_do_primary_2(char postcode[], int country, int service) -{ - /* Format structured primary for Mode 2 */ - int postcode_length, postcode_num, i; - - for(i = 0; i < 10; i++) { - if((postcode[i] < '0') || (postcode[i] > '9')) { - postcode[i] = '\0'; - } - } - - postcode_length = strlen(postcode); - postcode_num = atoi(postcode); - - maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2; - maxi_codeword[1] = ((postcode_num & 0xfc) >> 2); - maxi_codeword[2] = ((postcode_num & 0x3f00) >> 8); - maxi_codeword[3] = ((postcode_num & 0xfc000) >> 14); - maxi_codeword[4] = ((postcode_num & 0x3f00000) >> 20); - maxi_codeword[5] = ((postcode_num & 0x3c000000) >> 26) | ((postcode_length & 0x3) << 4); - maxi_codeword[6] = ((postcode_length & 0x3c) >> 2) | ((country & 0x3) << 4); - maxi_codeword[7] = (country & 0xfc) >> 2; - maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); - maxi_codeword[9] = ((service & 0x3f0) >> 4); -} - -void maxi_do_primary_3(char postcode[], int country, int service) -{ - /* Format structured primary for Mode 3 */ - int i, h; - - h = strlen(postcode); - to_upper((unsigned char*)postcode); - for(i = 0; i < h; i++) { - if((postcode[i] >= 'A') && (postcode[i] <= 'Z')) { - /* (Capital) letters shifted to Code Set A values */ - postcode[i] -= 64; - } - if(((postcode[i] == 27) || (postcode[i] == 31)) || ((postcode[i] == 33) || (postcode[i] >= 59))) { - /* Not a valid postcode character */ - postcode[i] = ' '; - } - /* Input characters lower than 27 (NUL - SUB) in postcode are - interpreted as capital letters in Code Set A (e.g. LF becomes 'J') */ - } - - maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3; - maxi_codeword[1] = ((postcode[4] & 0x03) << 4) | ((postcode[5] & 0x3c) >> 2); - maxi_codeword[2] = ((postcode[3] & 0x03) << 4) | ((postcode[4] & 0x3c) >> 2); - maxi_codeword[3] = ((postcode[2] & 0x03) << 4) | ((postcode[3] & 0x3c) >> 2); - maxi_codeword[4] = ((postcode[1] & 0x03) << 4) | ((postcode[2] & 0x3c) >> 2); - maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2); - maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4); - maxi_codeword[7] = (country & 0xfc) >> 2; - maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); - maxi_codeword[9] = ((service & 0x3f0) >> 4); -} - -int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0; - int bit_pattern[7], internal_error = 0, eclen, error_number; - char postcode[12], countrystr[4], servicestr[4]; - -#ifndef _MSC_VER - unsigned char local_source[length + 1]; -#else - unsigned char* local_source = (unsigned char*)_alloca(length + 1); -#endif - - mode = symbol->option_1; - strcpy(postcode, ""); - strcpy(countrystr, ""); - strcpy(servicestr, ""); - - /* The following to be replaced by ECI handling */ - switch(symbol->input_mode) { - case DATA_MODE: - case GS1_MODE: - memcpy(local_source, source, length); - local_source[length] = '\0'; - break; - case UNICODE_MODE: - error_number = latin1_process(symbol, source, local_source, &length); - if(error_number != 0) { return error_number; } - break; - } - memset(maxi_codeword, 0, sizeof(maxi_codeword)); - - if(mode == -1) { /* If mode is unspecified */ - lp = strlen(symbol->primary); - if(lp == 0) { - mode = 4; - } else { - mode = 2; - for(i = 0; i < 10 && i < lp; i++) { - if((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) { - mode = 3; - break; - } - } - } - } - - if((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */ - strcpy(symbol->errtxt, "Invalid Maxicode Mode"); - return ERROR_INVALID_OPTION; - } - - if((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */ - if(lp == 0){ /* Mode set manually means lp doesn't get set */ - lp = strlen( symbol->primary ); - } - if(lp != 15) { - strcpy(symbol->errtxt, "Invalid Primary String"); - return ERROR_INVALID_DATA1; - } - - for(i = 9; i < 15; i++) { /* check that country code and service are numeric */ - if((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) { - strcpy(symbol->errtxt, "Invalid Primary String"); - return ERROR_INVALID_DATA1; - } - } - - memcpy(postcode, symbol->primary, 9); - postcode[9] = '\0'; - - if(mode == 2) { - for(i = 0; i < 10; i++) { - if(postcode[i] == ' ') { - postcode[i] = '\0'; - } - } - } - else if(mode == 3) { postcode[6] = '\0'; } - - countrystr[0] = symbol->primary[9]; - countrystr[1] = symbol->primary[10]; - countrystr[2] = symbol->primary[11]; - countrystr[3] = '\0'; - - servicestr[0] = symbol->primary[12]; - servicestr[1] = symbol->primary[13]; - servicestr[2] = symbol->primary[14]; - servicestr[3] = '\0'; - - countrycode = atoi(countrystr); - service = atoi(servicestr); - - if(mode == 2) { maxi_do_primary_2(postcode, countrycode, service); } - if(mode == 3) { maxi_do_primary_3(postcode, countrycode, service); } - } else { - maxi_codeword[0] = mode; - } - - i = maxi_text_process(mode, local_source, length); - if(i == ERROR_TOO_LONG ) { - strcpy(symbol->errtxt, "Input data too long"); - return i; - } - - /* All the data is sorted - now do error correction */ - maxi_do_primary_check(); /* always EEC */ - - if ( mode == 5 ) - eclen = 56; // 68 data codewords , 56 error corrections - else - eclen = 40; // 84 data codewords, 40 error corrections - - maxi_do_secondary_chk_even(eclen/2); // do error correction of even - maxi_do_secondary_chk_odd(eclen/2); // do error correction of odd - - /* Copy data into symbol grid */ - for(i = 0; i < 33; i++) { - for(j = 0; j < 30; j++) { - block = (MaxiGrid[(i * 30) + j] + 5) / 6; - bit = (MaxiGrid[(i * 30) + j] + 5) % 6; - - if(block != 0) { - - bit_pattern[0] = (maxi_codeword[block - 1] & 0x20) >> 5; - bit_pattern[1] = (maxi_codeword[block - 1] & 0x10) >> 4; - bit_pattern[2] = (maxi_codeword[block - 1] & 0x8) >> 3; - bit_pattern[3] = (maxi_codeword[block - 1] & 0x4) >> 2; - bit_pattern[4] = (maxi_codeword[block - 1] & 0x2) >> 1; - bit_pattern[5] = (maxi_codeword[block - 1] & 0x1); - - if(bit_pattern[bit] != 0) { - set_module(symbol, i, j); - } - } - } - } - - /* Add orientation markings */ - set_module(symbol, 0, 28); // Top right filler - set_module(symbol, 0, 29); - set_module(symbol, 9, 10); // Top left marker - set_module(symbol, 9, 11); - set_module(symbol, 10, 11); - set_module(symbol, 15, 7); // Left hand marker - set_module(symbol, 16, 8); - set_module(symbol, 16, 20); // Right hand marker - set_module(symbol, 17, 20); - set_module(symbol, 22, 10); // Bottom left marker - set_module(symbol, 23, 10); - set_module(symbol, 22, 17); // Bottom right marker - set_module(symbol, 23, 17); - - symbol->width = 30; - symbol->rows = 33; - - return internal_error; -} diff --git a/3rdparty/zint-2.4.4/backend/maxicode.h b/3rdparty/zint-2.4.4/backend/maxicode.h deleted file mode 100644 index f03a902..0000000 --- a/3rdparty/zint-2.4.4/backend/maxicode.h +++ /dev/null @@ -1,90 +0,0 @@ -/* maxicode.h - Handles Maxicode */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -static int MaxiGrid[] = { /* ISO/IEC 16023 Figure 5 - MaxiCode Module Sequence */ /* 30 x 33 data grid */ - 122, 121, 128, 127, 134, 133, 140, 139, 146, 145, 152, 151, 158, 157, 164, 163, 170, 169, 176, 175, 182, 181, 188, 187, 194, 193, 200, 199, 0, 0, - 124, 123, 130, 129, 136, 135, 142, 141, 148, 147, 154, 153, 160, 159, 166, 165, 172, 171, 178, 177, 184, 183, 190, 189, 196, 195, 202, 201, 817, 0, - 126, 125, 132, 131, 138, 137, 144, 143, 150, 149, 156, 155, 162, 161, 168, 167, 174, 173, 180, 179, 186, 185, 192, 191, 198, 197, 204, 203, 819, 818, - 284, 283, 278, 277, 272, 271, 266, 265, 260, 259, 254, 253, 248, 247, 242, 241, 236, 235, 230, 229, 224, 223, 218, 217, 212, 211, 206, 205, 820, 0, - 286, 285, 280, 279, 274, 273, 268, 267, 262, 261, 256, 255, 250, 249, 244, 243, 238, 237, 232, 231, 226, 225, 220, 219, 214, 213, 208, 207, 822, 821, - 288, 287, 282, 281, 276, 275, 270, 269, 264, 263, 258, 257, 252, 251, 246, 245, 240, 239, 234, 233, 228, 227, 222, 221, 216, 215, 210, 209, 823, 0, - 290, 289, 296, 295, 302, 301, 308, 307, 314, 313, 320, 319, 326, 325, 332, 331, 338, 337, 344, 343, 350, 349, 356, 355, 362, 361, 368, 367, 825, 824, - 292, 291, 298, 297, 304, 303, 310, 309, 316, 315, 322, 321, 328, 327, 334, 333, 340, 339, 346, 345, 352, 351, 358, 357, 364, 363, 370, 369, 826, 0, - 294, 293, 300, 299, 306, 305, 312, 311, 318, 317, 324, 323, 330, 329, 336, 335, 342, 341, 348, 347, 354, 353, 360, 359, 366, 365, 372, 371, 828, 827, - 410, 409, 404, 403, 398, 397, 392, 391, 80, 79, 0, 0, 14, 13, 38, 37, 3, 0, 45, 44, 110, 109, 386, 385, 380, 379, 374, 373, 829, 0, - 412, 411, 406, 405, 400, 399, 394, 393, 82, 81, 41, 0, 16, 15, 40, 39, 4, 0, 0, 46, 112, 111, 388, 387, 382, 381, 376, 375, 831, 830, - 414, 413, 408, 407, 402, 401, 396, 395, 84, 83, 42, 0, 0, 0, 0, 0, 6, 5, 48, 47, 114, 113, 390, 389, 384, 383, 378, 377, 832, 0, - 416, 415, 422, 421, 428, 427, 104, 103, 56, 55, 17, 0, 0, 0, 0, 0, 0, 0, 21, 20, 86, 85, 434, 433, 440, 439, 446, 445, 834, 833, - 418, 417, 424, 423, 430, 429, 106, 105, 58, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 22, 88, 87, 436, 435, 442, 441, 448, 447, 835, 0, - 420, 419, 426, 425, 432, 431, 108, 107, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 90, 89, 438, 437, 444, 443, 450, 449, 837, 836, - 482, 481, 476, 475, 470, 469, 49, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 54, 53, 464, 463, 458, 457, 452, 451, 838, 0, - 484, 483, 478, 477, 472, 471, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 465, 460, 459, 454, 453, 840, 839, - 486, 485, 480, 479, 474, 473, 52, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 43, 468, 467, 462, 461, 456, 455, 841, 0, - 488, 487, 494, 493, 500, 499, 98, 97, 62, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 92, 91, 506, 505, 512, 511, 518, 517, 843, 842, - 490, 489, 496, 495, 502, 501, 100, 99, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 29, 28, 94, 93, 508, 507, 514, 513, 520, 519, 844, 0, - 492, 491, 498, 497, 504, 503, 102, 101, 66, 65, 18, 0, 0, 0, 0, 0, 0, 0, 19, 30, 96, 95, 510, 509, 516, 515, 522, 521, 846, 845, - 560, 559, 554, 553, 548, 547, 542, 541, 74, 73, 33, 0, 0, 0, 0, 0, 0, 11, 68, 67, 116, 115, 536, 535, 530, 529, 524, 523, 847, 0, - 562, 561, 556, 555, 550, 549, 544, 543, 76, 75, 0, 0, 8, 7, 36, 35, 12, 0, 70, 69, 118, 117, 538, 537, 532, 531, 526, 525, 849, 848, - 564, 563, 558, 557, 552, 551, 546, 545, 78, 77, 0, 34, 10, 9, 26, 25, 0, 0, 72, 71, 120, 119, 540, 539, 534, 533, 528, 527, 850, 0, - 566, 565, 572, 571, 578, 577, 584, 583, 590, 589, 596, 595, 602, 601, 608, 607, 614, 613, 620, 619, 626, 625, 632, 631, 638, 637, 644, 643, 852, 851, - 568, 567, 574, 573, 580, 579, 586, 585, 592, 591, 598, 597, 604, 603, 610, 609, 616, 615, 622, 621, 628, 627, 634, 633, 640, 639, 646, 645, 853, 0, - 570, 569, 576, 575, 582, 581, 588, 587, 594, 593, 600, 599, 606, 605, 612, 611, 618, 617, 624, 623, 630, 629, 636, 635, 642, 641, 648, 647, 855, 854, - 728, 727, 722, 721, 716, 715, 710, 709, 704, 703, 698, 697, 692, 691, 686, 685, 680, 679, 674, 673, 668, 667, 662, 661, 656, 655, 650, 649, 856, 0, - 730, 729, 724, 723, 718, 717, 712, 711, 706, 705, 700, 699, 694, 693, 688, 687, 682, 681, 676, 675, 670, 669, 664, 663, 658, 657, 652, 651, 858, 857, - 732, 731, 726, 725, 720, 719, 714, 713, 708, 707, 702, 701, 696, 695, 690, 689, 684, 683, 678, 677, 672, 671, 666, 665, 660, 659, 654, 653, 859, 0, - 734, 733, 740, 739, 746, 745, 752, 751, 758, 757, 764, 763, 770, 769, 776, 775, 782, 781, 788, 787, 794, 793, 800, 799, 806, 805, 812, 811, 861, 860, - 736, 735, 742, 741, 748, 747, 754, 753, 760, 759, 766, 765, 772, 771, 778, 777, 784, 783, 790, 789, 796, 795, 802, 801, 808, 807, 814, 813, 862, 0, - 738, 737, 744, 743, 750, 749, 756, 755, 762, 761, 768, 767, 774, 773, 780, 779, 786, 785, 792, 791, 798, 797, 804, 803, 810, 809, 816, 815, 864, 863 -}; - -int maxiCodeSet[256] = { /* from Appendix A - ASCII character to Code Set (e.g. 2 = Set B) */ - /* set 0 refers to special characters that fit into more than one set (e.g. GS) */ - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 3, 4, 3, 5, 5, 4, 4, 3, 3, 3, - 4, 3, 5, 4, 4, 3, 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -}; - -int maxiSymbolChar[256] = { /* from Appendix A - ASCII character to symbol value */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 30, 28, 29, 30, 35, 32, 53, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 37, - 38, 39, 40, 41, 52, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 43, 44, 45, 46, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 32, 54, 34, 35, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 36, - 37, 37, 38, 39, 40, 41, 42, 43, 38, 44, 37, 39, 38, 45, 46, 40, 41, 39, 40, 41, - 42, 42, 47, 43, 44, 43, 44, 45, 45, 46, 47, 46, 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, - 33, 34, 35, 36, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 33, 34, 35, 36 -}; - diff --git a/3rdparty/zint-2.4.4/backend/maxipng.h b/3rdparty/zint-2.4.4/backend/maxipng.h deleted file mode 100644 index d7beb6c..0000000 --- a/3rdparty/zint-2.4.4/backend/maxipng.h +++ /dev/null @@ -1,138 +0,0 @@ -/* maxipng.h - Shapes for Maxicode output to PNG file */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* This file contains the pixel-by-pixel representation of maxicode glyphs - at a resolution of 12 pixels per millimeter. hexagon[] is taken directly - from ISO 16023 Annex J. bullseye[] was calculated by the Gimp */ - -#define SSET "0123456789ABCDEF" - -static int hexagon[120] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static unsigned int bullseye_compressed[] = { - 0,0,0,0,0,255,248,0,0,0,0,0, - 0,0,0,0,31,255,255,192,0,0,0,0, - 0,0,0,1,255,255,255,252,0,0,0,0, - 0,0,0,7,255,255,255,255,0,0,0,0, - 0,0,0,31,255,255,255,255,192,0,0,0, - 0,0,0,127,255,255,255,255,240,0,0,0, - 0,0,1,255,255,255,255,255,252,0,0,0, - 0,0,7,255,255,255,255,255,255,0,0,0, - 0,0,15,255,255,0,7,255,255,128,0,0, - 0,0,63,255,240,0,0,127,255,224,0,0, - 0,0,127,255,128,0,0,15,255,240,0,0, - 0,0,255,252,0,0,0,1,255,248,0,0, - 0,1,255,240,0,0,0,0,127,252,0,0, - 0,3,255,224,0,0,0,0,63,254,0,0, - 0,7,255,128,0,0,0,0,15,255,0,0, - 0,15,255,0,0,0,0,0,7,255,128,0, - 0,31,252,0,0,127,240,0,1,255,192,0, - 0,63,248,0,7,255,255,0,0,255,224,0, - 0,127,240,0,63,255,255,224,0,127,240,0, - 0,127,224,0,255,255,255,248,0,63,240,0, - 0,255,192,1,255,255,255,252,0,31,248,0, - 1,255,128,7,255,255,255,255,0,15,252,0, - 1,255,0,15,255,255,255,255,128,7,252,0, - 3,255,0,63,255,255,255,255,224,7,254,0, - 3,254,0,127,255,192,31,255,240,3,254,0, - 7,252,0,255,252,0,1,255,248,1,255,0, - 7,252,1,255,240,0,0,127,252,1,255,0, - 15,248,1,255,192,0,0,31,252,0,255,128, - 15,240,3,255,128,0,0,15,254,0,127,128, - 31,240,7,255,0,0,0,7,255,0,127,192, - 31,224,7,254,0,0,0,3,255,0,63,192, - 63,224,15,252,0,0,0,1,255,128,63,224, - 63,224,31,248,0,63,192,0,255,192,63,224, - 63,192,31,240,0,255,240,0,127,192,31,224, - 63,192,63,224,3,255,252,0,63,224,31,224, - 127,192,63,224,7,255,254,0,63,224,31,240, - 127,128,63,192,15,255,255,0,31,224,15,240, - 127,128,127,192,31,255,255,128,31,240,15,240, - 127,128,127,128,63,255,255,192,15,240,15,240, - 127,128,127,128,63,255,255,192,15,240,15,240, - 255,0,127,128,127,240,255,224,15,240,7,240, - 255,0,255,128,127,192,63,224,15,248,7,240, - 255,0,255,0,255,128,31,240,7,248,7,240, - 255,0,255,0,255,128,31,240,7,248,7,240, - 255,0,255,0,255,0,15,240,7,248,7,240, - 255,0,255,0,255,0,15,240,7,248,7,240, - 255,0,255,0,255,0,15,240,7,248,7,240, - 255,0,255,0,255,0,15,240,7,248,7,240, - 255,0,255,0,255,128,31,240,7,248,7,240, - 255,0,255,0,255,128,31,240,7,248,7,240, - 255,0,255,0,127,192,63,224,7,248,7,240, - 255,0,255,128,127,240,255,224,15,248,7,240, - 255,0,127,128,63,255,255,192,15,240,7,240, - 127,128,127,128,63,255,255,192,15,240,15,240, - 127,128,127,128,31,255,255,128,15,240,15,240, - 127,128,127,192,15,255,255,0,31,240,15,240, - 127,128,63,192,7,255,254,0,31,224,15,240, - 127,192,63,224,3,255,252,0,63,224,31,240, - 63,192,63,224,0,255,240,0,63,224,31,224, - 63,192,31,240,0,63,192,0,127,192,31,224, - 63,224,31,248,0,0,0,0,255,192,63,224, - 63,224,15,252,0,0,0,1,255,128,63,224, - 31,224,7,254,0,0,0,3,255,0,63,192, - 31,240,7,255,0,0,0,7,255,0,127,192, - 15,240,3,255,128,0,0,15,254,0,127,128, - 15,248,1,255,192,0,0,31,252,0,255,128, - 7,252,1,255,240,0,0,127,252,1,255,0, - 7,252,0,255,252,0,1,255,248,1,255,0, - 3,254,0,127,255,192,31,255,240,3,254,0, - 3,255,0,63,255,255,255,255,224,7,254,0, - 1,255,0,15,255,255,255,255,128,7,252,0, - 1,255,128,7,255,255,255,255,0,15,252,0, - 0,255,192,1,255,255,255,252,0,31,248,0, - 0,127,224,0,255,255,255,248,0,63,240,0, - 0,127,240,0,63,255,255,224,0,127,240,0, - 0,63,248,0,7,255,255,0,0,255,224,0, - 0,31,252,0,0,127,240,0,1,255,192,0, - 0,15,255,0,0,0,0,0,7,255,128,0, - 0,7,255,128,0,0,0,0,15,255,0,0, - 0,3,255,224,0,0,0,0,63,254,0,0, - 0,1,255,240,0,0,0,0,127,252,0,0, - 0,0,255,252,0,0,0,1,255,248,0,0, - 0,0,127,255,128,0,0,15,255,240,0,0, - 0,0,63,255,240,0,0,127,255,224,0,0, - 0,0,15,255,255,0,7,255,255,128,0,0, - 0,0,7,255,255,255,255,255,255,0,0,0, - 0,0,1,255,255,255,255,255,252,0,0,0, - 0,0,0,127,255,255,255,255,240,0,0,0, - 0,0,0,31,255,255,255,255,192,0,0,0, - 0,0,0,7,255,255,255,255,0,0,0,0, - 0,0,0,1,255,255,255,252,0,0,0,0, - 0,0,0,0,31,255,255,192,0,0,0,0, - 0,0,0,0,0,255,248,0,0,0,0,0 -}; - diff --git a/3rdparty/zint-2.4.4/backend/medical.c b/3rdparty/zint-2.4.4/backend/medical.c deleted file mode 100644 index e26c410..0000000 --- a/3rdparty/zint-2.4.4/backend/medical.c +++ /dev/null @@ -1,308 +0,0 @@ -/* medical.c - Handles 1 track and 2 track pharmacode and Codabar */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include "common.h" - -extern int c39(struct zint_symbol *symbol, unsigned char source[], int length); -/* Codabar table checked against EN 798:1995 */ - -#define CALCIUM "0123456789-$:/.+ABCD" - -static char *CodaTable[20] = {"11111221", "11112211", "11121121", "22111111", "11211211", "21111211", - "12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121", - "21212111", "11212121", "11221211", "12121121", "11121221", "11122211"}; - -int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* "Pharmacode can represent only a single integer from 3 to 131070. Unlike other - commonly used one-dimensional barcode schemes, pharmacode does not store the data in a - form corresponding to the human-readable digits; the number is encoded in binary, rather - than decimal. Pharmacode is read from right to left: with n as the bar position starting - at 0 on the right, each narrow bar adds 2n to the value and each wide bar adds 2(2^n). - The minimum barcode is 2 bars and the maximum 16, so the smallest number that could - be encoded is 3 (2 narrow bars) and the biggest is 131070 (16 wide bars)." - - http://en.wikipedia.org/wiki/Pharmacode */ - - /* This code uses the One Track Pharamacode calculating algorithm as recommended by - the specification at http://www.laetus.com/laetus.php?request=file&id=69 */ - - unsigned long int tester; - int counter, error_number, h; - char inter[18] = { 0 }; /* 131070 -> 17 bits */ - char dest[64]; /* 17 * 2 + 1 */ - - error_number = 0; - - if(length > 6) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - tester = atoi((char*)source); - - if((tester < 3) || (tester > 131070)) { - strcpy(symbol->errtxt, "Data out of range"); - return ERROR_INVALID_DATA1; - } - - do - { - if(!(tester & 1)) { - concat(inter, "W"); - tester = (tester - 2) / 2; - } else { - concat(inter, "N"); - tester = (tester - 1) / 2; - } - } - while(tester != 0); - - h = strlen(inter) - 1; - *dest = '\0'; - for(counter = h; counter >= 0; counter--) { - if(inter[counter] == 'W') { - concat(dest, "32"); - } else { - concat(dest, "12"); - } - } - - expand(symbol, dest); - - return error_number; -} - -int pharma_two_calc(struct zint_symbol *symbol, unsigned char source[], char dest[]) -{ - /* This code uses the Two Track Pharamacode defined in the document at - http://www.laetus.com/laetus.php?request=file&id=69 and using a modified - algorithm from the One Track system. This standard accepts integet values - from 4 to 64570080. */ - - unsigned long int tester; - int counter, h; - char inter[17]; - int error_number; - - tester = atoi((char*)source); - - if((tester < 4) || (tester > 64570080)) - { - strcpy(symbol->errtxt, "Data out of range"); - return ERROR_INVALID_DATA1; - } - error_number = 0; - strcpy(inter, ""); - do - { - switch(tester%3) { - case 0: - concat(inter, "3"); - tester = (tester - 3) / 3; - break; - case 1: - concat(inter, "1"); - tester = (tester - 1) / 3; - break; - case 2: - concat(inter, "2"); - tester = (tester - 2) / 3; - break; - } - } - while(tester != 0); - - h = strlen(inter) - 1; - for(counter = h; counter >= 0; counter--) - { - dest[h - counter] = inter[counter]; - } - dest[h + 1] = '\0'; - - return error_number; -} - -int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Draws the patterns for two track pharmacode */ - char height_pattern[200]; - unsigned int loopey, h; - int writer; - int error_number = 0; - strcpy(height_pattern, ""); - - if(length > 8) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - error_number = pharma_two_calc(symbol, source, height_pattern); - if(error_number != 0) { - return error_number; - } - - writer = 0; - h = strlen(height_pattern); - for(loopey = 0; loopey < h; loopey++) - { - if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '3')) - { - set_module(symbol, 0, writer); - } - if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '3')) - { - set_module(symbol, 1, writer); - } - writer += 2; - } - symbol->rows = 2; - symbol->width = writer - 1; - - - return error_number; -} - -int codabar(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* The Codabar system consisting of simple substitution */ - - int i, error_number; - char dest[512]; - - error_number = 0; - strcpy(dest, ""); - - if(length > 60) { /* No stack smashing please */ - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - to_upper(source); - error_number = is_sane(CALCIUM, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - /* Codabar must begin and end with the characters A, B, C or D */ - if((source[0] != 'A') && (source[0] != 'B') && (source[0] != 'C') && (source[0] != 'D')) - { - strcpy(symbol->errtxt, "Invalid characters in data"); - return ERROR_INVALID_DATA1; - } - - if((source[length - 1] != 'A') && (source[length - 1] != 'B') && - (source[length - 1] != 'C') && (source[length - 1] != 'D')) - { - strcpy(symbol->errtxt, "Invalid characters in data"); - return ERROR_INVALID_DATA1; - } - - for(i = 0; i < length; i++) - { - lookup(CALCIUM, CodaTable, source[i], dest); - } - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return error_number; -} - -int code32(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Italian Pharmacode */ - int i, zeroes, error_number, checksum, checkpart, checkdigit; - char localstr[10], risultante[7]; - long int pharmacode, remainder, devisor; - int codeword[6]; - char tabella[34]; - - /* Validate the input */ - if(length > 8) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* Add leading zeros as required */ - zeroes = 8 - length; - memset(localstr, '0', zeroes); - strcpy(localstr + zeroes, (char*)source); - - /* Calculate the check digit */ - checksum = 0; - checkpart = 0; - for(i = 0; i < 4; i++) { - checkpart = ctoi(localstr[i * 2]); - checksum += checkpart; - checkpart = 2 * (ctoi(localstr[(i * 2) + 1])); - if(checkpart >= 10) { - checksum += (checkpart - 10) + 1; - } else { - checksum += checkpart; - } - } - - /* Add check digit to data string */ - checkdigit = checksum % 10; - localstr[8] = itoc(checkdigit); - localstr[9] = '\0'; - - /* Convert string into an integer value */ - pharmacode = atoi(localstr); - - /* Convert from decimal to base-32 */ - devisor = 33554432; - for(i = 5; i >= 0; i--) { - codeword[i] = pharmacode / devisor; - remainder = pharmacode % devisor; - pharmacode = remainder; - devisor /= 32; - } - - /* Look up values in 'Tabella di conversione' */ - strcpy(tabella, "0123456789BCDFGHJKLMNPQRSTUVWXYZ"); - for(i = 5; i >= 0; i--) { - risultante[5 - i] = tabella[codeword[i]]; - } - risultante[6] = '\0'; - /* Plot the barcode using Code 39 */ - error_number = c39(symbol, (unsigned char*)risultante, strlen(risultante)); - if(error_number != 0) { return error_number; } - - /* Override the normal text output with the Pharmacode number */ - ustrcpy(symbol->text, (unsigned char*)"A"); - uconcat(symbol->text, (unsigned char*)localstr); - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/pdf417.c b/3rdparty/zint-2.4.4/backend/pdf417.c deleted file mode 100644 index 91d47e6..0000000 --- a/3rdparty/zint-2.4.4/backend/pdf417.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* pdf417.c - Handles PDF417 stacked symbology */ - -/* Zint - A barcode generating program using libpng - Copyright (C) 2008 Robin Stuart - Portions Copyright (C) 2004 Grandzebu - Bug Fixes thanks to KL Chin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* This code is adapted from "Code barre PDF 417 / PDF 417 barcode" v2.5.0 - which is Copyright (C) 2004 (Grandzebu). - The original code can be downloaded from http://grandzebu.net/index.php */ - -/* NOTE: symbol->option_1 is used to specify the security level (i.e. control the - number of check codewords) - - symbol->option_2 is used to adjust the width of the resulting symbol (i.e. the - number of codeword columns not including row start and end data) */ - -/* @(#) $Id: pdf417.c,v 1.21 2010/01/28 17:55:59 hooper114 Exp $ */ - -#include -#include -#include -#include -#ifndef _MSC_VER -#include -#else -#include -#include "ms_stdint.h" -#endif -#include "pdf417.h" -#include "common.h" -#include "large.h" - -/* - Three figure numbers in comments give the location of command equivalents in the - original Visual Basic source code file pdf417.frm - this code retains some original (French) procedure and variable names to ease conversion */ - -/* text mode processing tables */ - -static int asciix[95] = { 7, 8, 8, 4, 12, 4, 4, 8, 8, 8, 12, 4, 12, 12, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 12, 8, 8, 4, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 8, 8, 8, 4, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 8, 8, 8, 8 }; - -static int asciiy[95] = { 26, 10, 20, 15, 18, 21, 10, 28, 23, 24, 22, 20, 13, 16, 17, 19, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 14, 0, 1, 23, 2, 25, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 4, 5, 6, 24, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 21, 27, 9 }; - -/* Automatic sizing table */ - -static int MicroAutosize[56] = -{ 4, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19, 20, 24, 29, 30, 33, 34, 37, 39, 46, 54, 58, 70, 72, 82, 90, 108, 126, - 1, 14, 2, 7, 3, 25, 8, 16, 5, 17, 9, 6, 10, 11, 28, 12, 19, 13, 29, 20, 30, 21, 22, 31, 23, 32, 33, 34 -}; - -int liste[2][1000]; /* global - okay, so I got _almost_ everything local! */ - -/* 866 */ - -int quelmode(char codeascii) -{ - int mode = BYT; - if ((codeascii == '\t') || (codeascii == '\n') || (codeascii == '\r') || ((codeascii >= ' ') && (codeascii <= '~'))) { mode = TEX; } - else if((codeascii >= '0') && (codeascii <= '9')) { mode = NUM; } - /* 876 */ - - return mode; -} - -/* 844 */ -void regroupe(int *indexliste) -{ - int i, j; - - /* bring together same type blocks */ - if(*(indexliste) > 1) { - i = 1; - while(i < *(indexliste)) { - if(liste[1][i - 1] == liste[1][i]) { - /* bring together */ - liste[0][i - 1] = liste[0][i - 1] + liste[0][i]; - j = i + 1; - - /* decreace the list */ - while(j < *(indexliste)) { - liste[0][j - 1] = liste[0][j]; - liste[1][j - 1] = liste[1][j]; - j++; - } - *(indexliste) = *(indexliste) - 1; - i--; - } - i++; - } - } - /* 865 */ -} - -/* 478 */ -void pdfsmooth(int *indexliste) -{ - int i, crnt, last, next, length; - - for(i = 0; i < *(indexliste); i++) { - crnt = liste[1][i]; - length = liste[0][i]; - if(i != 0) { last = liste[1][i - 1]; } else { last = FALSE; } - if(i != *(indexliste) - 1) { next = liste[1][i + 1]; } else { next = FALSE; } - - if(crnt == NUM) { - if(i == 0) { /* first block */ - if(*(indexliste) > 1) { /* and there are others */ - if((next == TEX) && (length < 8)) { liste[1][i] = TEX;} - if((next == BYT) && (length == 1)) { liste[1][i] = BYT; } - } - } else { - if(i == *(indexliste) - 1) { /* last block */ - if((last == TEX) && (length < 7)) { liste[1][i] = TEX; } - if((last == BYT) && (length == 1)) { liste[1][i] = BYT; } - } else { /* not first or last block */ - if(((last == BYT) && (next == BYT)) && (length < 4)) { liste[1][i] = BYT; } - if(((last == BYT) && (next == TEX)) && (length < 4)) { liste[1][i] = TEX; } - if(((last == TEX) && (next == BYT)) && (length < 5)) { liste[1][i] = TEX; } - if(((last == TEX) && (next == TEX)) && (length < 8)) { liste[1][i] = TEX; } - } - } - } - } - regroupe(indexliste); - /* 520 */ - for(i = 0; i < *(indexliste); i++) { - crnt = liste[1][i]; - length = liste[0][i]; - if(i != 0) { last = liste[1][i - 1]; } else { last = FALSE; } - if(i != *(indexliste) - 1) { next = liste[1][i + 1]; } else { next = FALSE; } - - if((crnt == TEX) && (i > 0)) { /* not the first */ - if(i == *(indexliste) - 1) { /* the last one */ - if((last == BYT) && (length == 1)) { liste[1][i] = BYT; } - } else { /* not the last one */ - if(((last == BYT) && (next == BYT)) && (length < 5)) { liste[1][i] = BYT; } - if((((last == BYT) && (next != BYT)) || ((last != BYT) && (next == BYT))) && (length < 3)) { - liste[1][i] = BYT; - } - } - } - } - /* 540 */ - regroupe(indexliste); -} - -/* 547 */ -void textprocess(int *chainemc, int *mclength, char chaine[], int start, int length, int block) -{ - int j, indexlistet, curtable, listet[2][5000], chainet[5000], wnet; - char codeascii; - - codeascii = 0; - wnet = 0; - - for(j = 0; j < 1000; j++) { - listet[0][j] = 0; - } - /* listet will contain the table numbers and the value of each characters */ - for(indexlistet = 0; indexlistet < length; indexlistet++) { - codeascii = chaine[start + indexlistet]; - switch(codeascii) { - case '\t': listet[0][indexlistet] = 12; listet[1][indexlistet] = 12; break; - case '\n': listet[0][indexlistet] = 8; listet[1][indexlistet] = 15; break; - case 13: listet[0][indexlistet] = 12; listet[1][indexlistet] = 11; break; - default: listet[0][indexlistet] = asciix[codeascii - 32]; - listet[1][indexlistet] = asciiy[codeascii - 32]; break; - } - } - - /* 570 */ - curtable = 1; /* default table */ - for(j = 0; j < length; j++) { - if(listet[0][j] & curtable) { /* The character is in the current table */ - chainet[wnet] = listet[1][j]; - wnet++; - } else { /* Obliged to change table */ - int flag = FALSE; /* True if we change table for only one character */ - if (j == (length - 1)) { - flag = TRUE; - } else { - if(!(listet[0][j] & listet[0][j + 1])) { flag = TRUE; } - } - - if (flag) { /* we change only one character - look for temporary switch */ - if((listet[0][j] & 1) && (curtable == 2)) { /* T_UPP */ - chainet[wnet] = 27; - chainet[wnet + 1] = listet[1][j]; - wnet += 2; - } - if(listet[0][j] & 8) { /* T_PUN */ - chainet[wnet] = 29; - chainet[wnet + 1] = listet[1][j]; - wnet += 2; - } - if(!(((listet[0][j] & 1) && (curtable == 2)) || (listet[0][j] & 8))) { - /* No temporary switch available */ - flag = FALSE; - } - } - - /* 599 */ - if (!(flag)) { - int newtable; - - if(j == (length - 1)) { - newtable = listet[0][j]; - } else { - if(!(listet[0][j] & listet[0][j + 1])) { - newtable = listet[0][j]; - } else { - newtable = listet[0][j] & listet[0][j + 1]; - } - } - - /* Maintain the first if several tables are possible */ - switch (newtable) { - case 3: - case 5: - case 7: - case 9: - case 11: - case 13: - case 15: - newtable = 1; break; - case 6: - case 10: - case 14: - newtable = 2; break; - case 12: - newtable = 4; break; - } - - /* 619 - select the switch */ - switch (curtable) { - case 1: - switch (newtable) { - case 2: chainet[wnet] = 27; wnet++; break; - case 4: chainet[wnet] = 28; wnet++; break; - case 8: chainet[wnet] = 28; wnet++; chainet[wnet] = 25; wnet++; break; - } break; - case 2: - switch (newtable) { - case 1: chainet[wnet] = 28; wnet++; chainet[wnet] = 28; wnet++; break; - case 4: chainet[wnet] = 28; wnet++; break; - case 8: chainet[wnet] = 28; wnet++; chainet[wnet] = 25; wnet++; break; - } break; - case 4: - switch (newtable) { - case 1: chainet[wnet] = 28; wnet++; break; - case 2: chainet[wnet] = 27; wnet++; break; - case 8: chainet[wnet] = 25; wnet++; break; - } break; - case 8: - switch (newtable) { - case 1: chainet[wnet] = 29; wnet++; break; - case 2: chainet[wnet] = 29; wnet++; chainet[wnet] = 27; wnet++; break; - case 4: chainet[wnet] = 29; wnet++; chainet[wnet] = 28; wnet++; break; - } break; - } - curtable = newtable; - /* 659 - at last we add the character */ - chainet[wnet] = listet[1][j]; - wnet++; - } - } - } - - /* 663 */ - if (wnet & 1) { - chainet[wnet] = 29; - wnet++; - } - /* Now translate the string chainet into codewords */ - chainemc[*(mclength)] = 900; - *(mclength) = *(mclength) + 1; - - for(j = 0; j < wnet; j+= 2) { - int cw_number; - - cw_number = (30 * chainet[j]) + chainet[j + 1]; - chainemc[*(mclength)] = cw_number; - *(mclength) = *(mclength) + 1; - - } -} - -/* 671 */ -void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int block) -{ - int debug = 0; - int len = 0; - unsigned int chunkLen = 0; - uint64_t mantisa = 0ULL; - uint64_t total = 0ULL; - - if(debug) printf("\nEntering byte mode at position %d\n", start); - - if(length == 1) { - chainemc[(*mclength)++] = 913; - chainemc[(*mclength)++] = chaine[start]; - if(debug) { printf("913 %d\n", chainemc[*mclength - 1]); } - } else { - /* select the switch for multiple of 6 bytes */ - if (length % 6 == 0) { - chainemc[(*mclength)++] = 924; - if(debug) printf("924 "); - } else { - chainemc[(*mclength)++] = 901; - if(debug) printf("901 "); - } - - while (len < length) - { - chunkLen = length - len; - if (6 <= chunkLen) /* Take groups of 6 */ - { - chunkLen = 6; - len += chunkLen; - total = 0ULL; - - while (chunkLen--) - { - mantisa = chaine[start++]; - total |= mantisa << (uint64_t)(chunkLen * 8ULL); - } - - chunkLen = 5; - - while (chunkLen--) - { - chainemc[*mclength + chunkLen] = (int)(total % 900ULL); - total /= 900ULL; - } - *mclength += 5; - } - else /* If it remain a group of less than 6 bytes */ - { - len += chunkLen; - while (chunkLen--) - { - chainemc[(*mclength)++] = chaine[start++]; - } - } - } - } -} - -/* 712 */ -void numbprocess(int *chainemc, int *mclength, char chaine[], int start, int length, int block) -{ - int j, loop, longueur, dummy[100], dumlength, diviseur, nombre; - char chainemod[50], chainemult[100], temp; - - strcpy(chainemod, ""); - for(loop = 0; loop <= 50; loop++) { - dummy[loop] = 0; - } - - chainemc[*(mclength)] = 902; - *(mclength) = *(mclength) + 1; - - j = 0; - while(j < length) { - dumlength = 0; - strcpy(chainemod, ""); - longueur = length - j; - if(longueur > 44) { longueur = 44; } - concat(chainemod, "1"); - for(loop = 1; loop <= longueur; loop++) { - chainemod[loop] = chaine[start + loop + j - 1]; - } - chainemod[longueur + 1] = '\0'; - do { - diviseur = 900; - - /* 877 - gosub Modulo */ - strcpy(chainemult, ""); - nombre = 0; - while(strlen(chainemod) != 0) { - nombre *= 10; - nombre += ctoi(chainemod[0]); - for(loop = 0; loop < strlen(chainemod); loop++) { - chainemod[loop] = chainemod[loop + 1]; - } - if (nombre < diviseur) { - if (strlen(chainemult) != 0) { concat(chainemult, "0"); } - } else { - temp = (nombre / diviseur) + '0'; - chainemult[strlen(chainemult) + 1] = '\0'; - chainemult[strlen(chainemult)] = temp; - } - nombre = nombre % diviseur; - } - diviseur = nombre; - /* return to 723 */ - - for(loop = dumlength; loop > 0; loop--) { - dummy[loop] = dummy[loop - 1]; - } - dummy[0] = diviseur; - dumlength++; - strcpy(chainemod, chainemult); - } while(strlen(chainemult) != 0); - for(loop = 0; loop < dumlength; loop++) { - chainemc[*(mclength)] = dummy[loop]; - *(mclength) = *(mclength) + 1; - } - j += longueur; - } -} - -/* 366 */ -int pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) -{ - int i, k, j, indexchaine, indexliste, mode, longueur, loop, mccorrection[520], offset; - int total, chainemc[2700], mclength, c1, c2, c3, dummy[35], codeerr; - char codebarre[140], pattern[580]; - int debug = 0; - - codeerr = 0; - - /* 456 */ - indexliste = 0; - indexchaine = 0; - - mode = quelmode(chaine[indexchaine]); - - for(i = 0; i < 1000; i++) { - liste[0][i] = 0; - } - - /* 463 */ - do { - liste[1][indexliste] = mode; - while ((liste[1][indexliste] == mode) && (indexchaine < length)) { - liste[0][indexliste]++; - indexchaine++; - mode = quelmode(chaine[indexchaine]); - } - indexliste++; - } while (indexchaine < length); - - /* 474 */ - pdfsmooth(&indexliste); - - if(debug) { - printf("Initial block pattern:\n"); - for(i = 0; i < indexliste; i++) { - printf("Len: %d Type: ", liste[0][i]); - switch(liste[1][i]) { - case TEX: printf("Text\n"); break; - case BYT: printf("Byte\n"); break; - case NUM: printf("Number\n"); break; - default: printf("ERROR\n"); break; - } - } - } - - /* 541 - now compress the data */ - indexchaine = 0; - mclength = 0; - if(symbol->output_options & READER_INIT) { - chainemc[mclength] = 921; /* Reader Initialisation */ - mclength++; - } - for(i = 0; i < indexliste; i++) { - switch(liste[1][i]) { - case TEX: /* 547 - text mode */ - textprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); - break; - case BYT: /* 670 - octet stream mode */ - byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i); - break; - case NUM: /* 712 - numeric mode */ - numbprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); - break; - } - indexchaine = indexchaine + liste[0][i]; - } - - if(debug) { - printf("\nCompressed data stream:\n"); - for(i = 0; i < mclength; i++) { - printf("%d ", chainemc[i]); - } - printf("\n\n"); - } - - /* 752 - Now take care of the number of CWs per row */ - if (symbol->option_1 < 0) { - symbol->option_1 = 6; - if(mclength <= 863) { symbol->option_1 = 5; } - if(mclength <= 320) { symbol->option_1 = 4; } - if(mclength <= 160) { symbol->option_1 = 3; } - if(mclength <= 40) { symbol->option_1 = 2; } - } - k = 1; - for(loop = 1; loop <= (symbol->option_1 + 1); loop++) - { - k *= 2; - } - longueur = mclength; - if(symbol->option_2 > 30) { symbol->option_2 = 30; } - if(symbol->option_2 < 1) { - symbol->option_2 = 0.5 + sqrt((longueur + k) / 3.0); - } - if(((longueur + k) / symbol->option_2) > 90) { - /* stop the symbol from becoming too high */ - symbol->option_2 = symbol->option_2 + 1; - } - - if(longueur + k > 928) { - /* Enforce maximum codeword limit */ - return 2; - } - - if(((longueur + k) / symbol->option_2) > 90) { - return 4; - } - - /* 781 - Padding calculation */ - longueur = mclength + 1 + k; - i = 0; - if ((longueur / symbol->option_2) < 3) { - i = (symbol->option_2 * 3) - longueur; /* A bar code must have at least three rows */ - } else { - if((longueur % symbol->option_2) > 0) { i = symbol->option_2 - (longueur % symbol->option_2); } - } - /* We add the padding */ - while (i > 0) { - chainemc[mclength] = 900; - mclength++; - i--; - } - /* we add the length descriptor */ - for(i = mclength; i > 0; i--) { - chainemc[i] = chainemc[i - 1]; - } - chainemc[0] = mclength + 1; - mclength++; - - /* 796 - we now take care of the Reed Solomon codes */ - switch(symbol->option_1) { - case 1: offset = 2; break; - case 2: offset = 6; break; - case 3: offset = 14; break; - case 4: offset = 30; break; - case 5: offset = 62; break; - case 6: offset = 126; break; - case 7: offset = 254; break; - case 8: offset = 510; break; - default: offset = 0; break; - } - - longueur = mclength; - for(loop = 0; loop < 520; loop++) { - mccorrection[loop] = 0; - } - total = 0; - for(i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[k - 1]) % 929; - for(j = k - 1; j > 0; j--) { - mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; - } - mccorrection[0] = (929 - (total * coefrs[offset + j]) % 929) % 929; - } - - /* we add these codes to the string */ - for(i = k - 1; i >= 0; i--) { - chainemc[mclength++] = mccorrection[i] ? 929 - mccorrection[i] : 0; - } - - /* 818 - The CW string is finished */ - c1 = (mclength / symbol->option_2 - 1) / 3; - c2 = symbol->option_1 * 3 + (mclength / symbol->option_2 - 1) % 3; - c3 = symbol->option_2 - 1; - - /* we now encode each row */ - for(i = 0; i <= (mclength / symbol->option_2) - 1; i++) { - for(j = 0; j < symbol->option_2 ; j++) { - dummy[j + 1] = chainemc[i * symbol->option_2 + j]; - } - k = (i / 3) * 30; - switch(i % 3) { - /* follows this pattern from US Patent 5,243,655: - Row 0: L0 (row #, # of rows) R0 (row #, # of columns) - Row 1: L1 (row #, security level) R1 (row #, # of rows) - Row 2: L2 (row #, # of columns) R2 (row #, security level) - Row 3: L3 (row #, # of rows) R3 (row #, # of columns) - etc. */ - case 0: - dummy[0] = k + c1; - dummy[symbol->option_2 + 1] = k + c3; - break; - case 1: - dummy[0] = k + c2; - dummy[symbol->option_2 + 1] = k + c1; - break; - case 2: - dummy[0] = k + c3; - dummy[symbol->option_2 + 1] = k + c2; - break; - } - strcpy(codebarre, "+*"); /* Start with a start char and a separator */ - if(symbol->symbology == BARCODE_PDF417TRUNC) { - /* truncated - so same as before except knock off the last 5 chars */ - for(j = 0; j <= symbol->option_2; j++) { - switch(i % 3) { - case 1: offset = 929; break; - case 2: offset = 1858; break; - default: offset = 0; break; - } - concat(codebarre, codagemc[offset + dummy[j]]); - concat(codebarre, "*"); - } - } else { - /* normal PDF417 symbol */ - for(j = 0; j <= symbol->option_2 + 1; j++) { - switch(i % 3) { - case 1: offset = 929; /* cluster(3) */ break; - case 2: offset = 1858; /* cluster(6) */ break; - default: offset = 0; /* cluster(0) */ break; - } - concat(codebarre, codagemc[offset + dummy[j]]); - concat(codebarre, "*"); - } - concat(codebarre, "-"); - } - - strcpy(pattern, ""); - for(loop = 0; loop < strlen(codebarre); loop++) { - lookup(BRSET, PDFttf, codebarre[loop], pattern); - } - for(loop = 0; loop < strlen(pattern); loop++) { - if(pattern[loop] == '1') { set_module(symbol, i, loop); } - } - if(symbol->height == 0) { - symbol->row_height[i] = 3; - } - } - symbol->rows = (mclength / symbol->option_2); - symbol->width = strlen(pattern); - - /* 843 */ - return codeerr; -} - -/* 345 */ -int pdf417enc(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int codeerr, error_number; - - error_number = 0; - - if((symbol->option_1 < -1) || (symbol->option_1 > 8)) { - strcpy(symbol->errtxt, "Security value out of range"); - symbol->option_1 = -1; - error_number = WARN_INVALID_OPTION; - } - if((symbol->option_2 < 0) || (symbol->option_2 > 30)) { - strcpy(symbol->errtxt, "Number of columns out of range"); - symbol->option_2 = 0; - error_number = WARN_INVALID_OPTION; - } - - /* 349 */ - codeerr = pdf417(symbol, source, length); - - /* 352 */ - if(codeerr != 0) { - switch(codeerr) { - case 1: - strcpy(symbol->errtxt, "No such file or file unreadable"); - error_number = ERROR_INVALID_OPTION; - break; - case 2: - strcpy(symbol->errtxt, "Input string too long"); - error_number = ERROR_TOO_LONG; - break; - case 3: - strcpy(symbol->errtxt, "Number of codewords per row too small"); - error_number = WARN_INVALID_OPTION; - break; - case 4: - strcpy(symbol->errtxt, "Data too long for specified number of columns"); - error_number = ERROR_TOO_LONG; - break; - default: - strcpy(symbol->errtxt, "Something strange happened"); - error_number = ERROR_ENCODING_PROBLEM; - break; - } - } - - /* 364 */ - return error_number; -} - - -int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], int length) -{ /* like PDF417 only much smaller! */ - - int i, k, j, indexchaine, indexliste, mode, longueur, mccorrection[50], offset; - int total, chainemc[2700], mclength, dummy[5], codeerr; - char codebarre[100], pattern[580]; - int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; - int LeftRAP, CentreRAP, RightRAP, Cluster, writer, flip, loop; - int debug = 0; - - /* Encoding starts out the same as PDF417, so use the same code */ - codeerr = 0; - - /* 456 */ - indexliste = 0; - indexchaine = 0; - - mode = quelmode(chaine[indexchaine]); - - for(i = 0; i < 1000; i++) { - liste[0][i] = 0; - } - - /* 463 */ - do { - liste[1][indexliste] = mode; - while ((liste[1][indexliste] == mode) && (indexchaine < length)) { - liste[0][indexliste]++; - indexchaine++; - mode = quelmode(chaine[indexchaine]); - } - indexliste++; - } while (indexchaine < length); - - /* 474 */ - pdfsmooth(&indexliste); - - if(debug) { - printf("Initial mapping:\n"); - for(i = 0; i < indexliste; i++) { - printf("len: %d type: ", liste[0][i]); - switch(liste[1][i]) { - case TEX: printf("TEXT\n"); break; - case BYT: printf("BYTE\n"); break; - case NUM: printf("NUMBER\n"); break; - default: printf("*ERROR*\n"); break; - } - } - } - - /* 541 - now compress the data */ - indexchaine = 0; - mclength = 0; - if(symbol->output_options & READER_INIT) { - chainemc[mclength] = 921; /* Reader Initialisation */ - mclength++; - } - for(i = 0; i < indexliste; i++) { - switch(liste[1][i]) { - case TEX: /* 547 - text mode */ - textprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); - break; - case BYT: /* 670 - octet stream mode */ - byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i); - break; - case NUM: /* 712 - numeric mode */ - numbprocess(chainemc, &mclength, (char*)chaine, indexchaine, liste[0][i], i); - break; - } - indexchaine = indexchaine + liste[0][i]; - } - - /* This is where it all changes! */ - - if(mclength > 126) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - if(symbol->option_2 > 4) { - strcpy(symbol->errtxt, "Specified width out of range"); - symbol->option_2 = 0; - codeerr = WARN_INVALID_OPTION; - } - - if(debug) { - printf("\nEncoded Data Stream:\n"); - for(i = 0; i < mclength; i++) { - printf("0x%02X ", chainemc[i]); - } - printf("\n"); - } - - /* Now figure out which variant of the symbol to use and load values accordingly */ - - variant = 0; - - if((symbol->option_2 == 1) && (mclength > 20)) { - /* the user specified 1 column but the data doesn't fit - go to automatic */ - symbol->option_2 = 0; - strcpy(symbol->errtxt, "Specified symbol size too small for data"); - codeerr = WARN_INVALID_OPTION; - } - - if((symbol->option_2 == 2) && (mclength > 37)) { - /* the user specified 2 columns but the data doesn't fit - go to automatic */ - symbol->option_2 = 0; - strcpy(symbol->errtxt, "Specified symbol size too small for data"); - codeerr = WARN_INVALID_OPTION; - } - - if((symbol->option_2 == 3) && (mclength > 82)) { - /* the user specified 3 columns but the data doesn't fit - go to automatic */ - symbol->option_2 = 0; - strcpy(symbol->errtxt, "Specified symbol size too small for data"); - codeerr = WARN_INVALID_OPTION; - } - - if(symbol->option_2 == 1) { - /* the user specified 1 column and the data does fit */ - variant = 6; - if(mclength <= 16) { variant = 5; } - if(mclength <= 12) { variant = 4; } - if(mclength <= 10) { variant = 3; } - if(mclength <= 7) { variant = 2; } - if(mclength <= 4) { variant = 1; } - } - - if(symbol->option_2 == 2) { - /* the user specified 2 columns and the data does fit */ - variant = 13; - if(mclength <= 33) { variant = 12; } - if(mclength <= 29) { variant = 11; } - if(mclength <= 24) { variant = 10; } - if(mclength <= 19) { variant = 9; } - if(mclength <= 13) { variant = 8; } - if(mclength <= 8) { variant = 7; } - } - - if(symbol->option_2 == 3) { - /* the user specified 3 columns and the data does fit */ - variant = 23; - if(mclength <= 70) { variant = 22; } - if(mclength <= 58) { variant = 21; } - if(mclength <= 46) { variant = 20; } - if(mclength <= 34) { variant = 19; } - if(mclength <= 24) { variant = 18; } - if(mclength <= 18) { variant = 17; } - if(mclength <= 14) { variant = 16; } - if(mclength <= 10) { variant = 15; } - if(mclength <= 6) { variant = 14; } - } - - if(symbol->option_2 == 4) { - /* the user specified 4 columns and the data does fit */ - variant = 34; - if(mclength <= 108) { variant = 33; } - if(mclength <= 90) { variant = 32; } - if(mclength <= 72) { variant = 31; } - if(mclength <= 54) { variant = 30; } - if(mclength <= 39) { variant = 29; } - if(mclength <= 30) { variant = 28; } - if(mclength <= 24) { variant = 27; } - if(mclength <= 18) { variant = 26; } - if(mclength <= 12) { variant = 25; } - if(mclength <= 8) { variant = 24; } - } - - if(variant == 0) { - /* Zint can choose automatically from all available variations */ - for(i = 27; i >= 0; i--) { - - if(MicroAutosize[i] >= mclength) { - variant = MicroAutosize[i + 28]; - } - } - } - - /* Now we have the variant we can load the data */ - variant --; - symbol->option_2 = MicroVariants[variant]; /* columns */ - symbol->rows = MicroVariants[variant + 34]; /* rows */ - k = MicroVariants[variant + 68]; /* number of EC CWs */ - longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */ - i = longueur - mclength; /* amount of padding required */ - offset = MicroVariants[variant + 102]; /* coefficient offset */ - - if(debug) { - printf("\nChoose symbol size:\n"); - printf("%d columns x %d rows\n", symbol->option_2, symbol->rows); - printf("%d data codewords (including %d pads), %d ecc codewords\n", longueur, i, k); - printf("\n"); - } - - /* We add the padding */ - while (i > 0) { - chainemc[mclength] = 900; - mclength++; - i--; - } - - /* Reed-Solomon error correction */ - longueur = mclength; - for(loop = 0; loop < 50; loop++) { - mccorrection[loop] = 0; - } - total = 0; - for(i = 0; i < longueur; i++) { - total = (chainemc[i] + mccorrection[k - 1]) % 929; - for(j = k - 1; j >= 0; j--) { - if(j == 0) { - mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929; - } else { - mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929; - } - } - } - - for(j = 0; j < k; j++) { - if(mccorrection[j] != 0) { mccorrection[j] = 929 - mccorrection[j]; } - } - /* we add these codes to the string */ - for(i = k - 1; i >= 0; i--) { - chainemc[mclength] = mccorrection[i]; - mclength++; - } - - if(debug) { - printf("Encoded Data Stream with ECC:\n"); - for(i = 0; i < mclength; i++) { - printf("0x%02X ", chainemc[i]); - } - printf("\n"); - } - - /* Now get the RAP (Row Address Pattern) start values */ - LeftRAPStart = RAPTable[variant]; - CentreRAPStart = RAPTable[variant + 34]; - RightRAPStart = RAPTable[variant + 68]; - StartCluster = RAPTable[variant + 102] / 3; - - /* That's all values loaded, get on with the encoding */ - - LeftRAP = LeftRAPStart; - CentreRAP = CentreRAPStart; - RightRAP = RightRAPStart; - Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ - - if(debug) printf("\nInternal row representation:\n"); - for(i = 0; i < symbol->rows; i++) { - if(debug) printf("row %d: ", i); - strcpy(codebarre, ""); - offset = 929 * Cluster; - for(j = 0; j < 5; j++) { - dummy[j] = 0; - } - for(j = 0; j < symbol->option_2 ; j++) { - dummy[j + 1] = chainemc[i * symbol->option_2 + j]; - if(debug) printf("[%d] ", dummy[j + 1]); - } - - /* Copy the data into codebarre */ - concat(codebarre, RAPLR[LeftRAP]); - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[1]]); - concat(codebarre, "1"); - if(symbol->option_2 == 3) { - concat(codebarre, RAPC[CentreRAP]); - } - if(symbol->option_2 >= 2) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[2]]); - concat(codebarre, "1"); - } - if(symbol->option_2 == 4) { - concat(codebarre, RAPC[CentreRAP]); - } - if(symbol->option_2 >= 3) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[3]]); - concat(codebarre, "1"); - } - if(symbol->option_2 == 4) { - concat(codebarre, "1"); - concat(codebarre, codagemc[offset + dummy[4]]); - concat(codebarre, "1"); - } - concat(codebarre, RAPLR[RightRAP]); - concat(codebarre, "1"); /* stop */ - if(debug) printf("%s\n", codebarre); - - /* Now codebarre is a mixture of letters and numbers */ - - writer = 0; - flip = 1; - strcpy(pattern, ""); - for(loop = 0; loop < strlen(codebarre); loop++) { - if((codebarre[loop] >= '0') && (codebarre[loop] <= '9')) { - for(k = 0; k < ctoi(codebarre[loop]); k++) { - if(flip == 0) { - pattern[writer] = '0'; - } else { - pattern[writer] = '1'; - } - writer++; - } - pattern[writer] = '\0'; - if(flip == 0) { - flip = 1; - } else { - flip = 0; - } - } else { - lookup(BRSET, PDFttf, codebarre[loop], pattern); - writer += 5; - } - } - symbol->width = writer; - - /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ - for(loop = 0; loop < strlen(pattern); loop++) { - if(pattern[loop] == '1') { set_module(symbol, i, loop); } - } - symbol->row_height[i] = 2; - - /* Set up RAPs and Cluster for next row */ - LeftRAP++; - CentreRAP++; - RightRAP++; - Cluster++; - - if(LeftRAP == 53) { - LeftRAP = 1; - } - if(CentreRAP == 53) { - CentreRAP = 1; - } - if(RightRAP == 53) { - RightRAP = 1; - } - if(Cluster == 3) { - Cluster = 0; - } - } - - return codeerr; -} - diff --git a/3rdparty/zint-2.4.4/backend/pdf417.h b/3rdparty/zint-2.4.4/backend/pdf417.h deleted file mode 100644 index 4e65ecf..0000000 --- a/3rdparty/zint-2.4.4/backend/pdf417.h +++ /dev/null @@ -1,438 +0,0 @@ -/* pdf417.h - PDF417 tables and coefficients */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - Portions Copyright (C) 2004 Grandzebu - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* this file contains the character table, the pre-calculated coefficients and the - codeword patterns taken from lines 416 to 454 of pdf417.frm */ - -#define TRUE 1 -#define FALSE 0 -#define TEX 900 -#define BYT 901 -#define NUM 902 - -#define BRSET "ABCDEFabcdefghijklmnopqrstuvwxyz*+-" - -/* PDF417 error correction coefficients from Grand Zebu */ -static int coefrs[1022] = { - /* k = 2 */ - 27, 917, - - /* k = 4 */ - 522, 568, 723, 809, - - /* k = 8 */ - 237, 308, 436, 284, 646, 653, 428, 379, - - /* k = 16 */ - 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, - - /* k = 32 */ - 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, - 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, - - /* k = 64 */ - 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, - 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, - 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, - 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543, - - /* k = 128 */ - 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, - 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, - 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, - 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, - 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, - 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, - 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, - 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539, - - /* k = 256 */ - 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, - 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, - 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, - 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, - 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, - 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, - 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, - 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, - 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, - 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, - 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, - 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, - 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, - 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, - 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, - 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10, - - /* k = 512 */ - 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, - 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, - 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, - 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, - 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, - 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, - 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, - 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, - 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, - 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, - 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, - 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, - 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, - 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, - 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, - 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, - 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, - 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, - 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, - 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, - 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, - 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, - 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, - 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, - 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, - 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, - 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, - 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, - 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, - 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, - 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, - 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 }; - - -static char *codagemc[2787] = { "urA", "xfs", "ypy", "unk", "xdw", "yoz", "pDA", "uls", "pBk", "eBA", - "pAs", "eAk", "prA", "uvs", "xhy", "pnk", "utw", "xgz", "fDA", "pls", "fBk", "frA", "pvs", - "uxy", "fnk", "ptw", "uwz", "fls", "psy", "fvs", "pxy", "ftw", "pwz", "fxy", "yrx", "ufk", - "xFw", "ymz", "onA", "uds", "xEy", "olk", "ucw", "dBA", "oks", "uci", "dAk", "okg", "dAc", - "ovk", "uhw", "xaz", "dnA", "ots", "ugy", "dlk", "osw", "ugj", "dks", "osi", "dvk", "oxw", - "uiz", "dts", "owy", "dsw", "owj", "dxw", "oyz", "dwy", "dwj", "ofA", "uFs", "xCy", "odk", - "uEw", "xCj", "clA", "ocs", "uEi", "ckk", "ocg", "ckc", "ckE", "cvA", "ohs", "uay", "ctk", - "ogw", "uaj", "css", "ogi", "csg", "csa", "cxs", "oiy", "cww", "oij", "cwi", "cyy", "oFk", - "uCw", "xBj", "cdA", "oEs", "uCi", "cck", "oEg", "uCb", "ccc", "oEa", "ccE", "oED", "chk", - "oaw", "uDj", "cgs", "oai", "cgg", "oab", "cga", "cgD", "obj", "cib", "cFA", "oCs", "uBi", - "cEk", "oCg", "uBb", "cEc", "oCa", "cEE", "oCD", "cEC", "cas", "cag", "caa", "cCk", "uAr", - "oBa", "oBD", "cCB", "tfk", "wpw", "yez", "mnA", "tds", "woy", "mlk", "tcw", "woj", "FBA", - "mks", "FAk", "mvk", "thw", "wqz", "FnA", "mts", "tgy", "Flk", "msw", "Fks", "Fkg", "Fvk", - "mxw", "tiz", "Fts", "mwy", "Fsw", "Fsi", "Fxw", "myz", "Fwy", "Fyz", "vfA", "xps", "yuy", - "vdk", "xow", "yuj", "qlA", "vcs", "xoi", "qkk", "vcg", "xob", "qkc", "vca", "mfA", "tFs", - "wmy", "qvA", "mdk", "tEw", "wmj", "qtk", "vgw", "xqj", "hlA", "Ekk", "mcg", "tEb", "hkk", - "qsg", "hkc", "EvA", "mhs", "tay", "hvA", "Etk", "mgw", "taj", "htk", "qww", "vij", "hss", - "Esg", "hsg", "Exs", "miy", "hxs", "Eww", "mij", "hww", "qyj", "hwi", "Eyy", "hyy", "Eyj", - "hyj", "vFk", "xmw", "ytj", "qdA", "vEs", "xmi", "qck", "vEg", "xmb", "qcc", "vEa", "qcE", - "qcC", "mFk", "tCw", "wlj", "qhk", "mEs", "tCi", "gtA", "Eck", "vai", "tCb", "gsk", "Ecc", - "mEa", "gsc", "qga", "mED", "EcC", "Ehk", "maw", "tDj", "gxk", "Egs", "mai", "gws", "qii", - "mab", "gwg", "Ega", "EgD", "Eiw", "mbj", "gyw", "Eii", "gyi", "Eib", "gyb", "gzj", "qFA", - "vCs", "xli", "qEk", "vCg", "xlb", "qEc", "vCa", "qEE", "vCD", "qEC", "qEB", "EFA", "mCs", - "tBi", "ghA", "EEk", "mCg", "tBb", "ggk", "qag", "vDb", "ggc", "EEE", "mCD", "ggE", "qaD", - "ggC", "Eas", "mDi", "gis", "Eag", "mDb", "gig", "qbb", "gia", "EaD", "giD", "gji", "gjb", - "qCk", "vBg", "xkr", "qCc", "vBa", "qCE", "vBD", "qCC", "qCB", "ECk", "mBg", "tAr", "gak", - "ECc", "mBa", "gac", "qDa", "mBD", "gaE", "ECC", "gaC", "ECB", "EDg", "gbg", "gba", "gbD", - "vAq", "vAn", "qBB", "mAq", "EBE", "gDE", "gDC", "gDB", "lfA", "sps", "wey", "ldk", "sow", - "ClA", "lcs", "soi", "Ckk", "lcg", "Ckc", "CkE", "CvA", "lhs", "sqy", "Ctk", "lgw", "sqj", - "Css", "lgi", "Csg", "Csa", "Cxs", "liy", "Cww", "lij", "Cwi", "Cyy", "Cyj", "tpk", "wuw", - "yhj", "ndA", "tos", "wui", "nck", "tog", "wub", "ncc", "toa", "ncE", "toD", "lFk", "smw", - "wdj", "nhk", "lEs", "smi", "atA", "Cck", "tqi", "smb", "ask", "ngg", "lEa", "asc", "CcE", - "asE", "Chk", "law", "snj", "axk", "Cgs", "trj", "aws", "nii", "lab", "awg", "Cga", "awa", - "Ciw", "lbj", "ayw", "Cii", "ayi", "Cib", "Cjj", "azj", "vpA", "xus", "yxi", "vok", "xug", - "yxb", "voc", "xua", "voE", "xuD", "voC", "nFA", "tms", "wti", "rhA", "nEk", "xvi", "wtb", - "rgk", "vqg", "xvb", "rgc", "nEE", "tmD", "rgE", "vqD", "nEB", "CFA", "lCs", "sli", "ahA", - "CEk", "lCg", "slb", "ixA", "agk", "nag", "tnb", "iwk", "rig", "vrb", "lCD", "iwc", "agE", - "naD", "iwE", "CEB", "Cas", "lDi", "ais", "Cag", "lDb", "iys", "aig", "nbb", "iyg", "rjb", - "CaD", "aiD", "Cbi", "aji", "Cbb", "izi", "ajb", "vmk", "xtg", "ywr", "vmc", "xta", "vmE", - "xtD", "vmC", "vmB", "nCk", "tlg", "wsr", "rak", "nCc", "xtr", "rac", "vna", "tlD", "raE", - "nCC", "raC", "nCB", "raB", "CCk", "lBg", "skr", "aak", "CCc", "lBa", "iik", "aac", "nDa", - "lBD", "iic", "rba", "CCC", "iiE", "aaC", "CCB", "aaB", "CDg", "lBr", "abg", "CDa", "ijg", - "aba", "CDD", "ija", "abD", "CDr", "ijr", "vlc", "xsq", "vlE", "xsn", "vlC", "vlB", "nBc", - "tkq", "rDc", "nBE", "tkn", "rDE", "vln", "rDC", "nBB", "rDB", "CBc", "lAq", "aDc", "CBE", - "lAn", "ibc", "aDE", "nBn", "ibE", "rDn", "CBB", "ibC", "aDB", "ibB", "aDq", "ibq", "ibn", - "xsf", "vkl", "tkf", "nAm", "nAl", "CAo", "aBo", "iDo", "CAl", "aBl", "kpk", "BdA", "kos", - "Bck", "kog", "seb", "Bcc", "koa", "BcE", "koD", "Bhk", "kqw", "sfj", "Bgs", "kqi", "Bgg", - "kqb", "Bga", "BgD", "Biw", "krj", "Bii", "Bib", "Bjj", "lpA", "sus", "whi", "lok", "sug", - "loc", "sua", "loE", "suD", "loC", "BFA", "kms", "sdi", "DhA", "BEk", "svi", "sdb", "Dgk", - "lqg", "svb", "Dgc", "BEE", "kmD", "DgE", "lqD", "BEB", "Bas", "kni", "Dis", "Bag", "knb", - "Dig", "lrb", "Dia", "BaD", "Bbi", "Dji", "Bbb", "Djb", "tuk", "wxg", "yir", "tuc", "wxa", - "tuE", "wxD", "tuC", "tuB", "lmk", "stg", "nqk", "lmc", "sta", "nqc", "tva", "stD", "nqE", - "lmC", "nqC", "lmB", "nqB", "BCk", "klg", "Dak", "BCc", "str", "bik", "Dac", "lna", "klD", - "bic", "nra", "BCC", "biE", "DaC", "BCB", "DaB", "BDg", "klr", "Dbg", "BDa", "bjg", "Dba", - "BDD", "bja", "DbD", "BDr", "Dbr", "bjr", "xxc", "yyq", "xxE", "yyn", "xxC", "xxB", "ttc", - "wwq", "vvc", "xxq", "wwn", "vvE", "xxn", "vvC", "ttB", "vvB", "llc", "ssq", "nnc", "llE", - "ssn", "rrc", "nnE", "ttn", "rrE", "vvn", "llB", "rrC", "nnB", "rrB", "BBc", "kkq", "DDc", - "BBE", "kkn", "bbc", "DDE", "lln", "jjc", "bbE", "nnn", "BBB", "jjE", "rrn", "DDB", "jjC", - "BBq", "DDq", "BBn", "bbq", "DDn", "jjq", "bbn", "jjn", "xwo", "yyf", "xwm", "xwl", "tso", - "wwf", "vto", "xwv", "vtm", "tsl", "vtl", "lko", "ssf", "nlo", "lkm", "rno", "nlm", "lkl", - "rnm", "nll", "rnl", "BAo", "kkf", "DBo", "lkv", "bDo", "DBm", "BAl", "jbo", "bDm", "DBl", - "jbm", "bDl", "jbl", "DBv", "jbv", "xwd", "vsu", "vst", "nku", "rlu", "rlt", "DAu", "bBu", - "jDu", "jDt", "ApA", "Aok", "keg", "Aoc", "AoE", "AoC", "Aqs", "Aqg", "Aqa", "AqD", "Ari", - "Arb", "kuk", "kuc", "sha", "kuE", "shD", "kuC", "kuB", "Amk", "kdg", "Bqk", "kvg", "kda", - "Bqc", "kva", "BqE", "kvD", "BqC", "AmB", "BqB", "Ang", "kdr", "Brg", "kvr", "Bra", "AnD", - "BrD", "Anr", "Brr", "sxc", "sxE", "sxC", "sxB", "ktc", "lvc", "sxq", "sgn", "lvE", "sxn", - "lvC", "ktB", "lvB", "Alc", "Bnc", "AlE", "kcn", "Drc", "BnE", "AlC", "DrE", "BnC", "AlB", - "DrC", "BnB", "Alq", "Bnq", "Aln", "Drq", "Bnn", "Drn", "wyo", "wym", "wyl", "swo", "txo", - "wyv", "txm", "swl", "txl", "kso", "sgf", "lto", "swv", "nvo", "ltm", "ksl", "nvm", "ltl", - "nvl", "Ako", "kcf", "Blo", "ksv", "Dno", "Blm", "Akl", "bro", "Dnm", "Bll", "brm", "Dnl", - "Akv", "Blv", "Dnv", "brv", "yze", "yzd", "wye", "xyu", "wyd", "xyt", "swe", "twu", "swd", - "vxu", "twt", "vxt", "kse", "lsu", "ksd", "ntu", "lst", "rvu", "ypk", "zew", "xdA", "yos", - "zei", "xck", "yog", "zeb", "xcc", "yoa", "xcE", "yoD", "xcC", "xhk", "yqw", "zfj", "utA", - "xgs", "yqi", "usk", "xgg", "yqb", "usc", "xga", "usE", "xgD", "usC", "uxk", "xiw", "yrj", - "ptA", "uws", "xii", "psk", "uwg", "xib", "psc", "uwa", "psE", "uwD", "psC", "pxk", "uyw", - "xjj", "ftA", "pws", "uyi", "fsk", "pwg", "uyb", "fsc", "pwa", "fsE", "pwD", "fxk", "pyw", - "uzj", "fws", "pyi", "fwg", "pyb", "fwa", "fyw", "pzj", "fyi", "fyb", "xFA", "yms", "zdi", - "xEk", "ymg", "zdb", "xEc", "yma", "xEE", "ymD", "xEC", "xEB", "uhA", "xas", "yni", "ugk", - "xag", "ynb", "ugc", "xaa", "ugE", "xaD", "ugC", "ugB", "oxA", "uis", "xbi", "owk", "uig", - "xbb", "owc", "uia", "owE", "uiD", "owC", "owB", "dxA", "oys", "uji", "dwk", "oyg", "ujb", - "dwc", "oya", "dwE", "oyD", "dwC", "dys", "ozi", "dyg", "ozb", "dya", "dyD", "dzi", "dzb", - "xCk", "ylg", "zcr", "xCc", "yla", "xCE", "ylD", "xCC", "xCB", "uak", "xDg", "ylr", "uac", - "xDa", "uaE", "xDD", "uaC", "uaB", "oik", "ubg", "xDr", "oic", "uba", "oiE", "ubD", "oiC", - "oiB", "cyk", "ojg", "ubr", "cyc", "oja", "cyE", "ojD", "cyC", "cyB", "czg", "ojr", "cza", - "czD", "czr", "xBc", "ykq", "xBE", "ykn", "xBC", "xBB", "uDc", "xBq", "uDE", "xBn", "uDC", - "uDB", "obc", "uDq", "obE", "uDn", "obC", "obB", "cjc", "obq", "cjE", "obn", "cjC", "cjB", - "cjq", "cjn", "xAo", "ykf", "xAm", "xAl", "uBo", "xAv", "uBm", "uBl", "oDo", "uBv", "oDm", - "oDl", "cbo", "oDv", "cbm", "cbl", "xAe", "xAd", "uAu", "uAt", "oBu", "oBt", "wpA", "yes", - "zFi", "wok", "yeg", "zFb", "woc", "yea", "woE", "yeD", "woC", "woB", "thA", "wqs", "yfi", - "tgk", "wqg", "yfb", "tgc", "wqa", "tgE", "wqD", "tgC", "tgB", "mxA", "tis", "wri", "mwk", - "tig", "wrb", "mwc", "tia", "mwE", "tiD", "mwC", "mwB", "FxA", "mys", "tji", "Fwk", "myg", - "tjb", "Fwc", "mya", "FwE", "myD", "FwC", "Fys", "mzi", "Fyg", "mzb", "Fya", "FyD", "Fzi", - "Fzb", "yuk", "zhg", "hjs", "yuc", "zha", "hbw", "yuE", "zhD", "hDy", "yuC", "yuB", "wmk", - "ydg", "zEr", "xqk", "wmc", "zhr", "xqc", "yva", "ydD", "xqE", "wmC", "xqC", "wmB", "xqB", - "tak", "wng", "ydr", "vik", "tac", "wna", "vic", "xra", "wnD", "viE", "taC", "viC", "taB", - "viB", "mik", "tbg", "wnr", "qyk", "mic", "tba", "qyc", "vja", "tbD", "qyE", "miC", "qyC", - "miB", "qyB", "Eyk", "mjg", "tbr", "hyk", "Eyc", "mja", "hyc", "qza", "mjD", "hyE", "EyC", - "hyC", "EyB", "Ezg", "mjr", "hzg", "Eza", "hza", "EzD", "hzD", "Ezr", "ytc", "zgq", "grw", - "ytE", "zgn", "gny", "ytC", "glz", "ytB", "wlc", "ycq", "xnc", "wlE", "ycn", "xnE", "ytn", - "xnC", "wlB", "xnB", "tDc", "wlq", "vbc", "tDE", "wln", "vbE", "xnn", "vbC", "tDB", "vbB", - "mbc", "tDq", "qjc", "mbE", "tDn", "qjE", "vbn", "qjC", "mbB", "qjB", "Ejc", "mbq", "gzc", - "EjE", "mbn", "gzE", "qjn", "gzC", "EjB", "gzB", "Ejq", "gzq", "Ejn", "gzn", "yso", "zgf", - "gfy", "ysm", "gdz", "ysl", "wko", "ycf", "xlo", "ysv", "xlm", "wkl", "xll", "tBo", "wkv", - "vDo", "tBm", "vDm", "tBl", "vDl", "mDo", "tBv", "qbo", "vDv", "qbm", "mDl", "qbl", "Ebo", - "mDv", "gjo", "Ebm", "gjm", "Ebl", "gjl", "Ebv", "gjv", "yse", "gFz", "ysd", "wke", "xku", - "wkd", "xkt", "tAu", "vBu", "tAt", "vBt", "mBu", "qDu", "mBt", "qDt", "EDu", "gbu", "EDt", - "gbt", "ysF", "wkF", "xkh", "tAh", "vAx", "mAx", "qBx", "wek", "yFg", "zCr", "wec", "yFa", - "weE", "yFD", "weC", "weB", "sqk", "wfg", "yFr", "sqc", "wfa", "sqE", "wfD", "sqC", "sqB", - "lik", "srg", "wfr", "lic", "sra", "liE", "srD", "liC", "liB", "Cyk", "ljg", "srr", "Cyc", - "lja", "CyE", "ljD", "CyC", "CyB", "Czg", "ljr", "Cza", "CzD", "Czr", "yhc", "zaq", "arw", - "yhE", "zan", "any", "yhC", "alz", "yhB", "wdc", "yEq", "wvc", "wdE", "yEn", "wvE", "yhn", - "wvC", "wdB", "wvB", "snc", "wdq", "trc", "snE", "wdn", "trE", "wvn", "trC", "snB", "trB", - "lbc", "snq", "njc", "lbE", "snn", "njE", "trn", "njC", "lbB", "njB", "Cjc", "lbq", "azc", - "CjE", "lbn", "azE", "njn", "azC", "CjB", "azB", "Cjq", "azq", "Cjn", "azn", "zio", "irs", - "rfy", "zim", "inw", "rdz", "zil", "ily", "ikz", "ygo", "zaf", "afy", "yxo", "ziv", "ivy", - "adz", "yxm", "ygl", "itz", "yxl", "wco", "yEf", "wto", "wcm", "xvo", "yxv", "wcl", "xvm", - "wtl", "xvl", "slo", "wcv", "tno", "slm", "vro", "tnm", "sll", "vrm", "tnl", "vrl", "lDo", - "slv", "nbo", "lDm", "rjo", "nbm", "lDl", "rjm", "nbl", "rjl", "Cbo", "lDv", "ajo", "Cbm", - "izo", "ajm", "Cbl", "izm", "ajl", "izl", "Cbv", "ajv", "zie", "ifw", "rFz", "zid", "idy", - "icz", "yge", "aFz", "ywu", "ygd", "ihz", "ywt", "wce", "wsu", "wcd", "xtu", "wst", "xtt", - "sku", "tlu", "skt", "vnu", "tlt", "vnt", "lBu", "nDu", "lBt", "rbu", "nDt", "rbt", "CDu", - "abu", "CDt", "iju", "abt", "ijt", "ziF", "iFy", "iEz", "ygF", "ywh", "wcF", "wsh", "xsx", - "skh", "tkx", "vlx", "lAx", "nBx", "rDx", "CBx", "aDx", "ibx", "iCz", "wFc", "yCq", "wFE", - "yCn", "wFC", "wFB", "sfc", "wFq", "sfE", "wFn", "sfC", "sfB", "krc", "sfq", "krE", "sfn", - "krC", "krB", "Bjc", "krq", "BjE", "krn", "BjC", "BjB", "Bjq", "Bjn", "yao", "zDf", "Dfy", - "yam", "Ddz", "yal", "wEo", "yCf", "who", "wEm", "whm", "wEl", "whl", "sdo", "wEv", "svo", - "sdm", "svm", "sdl", "svl", "kno", "sdv", "lro", "knm", "lrm", "knl", "lrl", "Bbo", "knv", - "Djo", "Bbm", "Djm", "Bbl", "Djl", "Bbv", "Djv", "zbe", "bfw", "npz", "zbd", "bdy", "bcz", - "yae", "DFz", "yiu", "yad", "bhz", "yit", "wEe", "wgu", "wEd", "wxu", "wgt", "wxt", "scu", - "stu", "sct", "tvu", "stt", "tvt", "klu", "lnu", "klt", "nru", "lnt", "nrt", "BDu", "Dbu", - "BDt", "bju", "Dbt", "bjt", "jfs", "rpy", "jdw", "roz", "jcy", "jcj", "zbF", "bFy", "zjh", - "jhy", "bEz", "jgz", "yaF", "yih", "yyx", "wEF", "wgh", "wwx", "xxx", "sch", "ssx", "ttx", - "vvx", "kkx", "llx", "nnx", "rrx", "BBx", "DDx", "bbx", "jFw", "rmz", "jEy", "jEj", "bCz", - "jaz", "jCy", "jCj", "jBj", "wCo", "wCm", "wCl", "sFo", "wCv", "sFm", "sFl", "kfo", "sFv", - "kfm", "kfl", "Aro", "kfv", "Arm", "Arl", "Arv", "yDe", "Bpz", "yDd", "wCe", "wau", "wCd", - "wat", "sEu", "shu", "sEt", "sht", "kdu", "kvu", "kdt", "kvt", "Anu", "Bru", "Ant", "Brt", - "zDp", "Dpy", "Doz", "yDF", "ybh", "wCF", "wah", "wix", "sEh", "sgx", "sxx", "kcx", "ktx", - "lvx", "Alx", "Bnx", "Drx", "bpw", "nuz", "boy", "boj", "Dmz", "bqz", "jps", "ruy", "jow", - "ruj", "joi", "job", "bmy", "jqy", "bmj", "jqj", "jmw", "rtj", "jmi", "jmb", "blj", "jnj", - "jli", "jlb", "jkr", "sCu", "sCt", "kFu", "kFt", "Afu", "Aft", "wDh", "sCh", "sax", "kEx", - "khx", "Adx", "Avx", "Buz", "Duy", "Duj", "buw", "nxj", "bui", "bub", "Dtj", "bvj", "jus", - "rxi", "jug", "rxb", "jua", "juD", "bti", "jvi", "btb", "jvb", "jtg", "rwr", "jta", "jtD", - "bsr", "jtr", "jsq", "jsn", "Bxj", "Dxi", "Dxb", "bxg", "nyr", "bxa", "bxD", "Dwr", "bxr", - "bwq", "bwn", "pjk", "urw", "ejA", "pbs", "uny", "ebk", "pDw", "ulz", "eDs", "pBy", "eBw", - "zfc", "fjk", "prw", "zfE", "fbs", "pny", "zfC", "fDw", "plz", "zfB", "fBy", "yrc", "zfq", - "frw", "yrE", "zfn", "fny", "yrC", "flz", "yrB", "xjc", "yrq", "xjE", "yrn", "xjC", "xjB", - "uzc", "xjq", "uzE", "xjn", "uzC", "uzB", "pzc", "uzq", "pzE", "uzn", "pzC", "djA", "ors", - "ufy", "dbk", "onw", "udz", "dDs", "oly", "dBw", "okz", "dAy", "zdo", "drs", "ovy", "zdm", - "dnw", "otz", "zdl", "dly", "dkz", "yno", "zdv", "dvy", "ynm", "dtz", "ynl", "xbo", "ynv", - "xbm", "xbl", "ujo", "xbv", "ujm", "ujl", "ozo", "ujv", "ozm", "ozl", "crk", "ofw", "uFz", - "cns", "ody", "clw", "ocz", "cky", "ckj", "zcu", "cvw", "ohz", "zct", "cty", "csz", "ylu", - "cxz", "ylt", "xDu", "xDt", "ubu", "ubt", "oju", "ojt", "cfs", "oFy", "cdw", "oEz", "ccy", - "ccj", "zch", "chy", "cgz", "ykx", "xBx", "uDx", "cFw", "oCz", "cEy", "cEj", "caz", "cCy", - "cCj", "FjA", "mrs", "tfy", "Fbk", "mnw", "tdz", "FDs", "mly", "FBw", "mkz", "FAy", "zFo", - "Frs", "mvy", "zFm", "Fnw", "mtz", "zFl", "Fly", "Fkz", "yfo", "zFv", "Fvy", "yfm", "Ftz", - "yfl", "wro", "yfv", "wrm", "wrl", "tjo", "wrv", "tjm", "tjl", "mzo", "tjv", "mzm", "mzl", - "qrk", "vfw", "xpz", "hbA", "qns", "vdy", "hDk", "qlw", "vcz", "hBs", "qky", "hAw", "qkj", - "hAi", "Erk", "mfw", "tFz", "hrk", "Ens", "mdy", "hns", "qty", "mcz", "hlw", "Eky", "hky", - "Ekj", "hkj", "zEu", "Evw", "mhz", "zhu", "zEt", "hvw", "Ety", "zht", "hty", "Esz", "hsz", - "ydu", "Exz", "yvu", "ydt", "hxz", "yvt", "wnu", "xru", "wnt", "xrt", "tbu", "vju", "tbt", - "vjt", "mju", "mjt", "grA", "qfs", "vFy", "gnk", "qdw", "vEz", "gls", "qcy", "gkw", "qcj", - "gki", "gkb", "Efs", "mFy", "gvs", "Edw", "mEz", "gtw", "qgz", "gsy", "Ecj", "gsj", "zEh", - "Ehy", "zgx", "gxy", "Egz", "gwz", "ycx", "ytx", "wlx", "xnx", "tDx", "vbx", "mbx", "gfk", - "qFw", "vCz", "gds", "qEy", "gcw", "qEj", "gci", "gcb", "EFw", "mCz", "ghw", "EEy", "ggy", - "EEj", "ggj", "Eaz", "giz", "gFs", "qCy", "gEw", "qCj", "gEi", "gEb", "ECy", "gay", "ECj", - "gaj", "gCw", "qBj", "gCi", "gCb", "EBj", "gDj", "gBi", "gBb", "Crk", "lfw", "spz", "Cns", - "ldy", "Clw", "lcz", "Cky", "Ckj", "zCu", "Cvw", "lhz", "zCt", "Cty", "Csz", "yFu", "Cxz", - "yFt", "wfu", "wft", "sru", "srt", "lju", "ljt", "arA", "nfs", "tpy", "ank", "ndw", "toz", - "als", "ncy", "akw", "ncj", "aki", "akb", "Cfs", "lFy", "avs", "Cdw", "lEz", "atw", "ngz", - "asy", "Ccj", "asj", "zCh", "Chy", "zax", "axy", "Cgz", "awz", "yEx", "yhx", "wdx", "wvx", - "snx", "trx", "lbx", "rfk", "vpw", "xuz", "inA", "rds", "voy", "ilk", "rcw", "voj", "iks", - "rci", "ikg", "rcb", "ika", "afk", "nFw", "tmz", "ivk", "ads", "nEy", "its", "rgy", "nEj", - "isw", "aci", "isi", "acb", "isb", "CFw", "lCz", "ahw", "CEy", "ixw", "agy", "CEj", "iwy", - "agj", "iwj", "Caz", "aiz", "iyz", "ifA", "rFs", "vmy", "idk", "rEw", "vmj", "ics", "rEi", - "icg", "rEb", "ica", "icD", "aFs", "nCy", "ihs", "aEw", "nCj", "igw", "raj", "igi", "aEb", - "igb", "CCy", "aay", "CCj", "iiy", "aaj", "iij", "iFk", "rCw", "vlj", "iEs", "rCi", "iEg", - "rCb", "iEa", "iED", "aCw", "nBj", "iaw", "aCi", "iai", "aCb", "iab", "CBj", "aDj", "ibj", - "iCs", "rBi", "iCg", "rBb", "iCa", "iCD", "aBi", "iDi", "aBb", "iDb", "iBg", "rAr", "iBa", - "iBD", "aAr", "iBr", "iAq", "iAn", "Bfs", "kpy", "Bdw", "koz", "Bcy", "Bcj", "Bhy", "Bgz", - "yCx", "wFx", "sfx", "krx", "Dfk", "lpw", "suz", "Dds", "loy", "Dcw", "loj", "Dci", "Dcb", - "BFw", "kmz", "Dhw", "BEy", "Dgy", "BEj", "Dgj", "Baz", "Diz", "bfA", "nps", "tuy", "bdk", - "now", "tuj", "bcs", "noi", "bcg", "nob", "bca", "bcD", "DFs", "lmy", "bhs", "DEw", "lmj", - "bgw", "DEi", "bgi", "DEb", "bgb", "BCy", "Day", "BCj", "biy", "Daj", "bij", "rpk", "vuw", - "xxj", "jdA", "ros", "vui", "jck", "rog", "vub", "jcc", "roa", "jcE", "roD", "jcC", "bFk", - "nmw", "ttj", "jhk", "bEs", "nmi", "jgs", "rqi", "nmb", "jgg", "bEa", "jga", "bED", "jgD", - "DCw", "llj", "baw", "DCi", "jiw", "bai", "DCb", "jii", "bab", "jib", "BBj", "DDj", "bbj", - "jjj", "jFA", "rms", "vti", "jEk", "rmg", "vtb", "jEc", "rma", "jEE", "rmD", "jEC", "jEB", - "bCs", "nli", "jas", "bCg", "nlb", "jag", "rnb", "jaa", "bCD", "jaD", "DBi", "bDi", "DBb", - "jbi", "bDb", "jbb", "jCk", "rlg", "vsr", "jCc", "rla", "jCE", "rlD", "jCC", "jCB", "bBg", - "nkr", "jDg", "bBa", "jDa", "bBD", "jDD", "DAr", "bBr", "jDr", "jBc", "rkq", "jBE", "rkn", - "jBC", "jBB", "bAq", "jBq", "bAn", "jBn", "jAo", "rkf", "jAm", "jAl", "bAf", "jAv", "Apw", - "kez", "Aoy", "Aoj", "Aqz", "Bps", "kuy", "Bow", "kuj", "Boi", "Bob", "Amy", "Bqy", "Amj", - "Bqj", "Dpk", "luw", "sxj", "Dos", "lui", "Dog", "lub", "Doa", "DoD", "Bmw", "ktj", "Dqw", - "Bmi", "Dqi", "Bmb", "Dqb", "Alj", "Bnj", "Drj", "bpA", "nus", "txi", "bok", "nug", "txb", - "boc", "nua", "boE", "nuD", "boC", "boB", "Dms", "lti", "bqs", "Dmg", "ltb", "bqg", "nvb", - "bqa", "DmD", "bqD", "Bli", "Dni", "Blb", "bri", "Dnb", "brb", "ruk", "vxg", "xyr", "ruc", - "vxa", "ruE", "vxD", "ruC", "ruB", "bmk", "ntg", "twr", "jqk", "bmc", "nta", "jqc", "rva", - "ntD", "jqE", "bmC", "jqC", "bmB", "jqB", "Dlg", "lsr", "bng", "Dla", "jrg", "bna", "DlD", - "jra", "bnD", "jrD", "Bkr", "Dlr", "bnr", "jrr", "rtc", "vwq", "rtE", "vwn", "rtC", "rtB", - "blc", "nsq", "jnc", "blE", "nsn", "jnE", "rtn", "jnC", "blB", "jnB", "Dkq", "blq", "Dkn", - "jnq", "bln", "jnn", "rso", "vwf", "rsm", "rsl", "bko", "nsf", "jlo", "bkm", "jlm", "bkl", - "jll", "Dkf", "bkv", "jlv", "rse", "rsd", "bke", "jku", "bkd", "jkt", "Aey", "Aej", "Auw", - "khj", "Aui", "Aub", "Adj", "Avj", "Bus", "kxi", "Bug", "kxb", "Bua", "BuD", "Ati", "Bvi", - "Atb", "Bvb", "Duk", "lxg", "syr", "Duc", "lxa", "DuE", "lxD", "DuC", "DuB", "Btg", "kwr", - "Dvg", "lxr", "Dva", "BtD", "DvD", "Asr", "Btr", "Dvr", "nxc", "tyq", "nxE", "tyn", "nxC", - "nxB", "Dtc", "lwq", "bvc", "nxq", "lwn", "bvE", "DtC", "bvC", "DtB", "bvB", "Bsq", "Dtq", - "Bsn", "bvq", "Dtn", "bvn", "vyo", "xzf", "vym", "vyl", "nwo", "tyf", "rxo", "nwm", "rxm", - "nwl", "rxl", "Dso", "lwf", "bto", "Dsm", "jvo", "btm", "Dsl", "jvm", "btl", "jvl", "Bsf", - "Dsv", "btv", "jvv", "vye", "vyd", "nwe", "rwu", "nwd", "rwt", "Dse", "bsu", "Dsd", "jtu", - "bst", "jtt", "vyF", "nwF", "rwh", "DsF", "bsh", "jsx", "Ahi", "Ahb", "Axg", "kir", "Axa", - "AxD", "Agr", "Axr", "Bxc", "kyq", "BxE", "kyn", "BxC", "BxB", "Awq", "Bxq", "Awn", "Bxn", - "lyo", "szf", "lym", "lyl", "Bwo", "kyf", "Dxo", "lyv", "Dxm", "Bwl", "Dxl", "Awf", "Bwv", - "Dxv", "tze", "tzd", "lye", "nyu", "lyd", "nyt", "Bwe", "Dwu", "Bwd", "bxu", "Dwt", "bxt", - "tzF", "lyF", "nyh", "BwF", "Dwh", "bwx", "Aiq", "Ain", "Ayo", "kjf", "Aym", "Ayl", "Aif", - "Ayv", "kze", "kzd", "Aye", "Byu", "Ayd", "Byt", "szp" }; - -/* converts values into bar patterns - replacing Grand Zebu's true type font */ -static char *PDFttf[35] = { "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", - "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", - "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", - "11011", "11100", "11101", "11110", "11111", "01", "1111111101010100", "11111101000101001"}; - -/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */ -static int Microcoeffs[344] = { - /* k = 7 */ - 76, 925, 537, 597, 784, 691, 437, - - /* k = 8 */ - 237, 308, 436, 284, 646, 653, 428, 379, - - /* k = 9 */ - 567, 527, 622, 257, 289, 362, 501, 441, 205, - - /* k = 10 */ - 377, 457, 64, 244, 826, 841, 818, 691, 266, 612, - - /* k = 11 */ - 462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904, - - /* k = 12 */ - 597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851, - - /* k = 13 */ - 764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692, - - /* k = 14 */ - 669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215, - - /* k = 15 */ - 460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642, - - /* k = 16 */ - 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, - - /* k = 18 */ - 279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756, - 760, 573, - - /* k = 21 */ - 108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691, - 347, 165, 193, 259, 568, - - /* k = 26 */ - 443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893, - 699, 245, 441, 454, 325, 858, 131, 847, 764, 169, - - /* k = 32 */ - 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, - 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, - - /* k = 38 */ - 234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684, - 445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771, - 554, 289, 231, 125, 117, 518, - - /* k = 44 */ - 476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405, - 417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213, - 31, 560, 231, 758, 103, 271, 572, 436, 339, 730, 82, 285, - - /* k = 50 */ - 923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303, - 188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26, - 579, 623, 766, 146, 10, 739, 246, 127, 71, 244, 211, 477, 920, 876, 427, 820, - 718, 435 }; - -/* rows, columns, error codewords, k-offset of valid MicroPDF417 sizes from ISO/IEC 24728:2006 */ -static int MicroVariants[170] = -{ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, - 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, - 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 }; -/* rows, columns, error codewords, k-offset */ - -/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables 10, 11 and 12 */ -static int RAPTable[136] = -{ 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, - 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, - 0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 }; - -/* Left and Right Row Address Pattern from Table 2 */ -static char *RAPLR[53] = {"", "221311", "311311", "312211", "222211", "213211", "214111", "223111", - "313111", "322111", "412111", "421111", "331111", "241111", "232111", "231211", "321211", - "411211", "411121", "411112", "321112", "312112", "311212", "311221", "311131", "311122", - "311113", "221113", "221122", "221131", "221221", "222121", "312121", "321121", "231121", - "231112", "222112", "213112", "212212", "212221", "212131", "212122", "212113", "211213", - "211123", "211132", "211141", "211231", "211222", "211312", "211321", "211411", "212311" }; - -/* Centre Row Address Pattern from Table 2 */ -static char *RAPC[53] = {"", "112231", "121231", "122131", "131131", "131221", "132121", "141121", - "141211", "142111", "133111", "132211", "131311", "122311", "123211", "124111", "115111", - "114211", "114121", "123121", "123112", "122212", "122221", "121321", "121411", "112411", - "113311", "113221", "113212", "113122", "122122", "131122", "131113", "122113", "113113", - "112213", "112222", "112312", "112321", "111421", "111331", "111322", "111232", "111223", - "111133", "111124", "111214", "112114", "121114", "121123", "121132", "112132", "112141" }; - -void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int block); \ No newline at end of file diff --git a/3rdparty/zint-2.4.4/backend/plessey.c b/3rdparty/zint-2.4.4/backend/plessey.c deleted file mode 100644 index 3c4cb5f..0000000 --- a/3rdparty/zint-2.4.4/backend/plessey.c +++ /dev/null @@ -1,498 +0,0 @@ -/* plessey.c - Handles Plessey and MSI Plessey */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include "common.h" - - -#define SSET "0123456789ABCDEF" -static char *PlessTable[16] = {"13131313", "31131313", "13311313", "31311313", "13133113", "31133113", - "13313113", "31313113", "13131331", "31131331", "13311331", "31311331", "13133131", - "31133131", "13313131", "31313131"}; - -static char *MSITable[10] = {"12121212", "12121221", "12122112", "12122121", "12211212", "12211221", - "12212112", "12212121", "21121212", "21121221"}; - - -int plessey(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Not MSI/Plessey but the older Plessey standard */ - - unsigned int i, check; - unsigned char *checkptr; - static char grid[9] = {1,1,1,1,0,1,0,0,1}; - char dest[1024]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 ~ 1024 */ - int error_number; - - error_number = 0; - - if(length > 65) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(SSET, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - checkptr = (unsigned char *)calloc (1, length * 4 + 8); - - /* Start character */ - strcpy(dest, "31311331"); - - /* Data area */ - for(i = 0; i < length; i++) - { - check = posn(SSET, source[i]); - lookup(SSET, PlessTable, source[i], dest); - checkptr[4*i] = check & 1; - checkptr[4*i+1] = (check >> 1) & 1; - checkptr[4*i+2] = (check >> 2) & 1; - checkptr[4*i+3] = (check >> 3) & 1; - } - - /* CRC check digit code adapted from code by Leonid A. Broukhis - used in GNU Barcode */ - - for (i = 0; i < (4 * length); i++) { - int j; - if (checkptr[i]) - for (j = 0; j < 9; j++) - checkptr[i+j] ^= grid[j]; - } - - for (i = 0; i < 8; i++) { - switch(checkptr[length * 4 + i]) - { - case 0: concat(dest, "13"); break; - case 1: concat(dest, "31"); break; - } - } - - /* Stop character */ - concat(dest, "331311313"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - free(checkptr); - return error_number; -} - -int msi_plessey(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Plain MSI Plessey - does not calculate any check character */ - - unsigned int i; - char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */ - - if(length > 55) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - for(i = 0; i < length; i++) - { - lookup(NEON, MSITable, source[i], dest); - } - - /* Stop character */ - concat (dest, "121"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return 0; -} - -int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island - http://www.barcodeisland.com/ */ - - int i; - unsigned long wright, dau, pedwar, pump, n; - char un[200], tri[32]; - int error_number, h; - char dest[1000]; - - error_number = 0; - - if(length > 18) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - /* draw data section */ - for(i = 0; i < length; i++) - { - lookup(NEON, MSITable, source[i], dest); - } - - /* caluculate check digit */ - wright = 0; - n = !(length & 1); - for(i = n; i < length; i += 2) - { - un[wright++] = source[i]; - } - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%ld", dau); - - pedwar = 0; - h = strlen(tri); - for(i = 0; i < h; i++) - { - pedwar += ctoi(tri[i]); - } - - n = length & 1; - for(i = n; i < length; i+=2) - { - pedwar += ctoi(source[i]); - } - - pump = (10 - pedwar % 10); - if(pump == 10) - { - pump = 0; - } - - /* draw check digit */ - lookup(NEON, MSITable, itoc(pump), dest); - - /* Stop character */ - concat (dest, "121"); - expand(symbol, dest); - - ustrcpy(symbol->text, source); - symbol->text[length] = itoc(pump); - symbol->text[length + 1] = '\0'; - return error_number; -} - -int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) -{ /* MSI Plessey with two Modulo 10 check digits - algorithm from - Barcode Island http://www.barcodeisland.com/ */ - - unsigned long i, n, wright, dau, pedwar, pump, chwech; - char un[16], tri[32]; - int error_number, h; - char dest[1000]; - - error_number = 0; - - if(src_len > 18) { /* No Entry Stack Smashers! limit because of str->number conversion*/ - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - /* draw data section */ - for(i = 0; i < src_len; i++) - { - lookup(NEON, MSITable, source[i], dest); - } - - /* calculate first check digit */ - wright = 0; - - n = !(src_len & 1); - for(i = n; i < src_len; i += 2) - { - un[wright++] = source[i]; - } - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%ld", dau); - - pedwar = 0; - h = strlen(tri); - for(i = 0; i < h; i++) - { - pedwar += ctoi(tri[i]); - } - - n = src_len & 1; - for(i = n; i < src_len; i += 2) - { - pedwar += ctoi(source[i]); - } - - pump = 10 - pedwar % 10; - if(pump == 10) - { - pump = 0; - } - - /* calculate second check digit */ - wright = 0; - n = src_len & 1; - for(i = n; i < src_len; i += 2) - { - un[wright++] = source[i]; - } - un[wright++] = itoc(pump); - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%ld", dau); - - pedwar = 0; - h = strlen(tri); - for(i = 0; i < h; i++) - { - pedwar += ctoi(tri[i]); - } - - - i = !(src_len & 1); - for(; i < src_len; i += 2) - { - pedwar += ctoi(source[i]); - } - - chwech = 10 - pedwar % 10; - if(chwech == 10) - { - chwech = 0; - } - - /* Draw check digits */ - lookup(NEON, MSITable, itoc(pump), dest); - lookup(NEON, MSITable, itoc(chwech), dest); - - /* Stop character */ - concat (dest, "121"); - - expand(symbol, dest); - - ustrcpy(symbol->text, source); - symbol->text[src_len] = itoc(pump); - symbol->text[src_len + 1] = itoc(chwech); - symbol->text[src_len + 2] = '\0'; - - return error_number; -} - - -int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) -{ - /* Calculate a Modulo 11 check digit using the system discussed on Wikipedia - - see http://en.wikipedia.org/wiki/Talk:MSI_Barcode */ - /* uses the IBM weight system */ - - int i, weight, x, check; - int error_number; - char dest[1000]; - - error_number = 0; - - if(src_len > 55) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - /* draw data section */ - for(i = 0; i < src_len; i++) - { - lookup(NEON, MSITable, source[i], dest); - } - - /* calculate check digit */ - x = 0; - weight = 2; - for(i = src_len - 1; i >= 0; i--) { - x += weight * ctoi(source[i]); - weight++; - if(weight > 7) { - weight = 2; - } - } - - check = (11 - (x % 11)) % 11; - if(check == 10) { - lookup(NEON, MSITable, '1', dest); - lookup(NEON, MSITable, '0', dest); - } else { - lookup(NEON, MSITable, itoc(check), dest); - } - - /* stop character */ - concat (dest, "121"); - - expand(symbol, dest); - - ustrcpy(symbol->text, source); - if(check == 10) { - concat((char* )symbol->text, "10"); - } else { - symbol->text[src_len] = itoc(check); - symbol->text[src_len + 1] = '\0'; - } - - return error_number; -} - -int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) -{ - /* Combining the Barcode Island and Wikipedia code */ - /* Verified against http://www.bokai.com/BarcodeJSP/applet/BarcodeSampleApplet.htm */ - /* Weighted using the IBM system */ - - int i; - unsigned long weight, x, check, wright, dau, pedwar, pump, h; - char un[16], tri[16]; - int error_number; - char dest[1000]; - unsigned char temp[32]; - unsigned int temp_len; - - error_number = 0; - - if(src_len > 18) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - /* draw data section */ - for(i = 0; i < src_len; i++) - { - lookup(NEON, MSITable, source[i], dest); - } - - /* calculate first (mod 11) digit */ - x = 0; - weight = 2; - for(i = src_len - 1; i >= 0; i--) { - x += weight * ctoi(source[i]); - weight++; - if(weight > 7) { - weight = 2; - } - } - - check = (11 - (x % 11)) % 11; - ustrcpy(temp, source); - temp_len = src_len; - if(check == 10) { - lookup(NEON, MSITable, '1', dest); - lookup(NEON, MSITable, '0', dest); - uconcat(temp, (unsigned char *)"10"); - temp_len += 2; - } else { - lookup(NEON, MSITable, itoc(check), dest); - temp[temp_len++] = itoc(check); - temp[temp_len] = '\0'; - } - - /* caluculate second (mod 10) check digit */ - wright = 0; - i = !(temp_len & 1); - for(; i < temp_len; i += 2) - { - un[wright++] = temp[i]; - } - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%ld", dau); - - pedwar = 0; - h = strlen(tri); - for(i = 0; i < h; i++) - { - pedwar += ctoi(tri[i]); - } - - i = temp_len & 1; - for(; i < temp_len; i+=2) - { - pedwar += ctoi(temp[i]); - } - - pump = 10 - pedwar % 10; - if(pump == 10) - { - pump = 0; - } - - /* draw check digit */ - lookup(NEON, MSITable, itoc(pump), dest); - - /* stop character */ - concat (dest, "121"); - expand(symbol, dest); - - temp[temp_len++] = itoc(pump); - temp[temp_len] = '\0'; - - - ustrcpy(symbol->text, temp); - return error_number; -} - -int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) { - int error_number; - - error_number = is_sane(NEON, source, length); - if(error_number != 0) { - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - - - if((symbol->option_2 < 0) || (symbol->option_2 > 4)) { - symbol->option_2 = 0; - } - - switch(symbol->option_2) { - case 0: error_number = msi_plessey(symbol, source, length); break; - case 1: error_number = msi_plessey_mod10(symbol, source, length); break; - case 2: error_number = msi_plessey_mod1010(symbol, source, length); break; - case 3: error_number = msi_plessey_mod11(symbol, source, length); break; - case 4: error_number = msi_plessey_mod1110(symbol, source, length); break; - } - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/png.c b/3rdparty/zint-2.4.4/backend/png.c deleted file mode 100644 index 251df8b..0000000 --- a/3rdparty/zint-2.4.4/backend/png.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* png.c - Handles output to PNG file */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#ifdef _MSC_VER -#include -#include -#endif -#include -#include -#include "common.h" - -#ifdef _MSC_VER -#include -#endif /* _MSC_VER */ - -#ifndef NO_PNG -#include "png.h" /* libpng header; includes zlib.h and setjmp.h */ -#endif /* NO_PNG */ -#include "maxipng.h" /* Maxicode shapes */ - -#include "font.h" /* Font for human readable text */ - -#define SSET "0123456789ABCDEF" - -#define PNG_DATA 100 -#define BMP_DATA 200 - -#ifndef NO_PNG -struct mainprog_info_type { - long width; - long height; - FILE *outfile; - jmp_buf jmpbuf; -}; - -static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) -{ - struct mainprog_info_type *graphic; - - fprintf(stderr, "writepng libpng error: %s\n", msg); - fflush(stderr); - - graphic = (struct mainprog_info_type*)png_get_error_ptr(png_ptr); - if (graphic == NULL) { /* we are completely hosed now */ - fprintf(stderr, - "writepng severe error: jmpbuf not recoverable; terminating.\n"); - fflush(stderr); - return; - } - longjmp(graphic->jmpbuf, 1); -} - -int png_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) -{ - struct mainprog_info_type wpng_info; - struct mainprog_info_type *graphic; - -#ifndef _MSC_VER - unsigned char outdata[image_width * 3]; -#else - unsigned char* outdata = (unsigned char*)_alloca(image_width * 3); -#endif - png_structp png_ptr; - png_infop info_ptr; - graphic = &wpng_info; - unsigned long rowbytes; - unsigned char *image_data; - int i, row, column, errno; - int fgred, fggrn, fgblu, bgred, bggrn, bgblu; - - switch(rotate_angle) { - case 0: - case 180: - graphic->width = image_width; - graphic->height = image_height; - break; - case 90: - case 270: - graphic->width = image_height; - graphic->height = image_width; - break; - } - - /* sort out colour options */ - to_upper((unsigned char*)symbol->fgcolour); - to_upper((unsigned char*)symbol->bgcolour); - - if(strlen(symbol->fgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - if(strlen(symbol->bgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - errno = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); - if (errno == ERROR_INVALID_DATA) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - errno = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); - if (errno == ERROR_INVALID_DATA) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - - fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - - /* Open output file in binary mode */ - if((symbol->output_options & BARCODE_STDOUT) != 0) { -#ifdef _MSC_VER - if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - strcpy(symbol->errtxt, "Can't open output file"); - return ERROR_FILE_ACCESS; - } -#endif - graphic->outfile = stdout; - } else { - if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) { - strcpy(symbol->errtxt, "Can't open output file"); - return ERROR_FILE_ACCESS; - } - } - - /* Set up error handling routine as proc() above */ - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic, writepng_error_handler, NULL); - if (!png_ptr) { - strcpy(symbol->errtxt, "Out of memory"); - return ERROR_MEMORY; - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, NULL); - strcpy(symbol->errtxt, "Out of memory"); - return ERROR_MEMORY; - } - - /* catch jumping here */ - if (setjmp(graphic->jmpbuf)) { - png_destroy_write_struct(&png_ptr, &info_ptr); - strcpy(symbol->errtxt, "libpng error occurred"); - return ERROR_MEMORY; - } - - /* open output file with libpng */ - png_init_io(png_ptr, graphic->outfile); - - /* set compression */ - png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); - - /* set Header block */ - png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height, - 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - /* write all chunks up to (but not including) first IDAT */ - png_write_info(png_ptr, info_ptr); - - /* set up the transformations: for now, just pack low-bit-depth pixels - into bytes (one, two or four pixels per byte) */ - png_set_packing(png_ptr); - - /* set rowbytes - depends on picture depth */ - rowbytes = wpng_info.width * 3; - - /* Pixel Plotting */ - - switch(rotate_angle) { - case 0: /* Plot the right way up */ - for(row = 0; row < image_height; row++) { - for(column = 0; column < image_width; column++) { - i = column * 3; - switch(*(pixelbuf + (image_width * row) + column)) - { - case '1': - outdata[i] = fgred; - outdata[i + 1] = fggrn; - outdata[i + 2] = fgblu; - break; - default: - outdata[i] = bgred; - outdata[i + 1] = bggrn; - outdata[i + 2] = bgblu; - break; - - } - } - /* write row contents to file */ - image_data = outdata; - png_write_row(png_ptr, image_data); - } - break; - case 90: /* Plot 90 degrees clockwise */ - for(row = 0; row < image_width; row++) { - for(column = 0; column < image_height; column++) { - i = column * 3; - switch(*(pixelbuf + (image_width * (image_height - column - 1)) + row)) - { - case '1': - outdata[i] = fgred; - outdata[i + 1] = fggrn; - outdata[i + 2] = fgblu; - break; - default: - outdata[i] = bgred; - outdata[i + 1] = bggrn; - outdata[i + 2] = bgblu; - break; - - } - } - - /* write row contents to file */ - image_data = outdata; - png_write_row(png_ptr, image_data); - } - break; - case 180: /* Plot upside down */ - for(row = 0; row < image_height; row++) { - for(column = 0; column < image_width; column++) { - i = column * 3; - switch(*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1))) - { - case '1': - outdata[i] = fgred; - outdata[i + 1] = fggrn; - outdata[i + 2] = fgblu; - break; - default: - outdata[i] = bgred; - outdata[i + 1] = bggrn; - outdata[i + 2] = bgblu; - break; - - } - } - - /* write row contents to file */ - image_data = outdata; - png_write_row(png_ptr, image_data); - } - break; - case 270: /* Plot 90 degrees anti-clockwise */ - for(row = 0; row < image_width; row++) { - for(column = 0; column < image_height; column++) { - i = column * 3; - switch(*(pixelbuf + (image_width * column) + (image_width - row - 1))) - { - case '1': - outdata[i] = fgred; - outdata[i + 1] = fggrn; - outdata[i + 2] = fgblu; - break; - default: - outdata[i] = bgred; - outdata[i + 1] = bggrn; - outdata[i + 2] = bgblu; - break; - - } - } - - /* write row contents to file */ - image_data = outdata; - png_write_row(png_ptr, image_data); - } - break; - } - - /* End the file */ - png_write_end(png_ptr, NULL); - - /* make sure we have disengaged */ - if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(wpng_info.outfile); - return 0; -} -#endif /* NO_PNG */ - -int bmp_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) -{ - unsigned long rowbytes; - int i, row, column, errno; - int fgred, fggrn, fgblu, bgred, bggrn, bgblu; - - switch(rotate_angle) { - case 0: - case 180: - symbol->bitmap_width = image_width; - symbol->bitmap_height = image_height; - break; - case 90: - case 270: - symbol->bitmap_width = image_height; - symbol->bitmap_height = image_width; - break; - } - - if (symbol->bitmap != NULL) - free(symbol->bitmap); - - symbol->bitmap = (char *) malloc(image_width * image_height * 3); - - - /* sort out colour options */ - to_upper((unsigned char*)symbol->fgcolour); - to_upper((unsigned char*)symbol->bgcolour); - - if(strlen(symbol->fgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - if(strlen(symbol->bgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - errno = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); - if (errno == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - errno = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->fgcolour)); - if (errno == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - - fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - - /* set rowbytes - depends on picture depth */ - rowbytes = symbol->bitmap_width * 3; - - /* Pixel Plotting */ - i = 0; - switch(rotate_angle) { - case 0: /* Plot the right way up */ - for(row = 0; row < image_height; row++) { - for(column = 0; column < image_width; column++) { - switch(*(pixelbuf + (image_width * row) + column)) - { - case '1': - symbol->bitmap[i++] = fgred; - symbol->bitmap[i++] = fggrn; - symbol->bitmap[i++] = fgblu; - break; - default: - symbol->bitmap[i++] = bgred; - symbol->bitmap[i++] = bggrn; - symbol->bitmap[i++] = bgblu; - break; - - } - } - } - break; - case 90: /* Plot 90 degrees clockwise */ - for(row = 0; row < image_width; row++) { - for(column = 0; column < image_height; column++) { - switch(*(pixelbuf + (image_width * (image_height - column - 1)) + row)) - { - case '1': - symbol->bitmap[i++] = fgred; - symbol->bitmap[i++] = fggrn; - symbol->bitmap[i++] = fgblu; - break; - default: - symbol->bitmap[i++] = bgred; - symbol->bitmap[i++] = bggrn; - symbol->bitmap[i++] = bgblu; - break; - - } - } - } - break; - case 180: /* Plot upside down */ - for(row = 0; row < image_height; row++) { - for(column = 0; column < image_width; column++) { - switch(*(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1))) - { - case '1': - symbol->bitmap[i++] = fgred; - symbol->bitmap[i++] = fggrn; - symbol->bitmap[i++] = fgblu; - break; - default: - symbol->bitmap[i++] = bgred; - symbol->bitmap[i++] = bggrn; - symbol->bitmap[i++] = bgblu; - break; - - } - } - } - break; - case 270: /* Plot 90 degrees anti-clockwise */ - for(row = 0; row < image_width; row++) { - for(column = 0; column < image_height; column++) { - switch(*(pixelbuf + (image_width * column) + (image_width - row - 1))) - { - case '1': - symbol->bitmap[i++] = fgred; - symbol->bitmap[i++] = fggrn; - symbol->bitmap[i++] = fgblu; - break; - default: - symbol->bitmap[i++] = bgred; - symbol->bitmap[i++] = bggrn; - symbol->bitmap[i++] = bgblu; - break; - - } - } - } - break; - } - - return 0; -} - -int png_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) -{ - int error_number; - float scaler = symbol->scale; - char *scaled_pixelbuf; - int horiz, vert, i; - int scale_width, scale_height; - - if(scaler == 0) { scaler = 0.5; } - scale_width = image_width * scaler; - scale_height = image_height * scaler; - - /* Apply scale options by creating another pixel buffer */ - if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { - printf("Insufficient memory for pixel buffer"); - return ERROR_ENCODING_PROBLEM; - } else { - for(i = 0; i < (scale_width * scale_height); i++) { - *(scaled_pixelbuf + i) = '0'; - } - } - - for(vert = 0; vert < scale_height; vert++) { - for(horiz = 0; horiz < scale_width; horiz++) { - *(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int)(vert / scaler) * image_width) + (int)(horiz / scaler)); - } - } - - if(image_type == PNG_DATA) { -#ifndef NO_PNG - error_number = png_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle); -#else - return ERROR_INVALID_OPTION; -#endif - } else { - error_number = bmp_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle); - } - - free(scaled_pixelbuf); - - return error_number; -} - -void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) -{ - /* Draw a rectangle */ - int i, j, png_ypos; - - png_ypos = image_height - ypos - ylen; - /* This fudge is needed because EPS measures height from the bottom up but - PNG measures y position from the top down */ - - for(i = (xpos); i < (xpos + xlen); i++) { - for( j = (png_ypos); j < (png_ypos + ylen); j++) { - *(pixelbuf + (image_width * j) + i) = '1'; - } - } -} - -int bullseye_pixel(int row, int col) { - int block_val, block_pos, return_val; - - block_val = bullseye_compressed[(row * 12) + (col / 8)]; - return_val = 0; - block_pos = col % 8; - - switch(block_pos) { - case 0: if((block_val & 0x80) != 0) { return_val = 1; } break; - case 1: if((block_val & 0x40) != 0) { return_val = 1; } break; - case 2: if((block_val & 0x20) != 0) { return_val = 1; } break; - case 3: if((block_val & 0x10) != 0) { return_val = 1; } break; - case 4: if((block_val & 0x08) != 0) { return_val = 1; } break; - case 5: if((block_val & 0x04) != 0) { return_val = 1; } break; - case 6: if((block_val & 0x02) != 0) { return_val = 1; } break; - case 7: if((block_val & 0x01) != 0) { return_val = 1; } break; - } - - return return_val; -} - -void draw_bullseye(char *pixelbuf, int image_width, int xoffset, int yoffset) -{ - /* Central bullseye in Maxicode symbols */ - int i, j; - - for(j = 103; j < 196; j++) { - for(i = 0; i < 93; i++) { - if(bullseye_pixel(j - 103, i)) { - /* if(bullseye[(((j - 103) * 93) + i)] == 1) { */ - *(pixelbuf + (image_width * j) + (image_width * yoffset) + i + 99 + xoffset) = '1'; - } - } - } -} - -void draw_hexagon(char *pixelbuf, int image_width, int xposn, int yposn) -{ - /* Put a hexagon into the pixel buffer */ - int i, j; - - for(i = 0; i < 12; i++) { - for(j = 0; j < 10; j++) { - if(hexagon[(i * 10) + j] == 1) { - *(pixelbuf + (image_width * i) + (image_width * yposn) + xposn + j) = '1'; - } - } - } -} - -void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int smalltext, int image_width, int image_height) -{ - /* Put a letter into a position */ - int skip, i, j, glyph_no, alphabet; - - skip = 0; - alphabet = 0; - - if(letter < 33) { skip = 1; } - if((letter > 127) && (letter < 161)) { skip = 1; } - - if(skip == 0) { - if(letter > 128) { - alphabet = 1; - glyph_no = letter - 161; - } else { - glyph_no = letter - 33; - } - - if(smalltext) { - for(i = 0; i <= 8; i++) { - for(j = 0; j < 5; j++) { - if(alphabet == 0) { - if(small_font[(glyph_no * 5) + (i * 475) + j - 1] == 1) { - *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1'; - } - } else { - if(small_font_extended[(glyph_no * 5) + (i * 475) + j - 1] == 1) { - *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1'; - } - } - } - } - } else { - for(i = 0; i <= 13; i++) { - for(j = 0; j < 7 ; j++) { - if(alphabet == 0) { - if(ascii_font[(glyph_no * 7) + (i * 665) + j - 1] == 1) { - *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1'; - } - } else { - if(ascii_ext_font[(glyph_no * 7) + (i * 665) + j - 1] == 1) { - *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1'; - } - } - } - } - } - } -} - -void draw_string(char *pixbuf, char input_string[], int xposn, int yposn, int smalltext, int image_width, int image_height) -{ - /* Plot a string into the pixel buffer */ - int i, string_length, string_left_hand; - - string_length = strlen(input_string); - string_left_hand = xposn - ((7 * string_length) / 2); - - for(i = 0; i < string_length; i++) { - draw_letter(pixbuf, input_string[i], string_left_hand + (i * 7), yposn, smalltext, image_width, image_height); - } - -} - -int maxi_png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) -{ - int i, row, column, xposn, yposn; - int image_height, image_width; - char *pixelbuf; - int error_number; - int xoffset, yoffset; - - xoffset = symbol->border_width + symbol->whitespace_width; - yoffset = symbol->border_width; - image_width = 300 + (2 * xoffset * 2); - image_height = 300 + (2 * yoffset * 2); - - if (!(pixelbuf = (char *) malloc(image_width * image_height))) { - printf("Insifficient memory for pixel buffer"); - return ERROR_ENCODING_PROBLEM; - } else { - for(i = 0; i < (image_width * image_height); i++) { - *(pixelbuf + i) = '0'; - } - } - - draw_bullseye(pixelbuf, image_width, (2 * xoffset), (2 * yoffset)); - - for(row = 0; row < symbol->rows; row++) { - yposn = row * 9; - for(column = 0; column < symbol->width; column++) { - xposn = column * 10; - if(module_is_set(symbol, row, column)) { - if(row & 1) { - /* Odd (reduced) row */ - xposn += 5; - draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset)); - } else { - /* Even (full) row */ - draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset)); - } - } - } - } - - if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - /* boundary bars */ - draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height); - draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height); - } - - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height); - draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height); - } - - error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); - free(pixelbuf); - return error_number; -} - -void to_latin1(unsigned char source[], unsigned char preprocessed[]) -{ - int j, i, input_length; - - input_length = ustrlen(source); - - j = 0; - i = 0; - do { - if(source[i] < 128) { - preprocessed[j] = source[i]; - j++; - i++; - } else { - if(source[i] == 0xC2) { - preprocessed[j] = source[i + 1]; - j++; - i += 2; - } - if(source[i] == 0xC3) { - preprocessed[j] = source[i + 1] + 64; - j++; - i += 2; - } - } - } while (i < input_length); - preprocessed[j] = '\0'; - - return; -} - -int png_plot(struct zint_symbol *symbol, int rotate_angle, int data_type) -{ - int textdone, main_width, comp_offset, large_bar_count; - char textpart[10], addon[6]; - float addon_text_posn, preset_height, large_bar_height; - int i, r, textoffset, yoffset, xoffset, latch, image_width, image_height; - char *pixelbuf; - int addon_latch = 0, smalltext = 0; - int this_row, block_width, plot_height, plot_yposn, textpos; - float row_height, row_posn; - int error_number; - int default_text_posn; - int next_yposn; -#ifndef _MSC_VER - unsigned char local_text[ustrlen(symbol->text) + 1]; -#else - unsigned char* local_text = (unsigned char*)_alloca(ustrlen(symbol->text) + 1); -#endif - - if(symbol->show_hrt != 0) { - to_latin1(symbol->text, local_text); - } else { - local_text[0] = '\0'; - } - - textdone = 0; - main_width = symbol->width; - strcpy(addon, ""); - comp_offset = 0; - addon_text_posn = 0.0; - row_height = 0; - if(symbol->output_options & SMALL_TEXT) { - smalltext = 1; - } - - if (symbol->height == 0) { - symbol->height = 50; - } - - large_bar_count = 0; - preset_height = 0.0; - for(i = 0; i < symbol->rows; i++) { - preset_height += symbol->row_height[i]; - if(symbol->row_height[i] == 0) { - large_bar_count++; - } - } - - if (large_bar_count == 0) { - symbol->height = preset_height; - large_bar_height = 10; - } else { - large_bar_height = (symbol->height - preset_height) / large_bar_count; - } - - while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { - comp_offset++; - } - - /* Certain symbols need whitespace otherwise characters get chopped off the sides */ - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) - || (symbol->symbology == BARCODE_ISBNX)) { - switch(ustrlen(local_text)) { - case 13: /* EAN 13 */ - case 16: - case 19: - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - } - main_width = 96 + comp_offset; - break; - default: - main_width = 68 + comp_offset; - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_width = 96 + comp_offset; - } - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_width = 51 + comp_offset; - } - } - - latch = 0; - r = 0; - /* Isolate add-on text */ - if(is_extendable(symbol->symbology)) { - for(i = 0; i < ustrlen(local_text); i++) { - if (latch == 1) { - addon[r] = local_text[i]; - r++; - } - if (symbol->text[i] == '+') { - latch = 1; - } - } - } - addon[r] = '\0'; - - if(ustrlen(local_text) != 0) { - textoffset = 9; - } else { - textoffset = 0; - } - xoffset = symbol->border_width + symbol->whitespace_width; - yoffset = symbol->border_width; - image_width = 2 * (symbol->width + xoffset + xoffset); - image_height = 2 * (symbol->height + textoffset + yoffset + yoffset); - - if (!(pixelbuf = (char *) malloc(image_width * image_height))) { - printf("Insufficient memory for pixel buffer"); - return ERROR_ENCODING_PROBLEM; - } else { - for(i = 0; i < (image_width * image_height); i++) { - *(pixelbuf + i) = '0'; - } - } - - if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - default_text_posn = image_height - 17; - } else { - default_text_posn = image_height - 17 - symbol->border_width - symbol->border_width; - } - - row_posn = textoffset + yoffset; - next_yposn = textoffset + yoffset; - row_height = 0; - - /* Plot the body of the symbol to the pixel buffer */ - for(r = 0; r < symbol->rows; r++) { - this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ - row_posn += row_height; - plot_yposn = next_yposn; - if(symbol->row_height[this_row] == 0) { - row_height = large_bar_height; - } else { - row_height = symbol->row_height[this_row]; - } - next_yposn = (int)(row_posn + row_height); - plot_height = next_yposn - plot_yposn; - - i = 0; - if(module_is_set(symbol, this_row, 0)) { - latch = 1; - } else { - latch = 0; - } - - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); - if((addon_latch == 0) && (r == 0) && (i > main_width)) { - plot_height = (int)(row_height - 5.0); - plot_yposn = (int)(row_posn - 5.0); - addon_text_posn = row_posn + row_height - 8.0; - addon_latch = 1; - } - if(latch == 1) { - /* a bar */ - draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - - } while (i < symbol->width); - } - - xoffset += comp_offset; - - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { - /* guard bar extensions and text formatting for EAN8 and EAN13 */ - switch(ustrlen(local_text)) { - case 8: /* EAN-8 */ - case 11: - case 14: - draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i]; - } - textpart[4] = '\0'; - textpos = 2 * (17 + xoffset); - - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i + 4]; - } - textpart[4] = '\0'; - textpos = 2 * (50 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = 2 * (xoffset + 86); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - case 5: - textpos = 2 * (xoffset + 100); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - } - - break; - case 13: /* EAN 13 */ - case 16: - case 19: - draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = 2 * (-7 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - textpos = 2 * (24 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 7]; - } - textpart[6] = '\0'; - textpos = 2 * (71 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = 2 * (xoffset + 114); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - case 5: - textpos = 2 * (xoffset + 128); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - } - break; - - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - /* guard bar extensions and text formatting for UPCA */ - latch = 1; - - i = 0 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); - if(latch == 1) { - /* a bar */ - draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - } while (i < 11 + comp_offset); - draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - latch = 1; - i = 85 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); - if(latch == 1) { - /* a bar */ - draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - } while (i < 96 + comp_offset); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = 2 * (-5 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[5] = '\0'; - textpos = 2 * (27 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 6]; - } - textpart[6] = '\0'; - textpos = 2 * (68 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - textpart[0] = symbol->text[11]; - textpart[1] = '\0'; - textpos = 2 * (100 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = 2 * (xoffset + 116); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - case 5: - textpos = 2 * (xoffset + 130); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - } - - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - /* guard bar extensions and text formatting for UPCE */ - draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int)yoffset) * 2, 5 * 2, image_width, image_height); - - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = 2 * (-5 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - textpos = 2 * (24 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - textpart[0] = symbol->text[7]; - textpart[1] = '\0'; - textpos = 2 * (55 + xoffset); - draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, image_width, image_height); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = 2 * (xoffset + 70); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - case 5: - textpos = 2 * (xoffset + 84); - draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height); - break; - } - - } - - xoffset -= comp_offset; - - /* Put boundary bars or box around symbol */ - if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - /* boundary bars */ - draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height); - draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height); - if((symbol->output_options & BARCODE_BIND) != 0) { - if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { - /* row binding */ - for(r = 1; r < symbol->rows; r++) { - draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height); - } - } - } - } - - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); - draw_bar(pixelbuf, (symbol->width + xoffset + xoffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); - } - - /* Put the human readable text at the bottom */ - if((textdone == 0) && (ustrlen(local_text) != 0)) { - textpos = (image_width / 2); - draw_string(pixelbuf, (char*)local_text, textpos, default_text_posn, smalltext, image_width, image_height); - } - - error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); - free(pixelbuf); - return error_number; -} - -#ifndef NO_PNG -int png_handle(struct zint_symbol *symbol, int rotate_angle) -{ - int error; - - if(symbol->symbology == BARCODE_MAXICODE) { - error = maxi_png_plot(symbol, rotate_angle, PNG_DATA); - } else { - - error = png_plot(symbol, rotate_angle, PNG_DATA); - } - - return error; -} -#endif /* NO_PNG */ - -int bmp_handle(struct zint_symbol *symbol, int rotate_angle) -{ - int error; - - if(symbol->symbology == BARCODE_MAXICODE) { - error = maxi_png_plot(symbol, rotate_angle, BMP_DATA); - } else { - error = png_plot(symbol, rotate_angle, BMP_DATA); - } - - return error; -} - diff --git a/3rdparty/zint-2.4.4/backend/postal.c b/3rdparty/zint-2.4.4/backend/postal.c deleted file mode 100644 index f6a480f..0000000 --- a/3rdparty/zint-2.4.4/backend/postal.c +++ /dev/null @@ -1,594 +0,0 @@ -/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */ - -/* Zint - A barcode generating program using libpng - Copyright (C) 2008 Robin Stuart - Including bug fixes by Bryan Hatton - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" - -#define DAFTSET "DAFT" -#define KRSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define KASUTSET "1234567890-abcdefgh" -#define CHKASUTSET "0123456789-abcdefgh" -#define SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" - -/* PostNet number encoding table - In this table L is long as S is short */ -static char *PNTable[10] = {"LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL", - "LSSLS", "LSLSS"}; -static char *PLTable[10] = {"SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS", - "SLLSL", "SLSLL"}; - -static char *RoyalValues[36] = {"11", "12", "13", "14", "15", "10", "21", "22", "23", "24", "25", - "20", "31", "32", "33", "34", "35", "30", "41", "42", "43", "44", "45", "40", "51", "52", - "53", "54", "55", "50", "01", "02", "03", "04", "05", "00"}; - -/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */ -static char *RoyalTable[36] = {"3300", "3210", "3201", "2310", "2301", "2211", "3120", "3030", "3021", - "2130", "2121", "2031", "3102", "3012", "3003", "2112", "2103", "2013", "1320", "1230", - "1221", "0330", "0321", "0231", "1302", "1212", "1203", "0312", "0303", "0213", "1122", - "1032", "1023", "0132", "0123", "0033"}; - -static char *FlatTable[10] = {"0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711", - "0810"}; - -static char *KoreaTable[10] = {"1313150613", "0713131313", "0417131313", "1506131313", - "0413171313", "17171313", "1315061313", "0413131713", "17131713", "13171713"}; - -static char *JapanTable[19] = {"114", "132", "312", "123", "141", "321", "213", "231", "411", "144", - "414", "324", "342", "234", "432", "243", "423", "441", "111"}; - -int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) -{ - /* Handles the PostNet system used for Zip codes in the US */ - unsigned int sum, check_digit; - int i, error_number; - - error_number = 0; - - if(length > 38) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - sum = 0; - - /* start character */ - strcpy(dest, "L"); - - for (i=0; i < length; i++) - { - lookup(NEON, PNTable, source[i], dest); - sum += ctoi(source[i]); - } - - check_digit = (10 - (sum % 10)) % 10; - concat(dest, PNTable[check_digit]); - - /* stop character */ - concat (dest, "L"); - - return error_number; -} - -int post_plot(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Puts PostNet barcodes into the pattern matrix */ - char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */ - unsigned int loopey, h; - int writer; - int error_number; - - error_number = 0; - - error_number = postnet(symbol, source, height_pattern, length); - if(error_number != 0) { - return error_number; - } - - writer = 0; - h = strlen(height_pattern); - for(loopey = 0; loopey < h; loopey++) - { - if(height_pattern[loopey] == 'L') - { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - writer += 3; - } - symbol->row_height[0] = 6; - symbol->row_height[1] = 6; - symbol->rows = 2; - symbol->width = writer - 1; - - return error_number; -} - -int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) -{ - /* Handles the PLANET system used for item tracking in the US */ - unsigned int sum, check_digit; - int i, error_number; - - error_number = 0; - - if(length > 38) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - sum = 0; - - /* start character */ - strcpy(dest, "L"); - - for (i=0; i < length; i++) { - lookup(NEON, PLTable, source[i], dest); - sum += ctoi(source[i]); - } - - check_digit = (10 - (sum % 10)) % 10; - concat(dest, PLTable[check_digit]); - - /* stop character */ - concat (dest, "L"); - - return error_number; -} - -int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Puts PLANET barcodes into the pattern matrix */ - char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */ - unsigned int loopey, h; - int writer; - int error_number; - - error_number = 0; - - error_number = planet(symbol, source, height_pattern, length); - if(error_number != 0) { - return error_number; - } - - writer = 0; - h = strlen(height_pattern); - for(loopey = 0; loopey < h; loopey++) - { - if(height_pattern[loopey] == 'L') - { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - writer += 3; - } - symbol->row_height[0] = 6; - symbol->row_height[1] = 6; - symbol->rows = 2; - symbol->width = writer - 1; - return error_number; -} - -int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Korean Postal Authority */ - - int total, loop, check, zeroes, error_number; - char localstr[8], dest[80]; - - error_number = 0; - if(length > 6) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - zeroes = 6 - length; - memset(localstr, '0', zeroes); - strcpy(localstr + zeroes, (char *)source); - - total = 0; - for(loop = 0; loop < 6; loop++) { - total += ctoi(localstr[loop]); - } - check = 10 - (total % 10); - if(check == 10) { check = 0; } - localstr[6] = itoc(check); - localstr[7] = '\0'; - *dest = '\0'; - for(loop = 5; loop >= 0; loop--) { - lookup(NEON, KoreaTable, localstr[loop], dest); - } - lookup(NEON, KoreaTable, localstr[6], dest); - expand(symbol, dest); - ustrcpy(symbol->text, (unsigned char*)localstr); - return error_number; -} - -int fim(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* The simplest barcode symbology ever! Supported by MS Word, so here it is! */ - /* glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */ - - char dest[16] = { 0 }; - - if(length > 1) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - switch((char)source[0]) { - case 'a': - case 'A': - strcpy(dest, "111515111"); - break; - case 'b': - case 'B': - strcpy(dest, "13111311131"); - break; - case 'c': - case 'C': - strcpy(dest, "11131313111"); - break; - case 'd': - case 'D': - strcpy(dest, "1111131311111"); - break; - default: - strcpy(symbol->errtxt, "Invalid characters in data"); - return ERROR_INVALID_DATA1; - break; - } - - expand(symbol, dest); - return 0; -} - -char rm4scc(char source[], unsigned char dest[], int length) -{ - /* Handles the 4 State barcodes used in the UK by Royal Mail */ - unsigned int i; - int top, bottom, row, column, check_digit; - char values[3], set_copy[] = KRSET; - - top = 0; - bottom = 0; - - /* start character */ - strcpy((char*)dest, "1"); - - for (i = 0; i < length; i++) { - lookup(KRSET, RoyalTable, source[i], (char*)dest); - strcpy(values, RoyalValues[posn(KRSET, source[i])]); - top += ctoi(values[0]); - bottom += ctoi(values[1]); - } - - /* Calculate the check digit */ - row = (top % 6) - 1; - column = (bottom % 6) - 1; - if(row == -1) { row = 5; } - if(column == -1) { column = 5; } - check_digit = (6 * row) + column; - concat((char*)dest, RoyalTable[check_digit]); - - /* stop character */ - concat ((char*)dest, "0"); - - return set_copy[check_digit]; -} - -int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Puts RM4SCC into the data matrix */ - char height_pattern[200], check; - int loopey, h, writer; - int error_number; - strcpy(height_pattern, ""); - - error_number = 0; - - if(length > 120) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - to_upper(source); - error_number = is_sane(KRSET, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - check = rm4scc((char*)source, (unsigned char*)height_pattern, length); - - writer = 0; - h = strlen(height_pattern); - for(loopey = 0; loopey < h; loopey++) { - if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) { - set_module(symbol, 2, writer); - } - writer += 2; - } - - symbol->row_height[0] = 3; - symbol->row_height[1] = 2; - symbol->row_height[2] = 3; - symbol->rows = 3; - symbol->width = writer - 1; - - return error_number; -} - -int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Handles Dutch Post TNT KIX symbols */ - /* The same as RM4SCC but without check digit */ - /* Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */ - char height_pattern[50], localstr[20]; - int loopey, writer, i, h; - int error_number; /* zeroes; */ - strcpy(height_pattern, ""); - - error_number = 0; - - if(length > 18) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - to_upper(source); - error_number = is_sane(KRSET, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* Add leading zeroes */ - /* zeroes = 11 - length; - memset(localstr, '0', zeroes); - strcpy(localstr + zeroes, (char *)source);*/ - strcpy(localstr, (char *)source); - - /* Encode data */ - for (i = 0; i < 18; i++) { - lookup(KRSET, RoyalTable, localstr[i], height_pattern); - } - - writer = 0; - h = strlen(height_pattern); - for(loopey = 0; loopey < h; loopey++) { - if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) { - set_module(symbol, 2, writer); - } - writer += 2; - } - - symbol->row_height[0] = 3; - symbol->row_height[1] = 2; - symbol->row_height[2] = 3; - symbol->rows = 3; - symbol->width = writer - 1; - - return error_number; -} - -int daft_code(struct zint_symbol *symbol, unsigned char source[], int length) -{ - /* Handles DAFT Code symbols */ - /* Presumably 'daft' doesn't mean the same thing in Germany as it does in the UK! */ - char height_pattern[100]; - unsigned int loopey, h; - int writer, i, error_number; - strcpy(height_pattern, ""); - - error_number = 0; - if(length > 50) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - to_upper((unsigned char*)source); - error_number = is_sane(DAFTSET, (unsigned char*)source, length); - - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - for (i = 0; i < length; i++) { - if(source[i] == 'D') { concat(height_pattern, "2"); } - if(source[i] == 'A') { concat(height_pattern, "1"); } - if(source[i] == 'F') { concat(height_pattern, "0"); } - if(source[i] == 'T') { concat(height_pattern, "3"); } - } - - writer = 0; - h = strlen(height_pattern); - for(loopey = 0; loopey < h; loopey++) - { - if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) - { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) - { - set_module(symbol, 2, writer); - } - writer += 2; - } - - symbol->row_height[0] = 3; - symbol->row_height[1] = 2; - symbol->row_height[2] = 3; - symbol->rows = 3; - symbol->width = writer - 1; - - return error_number; -} - -int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Flattermarken - Not really a barcode symbology and (in my opinion) probably not much use - but it's supported by TBarCode so it's supported by Zint! */ - int loop, error_number; - char dest[512]; /* 90 * 4 + 1 ~ */ - - error_number = 0; - - if(length > 90) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - *dest = '\0'; - for(loop = 0; loop < length; loop++) { - lookup(NEON, FlatTable, source[loop], dest); - } - - expand(symbol, dest); - return error_number; -} - -int japan_post(struct zint_symbol *symbol, unsigned char source[], int length) -{ /* Japanese Postal Code (Kasutama Barcode) */ - int error_number, h; - char pattern[69]; - int writer, loopey, inter_posn, i, sum, check; - char check_char; - char inter[23]; - -#ifndef _MSC_VER - char local_source[length + 1]; -#else - char* local_source = (char*)_alloca(length + 1); -#endif - - inter_posn = 0; - error_number = 0; - - strcpy(local_source, (char*)source); - for(i = 0; i < length; i++) { - local_source[i] = source[i]; - } - to_upper((unsigned char*)local_source); - error_number = is_sane(SHKASUTSET, (unsigned char*)local_source, length); - - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - memset(inter, 'd', 20);/* Pad character CC4 */ - inter[20] = '\0'; - - i = 0; - inter_posn = 0; - do { - if(((local_source[i] >= '0') && (local_source[i] <= '9')) || (local_source[i] == '-')) { - inter[inter_posn] = local_source[i]; - inter_posn++; - } else { - if((local_source[i] >= 'A') && (local_source[i] <= 'J')) { - inter[inter_posn] = 'a'; - inter[inter_posn + 1] = local_source[i] - 'A' + '0'; - inter_posn += 2; - } - if((local_source[i] >= 'K') && (local_source[i] <= 'T')) { - inter[inter_posn] = 'b'; - inter[inter_posn + 1] = local_source[i] - 'K' + '0'; - inter_posn += 2; - } - if((local_source[i] >= 'U') && (local_source[i] <= 'Z')) { - inter[inter_posn] = 'c'; - inter[inter_posn + 1] = local_source[i] - 'U' + '0'; - inter_posn += 2; - } - } - i++; - }while((i < length) && (inter_posn < 20)); - inter[20] = '\0'; - - strcpy(pattern, "13"); /* Start */ - - sum = 0; - for(i = 0; i < 20; i++) { - concat(pattern, JapanTable[posn(KASUTSET, inter[i])]); - sum += posn(CHKASUTSET, inter[i]); - /* printf("%c (%d)\n", inter[i], posn(CHKASUTSET, inter[i])); */ - } - - /* Calculate check digit */ - check = 19 - (sum % 19); - if(check == 19) { check = 0; } - if(check <= 9) { check_char = check + '0'; } - if(check == 10) { check_char = '-'; } - if(check >= 11) { check_char = (check - 11) + 'a'; } - concat(pattern, JapanTable[posn(KASUTSET, check_char)]); - /* printf("check %c (%d)\n", check_char, check); */ - - concat(pattern, "31"); /* Stop */ - - /* Resolve pattern to 4-state symbols */ - writer = 0; - h = strlen(pattern); - for(loopey = 0; loopey < h; loopey++) - { - if((pattern[loopey] == '2') || (pattern[loopey] == '1')) - { - set_module(symbol, 0, writer); - } - set_module(symbol, 1, writer); - if((pattern[loopey] == '3') || (pattern[loopey] == '1')) - { - set_module(symbol, 2, writer); - } - writer += 2; - } - - symbol->row_height[0] = 3; - symbol->row_height[1] = 2; - symbol->row_height[2] = 3; - symbol->rows = 3; - symbol->width = writer - 1; - - return error_number; -} diff --git a/3rdparty/zint-2.4.4/backend/ps.c b/3rdparty/zint-2.4.4/backend/ps.c deleted file mode 100644 index 7543561..0000000 --- a/3rdparty/zint-2.4.4/backend/ps.c +++ /dev/null @@ -1,761 +0,0 @@ -/* ps.c - Post Script output */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#include "common.h" - -#define SSET "0123456789ABCDEF" - -/* This file has expanded quite a bit since version 1.5 in order to accomodate - the formatting rules for EAN and UPC symbols as set out in EN 797:1995 - the - down side of this support is that the code is now vertually unreadable! */ - -int ps_plot(struct zint_symbol *symbol) -{ - int i, block_width, latch, r, this_row; - float textpos, large_bar_height, preset_height, row_height, row_posn; - FILE *feps; - int fgred, fggrn, fgblu, bgred, bggrn, bgblu; - float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; - int error_number = 0; - int textoffset, xoffset, yoffset, textdone, main_width; - char textpart[10], addon[6]; - int large_bar_count, comp_offset; - float addon_text_posn; - float scaler = symbol->scale; - float default_text_posn; - int plot_text = 1; - const char *locale = NULL; - - row_height=0; - textdone = 0; - main_width = symbol->width; - strcpy(addon, ""); - comp_offset = 0; - addon_text_posn = 0.0; - - if((symbol->output_options & BARCODE_STDOUT) != 0) { - feps = stdout; - } else { - feps = fopen(symbol->outfile, "w"); - } - if(feps == NULL) { - strcpy(symbol->errtxt, "Could not open output file"); - return ERROR_FILE_ACCESS; - } - - /* sort out colour options */ - to_upper((unsigned char*)symbol->fgcolour); - to_upper((unsigned char*)symbol->bgcolour); - - if(strlen(symbol->fgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - if(strlen(symbol->bgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); - if (error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); - if (error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - locale = setlocale(LC_ALL, "C"); - - fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - red_ink = fgred / 256.0; - green_ink = fggrn / 256.0; - blue_ink = fgblu / 256.0; - red_paper = bgred / 256.0; - green_paper = bggrn / 256.0; - blue_paper = bgblu / 256.0; - - if (symbol->height == 0) { - symbol->height = 50; - } - - large_bar_count = 0; - preset_height = 0.0; - for(i = 0; i < symbol->rows; i++) { - preset_height += symbol->row_height[i]; - if(symbol->row_height[i] == 0) { - large_bar_count++; - } - } - large_bar_height = (symbol->height - preset_height) / large_bar_count; - - if (large_bar_count == 0) { - symbol->height = preset_height; - } - - while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { - comp_offset++; - } - - /* Certain symbols need whitespace otherwise characters get chopped off the sides */ - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) - || (symbol->symbology == BARCODE_ISBNX)) { - switch(ustrlen(symbol->text)) { - case 13: /* EAN 13 */ - case 16: - case 19: - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - } - main_width = 96 + comp_offset; - break; - default: - main_width = 68 + comp_offset; - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_width = 96 + comp_offset; - } - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_width = 51 + comp_offset; - } - } - - latch = 0; - r = 0; - /* Isolate add-on text */ - if(is_extendable(symbol->symbology)) { - for(i = 0; i < ustrlen(symbol->text); i++) { - if (latch == 1) { - addon[r] = symbol->text[i]; - r++; - } - if (symbol->text[i] == '+') { - latch = 1; - } - } - } - addon[r] = '\0'; - - if((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) { - plot_text = 0; - } - if(plot_text) { - textoffset = 9; - } else { - textoffset = 0; - } - xoffset = symbol->border_width + symbol->whitespace_width; - yoffset = symbol->border_width; - - /* Start writing the header */ - fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n"); - fprintf(feps, "%%%%Creator: Zint %s\n", ZINT_VERSION); - if(ustrlen(symbol->text) != 0) { - fprintf(feps, "%%%%Title: %s\n",symbol->text); - } else { - fprintf(feps, "%%%%Title: Zint Generated Symbol\n"); - } - fprintf(feps, "%%%%Pages: 0\n"); - if(symbol->symbology != BARCODE_MAXICODE) { - fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); - } else { - fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler)); - } - fprintf(feps, "%%%%EndComments\n"); - - /* Definitions */ - fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n"); - fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n"); - fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n"); - fprintf(feps, "/TB { 2 copy } bind def\n"); - fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n"); - fprintf(feps, "/TE { pop pop } bind def\n"); - - fprintf(feps, "newpath\n"); - - /* Now the actual representation */ - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper); - fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", (symbol->height + textoffset + yoffset + yoffset) * scaler, (symbol->width + xoffset + xoffset) * scaler); - - if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - default_text_posn = 0.5 * scaler; - } else { - default_text_posn = (symbol->border_width + 0.5) * scaler; - } - - if(symbol->symbology == BARCODE_MAXICODE) { - /* Maxicode uses hexagons */ - float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; - - - textoffset = 0.0; - if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + 72.0 + symbol->border_width) * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); - } - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, (74.0 + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); - } - - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, (44.73 + xoffset) * scaler, (35.60 + yoffset) * scaler); - fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, (40.98 + xoffset) * scaler, (35.60 + yoffset) * scaler); - fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, (37.19 + xoffset) * scaler, (35.60 + yoffset) * scaler); - for(r = 0; r < symbol->rows; r++) { - for(i = 0; i < symbol->width; i++) { - if(module_is_set(symbol, r, i)) { - /* Dump a hexagon */ - my = ((symbol->rows - r - 1)) * 2.135 + 1.43; - ay = my + 1.0 + yoffset; - by = my + 0.5 + yoffset; - cy = my - 0.5 + yoffset; - dy = my - 1.0 + yoffset; - ey = my - 0.5 + yoffset; - fy = my + 0.5 + yoffset; - - mx = 2.46 * i + 1.23 + (r & 1 ? 1.23 : 0); - - ax = mx + xoffset; - bx = mx + 0.86 + xoffset; - cx = mx + 0.86 + xoffset; - dx = mx + xoffset; - ex = mx - 0.86 + xoffset; - fx = mx - 0.86 + xoffset; - fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); - } - } - } - } - - if(symbol->symbology != BARCODE_MAXICODE) { - /* everything else uses rectangles (or squares) */ - /* Works from the bottom of the symbol up */ - int addon_latch = 0; - - for(r = 0; r < symbol->rows; r++) { - this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ - if(symbol->row_height[this_row] == 0) { - row_height = large_bar_height; - } else { - row_height = symbol->row_height[this_row]; - } - row_posn = 0; - for(i = 0; i < r; i++) { - if(symbol->row_height[symbol->rows - i - 1] == 0) { - row_posn += large_bar_height; - } else { - row_posn += symbol->row_height[symbol->rows - i - 1]; - } - } - row_posn += (textoffset + yoffset); - - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f ", row_height * scaler, row_posn * scaler); - i = 0; - if(module_is_set(symbol, this_row, 0)) { - latch = 1; - } else { - latch = 0; - } - - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); - if((addon_latch == 0) && (r == 0) && (i > main_width)) { - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f ", (row_height - 5.0) * scaler, (row_posn - 5.0) * scaler); - addon_text_posn = row_posn + row_height - 8.0; - addon_latch = 1; - } - if(latch == 1) { - /* a bar */ - fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset) * scaler, block_width * scaler); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - - } while (i < symbol->width); - } - } - /* That's done the actual data area, everything else is human-friendly */ - - xoffset += comp_offset; - - if (plot_text) { - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || - (symbol->symbology == BARCODE_ISBNX)) { - /* guard bar extensions and text formatting for EAN8 and EAN13 */ - switch(ustrlen(symbol->text)) { - case 8: /* EAN-8 */ - case 11: - case 14: - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (32 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (34 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (64 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (66 + xoffset) * scaler, 1 * scaler); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i]; - } - textpart[4] = '\0'; - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 17; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i + 4]; - } - textpart[4] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 50; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 86; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - case 5: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 100; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - } - - break; - case 13: /* EAN 13 */ - case 16: - case 19: - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (92 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (94 + xoffset) * scaler, 1 * scaler); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = -7; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 24; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 7]; - } - textpart[6] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 71; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 114; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - case 5: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 128; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - } - break; - - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - /* guard bar extensions and text formatting for UPCA */ - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); - latch = 1; - - i = 0 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); - if(latch == 1) { - /* a bar */ - fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - } while (i < 11 + comp_offset); - fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); - latch = 1; - i = 85 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); - if(latch == 1) { - /* a bar */ - fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - } while (i < 96 + comp_offset); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); - textpos = -5; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[5] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 27; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 6]; - } - textpart[6] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 68; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - textpart[0] = symbol->text[11]; - textpart[1] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); - textpos = 100; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 116; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - case 5: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 130; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - } - - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - /* guard bar extensions and text formatting for UPCE */ - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); - fprintf(feps, "TB %.2f %.2f TR\n", (50 + xoffset) * scaler, 1 * scaler); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); - textpos = -5; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = 24; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - textpart[0] = symbol->text[7]; - textpart[1] = '\0'; - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); - textpos = 55; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", textpart); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", textpart); - fprintf(feps, "setmatrix\n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 70; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - case 5: - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); - textpos = xoffset + 84; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); - fprintf(feps, " (%s) stringwidth\n", addon); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", addon); - fprintf(feps, "setmatrix\n"); - break; - } - - } - } /* if (plot_text) */ - - xoffset -= comp_offset; - - switch(symbol->symbology) { - case BARCODE_MAXICODE: - /* Do nothing! (It's already been done) */ - break; - default: - if((symbol->output_options & BARCODE_BIND) != 0) { - if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { - /* row binding */ - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - for(r = 1; r < symbol->rows; r++) { - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, xoffset * scaler, symbol->width * scaler); - } - } - } - if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); - } - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); - } - break; - } - - /* Put the human readable text at the bottom */ - if(plot_text && (textdone == 0)) { - fprintf(feps, "TE\n"); - fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); - fprintf(feps, "matrix currentmatrix\n"); - fprintf(feps, "/Helvetica findfont\n"); - fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); - textpos = symbol->width / 2.0; - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); - fprintf(feps, " (%s) stringwidth\n", symbol->text); - fprintf(feps, "pop\n"); - fprintf(feps, "-2 div 0 rmoveto\n"); - fprintf(feps, " (%s) show\n", symbol->text); - fprintf(feps, "setmatrix\n"); - } - fprintf(feps, "\nshowpage\n"); - - fclose(feps); - - if (locale) - setlocale(LC_ALL, locale); - - return error_number; -} - diff --git a/3rdparty/zint-2.4.4/backend/qr.c b/3rdparty/zint-2.4.4/backend/qr.c deleted file mode 100644 index 23b4743..0000000 --- a/3rdparty/zint-2.4.4/backend/qr.c +++ /dev/null @@ -1,2244 +0,0 @@ -/* qr.c Handles QR Code */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include -#include "sjis.h" -#include "qr.h" -#include "reedsol.h" - -int in_alpha(int glyph) { - /* Returns true if input glyph is in the Alphanumeric set */ - int retval = 0; - char cglyph = (char) glyph; - - if((cglyph >= '0') && (cglyph <= '9')) { - retval = 1; - } - if((cglyph >= 'A') && (cglyph <= 'Z')) { - retval = 1; - } - switch (cglyph) { - case ' ': - case '$': - case '%': - case '*': - case '+': - case '-': - case '.': - case '/': - case ':': - retval = 1; - break; - } - - return retval; -} - -void define_mode(char mode[], int jisdata[], int length, int gs1) -{ - /* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */ - int i, mlen, j; - - for(i = 0; i < length; i++) { - if(jisdata[i] > 0xff) { - mode[i] = 'K'; - } else { - mode[i] = 'B'; - if(in_alpha(jisdata[i])) { mode[i] = 'A'; } - if(gs1 && (jisdata[i] == '[')) { mode[i] = 'A'; } - if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { mode[i] = 'N'; } - } - } - - /* If less than 6 numeric digits together then don't use numeric mode */ - for(i = 0; i < length; i++) { - if(mode[i] == 'N') { - if(((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) { - mlen = 0; - while (((mlen + i) < length) && (mode[mlen + i] == 'N')) { - mlen++; - }; - if(mlen < 6) { - for(j = 0; j < mlen; j++) { - mode[i + j] = 'A'; - } - } - } - } - } - - /* If less than 4 alphanumeric characters together then don't use alphanumeric mode */ - for(i = 0; i < length; i++) { - if(mode[i] == 'A') { - if(((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) { - mlen = 0; - while (((mlen + i) < length) && (mode[mlen + i] == 'A')) { - mlen++; - }; - if(mlen < 6) { - for(j = 0; j < mlen; j++) { - mode[i + j] = 'B'; - } - } - } - } - } -} - -int estimate_binary_length(char mode[], int length, int gs1) -{ - /* Make an estimate (worst case scenario) of how long the binary string will be */ - int i, count = 0; - char current = 0; - int a_count = 0; - int n_count = 0; - - if(gs1) { count += 4; } - - for(i = 0; i < length; i++) { - if(mode[i] != current) { - switch(mode[i]) { - case 'K': count += 12 + 4; current = 'K'; break; - case 'B': count += 16 + 4; current = 'B'; break; - case 'A': count += 13 + 4; current = 'A'; a_count = 0; break; - case 'N': count += 14 + 4; current = 'N'; n_count = 0; break; - } - } - - switch(mode[i]) { - case 'K': count += 13; break; - case 'B': count += 8; break; - case 'A': - a_count++; - if((a_count & 1) == 0) { - count += 5; // 11 in total - a_count = 0; - } - else - count += 6; - break; - case 'N': - n_count++; - if((n_count % 3) == 0) { - count += 3; // 10 in total - n_count = 0; - } - else if ((n_count & 1) == 0) - count += 3; // 7 in total - else - count += 4; - break; - } - } - - return count; -} - -static void qr_bscan(char *binary, int data, int h) -{ - for (; h; h>>=1) { - concat(binary, data & h ? "1" : "0"); - } -} - -void qr_binary(int datastream[], int version, int target_binlen, char mode[], int jisdata[], int length, int gs1, int est_binlen) -{ - /* Convert input data to a binary stream and add padding */ - int position = 0, debug = 0; - int short_data_block_length, i, scheme = 1; - char data_block, padbits; - int current_binlen, current_bytes; - int toggle, percent; - -#ifndef _MSC_VER - char binary[est_binlen + 12]; -#else - char* binary = (char *)_alloca(est_binlen + 12); -#endif - strcpy(binary, ""); - - if(gs1) { - concat(binary, "0101"); /* FNC1 */ - } - - if(version <= 9) { - scheme = 1; - } else if((version >= 10) && (version <= 26)) { - scheme = 2; - } else if(version >= 27) { - scheme = 3; - } - - if(debug) { - for(i = 0; i < length; i++) { - printf("%c", mode[i]); - } - printf("\n"); - } - - percent = 0; - - do { - data_block = mode[position]; - short_data_block_length = 0; - do { - short_data_block_length++; - } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block)); - - switch(data_block) { - case 'K': - /* Kanji mode */ - /* Mode indicator */ - concat(binary, "1000"); - - /* Character count indicator */ - qr_bscan(binary, short_data_block_length, 0x20 << (scheme*2)); /* scheme = 1..3 */ - - if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - for(i = 0; i < short_data_block_length; i++) { - int jis = jisdata[position + i]; - int msb, lsb, prod; - - if(jis > 0x9fff) { jis -= 0xc140; } - msb = (jis & 0xff00) >> 4; - lsb = (jis & 0xff); - prod = (msb * 0xc0) + lsb; - - qr_bscan(binary, prod, 0x1000); - - if(debug) { printf("0x%4X ", prod); } - } - - if(debug) { printf("\n"); } - - break; - case 'B': - /* Byte mode */ - /* Mode indicator */ - concat(binary, "0100"); - - /* Character count indicator */ - qr_bscan(binary, short_data_block_length, scheme > 1 ? 0x8000 : 0x80); /* scheme = 1..3 */ - - if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - for(i = 0; i < short_data_block_length; i++) { - int byte = jisdata[position + i]; - - if(gs1 && (byte == '[')) { - byte = 0x1d; /* FNC1 */ - } - - qr_bscan(binary, byte, 0x80); - - if(debug) { printf("0x%2X(%d) ", byte, byte); } - } - - if(debug) { printf("\n"); } - - break; - case 'A': - /* Alphanumeric mode */ - /* Mode indicator */ - concat(binary, "0010"); - - /* Character count indicator */ - qr_bscan(binary, short_data_block_length, 0x40 << (2 * scheme)); /* scheme = 1..3 */ - - if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - i = 0; - while ( i < short_data_block_length ) { - int count; - int first = 0, second = 0, prod; - - if(percent == 0) { - if(gs1 && (jisdata[position + i] == '%')) { - first = posn(RHODIUM, '%'); - second = posn(RHODIUM, '%'); - count = 2; - prod = (first * 45) + second; - i++; - } else { - if(gs1 && (jisdata[position + i] == '[')) { - first = posn(RHODIUM, '%'); /* FNC1 */ - } else { - first = posn(RHODIUM, (char) jisdata[position + i]); - } - count = 1; - i++; - prod = first; - - if(mode[position + i] == 'A') { - if(gs1 && (jisdata[position + i] == '%')) { - second = posn(RHODIUM, '%'); - count = 2; - prod = (first * 45) + second; - percent = 1; - } else { - if(gs1 && (jisdata[position + i] == '[')) { - second = posn(RHODIUM, '%'); /* FNC1 */ - } else { - second = posn(RHODIUM, (char) jisdata[position + i]); - } - count = 2; - i++; - prod = (first * 45) + second; - } - } - } - } else { - first = posn(RHODIUM, '%'); - count = 1; - i++; - prod = first; - percent = 0; - - if(mode[position + i] == 'A') { - if(gs1 && (jisdata[position + i] == '%')) { - second = posn(RHODIUM, '%'); - count = 2; - prod = (first * 45) + second; - percent = 1; - } else { - if(gs1 && (jisdata[position + i] == '[')) { - second = posn(RHODIUM, '%'); /* FNC1 */ - } else { - second = posn(RHODIUM, (char) jisdata[position + i]); - } - count = 2; - i++; - prod = (first * 45) + second; - } - } - } - - qr_bscan(binary, prod, count == 2 ? 0x400 : 0x20); /* count = 1..2 */ - - if(debug) { printf("0x%4X ", prod); } - }; - - if(debug) { printf("\n"); } - - break; - case 'N': - /* Numeric mode */ - /* Mode indicator */ - concat(binary, "0001"); - - /* Character count indicator */ - qr_bscan(binary, short_data_block_length, 0x80 << (2 * scheme)); /* scheme = 1..3 */ - - if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - i = 0; - while ( i < short_data_block_length ) { - int count; - int first = 0, second = 0, third = 0, prod; - - first = posn(NEON, (char) jisdata[position + i]); - count = 1; - prod = first; - - if(mode[position + i + 1] == 'N') { - second = posn(NEON, (char) jisdata[position + i + 1]); - count = 2; - prod = (prod * 10) + second; - - if(mode[position + i + 2] == 'N') { - third = posn(NEON, (char) jisdata[position + i + 2]); - count = 3; - prod = (prod * 10) + third; - } - } - - qr_bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */ - - if(debug) { printf("0x%4X (%d)", prod, prod); } - - i += count; - }; - - if(debug) { printf("\n"); } - - break; - } - - position += short_data_block_length; - } while (position < length) ; - - /* Terminator */ - concat(binary, "0000"); - - current_binlen = strlen(binary); - padbits = 8 - (current_binlen % 8); - if(padbits == 8) { padbits = 0; } - current_bytes = (current_binlen + padbits) / 8; - - /* Padding bits */ - for(i = 0; i < padbits; i++) { - concat(binary, "0"); - } - - /* Put data into 8-bit codewords */ - for(i = 0; i < current_bytes; i++) { - datastream[i] = 0x00; - if(binary[i * 8] == '1') { datastream[i] += 0x80; } - if(binary[i * 8 + 1] == '1') { datastream[i] += 0x40; } - if(binary[i * 8 + 2] == '1') { datastream[i] += 0x20; } - if(binary[i * 8 + 3] == '1') { datastream[i] += 0x10; } - if(binary[i * 8 + 4] == '1') { datastream[i] += 0x08; } - if(binary[i * 8 + 5] == '1') { datastream[i] += 0x04; } - if(binary[i * 8 + 6] == '1') { datastream[i] += 0x02; } - if(binary[i * 8 + 7] == '1') { datastream[i] += 0x01; } - } - - /* Add pad codewords */ - toggle = 0; - for(i = current_bytes; i < target_binlen; i++) { - if(toggle == 0) { - datastream[i] = 0xec; - toggle = 1; - } else { - datastream[i] = 0x11; - toggle = 0; - } - } - - if(debug) { - printf("Resulting codewords:\n\t"); - for(i = 0; i < target_binlen; i++) { - printf("0x%2X ", datastream[i]); - } - printf("\n"); - } -} - -void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int blocks) -{ - /* Split data into blocks, add error correction and then interleave the blocks and error correction data */ - int ecc_cw = qr_total_codewords[version - 1] - data_cw; - int short_data_block_length = data_cw / blocks; - int qty_long_blocks = data_cw % blocks; - int qty_short_blocks = blocks - qty_long_blocks; - int ecc_block_length = ecc_cw / blocks; - int i, j, length_this_block, posn, debug = 0; - - -#ifndef _MSC_VER - unsigned char data_block[short_data_block_length + 2]; - unsigned char ecc_block[ecc_block_length + 2]; - int interleaved_data[data_cw + 2]; - int interleaved_ecc[ecc_cw + 2]; -#else - unsigned char* data_block = (unsigned char *)_alloca(short_data_block_length + 2); - unsigned char* ecc_block = (unsigned char *)_alloca(ecc_block_length + 2); - int* interleaved_data = (int *)_alloca((data_cw + 2) * sizeof(int)); - int* interleaved_ecc = (int *)_alloca((ecc_cw + 2) * sizeof(int)); -#endif - - posn = 0; - - for(i = 0; i < blocks; i++) { - if(i < qty_short_blocks) { length_this_block = short_data_block_length; } else { length_this_block = short_data_block_length + 1; } - - for(j = 0; j < ecc_block_length; j++) { - ecc_block[j] = 0; - } - - for(j = 0; j < length_this_block; j++) { - data_block[j] = (unsigned char) datastream[posn + j]; - } - - rs_init_gf(0x11d); - rs_init_code(ecc_block_length, 0); - rs_encode(length_this_block, data_block, ecc_block); - rs_free(); - - if(debug) { - printf("Block %d: ", i + 1); - for(j = 0; j < length_this_block; j++) { - printf("%2X ", data_block[j]); - } - if(i < qty_short_blocks) { - printf(" "); - } - printf(" // "); - for(j = 0; j < ecc_block_length; j++) { - printf("%2X ", ecc_block[ecc_block_length - j - 1]); - } - printf("\n"); - } - - for(j = 0; j < short_data_block_length; j++) { - interleaved_data[(j * blocks) + i] = (int) data_block[j]; - } - - if(i >= qty_short_blocks){ - interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = (int) data_block[short_data_block_length]; - } - - for(j = 0; j < ecc_block_length; j++) { - interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1]; - } - - posn += length_this_block; - } - - for(j = 0; j < data_cw; j++) { - fullstream[j] = interleaved_data[j]; - } - for(j = 0; j < ecc_cw; j++) { - fullstream[j + data_cw] = interleaved_ecc[j]; - } - - if(debug) { - printf("\nData Stream: \n"); - for(j = 0; j < (data_cw + ecc_cw); j++) { - printf("%2X ", fullstream[j]); - } - printf("\n"); - } -} - -void place_finder(unsigned char grid[], int size, int x, int y) -{ - int xp, yp; - - int finder[] = { - 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 1, - 1, 0, 1, 1, 1, 0, 1, - 1, 0, 1, 1, 1, 0, 1, - 1, 0, 1, 1, 1, 0, 1, - 1, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1 - }; - - for(xp = 0; xp < 7; xp++) { - for(yp = 0; yp < 7; yp++) { - if (finder[xp + (7 * yp)] == 1) { - grid[((yp + y) * size) + (xp + x)] = 0x11; - } else { - grid[((yp + y) * size) + (xp + x)] = 0x10; - } - } - } -} - -void place_align(unsigned char grid[], int size, int x, int y) -{ - int xp, yp; - - int alignment[] = { - 1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, - 1, 0, 1, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1 - }; - - x -= 2; - y -= 2; /* Input values represent centre of pattern */ - - for(xp = 0; xp < 5; xp++) { - for(yp = 0; yp < 5; yp++) { - if (alignment[xp + (5 * yp)] == 1) { - grid[((yp + y) * size) + (xp + x)] = 0x11; - } else { - grid[((yp + y) * size) + (xp + x)] = 0x10; - } - } - } -} - -void setup_grid(unsigned char* grid, int size, int version) -{ - int i, toggle = 1; - int loopsize, x, y, xcoord, ycoord; - - /* Add timing patterns */ - for(i = 0; i < size; i++) { - if(toggle == 1) { - grid[(6 * size) + i] = 0x21; - grid[(i * size) + 6] = 0x21; - toggle = 0; - } else { - grid[(6 * size) + i] = 0x20; - grid[(i * size) + 6] = 0x20; - toggle = 1; - } - } - - /* Add finder patterns */ - place_finder(grid, size, 0, 0); - place_finder(grid, size, 0, size - 7); - place_finder(grid, size, size - 7, 0); - - /* Add separators */ - for(i = 0; i < 7; i++) { - grid[(7 * size) + i] = 0x10; - grid[(i * size) + 7] = 0x10; - grid[(7 * size) + (size - 1 - i)] = 0x10; - grid[(i * size) + (size - 8)] = 0x10; - grid[((size - 8) * size) + i] = 0x10; - grid[((size - 1 - i) * size) + 7] = 0x10; - } - grid[(7 * size) + 7] = 0x10; - grid[(7 * size) + (size - 8)] = 0x10; - grid[((size - 8) * size) + 7] = 0x10; - - /* Add alignment patterns */ - if(version != 1) { - /* Version 1 does not have alignment patterns */ - - loopsize = qr_align_loopsize[version - 1]; - for(x = 0; x < loopsize; x++) { - for(y = 0; y < loopsize; y++) { - xcoord = qr_table_e1[((version - 2) * 7) + x]; - ycoord = qr_table_e1[((version - 2) * 7) + y]; - - if(!(grid[(ycoord * size) + xcoord] & 0x10)) { - place_align(grid, size, xcoord, ycoord); - } - } - } - } - - /* Reserve space for format information */ - for(i = 0; i < 8; i++) { - grid[(8 * size) + i] += 0x20; - grid[(i * size) + 8] += 0x20; - grid[(8 * size) + (size - 1 - i)] = 0x20; - grid[((size - 1 - i) * size) + 8] = 0x20; - } - grid[(8 * size) + 8] += 20; - grid[((size - 1 - 7) * size) + 8] = 0x21; /* Dark Module from Figure 25 */ - - /* Reserve space for version information */ - if(version >= 7) { - for(i = 0; i < 6; i++) { - grid[((size - 9) * size) + i] = 0x20; - grid[((size - 10) * size) + i] = 0x20; - grid[((size - 11) * size) + i] = 0x20; - grid[(i * size) + (size - 9)] = 0x20; - grid[(i * size) + (size - 10)] = 0x20; - grid[(i * size) + (size - 11)] = 0x20; - } - } -} - -int cwbit(int* datastream, int i) { - int word = i / 8; - int bit = i % 8; - int resultant = 0; - - switch(bit) { - case 0: if(datastream[word] & 0x80) { resultant = 1; } else { resultant = 0; } break; - case 1: if(datastream[word] & 0x40) { resultant = 1; } else { resultant = 0; } break; - case 2: if(datastream[word] & 0x20) { resultant = 1; } else { resultant = 0; } break; - case 3: if(datastream[word] & 0x10) { resultant = 1; } else { resultant = 0; } break; - case 4: if(datastream[word] & 0x08) { resultant = 1; } else { resultant = 0; } break; - case 5: if(datastream[word] & 0x04) { resultant = 1; } else { resultant = 0; } break; - case 6: if(datastream[word] & 0x02) { resultant = 1; } else { resultant = 0; } break; - case 7: if(datastream[word] & 0x01) { resultant = 1; } else { resultant = 0; } break; - } - - return resultant; -} - -void populate_grid(unsigned char* grid, int size, int* datastream, int cw) -{ - int direction = 1; /* up */ - int row = 0; /* right hand side */ - - int i, n, x, y; - - n = cw * 8; - y = size - 1; - i = 0; - do { - x = (size - 2) - (row * 2); - if(x < 6) - x--; /* skip over vertical timing pattern */ - - if(!(grid[(y * size) + (x + 1)] & 0xf0)) { - if (cwbit(datastream, i)) { - grid[(y * size) + (x + 1)] = 0x01; - } else { - grid[(y * size) + (x + 1)] = 0x00; - } - i++; - } - - if(i < n) { - if(!(grid[(y * size) + x] & 0xf0)) { - if (cwbit(datastream, i)) { - grid[(y * size) + x] = 0x01; - } else { - grid[(y * size) + x] = 0x00; - } - i++; - } - } - - if(direction) { y--; } else { y++; } - if(y == -1) { - /* reached the top */ - row++; - y = 0; - direction = 0; - } - if(y == size) { - /* reached the bottom */ - row++; - y = size - 1; - direction = 1; - } - } while (i < n); -} - -int evaluate(unsigned char *grid, int size, int pattern) -{ - int x, y, block; - int result = 0; - char state; - int p; - int dark_mods; - int percentage, k; - -#ifndef _MSC_VER - char local[size * size]; -#else - char* local = (char *)_alloca((size * size) * sizeof(char)); -#endif - - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - switch(pattern) { - case 0: if (grid[(y * size) + x] & 0x01) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 1: if (grid[(y * size) + x] & 0x02) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 2: if (grid[(y * size) + x] & 0x04) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 3: if (grid[(y * size) + x] & 0x08) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 4: if (grid[(y * size) + x] & 0x10) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 5: if (grid[(y * size) + x] & 0x20) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 6: if (grid[(y * size) + x] & 0x40) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - case 7: if (grid[(y * size) + x] & 0x80) { local[(y * size) + x] = '1'; } else { local[(y * size) + x] = '0'; } break; - } - } - } - - /* Test 1: Adjacent modules in row/column in same colour */ - /* Vertical */ - for(x = 0; x < size; x++) { - state = local[x]; - block = 0; - for(y = 0; y < size; y++) { - if(local[(y * size) + x] == state) { - block++; - } else { - if(block > 5) { - result += (3 + block); - } - block = 0; - state = local[(y * size) + x]; - } - } - if(block > 5) { - result += (3 + block); - } - } - - /* Horizontal */ - for(y = 0; y < size; y++) { - state = local[y * size]; - block = 0; - for(x = 0; x < size; x++) { - if(local[(y * size) + x] == state) { - block++; - } else { - if(block > 5) { - result += (3 + block); - } - block = 0; - state = local[(y * size) + x]; - } - } - if(block > 5) { - result += (3 + block); - } - } - - /* Test 2 is not implimented */ - - /* Test 3: 1:1:3:1:1 ratio pattern in row/column */ - /* Vertical */ - for(x = 0; x < size; x++) { - for(y = 0; y < (size - 7); y++) { - p = 0; - if(local[(y * size) + x] == '1') { p += 0x40; } - if(local[((y + 1) * size) + x] == '1') { p += 0x20; } - if(local[((y + 2) * size) + x] == '1') { p += 0x10; } - if(local[((y + 3) * size) + x] == '1') { p += 0x08; } - if(local[((y + 4) * size) + x] == '1') { p += 0x04; } - if(local[((y + 5) * size) + x] == '1') { p += 0x02; } - if(local[((y + 6) * size) + x] == '1') { p += 0x01; } - if(p == 0x5d) { - result += 40; - } - } - } - - /* Horizontal */ - for(y = 0; y < size; y++) { - for(x = 0; x < (size - 7); x++) { - p = 0; - if(local[(y * size) + x] == '1') { p += 0x40; } - if(local[(y * size) + x + 1] == '1') { p += 0x20; } - if(local[(y * size) + x + 2] == '1') { p += 0x10; } - if(local[(y * size) + x + 3] == '1') { p += 0x08; } - if(local[(y * size) + x + 4] == '1') { p += 0x04; } - if(local[(y * size) + x + 5] == '1') { p += 0x02; } - if(local[(y * size) + x + 6] == '1') { p += 0x01; } - if(p == 0x5d) { - result += 40; - } - } - } - - /* Test 4: Proportion of dark modules in entire symbol */ - dark_mods = 0; - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - if(local[(y * size) + x] == '1') { - dark_mods++; - } - } - } - percentage = 100 * (dark_mods / (size * size)); - if(percentage <= 50) { - k = ((100 - percentage) - 50) / 5; - } else { - k = (percentage - 50) / 5; - } - - result += 10 * k; - - return result; -} - - -int apply_bitmask(unsigned char *grid, int size) -{ - int x, y; - unsigned char p; - int pattern, penalty[8]; - int best_val, best_pattern; - int bit; - -#ifndef _MSC_VER - unsigned char mask[size * size]; - unsigned char eval[size * size]; -#else - unsigned char* mask = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); - unsigned char* eval = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); -#endif - - /* Perform data masking */ - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - mask[(y * size) + x] = 0x00; - - if (!(grid[(y * size) + x] & 0xf0)) { - if(((y + x) & 1) == 0) { mask[(y * size) + x] += 0x01; } - if((y & 1) == 0) { mask[(y * size) + x] += 0x02; } - if((x % 3) == 0) { mask[(y * size) + x] += 0x04; } - if(((y + x) % 3) == 0) { mask[(y * size) + x] += 0x08; } - if((((y / 2) + (x / 3)) & 1) == 0) { mask[(y * size) + x] += 0x10; } - if((((y * x) & 1) + ((y * x) % 3)) == 0) { mask[(y * size) + x] += 0x20; } - if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x40; } - if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x80; } - } - } - } - - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; } - - eval[(y * size) + x] = mask[(y * size) + x] ^ p; - } - } - - - /* Evaluate result */ - for(pattern = 0; pattern < 8; pattern++) { - penalty[pattern] = evaluate(eval, size, pattern); - } - - best_pattern = 0; - best_val = penalty[0]; - for(pattern = 1; pattern < 8; pattern++) { - if(penalty[pattern] < best_val) { - best_pattern = pattern; - best_val = penalty[pattern]; - } - } - - /* Apply mask */ - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - bit = 0; - switch(best_pattern) { - case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break; - case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break; - case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break; - case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break; - case 4: if(mask[(y * size) + x] & 0x10) { bit = 1; } break; - case 5: if(mask[(y * size) + x] & 0x20) { bit = 1; } break; - case 6: if(mask[(y * size) + x] & 0x40) { bit = 1; } break; - case 7: if(mask[(y * size) + x] & 0x80) { bit = 1; } break; - } - if(bit == 1) { - if(grid[(y * size) + x] & 0x01) { - grid[(y * size) + x] = 0x00; - } else { - grid[(y * size) + x] = 0x01; - } - } - } - } - - return best_pattern; -} - -void add_format_info(unsigned char *grid, int size, int ecc_level, int pattern) -{ - /* Add format information to grid */ - - int format = pattern; - unsigned int seq; - int i; - - switch(ecc_level) { - case LEVEL_L: format += 0x08; break; - case LEVEL_Q: format += 0x18; break; - case LEVEL_H: format += 0x10; break; - } - - seq = qr_annex_c[format]; - - for(i = 0; i < 6; i++) { - grid[(i * size) + 8] += (seq >> i) & 0x01; - } - - for(i = 0; i < 8; i++) { - grid[(8 * size) + (size - i - 1)] += (seq >> i) & 0x01; - } - - for(i = 0; i < 6; i++) { - grid[(8 * size) + (5 - i)] += (seq >> (i + 9)) & 0x01; - } - - for(i = 0; i < 7; i++) { - grid[(((size - 7) + i) * size) + 8] += (seq >> (i + 8)) & 0x01; - } - - grid[(7 * size) + 8] += (seq >> 6) & 0x01; - grid[(8 * size) + 8] += (seq >> 7) & 0x01; - grid[(8 * size) + 7] += (seq >> 8) & 0x01; -} - -void add_version_info(unsigned char *grid, int size, int version) -{ - /* Add version information */ - int i; - - long int version_data = qr_annex_d[version - 7]; - for(i = 0; i < 6; i++) { - grid[((size - 11) * size) + i] += (version_data >> (i * 3)) & 0x01; - grid[((size - 10) * size) + i] += (version_data >> ((i * 3) + 1)) & 0x01; - grid[((size - 9) * size) + i] += (version_data >> ((i * 3) + 2)) & 0x01; - grid[(i * size) + (size - 11)] += (version_data >> (i * 3)) & 0x01; - grid[(i * size) + (size - 10)] += (version_data >> ((i * 3) + 1)) & 0x01; - grid[(i * size) + (size - 9)] += (version_data >> ((i * 3) + 2)) & 0x01; - } -} - -int qr_code(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int error_number, i, j, glyph, est_binlen; - int ecc_level, autosize, version, max_cw, target_binlen, blocks, size; - int bitmask, gs1; - -#ifndef _MSC_VER - int utfdata[length + 1]; - int jisdata[length + 1]; - char mode[length + 1]; -#else - int* datastream; - int* fullstream; - unsigned char* grid; - int* utfdata = (int *)_alloca((length + 1) * sizeof(int)); - int* jisdata = (int *)_alloca((length + 1) * sizeof(int)); - char* mode = (char *)_alloca(length + 1); -#endif - - gs1 = (symbol->input_mode == GS1_MODE); - - switch(symbol->input_mode) { - case DATA_MODE: - for(i = 0; i < length; i++) { - jisdata[i] = (int)source[i]; - } - break; - default: - /* Convert Unicode input to Shift-JIS */ - error_number = utf8toutf16(symbol, source, utfdata, &length); - if(error_number != 0) { return error_number; } - - for(i = 0; i < length; i++) { - if(utfdata[i] <= 0xff) { - jisdata[i] = utfdata[i]; - } else { - j = 0; - glyph = 0; - do { - if(sjis_lookup[j * 2] == utfdata[i]) { - glyph = sjis_lookup[(j * 2) + 1]; - } - j++; - } while ((j < 6843) && (glyph == 0)); - if(glyph == 0) { - strcpy(symbol->errtxt, "Invalid character in input data"); - return ERROR_INVALID_DATA1; - } - jisdata[i] = glyph; - } - } - break; - } - - define_mode(mode, jisdata, length, gs1); - est_binlen = estimate_binary_length(mode, length, gs1); - - ecc_level = LEVEL_L; - max_cw = 2956; - if((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) { - switch (symbol->option_1) { - case 1: ecc_level = LEVEL_L; max_cw = 2956; break; - case 2: ecc_level = LEVEL_M; max_cw = 2334; break; - case 3: ecc_level = LEVEL_Q; max_cw = 1666; break; - case 4: ecc_level = LEVEL_H; max_cw = 1276; break; - } - } - - if(est_binlen > (8 * max_cw)) { - strcpy(symbol->errtxt, "Input too long for selected error correction level"); - return ERROR_TOO_LONG; - } - - autosize = 40; - for(i = 39; i >= 0; i--) { - switch(ecc_level) { - case LEVEL_L: - if ((8 * qr_data_codewords_L[i]) >= est_binlen) { - autosize = i + 1; - } - break; - case LEVEL_M: - if ((8 * qr_data_codewords_M[i]) >= est_binlen) { - autosize = i + 1; - } - break; - case LEVEL_Q: - if ((8 * qr_data_codewords_Q[i]) >= est_binlen) { - autosize = i + 1; - } - break; - case LEVEL_H: - if ((8 * qr_data_codewords_H[i]) >= est_binlen) { - autosize = i + 1; - } - break; - } - } - - if((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) { - if (symbol->option_2 > autosize) { - version = symbol->option_2; - } else { - version = autosize; - } - } else { - version = autosize; - } - - /* Ensure maxium error correction capacity */ - if(est_binlen <= qr_data_codewords_M[version - 1]) { ecc_level = LEVEL_M; } - if(est_binlen <= qr_data_codewords_Q[version - 1]) { ecc_level = LEVEL_Q; } - if(est_binlen <= qr_data_codewords_H[version - 1]) { ecc_level = LEVEL_H; } - - target_binlen = qr_data_codewords_L[version - 1]; blocks = qr_blocks_L[version - 1]; - switch(ecc_level) { - case LEVEL_M: target_binlen = qr_data_codewords_M[version - 1]; blocks = qr_blocks_M[version - 1]; break; - case LEVEL_Q: target_binlen = qr_data_codewords_Q[version - 1]; blocks = qr_blocks_Q[version - 1]; break; - case LEVEL_H: target_binlen = qr_data_codewords_H[version - 1]; blocks = qr_blocks_H[version - 1]; break; - } - -#ifndef _MSC_VER - int datastream[target_binlen + 1]; - int fullstream[qr_total_codewords[version - 1] + 1]; -#else - datastream = (int *)_alloca((target_binlen + 1) * sizeof(int)); - fullstream = (int *)_alloca((qr_total_codewords[version - 1] + 1) * sizeof(int)); -#endif - - qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, est_binlen); - add_ecc(fullstream, datastream, version, target_binlen, blocks); - - size = qr_sizes[version - 1]; -#ifndef _MSC_VER - unsigned char grid[size * size]; -#else - grid = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); -#endif - - for(i = 0; i < size; i++) { - for(j = 0; j < size; j++) { - grid[(i * size) + j] = 0; - } - } - - setup_grid(grid, size, version); - populate_grid(grid, size, fullstream, qr_total_codewords[version - 1]); - bitmask = apply_bitmask(grid, size); - add_format_info(grid, size, ecc_level, bitmask); - if(version >= 7) { - add_version_info(grid, size, version); - } - - symbol->width = size; - symbol->rows = size; - - for(i = 0; i < size; i++) { - for(j = 0; j < size; j++) { - if(grid[(i * size) + j] & 0x01) { - set_module(symbol, i, j); - } - } - symbol->row_height[i] = 1; - } - - return 0; -} - -/* NOTE: From this point forward concerns Micro QR Code only */ - -int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, int *kanji_used, int *alphanum_used, int *byte_used) -{ - /* Convert input data to an "intermediate stage" where data is binary encoded but - control information is not */ - int position = 0, debug = 0; - int short_data_block_length, i; - char data_block; - char buffer[2]; - - strcpy(binary, ""); - - if(debug) { - for(i = 0; i < length; i++) { - printf("%c", mode[i]); - } - printf("\n"); - } - - do { - if(strlen(binary) > 128) { - return ERROR_TOO_LONG; - } - - data_block = mode[position]; - short_data_block_length = 0; - do { - short_data_block_length++; - } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block)); - - switch(data_block) { - case 'K': - /* Kanji mode */ - /* Mode indicator */ - concat(binary, "K"); - *kanji_used = 1; - - /* Character count indicator */ - buffer[0] = short_data_block_length; - buffer[1] = '\0'; - concat(binary, buffer); - - if(debug) { printf("Kanji block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - for(i = 0; i < short_data_block_length; i++) { - int jis = jisdata[position + i]; - int msb, lsb, prod; - - if(jis > 0x9fff) { jis -= 0xc140; } - msb = (jis & 0xff00) >> 4; - lsb = (jis & 0xff); - prod = (msb * 0xc0) + lsb; - - qr_bscan(binary, prod, 0x1000); - - if(debug) { printf("0x%4X ", prod); } - - if(strlen(binary) > 128) { - return ERROR_TOO_LONG; - } - } - - if(debug) { printf("\n"); } - - break; - case 'B': - /* Byte mode */ - /* Mode indicator */ - concat(binary, "B"); - *byte_used = 1; - - /* Character count indicator */ - buffer[0] = short_data_block_length; - buffer[1] = '\0'; - concat(binary, buffer); - - if(debug) { printf("Byte block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - for(i = 0; i < short_data_block_length; i++) { - int byte = jisdata[position + i]; - - qr_bscan(binary, byte, 0x80); - - if(debug) { printf("0x%4X ", byte); } - - if(strlen(binary) > 128) { - return ERROR_TOO_LONG; - } - } - - if(debug) { printf("\n"); } - - break; - case 'A': - /* Alphanumeric mode */ - /* Mode indicator */ - concat(binary, "A"); - *alphanum_used = 1; - - /* Character count indicator */ - buffer[0] = short_data_block_length; - buffer[1] = '\0'; - concat(binary, buffer); - - if(debug) { printf("Alpha block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - i = 0; - while ( i < short_data_block_length ) { - int count; - int first = 0, second = 0, prod; - - first = posn(RHODIUM, (char) jisdata[position + i]); - count = 1; - prod = first; - - if(mode[position + i + 1] == 'A') { - second = posn(RHODIUM, (char) jisdata[position + i + 1]); - count = 2; - prod = (first * 45) + second; - } - - qr_bscan(binary, prod, 1 << (5 * count)); /* count = 1..2 */ - - if(debug) { printf("0x%4X ", prod); } - - if(strlen(binary) > 128) { - return ERROR_TOO_LONG; - } - - i += 2; - }; - - if(debug) { printf("\n"); } - - break; - case 'N': - /* Numeric mode */ - /* Mode indicator */ - concat(binary, "N"); - - /* Character count indicator */ - buffer[0] = short_data_block_length; - buffer[1] = '\0'; - concat(binary, buffer); - - if(debug) { printf("Number block (length %d)\n\t", short_data_block_length); } - - /* Character representation */ - i = 0; - while ( i < short_data_block_length ) { - int count; - int first = 0, second = 0, third = 0, prod; - - first = posn(NEON, (char) jisdata[position + i]); - count = 1; - prod = first; - - if(mode[position + i + 1] == 'N') { - second = posn(NEON, (char) jisdata[position + i + 1]); - count = 2; - prod = (prod * 10) + second; - } - - if(mode[position + i + 2] == 'N') { - third = posn(NEON, (char) jisdata[position + i + 2]); - count = 3; - prod = (prod * 10) + third; - } - - qr_bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */ - - if(debug) { printf("0x%4X (%d)", prod, prod); } - - if(strlen(binary) > 128) { - return ERROR_TOO_LONG; - } - - i += 3; - }; - - if(debug) { printf("\n"); } - - break; - } - - position += short_data_block_length; - } while (position < length - 1) ; - - return 0; -} - -void get_bitlength(int count[], char stream[]) { - int length, i; - - length = strlen(stream); - - for(i = 0; i < 4; i++) { - count[i] = 0; - } - - i = 0; - do { - if((stream[i] == '0') || (stream[i] == '1')) { - count[0]++; - count[1]++; - count[2]++; - count[3]++; - i++; - } else { - switch(stream[i]) { - case 'K': - count[2] += 5; - count[3] += 7; - i += 2; - break; - case 'B': - count[2] += 6; - count[3] += 8; - i += 2; - break; - case 'A': - count[1] += 4; - count[2] += 6; - count[3] += 8; - i += 2; - break; - case 'N': - count[0] += 3; - count[1] += 5; - count[2] += 7; - count[3] += 9; - i += 2; - break; - } - } - } while (i < length); -} - -void microqr_expand_binary(char binary_stream[], char full_stream[], int version) -{ - int i, length; - - length = strlen(binary_stream); - - i = 0; - do { - switch(binary_stream[i]) { - case '1': concat(full_stream, "1"); i++; break; - case '0': concat(full_stream, "0"); i++; break; - case 'N': - /* Numeric Mode */ - /* Mode indicator */ - switch(version) { - case 1: concat(full_stream, "0"); break; - case 2: concat(full_stream, "00"); break; - case 3: concat(full_stream, "000"); break; - } - - /* Character count indicator */ - qr_bscan(full_stream, binary_stream[i + 1], 4 << version); /* version = 0..3 */ - - i += 2; - break; - case 'A': - /* Alphanumeric Mode */ - /* Mode indicator */ - switch(version) { - case 1: concat(full_stream, "1"); break; - case 2: concat(full_stream, "01"); break; - case 3: concat(full_stream, "001"); break; - } - - /* Character count indicator */ - qr_bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 1..3 */ - - i += 2; - break; - case 'B': - /* Byte Mode */ - /* Mode indicator */ - switch(version) { - case 2: concat(full_stream, "10"); break; - case 3: concat(full_stream, "010"); break; - } - - /* Character count indicator */ - qr_bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 2..3 */ - - i += 2; - break; - case 'K': - /* Kanji Mode */ - /* Mode indicator */ - switch(version) { - case 2: concat(full_stream, "11"); break; - case 3: concat(full_stream, "011"); break; - } - - /* Character count indicator */ - qr_bscan(full_stream, binary_stream[i + 1], 1 << version); /* version = 2..3 */ - - i += 2; - break; - } - - } while (i < length); -} - -void micro_qr_m1(char binary_data[]) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[4], ecc_blocks[3]; - - bits_total = 20; - latch = 0; - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 3) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "000"); - } - - if(latch == 0) { - /* Manage last (4-bit) block */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 4) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - if(bits_left > 4) { - remainder = (bits_left - 4) / 8; - for(i = 0; i < remainder; i++) { - concat(binary_data, i & 1 ? "00010001" : "11101100"); - } - } - concat(binary_data, "0000"); - } - - data_codewords = 3; - ecc_codewords = 2; - - /* Copy data into codewords */ - for(i = 0; i < (data_codewords - 1); i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - data_blocks[2] = 0; - if(binary_data[16] == '1') { data_blocks[2] += 0x08; } - if(binary_data[17] == '1') { data_blocks[2] += 0x04; } - if(binary_data[18] == '1') { data_blocks[2] += 0x02; } - if(binary_data[19] == '1') { data_blocks[2] += 0x01; } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80); - } -} - -void micro_qr_m2(char binary_data[], int ecc_mode) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[6], ecc_blocks[7]; - - latch = 0; - - if(ecc_mode == LEVEL_L) { bits_total = 40; } - if(ecc_mode == LEVEL_M) { bits_total = 32; } - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 5) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "00000"); - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - remainder = bits_left / 8; - for(i = 0; i < remainder; i++) { - concat(binary_data, i & 1 ? "00010001" : "11101100"); - } - } - - if(ecc_mode == LEVEL_L) { data_codewords = 5; ecc_codewords = 5; } - if(ecc_mode == LEVEL_M) { data_codewords = 4; ecc_codewords = 6; } - - /* Copy data into codewords */ - for(i = 0; i < data_codewords; i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80); - } - - return; -} - -void micro_qr_m3(char binary_data[], int ecc_mode) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[12], ecc_blocks[9]; - - latch = 0; - - if(ecc_mode == LEVEL_L) { bits_total = 84; } - if(ecc_mode == LEVEL_M) { bits_total = 68; } - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 7) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "0000000"); - } - - if(latch == 0) { - /* Manage last (4-bit) block */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 4) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - if(bits_left > 4) { - remainder = (bits_left - 4) / 8; - for(i = 0; i < remainder; i++) { - concat(binary_data, i & 1 ? "00010001" : "11101100"); - } - } - concat(binary_data, "0000"); - } - - if(ecc_mode == LEVEL_L) { data_codewords = 11; ecc_codewords = 6; } - if(ecc_mode == LEVEL_M) { data_codewords = 9; ecc_codewords = 8; } - - /* Copy data into codewords */ - for(i = 0; i < (data_codewords - 1); i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - - if(ecc_mode == LEVEL_L) { - data_blocks[11] = 0; - if(binary_data[80] == '1') { data_blocks[2] += 0x08; } - if(binary_data[81] == '1') { data_blocks[2] += 0x04; } - if(binary_data[82] == '1') { data_blocks[2] += 0x02; } - if(binary_data[83] == '1') { data_blocks[2] += 0x01; } - } - - if(ecc_mode == LEVEL_M) { - data_blocks[9] = 0; - if(binary_data[64] == '1') { data_blocks[2] += 0x08; } - if(binary_data[65] == '1') { data_blocks[2] += 0x04; } - if(binary_data[66] == '1') { data_blocks[2] += 0x02; } - if(binary_data[67] == '1') { data_blocks[2] += 0x01; } - } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80); - } - - return; -} - -void micro_qr_m4(char binary_data[], int ecc_mode) -{ - int i, latch; - int bits_total, bits_left, remainder; - int data_codewords, ecc_codewords; - unsigned char data_blocks[17], ecc_blocks[15]; - - latch = 0; - - if(ecc_mode == LEVEL_L) { bits_total = 128; } - if(ecc_mode == LEVEL_M) { bits_total = 112; } - if(ecc_mode == LEVEL_Q) { bits_total = 80; } - - /* Add terminator */ - bits_left = bits_total - strlen(binary_data); - if(bits_left <= 9) { - for(i = 0; i < bits_left; i++) { - concat(binary_data, "0"); - } - latch = 1; - } else { - concat(binary_data, "000000000"); - } - - if(latch == 0) { - /* Complete current byte */ - remainder = 8 - (strlen(binary_data) % 8); - if(remainder == 8) { remainder = 0; } - for(i = 0; i < remainder; i++) { - concat(binary_data, "0"); - } - - /* Add padding */ - bits_left = bits_total - strlen(binary_data); - remainder = bits_left / 8; - for(i = 0; i < remainder; i++) { - concat(binary_data, i & 1 ? "00010001" : "11101100"); - } - } - - if(ecc_mode == LEVEL_L) { data_codewords = 16; ecc_codewords = 8; } - if(ecc_mode == LEVEL_M) { data_codewords = 14; ecc_codewords = 10; } - if(ecc_mode == LEVEL_Q) { data_codewords = 10; ecc_codewords = 14; } - - /* Copy data into codewords */ - for(i = 0; i < data_codewords; i++) { - data_blocks[i] = 0; - if(binary_data[i * 8] == '1') { data_blocks[i] += 0x80; } - if(binary_data[(i * 8) + 1] == '1') { data_blocks[i] += 0x40; } - if(binary_data[(i * 8) + 2] == '1') { data_blocks[i] += 0x20; } - if(binary_data[(i * 8) + 3] == '1') { data_blocks[i] += 0x10; } - if(binary_data[(i * 8) + 4] == '1') { data_blocks[i] += 0x08; } - if(binary_data[(i * 8) + 5] == '1') { data_blocks[i] += 0x04; } - if(binary_data[(i * 8) + 6] == '1') { data_blocks[i] += 0x02; } - if(binary_data[(i * 8) + 7] == '1') { data_blocks[i] += 0x01; } - } - - /* Calculate Reed-Solomon error codewords */ - rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 0); - rs_encode(data_codewords,data_blocks,ecc_blocks); - rs_free(); - - /* Add Reed-Solomon codewords to binary data */ - for(i = 0; i < ecc_codewords; i++) { - qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80); - } -} - -void micro_setup_grid(unsigned char* grid, int size) -{ - int i, toggle = 1; - - /* Add timing patterns */ - for(i = 0; i < size; i++) { - if(toggle == 1) { - grid[i] = 0x21; - grid[(i * size)] = 0x21; - toggle = 0; - } else { - grid[i] = 0x20; - grid[(i * size)] = 0x20; - toggle = 1; - } - } - - /* Add finder patterns */ - place_finder(grid, size, 0, 0); - - /* Add separators */ - for(i = 0; i < 7; i++) { - grid[(7 * size) + i] = 0x10; - grid[(i * size) + 7] = 0x10; - } - grid[(7 * size) + 7] = 0x10; - - - /* Reserve space for format information */ - for(i = 0; i < 8; i++) { - grid[(8 * size) + i] += 0x20; - grid[(i * size) + 8] += 0x20; - } - grid[(8 * size) + 8] += 20; -} - -void micro_populate_grid(unsigned char* grid, int size, char full_stream[]) -{ - int direction = 1; /* up */ - int row = 0; /* right hand side */ - - int i, n, x, y; - - n = strlen(full_stream); - y = size - 1; - i = 0; - do { - x = (size - 2) - (row * 2); - - if(!(grid[(y * size) + (x + 1)] & 0xf0)) { - if (full_stream[i] == '1') { - grid[(y * size) + (x + 1)] = 0x01; - } else { - grid[(y * size) + (x + 1)] = 0x00; - } - i++; - } - - if(i < n) { - if(!(grid[(y * size) + x] & 0xf0)) { - if (full_stream[i] == '1') { - grid[(y * size) + x] = 0x01; - } else { - grid[(y * size) + x] = 0x00; - } - i++; - } - } - - if(direction) { y--; } else { y++; } - if(y == 0) { - /* reached the top */ - row++; - y = 1; - direction = 0; - } - if(y == size) { - /* reached the bottom */ - row++; - y = size - 1; - direction = 1; - } - } while (i < n); -} - -int micro_evaluate(unsigned char *grid, int size, int pattern) -{ - int sum1, sum2, i, filter = 0, retval; - - switch(pattern) { - case 0: filter = 0x01; break; - case 1: filter = 0x02; break; - case 2: filter = 0x04; break; - case 3: filter = 0x08; break; - } - - sum1 = 0; - sum2 = 0; - for(i = 1; i < size; i++) { - if(grid[(i * size) + size - 1] & filter) { sum1++; } - if(grid[((size - 1) * size) + i] & filter) { sum2++; } - } - - if(sum1 <= sum2) { retval = (sum1 * 16) + sum2; } else { retval = (sum2 * 16) + sum1; } - - return retval; -} - -int micro_apply_bitmask(unsigned char *grid, int size) -{ - int x, y; - unsigned char p; - int pattern, value[8]; - int best_val, best_pattern; - int bit; - -#ifndef _MSC_VER - unsigned char mask[size * size]; - unsigned char eval[size * size]; -#else - unsigned char* mask = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); - unsigned char* eval = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); -#endif - - /* Perform data masking */ - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - mask[(y * size) + x] = 0x00; - - if (!(grid[(y * size) + x] & 0xf0)) { - if((y & 1) == 0) { - mask[(y * size) + x] += 0x01; - } - - if((((y / 2) + (x / 3)) & 1) == 0) { - mask[(y * size) + x] += 0x02; - } - - if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { - mask[(y * size) + x] += 0x04; - } - - if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { - mask[(y * size) + x] += 0x08; - } - } - } - } - - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - if(grid[(y * size) + x] & 0x01) { p = 0xff; } else { p = 0x00; } - - eval[(y * size) + x] = mask[(y * size) + x] ^ p; - } - } - - - /* Evaluate result */ - for(pattern = 0; pattern < 8; pattern++) { - value[pattern] = micro_evaluate(eval, size, pattern); - } - - best_pattern = 0; - best_val = value[0]; - for(pattern = 1; pattern < 4; pattern++) { - if(value[pattern] > best_val) { - best_pattern = pattern; - best_val = value[pattern]; - } - } - - /* Apply mask */ - for(x = 0; x < size; x++) { - for(y = 0; y < size; y++) { - bit = 0; - switch(best_pattern) { - case 0: if(mask[(y * size) + x] & 0x01) { bit = 1; } break; - case 1: if(mask[(y * size) + x] & 0x02) { bit = 1; } break; - case 2: if(mask[(y * size) + x] & 0x04) { bit = 1; } break; - case 3: if(mask[(y * size) + x] & 0x08) { bit = 1; } break; - } - if(bit == 1) { - if(grid[(y * size) + x] & 0x01) { - grid[(y * size) + x] = 0x00; - } else { - grid[(y * size) + x] = 0x01; - } - } - } - } - - return best_pattern; -} - -int microqr(struct zint_symbol *symbol, unsigned char source[], int length) -{ - int i, j, glyph, size; - char binary_stream[200]; - char full_stream[200]; - int utfdata[40]; - int jisdata[40]; - char mode[40]; - int error_number, kanji_used = 0, alphanum_used = 0, byte_used = 0; - int version_valid[4]; - int binary_count[4]; - int ecc_level, autoversion, version; - int n_count, a_count, bitmask, format, format_full; - -#ifdef _MSC_VER - unsigned char* grid; -#endif - - if(length > 35) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - - for(i = 0; i < 4; i++) { - version_valid[i] = 1; - } - - switch(symbol->input_mode) { - case DATA_MODE: - for(i = 0; i < length; i++) { - jisdata[i] = (int)source[i]; - } - break; - default: - /* Convert Unicode input to Shift-JIS */ - error_number = utf8toutf16(symbol, source, utfdata, &length); - if(error_number != 0) { return error_number; } - - for(i = 0; i < length; i++) { - if(utfdata[i] <= 0xff) { - jisdata[i] = utfdata[i]; - } else { - j = 0; - glyph = 0; - do { - if(sjis_lookup[j * 2] == utfdata[i]) { - glyph = sjis_lookup[(j * 2) + 1]; - } - j++; - } while ((j < 6843) && (glyph == 0)); - if(glyph == 0) { - strcpy(symbol->errtxt, "Invalid character in input data"); - return ERROR_INVALID_DATA1; - } - jisdata[i] = glyph; - } - } - break; - } - - define_mode(mode, jisdata, length, 0); - - n_count = 0; - a_count = 0; - for(i = 0; i < length; i++) { - if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { n_count++; } - if(in_alpha(jisdata[i])) { a_count++; } - } - - if(a_count == length) { - /* All data can be encoded in Alphanumeric mode */ - for(i = 0; i < length; i++) { - mode[i] = 'A'; - } - } - - if(n_count == length) { - /* All data can be encoded in Numeric mode */ - for(i = 0; i < length; i++) { - mode[i] = 'N'; - } - } - - error_number = micro_qr_intermediate(binary_stream, jisdata, mode, length, &kanji_used, &alphanum_used, &byte_used); - if(error_number != 0) { - strcpy(symbol->errtxt, "Input data too long"); - return error_number; - } - - get_bitlength(binary_count, binary_stream); - - /* Eliminate possivle versions depending on type of content */ - if(byte_used) { - version_valid[0] = 0; - version_valid[1] = 0; - } - - if(alphanum_used) { - version_valid[0] = 0; - } - - if(kanji_used) { - version_valid[0] = 0; - version_valid[1] = 0; - } - - /* Eliminate possible versions depending on length of binary data */ - if(binary_count[0] > 20) { version_valid[0] = 0; } - if(binary_count[1] > 40) { version_valid[1] = 0; } - if(binary_count[2] > 84) { version_valid[2] = 0; } - if(binary_count[3] > 128) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - - /* Eliminate possible versions depending on error correction level specified */ - ecc_level = LEVEL_L; - if((symbol->option_1 >= 1) && (symbol->option_2 <= 4)) { - ecc_level = symbol->option_1; - } - - if(ecc_level == LEVEL_H) { - strcpy(symbol->errtxt, "Error correction level H not available"); - return ERROR_INVALID_OPTION; - } - - if(ecc_level == LEVEL_Q) { - version_valid[0] = 0; - version_valid[1] = 0; - version_valid[2] = 0; - if(binary_count[3] > 80) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - } - - if(ecc_level == LEVEL_M) { - version_valid[0] = 0; - if(binary_count[1] > 32) { version_valid[1] = 0; } - if(binary_count[2] > 68) { version_valid[2] = 0; } - if(binary_count[3] > 112) { - strcpy(symbol->errtxt, "Input data too long"); - return ERROR_TOO_LONG; - } - } - - autoversion = 3; - if(version_valid[2]) { autoversion = 2; } - if(version_valid[1]) { autoversion = 1; } - if(version_valid[0]) { autoversion = 0; } - - version = autoversion; - /* Get version from user */ - if((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) { - if(symbol->option_2 >= autoversion) { - version = symbol->option_2; - } - } - - /* If there is enough unused space then increase the error correction level */ - if(version == 3) { - if(binary_count[3] <= 112) { ecc_level = LEVEL_M; } - if(binary_count[3] <= 80) { ecc_level = LEVEL_Q; } - } - - if(version == 2) { - if(binary_count[2] <= 68) { ecc_level = LEVEL_M; } - } - - if(version == 1) { - if(binary_count[1] <= 32) { ecc_level = LEVEL_M; } - } - - strcpy(full_stream, ""); - microqr_expand_binary(binary_stream, full_stream, version); - - switch(version) { - case 0: micro_qr_m1(full_stream); break; - case 1: micro_qr_m2(full_stream, ecc_level); break; - case 2: micro_qr_m3(full_stream, ecc_level); break; - case 3: micro_qr_m4(full_stream, ecc_level); break; - } - - size = micro_qr_sizes[version]; -#ifndef _MSC_VER - unsigned char grid[size * size]; -#else - grid = (unsigned char *)_alloca((size * size) * sizeof(unsigned char)); -#endif - - for(i = 0; i < size; i++) { - for(j = 0; j < size; j++) { - grid[(i * size) + j] = 0; - } - } - - micro_setup_grid(grid, size); - micro_populate_grid(grid, size, full_stream); - bitmask = micro_apply_bitmask(grid, size); - - /* Add format data */ - format = 0; - switch(version) { - case 1: switch(ecc_level) { - case 1: format = 1; break; - case 2: format = 2; break; - } - break; - case 2: switch(ecc_level) { - case 1: format = 3; break; - case 2: format = 4; break; - } - break; - case 3: switch(ecc_level) { - case 1: format = 5; break; - case 2: format = 6; break; - case 3: format = 7; break; - } - break; - } - - format_full = qr_annex_c1[(format << 2) + bitmask]; - - if(format_full & 0x4000) { grid[(8 * size) + 1] += 0x01; } - if(format_full & 0x2000) { grid[(8 * size) + 2] += 0x01; } - if(format_full & 0x1000) { grid[(8 * size) + 3] += 0x01; } - if(format_full & 0x800) { grid[(8 * size) + 4] += 0x01; } - if(format_full & 0x400) { grid[(8 * size) + 5] += 0x01; } - if(format_full & 0x200) { grid[(8 * size) + 6] += 0x01; } - if(format_full & 0x100) { grid[(8 * size) + 7] += 0x01; } - if(format_full & 0x80) { grid[(8 * size) + 8] += 0x01; } - if(format_full & 0x40) { grid[(7 * size) + 8] += 0x01; } - if(format_full & 0x20) { grid[(6 * size) + 8] += 0x01; } - if(format_full & 0x10) { grid[(5 * size) + 8] += 0x01; } - if(format_full & 0x08) { grid[(4 * size) + 8] += 0x01; } - if(format_full & 0x04) { grid[(3 * size) + 8] += 0x01; } - if(format_full & 0x02) { grid[(2 * size) + 8] += 0x01; } - if(format_full & 0x01) { grid[(1 * size) + 8] += 0x01; } - - symbol->width = size; - symbol->rows = size; - - for(i = 0; i < size; i++) { - for(j = 0; j < size; j++) { - if(grid[(i * size) + j] & 0x01) { - set_module(symbol, i, j); - } - } - symbol->row_height[i] = 1; - } - - return 0; -} diff --git a/3rdparty/zint-2.4.4/backend/qr.h b/3rdparty/zint-2.4.4/backend/qr.h deleted file mode 100644 index 47576d5..0000000 --- a/3rdparty/zint-2.4.4/backend/qr.h +++ /dev/null @@ -1,156 +0,0 @@ -/* qr.h Data for QR Code */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - Copyright (C) 2006 Kentaro Fukuchi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define LEVEL_L 1 -#define LEVEL_M 2 -#define LEVEL_Q 3 -#define LEVEL_H 4 - -#define RHODIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" - -/* From ISO/IEC 18004:2006 Table 7 */ -static int qr_data_codewords_L[] = { - 19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647, - 721, 795, 861, 932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631, - 1735, 1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956 -}; - -static int qr_data_codewords_M[] = { - 16, 28, 44, 64, 86, 108, 124, 154, 182, 216, 254, 290, 334, 365, 415, 453, 507, - 563, 627, 669, 714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267, - 1373, 1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334 -}; - -static int qr_data_codewords_Q[] = { - 13, 22, 34, 48, 62, 76, 88, 110, 132, 154, 180, 206, 244, 261, 295, 325, 367, - 397, 445, 485, 512, 568, 614, 664, 718, 754, 808, 871, 911, - 985, 1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666 -}; - -static int qr_data_codewords_H[] = { - 9, 16, 26, 36, 46, 60, 66, 86, 100, 122, 140, 158, 180, 197, 223, 253, 283, - 313, 341, 385, 406, 442, 464, 514, 538, 596, 628, 661, 701, - 745, 793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276 -}; - -static int qr_total_codewords[] = { - 26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815, - 901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, - 2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706 -}; - -static int qr_blocks_L[] = { - 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, - 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25 -}; - -static int qr_blocks_M[] = { - 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, - 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49 -}; - -static int qr_blocks_Q[] = { - 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, - 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68 -}; - -static int qr_blocks_H[] = { - 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, - 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81 -}; - -static int qr_sizes[] = { - 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, - 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177 -}; - -static int micro_qr_sizes[] = { - 11, 13, 15, 17 -}; - -static int qr_align_loopsize[] = { - 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 -}; - -static int qr_table_e1[] = { - 6, 18, 0, 0, 0, 0, 0, - 6, 22, 0, 0, 0, 0, 0, - 6, 26, 0, 0, 0, 0, 0, - 6, 30, 0, 0, 0, 0, 0, - 6, 34, 0, 0, 0, 0, 0, - 6, 22, 38, 0, 0, 0, 0, - 6, 24, 42, 0, 0, 0, 0, - 6, 26, 46, 0, 0, 0, 0, - 6, 28, 50, 0, 0, 0, 0, - 6, 30, 54, 0, 0, 0, 0, - 6, 32, 58, 0, 0, 0, 0, - 6, 34, 62, 0, 0, 0, 0, - 6, 26, 46, 66, 0, 0, 0, - 6, 26, 48, 70, 0, 0, 0, - 6, 26, 50, 74, 0, 0, 0, - 6, 30, 54, 78, 0, 0, 0, - 6, 30, 56, 82, 0, 0, 0, - 6, 30, 58, 86, 0, 0, 0, - 6, 34, 62, 90, 0, 0, 0, - 6, 28, 50, 72, 94, 0, 0, - 6, 26, 50, 74, 98, 0, 0, - 6, 30, 54, 78, 102, 0, 0, - 6, 28, 54, 80, 106, 0, 0, - 6, 32, 58, 84, 110, 0, 0, - 6, 30, 58, 86, 114, 0, 0, - 6, 34, 62, 90, 118, 0, 0, - 6, 26, 50, 74, 98, 122, 0, - 6, 30, 54, 78, 102, 126, 0, - 6, 26, 52, 78, 104, 130, 0, - 6, 30, 56, 82, 108, 134, 0, - 6, 34, 60, 86, 112, 138, 0, - 6, 30, 58, 86, 114, 142, 0, - 6, 34, 62, 90, 118, 146, 0, - 6, 30, 54, 78, 102, 126, 150, - 6, 24, 50, 76, 102, 128, 154, - 6, 28, 54, 80, 106, 132, 158, - 6, 32, 58, 84, 110, 136, 162, - 6, 26, 54, 82, 110, 138, 166, - 6, 30, 58, 86, 114, 142, 170 -}; - -static unsigned int qr_annex_c[] = { - /* Format information bit sequences */ - 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, 0x77c4, 0x72f3, 0x7daa, 0x789d, - 0x662f, 0x6318, 0x6c41, 0x6976, 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b, - 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed -}; - -static long int qr_annex_d[] = { - /* Version information bit sequences */ - 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78, - 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab, - 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, - 0x2542e, 0x26a64, 0x27541, 0x28c69 -}; - -static int qr_annex_c1[] = { - /* Micro QR Code format information */ - 0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7, 0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f, - 0x7c16, 0x7921, 0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c, 0x2508, 0x203f, 0x2f66, 0x2a51, 0x34e3, - 0x31d4, 0x3e8d, 0x3bba -}; \ No newline at end of file diff --git a/3rdparty/zint-2.4.4/backend/reedsol.c b/3rdparty/zint-2.4.4/backend/reedsol.c deleted file mode 100644 index b37950b..0000000 --- a/3rdparty/zint-2.4.4/backend/reedsol.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - * - * This is a simple Reed-Solomon encoder - * (C) Cliff Hones 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -// It is not written with high efficiency in mind, so is probably -// not suitable for real-time encoding. The aim was to keep it -// simple, general and clear. -// -// - -// Usage: -// First call rs_init_gf(poly) to set up the Galois Field parameters. -// Then call rs_init_code(size, index) to set the encoding size -// Then call rs_encode(datasize, data, out) to encode the data. -// -// These can be called repeatedly as required - but note that -// rs_init_code must be called following any rs_init_gf call. -// -// If the parameters are fixed, some of the statics below can be -// replaced with constants in the obvious way, and additionally -// malloc/free can be avoided by using static arrays of a suitable -// size. - -#include // only needed for debug (main) -#include // only needed for malloc/free -#include "reedsol.h" -static int gfpoly; -static int symsize; // in bits -static int logmod; // 2**symsize - 1 -static int rlen; - -static int *logt = NULL, *alog = NULL, *rspoly = NULL; - -// rs_init_gf(poly) initialises the parameters for the Galois Field. -// The symbol size is determined from the highest bit set in poly -// This implementation will support sizes up to 30 bits (though that -// will result in very large log/antilog tables) - bit sizes of -// 8 or 4 are typical -// -// The poly is the bit pattern representing the GF characteristic -// polynomial. e.g. for ECC200 (8-bit symbols) the polynomial is -// a**8 + a**5 + a**3 + a**2 + 1, which translates to 0x12d. - -void rs_init_gf(int poly) -{ - int m, b, p, v; - - // Find the top bit, and hence the symbol size - for (b = 1, m = 0; b <= poly; b <<= 1) - m++; - b >>= 1; - m--; - gfpoly = poly; - symsize = m; - - // Calculate the log/alog tables - logmod = (1 << m) - 1; - logt = (int *)malloc(sizeof(int) * (logmod + 1)); - alog = (int *)malloc(sizeof(int) * logmod); - - for (p = 1, v = 0; v < logmod; v++) { - alog[v] = p; - logt[p] = v; - p <<= 1; - if (p & b) - p ^= poly; - } -} - -// rs_init_code(nsym, index) initialises the Reed-Solomon encoder -// nsym is the number of symbols to be generated (to be appended -// to the input data). index is usually 1 - it is the index of -// the constant in the first term (i) of the RS generator polynomial: -// (x + 2**i)*(x + 2**(i+1))*... [nsym terms] -// For ECC200, index is 1. - -void rs_init_code(int nsym, int index) -{ - int i, k; - - rspoly = (int *)malloc(sizeof(int) * (nsym + 1)); - - rlen = nsym; - - rspoly[0] = 1; - for (i = 1; i <= nsym; i++) { - rspoly[i] = 1; - for (k = i - 1; k > 0; k--) { - if (rspoly[k]) - rspoly[k] = alog[(logt[rspoly[k]] + index) % logmod]; - rspoly[k] ^= rspoly[k - 1]; - } - rspoly[0] = alog[(logt[rspoly[0]] + index) % logmod]; - index++; - } -} - -void rs_encode(int len, unsigned char *data, unsigned char *res) -{ - int i, k, m; - for (i = 0; i < rlen; i++) - res[i] = 0; - for (i = 0; i < len; i++) { - m = res[rlen - 1] ^ data[i]; - for (k = rlen - 1; k > 0; k--) { - if (m && rspoly[k]) - res[k] = res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]; - else - res[k] = res[k - 1]; - } - if (m && rspoly[0]) - res[0] = alog[(logt[m] + logt[rspoly[0]]) % logmod]; - else - res[0] = 0; - } -} - -void rs_encode_long(int len, unsigned int *data, unsigned int *res) -{ /* The same as above but for larger bitlengths - Aztec code compatible */ - int i, k, m; - for (i = 0; i < rlen; i++) - res[i] = 0; - for (i = 0; i < len; i++) { - m = res[rlen - 1] ^ data[i]; - for (k = rlen - 1; k > 0; k--) { - if (m && rspoly[k]) - res[k] = res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]; - else - res[k] = res[k - 1]; - } - if (m && rspoly[0]) - res[0] = alog[(logt[m] + logt[rspoly[0]]) % logmod]; - else - res[0] = 0; - } -} - -void rs_free(void) -{ /* Free memory */ - free(logt); - free(alog); - free(rspoly); - rspoly = NULL; -} diff --git a/3rdparty/zint-2.4.4/backend/reedsol.h b/3rdparty/zint-2.4.4/backend/reedsol.h deleted file mode 100644 index 3a7f8ef..0000000 --- a/3rdparty/zint-2.4.4/backend/reedsol.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * - * This is a simple Reed-Solomon encoder - * (C) Cliff Hones 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef __REEDSOL_H -#define __REEDSOL_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -extern void rs_init_gf(int poly); -extern void rs_init_code(int nsym, int index); -extern void rs_encode(int len, unsigned char *data, unsigned char *res); -extern void rs_encode_long(int len, unsigned int *data, unsigned int *res); -extern void rs_free(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __REEDSOL_H */ diff --git a/3rdparty/zint-2.4.4/backend/render.c b/3rdparty/zint-2.4.4/backend/render.c deleted file mode 100644 index de086d5..0000000 --- a/3rdparty/zint-2.4.4/backend/render.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * render.c - Generic Rendered Format - * - * Initiall written by Sam Lown for use in gLabels. Converts encoded - * data into a generic internal structure of lines and characters - * usable in external applications. - */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" - -#define GL_CONST 2.8346 - -struct zint_render_line *render_plot_create_line(float x, float y, float width, float length); -int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line); -struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width); -int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring); -struct zint_render_hexagon *render_plot_create_hexagon(float x, float y); -int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *ring, struct zint_render_hexagon **last_hexagon); - -int render_plot_add_string(struct zint_symbol *symbol, unsigned char *text, float x, float y, float fsize, float width, struct zint_render_string **last_string); - -int render_plot(struct zint_symbol *symbol, float width, float height) -{ - struct zint_render *render; - struct zint_render_line *line, *last_line = NULL; - struct zint_render_string *last_string = NULL; - struct zint_render_ring *ring, *last_ring = NULL; - struct zint_render_hexagon *hexagon, *last_hexagon = NULL; - - int i, r, block_width, latch, this_row; - float textpos, textwidth, large_bar_height, preset_height, row_height, row_posn = 0.0; - // int error_number = 0; - int text_offset, text_height, xoffset, yoffset, textdone, main_symbol_width_x, addon_width_x; - char addon[6], textpart[10]; - int large_bar_count, symbol_lead_in, total_symbol_width_x, total_area_width_x; - float addon_text_posn; - float default_text_posn; - float scaler; - const char *locale = NULL; - int hide_text = 0; - float required_aspect; - float symbol_aspect = 1; - float x_dimension; - int upceanflag = 0; - - // Allocate memory for the rendered version -#ifndef _MSC_VER - render = symbol->rendered = malloc(sizeof(struct zint_render)); -#else - render = symbol->rendered = (struct zint_render *)_alloca(sizeof(struct zint_render)); -#endif - render->lines = NULL; - render->strings = NULL; - render->rings = NULL; - render->hexagons = NULL; - - locale = setlocale(LC_ALL, "C"); - - row_height = 0; - textdone = 0; - textpos = 0.0; - main_symbol_width_x = symbol->width; - strcpy(addon, ""); - symbol_lead_in = 0; - addon_text_posn = 0.0; - addon_width_x = 0; - - /* - * Determine if there will be any addon texts and text height - */ - latch = 0; - r = 0; - /* Isolate add-on text */ - if(is_extendable(symbol->symbology)) { - for(i = 0; i < ustrlen(symbol->text); i++) { - if (latch == 1) { - addon[r] = symbol->text[i]; - r++; - } - if (symbol->text[i] == '+') { - latch = 1; - } - } - } - addon[r] = '\0'; - - if((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)) { - hide_text = 1; - text_height = text_offset = 0.0; - } else { - text_height = 9.0; - text_offset = 2.0; - } - - - /* - * Calculate the width of the barcode, especially if there are any extra - * borders or white space to add. - */ - - while(!(module_is_set(symbol, symbol->rows - 1, symbol_lead_in))) { - symbol_lead_in++; - } - - /* Certain symbols need whitespace otherwise characters get chopped off the sides */ - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) - || (symbol->symbology == BARCODE_ISBNX)) { - switch(ustrlen(symbol->text)) { - case 13: /* EAN 13 */ - case 16: - case 19: - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - } - main_symbol_width_x = 96 + symbol_lead_in; - upceanflag = 13; - break; - case 2: - main_symbol_width_x = 22 + symbol_lead_in; - upceanflag = 2; - break; - case 5: - main_symbol_width_x = 49 + symbol_lead_in; - upceanflag = 5; - break; - default: - main_symbol_width_x = 68 + symbol_lead_in; - upceanflag = 8; - } - switch(ustrlen(symbol->text)) { - case 11: - case 16: - /* EAN-2 add-on */ - addon_width_x = 31; - break; - case 14: - case 19: - /* EAN-5 add-on */ - addon_width_x = 58; - break; - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - upceanflag = 12; - if(symbol->whitespace_width < 10) { - symbol->whitespace_width = 10; - main_symbol_width_x = 96 + symbol_lead_in; - } - switch(ustrlen(symbol->text)) { - case 15: - /* EAN-2 add-on */ - addon_width_x = 31; - break; - case 18: - /* EAN-5 add-on */ - addon_width_x = 58; - break; - } - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - upceanflag = 6; - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_symbol_width_x = 51 + symbol_lead_in; - } - switch(ustrlen(symbol->text)) { - case 11: - /* EAN-2 add-on */ - addon_width_x = 31; - break; - case 14: - /* EAN-5 add-on */ - addon_width_x = 58; - break; - } - } - - total_symbol_width_x = main_symbol_width_x + addon_width_x; - total_area_width_x = total_symbol_width_x + (2 * (symbol->border_width + symbol->whitespace_width)); - - xoffset = symbol->border_width + symbol->whitespace_width; - yoffset = symbol->border_width; - - // Determine if height should be overridden - large_bar_count = 0; - preset_height = 0.0; - for(i = 0; i < symbol->rows; i++) { - preset_height += symbol->row_height[i]; - if(symbol->row_height[i] == 0) { - large_bar_count++; - } - } - - if (large_bar_count == 0) { - required_aspect = width / height; - symbol_aspect = (total_symbol_width_x + (2 * xoffset)) / (preset_height + (2 * yoffset) + text_offset + text_height); - symbol->height = preset_height; - if (required_aspect > symbol_aspect) { - /* the area is too wide */ - scaler = height / (preset_height + (2 * yoffset) + text_offset + text_height); - render->width = symbol_aspect * height; - render->height = height; - } else { - /* the area is too high */ - scaler = width / (total_symbol_width_x + (2 * xoffset)); - render->width = width; - render->height = width / symbol_aspect; - } - } else { - scaler = width / (total_symbol_width_x + (2 * xoffset)); - symbol->height = (height / scaler) - ((2 * yoffset) + text_offset + text_height); - - render->width = width; - render->height = height; - } - large_bar_height = (symbol->height - preset_height) / large_bar_count; - - if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler; - } else { - default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler; - } - - x_dimension = render->width / total_area_width_x; - x_dimension /= GL_CONST; - - /* Set minimum size of symbol */ - /* Barcode must be at least 2mm high by 2mm across */ - if(render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST) { - render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST; - } - if(render->width < (2.0 * GL_CONST)) { - render->width = (2.0 * GL_CONST); - } - - if(symbol->symbology == BARCODE_CODABAR) { - /* The minimum X-dimension of Codabar is 0.191mm. The minimum bar height is 5mm */ - if(x_dimension < 0.191) { - render->width = 0.191 * GL_CONST * total_area_width_x; - } - if(render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST) { - render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST; - } - } - - if(symbol->symbology == BARCODE_CODE49) { - /* The minimum X-dimension of Code 49 is 0.191mm */ - if(x_dimension < 0.191) { - render->width = 0.191 * GL_CONST * total_area_width_x; - render->height = render->width / symbol_aspect; - } - } - - if(upceanflag != 0) { - /* The X-dimension of UPC/EAN symbols is fixed at 0.330mm */ - /* NOTE: This code will need adjustment before it correctly deals with composite symbols */ - render->width = 0.330 * GL_CONST * total_area_width_x; - /* The height is also fixed */ - switch (upceanflag) { - case 6: - case 12: - case 13: - /* UPC-A, UPC-E and EAN-13 */ - /* Height of bars should be 22.85mm */ - render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 22.85) * GL_CONST; - break; - case 8: - /* EAN-8 */ - /* Height of bars should be 18.23mm */ - render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 18.23) * GL_CONST; - break; - default: - /* EAN-2 and EAN-5 */ - /* Height of bars should be 21.10mm */ - render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 21.10) * GL_CONST; - } - } - - if(symbol->symbology == BARCODE_ONECODE) { - /* The size of USPS Intelligent Mail barcode is fixed */ - render->width = 0.508 * GL_CONST * total_area_width_x; - render->height = 4.064 * GL_CONST; - } - - if((symbol->symbology == BARCODE_POSTNET) || (symbol->symbology == BARCODE_PLANET)) { - /* The size of PostNet and PLANET are fized */ - render->width = 0.508 * GL_CONST * total_area_width_x; - render->height = 2.921 * GL_CONST; - } - - if(((symbol->symbology == BARCODE_AUSPOST) || (symbol->symbology == BARCODE_AUSREPLY)) || - ((symbol->symbology == BARCODE_AUSROUTE) || (symbol->symbology == BARCODE_AUSREDIRECT))) { - /* Australia Post use the same sizes as USPS */ - render->width = 0.508 * GL_CONST * total_area_width_x; - render->height = 4.064 * GL_CONST; - } - - if((symbol->symbology == BARCODE_RM4SCC) || (symbol->symbology == BARCODE_KIX)) { - /* Royal Mail and KIX Code uses 22 bars per inch */ - render->width = 0.577 * GL_CONST * total_area_width_x; - render->height = 5.22 * GL_CONST; - } - - if(symbol->symbology == BARCODE_MAXICODE) { - /* Maxicode is a fixed size */ - scaler = GL_CONST; /* Converts from millimeters to the scale used by glabels */ - render->width = 28.16 * scaler; - render->height = 26.86 * scaler; - - /* Central bullseye pattern */ - ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 0.85 * scaler, 0.67 * scaler); - render_plot_add_ring(symbol, ring, &last_ring); - ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 2.20 * scaler, 0.67 * scaler); - render_plot_add_ring(symbol, ring, &last_ring); - ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 3.54 * scaler, 0.67 * scaler); - render_plot_add_ring(symbol, ring, &last_ring); - - /* Hexagons */ - for(r = 0; r < symbol->rows; r++) { - for(i = 0; i < symbol->width; i++) { - if(module_is_set(symbol, r, i)) { - hexagon = render_plot_create_hexagon(((i * 0.88) + (r & 1 ? 1.76 : 1.32)) * scaler, ((r * 0.76) + 0.76) * scaler); - render_plot_add_hexagon(symbol, hexagon, &last_hexagon); - } - } - } - - } else { - /* everything else uses rectangles (or squares) */ - /* Works from the bottom of the symbol up */ - int addon_latch = 0; - - for(r = 0; r < symbol->rows; r++) { - this_row = r; - if(symbol->row_height[this_row] == 0) { - row_height = large_bar_height; - } else { - row_height = symbol->row_height[this_row]; - } - row_posn = 0; - for(i = 0; i < r; i++) { - if(symbol->row_height[i] == 0) { - row_posn += large_bar_height; - } else { - row_posn += symbol->row_height[i]; - } - } - row_posn += yoffset; - - i = 0; - if(module_is_set(symbol, this_row, 0)) { - latch = 1; - } else { - latch = 0; - } - - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); - if((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_symbol_width_x)) { - addon_text_posn = row_posn * scaler; - addon_latch = 1; - } - if(latch == 1) { - /* a bar */ - if(addon_latch == 0) { - line = render_plot_create_line((i + xoffset) * scaler, (row_posn) * scaler, block_width * scaler, row_height * scaler); - } else { - line = render_plot_create_line((i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); - } - latch = 0; - - render_plot_add_line(symbol, line, &last_line); - } else { - /* a space */ - latch = 1; - } - i += block_width; - - } while (i < symbol->width); - } - } - /* That's done the actual data area, everything else is human-friendly */ - - - /* Add the text */ - xoffset -= symbol_lead_in; - row_posn = (row_posn + large_bar_height) * scaler; - - if (!hide_text) { - if(upceanflag == 8) { - /* guard bar extensions and text formatting for EAN-8 */ - i = 0; - for (line = symbol->rendered->lines; line != NULL; line = line->next) { - switch(i) { - case 0: - case 1: - case 10: - case 11: - case 20: - case 21: - line->length += (5.0 * scaler); - break; - } - i++; - } - - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i]; - } - textpart[4] = '\0'; - textpos = 17; - textwidth = 4.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i + 4]; - } - textpart[4] = '\0'; - textpos = 50; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 86; - textwidth = 2.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - case 5: - textpos = xoffset + 100; - textwidth = 5.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - } - - } - - if(upceanflag == 13) { - /* guard bar extensions and text formatting for EAN-13 */ - i = 0; - for (line = symbol->rendered->lines; line != NULL; line = line->next) { - switch(i) { - case 0: - case 1: - case 14: - case 15: - case 28: - case 29: - line->length += (5.0 * scaler); - break; - } - i++; - } - - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = -5; // 7 - textwidth = 8.5; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - textpos = 25; - textwidth = 6.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 7]; - } - textpart[6] = '\0'; - textpos = 72; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 114; - textwidth = 2.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - case 5: - textpos = xoffset + 128; - textwidth = 5.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - } - } - - if (upceanflag == 12) { - /* guard bar extensions and text formatting for UPCA */ - i = 0; - for (line = symbol->rendered->lines; line != NULL; line = line->next) { - switch(i) { - case 0: - case 1: - case 2: - case 3: - case 14: - case 15: - case 26: - case 27: - case 28: - case 29: - line->length += (5.0 * scaler); - break; - } - i++; - } - - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = -5; - textwidth = 6.2; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[5] = '\0'; - textpos = 27; - textwidth = 5.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 6]; - } - textpos = 68; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - textpart[0] = symbol->text[11]; - textpart[1] = '\0'; - textpos = 100; - textwidth = 6.2; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 116; - textwidth = 2.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - case 5: - textpos = xoffset + 130; - textwidth = 5.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - } - } - - if (upceanflag == 6) { - /* guard bar extensions and text formatting for UPCE */ - i = 0; - for (line = symbol->rendered->lines; line != NULL; line = line->next) { - switch(i) { - case 0: - case 1: - case 14: - case 15: - case 16: - line->length += (5.0 * scaler); - break; - } - i++; - } - - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = -5; - textwidth = 6.2; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - textpos = 24; - textwidth = 6.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); - textpart[0] = symbol->text[7]; - textpart[1] = '\0'; - textpos = 55; - textwidth = 6.2; - render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 70; - textwidth = 2.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - case 5: - textpos = xoffset + 84; - textwidth = 5.0 * 8.5; - render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); - break; - } - } - - /* Put normal human readable text at the bottom (and centered) */ - if (textdone == 0) { - // caculate start xoffset to center text - render_plot_add_string(symbol, symbol->text, ((symbol->width / 2.0) + xoffset) * scaler, default_text_posn, 9.0 * scaler, 0.0, &last_string); - } - } - - switch(symbol->symbology) { - case BARCODE_MAXICODE: - /* Do nothing! */ - break; - default: - if((symbol->output_options & BARCODE_BIND) != 0) { - if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { - /* row binding */ - for(r = 1; r < symbol->rows; r++) { - line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); - render_plot_add_line(symbol, line, &last_line); - } - } - } - if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); - render_plot_add_line(symbol, line, &last_line); - line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); - render_plot_add_line(symbol, line, &last_line); - } - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); - render_plot_add_line(symbol, line, &last_line); - line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); - render_plot_add_line(symbol, line, &last_line); - } - break; - } - - if (locale) - setlocale(LC_ALL, locale); - - return 1; -} - - -/* - * Create a new line with its memory allocated ready for adding to the - * rendered structure. - * - * This is much quicker than writing out each line manually (in some cases!) - */ -struct zint_render_line *render_plot_create_line(float x, float y, float width, float length) -{ - struct zint_render_line *line; - -#ifndef _MSC_VER - line = malloc(sizeof(struct zint_render_line)); -#else - line = (struct zint_render_line *)_alloca(sizeof(struct zint_render_line)); -#endif - line->next = NULL; - line->x = x; - line->y = y; - line->width = width; - line->length = length; - - return line; -} - -/* - * Add the line to the current rendering and update the last line's - * next value. - */ -int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line) -{ - if (*last_line) - (*last_line)->next = line; - else - symbol->rendered->lines = line; // first line - - *last_line = line; - return 1; -} - -struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width) -{ - struct zint_render_ring *ring; - -#ifndef _MSC_VER - ring = malloc(sizeof(struct zint_render_ring)); -#else - ring = (struct zint_render_ring *)_alloca(sizeof(struct zint_render_ring)); -#endif - ring->next = NULL; - ring->x = x; - ring->y = y; - ring->radius = radius; - ring->line_width = line_width; - - return ring; -} - -int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring) -{ - if (*last_ring) - (*last_ring)->next = ring; - else - symbol->rendered->rings = ring; // first ring - - *last_ring = ring; - return 1; -} - -struct zint_render_hexagon *render_plot_create_hexagon(float x, float y) -{ - struct zint_render_hexagon *hexagon; - -#ifndef _MSC_VER - hexagon = malloc(sizeof(struct zint_render_hexagon)); -#else - hexagon = (struct zint_render_hexagon *)_alloca(sizeof(struct zint_render_hexagon)); -#endif - hexagon->next = NULL; - hexagon->x = x; - hexagon->y = y; - - return hexagon; -} - -int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *hexagon, struct zint_render_hexagon **last_hexagon) -{ - if (*last_hexagon) - (*last_hexagon)->next = hexagon; - else - symbol->rendered->hexagons = hexagon; // first hexagon - - *last_hexagon = hexagon; - return 1; -} - -/* - * Add a string structure to the symbol. - * Coordinates assumed to be from top-center. - */ -int render_plot_add_string(struct zint_symbol *symbol, - unsigned char *text, float x, float y, float fsize, float width, - struct zint_render_string **last_string) -{ - struct zint_render_string *string; - -#ifndef _MSC_VER - string = malloc(sizeof(struct zint_render_string)); -#else - string = (struct zint_render_string *)_alloca(sizeof(struct zint_render_string)); -#endif - string->next = NULL; - string->x = x; - string->y = y; - string->width = width; - string->fsize = fsize; - string->length = ustrlen(text); -#ifndef _MSC_VER - string->text = malloc(sizeof(unsigned char) * (ustrlen(text) + 1)); -#else - string->text = (unsigned char *)_alloca((ustrlen(text) + 1) * sizeof(unsigned char)); -#endif - ustrcpy(string->text, text); - - if (*last_string) - (*last_string)->next = string; - else - symbol->rendered->strings = string; // First character - *last_string = string; - - return 1; -} diff --git a/3rdparty/zint-2.4.4/backend/rss.c b/3rdparty/zint-2.4.4/backend/rss.c deleted file mode 100644 index edf1cdc..0000000 --- a/3rdparty/zint-2.4.4/backend/rss.c +++ /dev/null @@ -1,2264 +0,0 @@ -/* rss.c - Handles Reduced Space Symbology (GS1 DataBar) */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* The functions "combins" and "getRSSwidths" are copyright BSI and are - released with permission under the following terms: - - "Copyright subsists in all BSI publications. BSI also holds the copyright, in the - UK, of the international standardisation bodies. Except as - permitted under the Copyright, Designs and Patents Act 1988 no extract may be - reproduced, stored in a retrieval system or transmitted in any form or by any - means - electronic, photocopying, recording or otherwise - without prior written - permission from BSI. - - "This does not preclude the free use, in the course of implementing the standard, - of necessary details such as symbols, and size, type or grade designations. If these - details are to be used for any other purpose than implementation then the prior - written permission of BSI must be obtained." - - The date of publication for these functions is 30 November 2006 -*/ - -/* Includes numerous bugfixes thanks to Pablo Orduña @ the PIRAmIDE project */ - -#include -#include -#include -#ifdef _MSC_VER -#include -#endif -#include "common.h" -#include "large.h" -#include "rss.h" -#include "gs1.h" - -/********************************************************************** -* combins(n,r): returns the number of Combinations of r selected from n: -* Combinations = n! / ((n - r)! * r!) -**********************************************************************/ -int combins(int n, int r) { - int i, j; - int maxDenom, minDenom; - int val; - - if (n-r > r) { - minDenom = r; - maxDenom = n-r; - } - else { - minDenom = n-r; - maxDenom = r; - } - val = 1; - j = 1; - for (i = n; i > maxDenom; i--) { - val *= i; - if (j <= minDenom) { - val /= j; - j++; - } - } - for (; j <= minDenom; j++) { - val /= j; - } - return(val); -} - -/********************************************************************** -* getRSSwidths -* routine to generate widths for RSS elements for a given value.# -* -* Calling arguments: -* val = required value -* n = number of modules -* elements = elements in a set (RSS-14 & Expanded = 4; RSS Limited = 7) -* maxWidth = maximum module width of an element -* noNarrow = 0 will skip patterns without a one module wide element -* -* Return: -* static int widths[] = element widths -**********************************************************************/ -void getRSSwidths(int val, int n, int elements, int maxWidth, int noNarrow) -{ - int bar; - int elmWidth; - int mxwElement; - int subVal, lessVal; - int narrowMask = 0; - for (bar = 0; bar < elements-1; bar++) - { - for(elmWidth = 1, narrowMask |= (1<= elements-bar-1)) - { - subVal -= combins(n-elmWidth-(elements-bar), elements-bar-2); - } - /* less combinations with elements > maxVal */ - if (elements-bar-1 > 1) - { - lessVal = 0; - for (mxwElement = n-elmWidth-(elements-bar-2); - mxwElement > maxWidth; - mxwElement--) - { - lessVal += combins(n-elmWidth-mxwElement-1, elements-bar-3); - } - subVal -= lessVal * (elements-1-bar); - } - else if (n-elmWidth > maxWidth) - { - subVal--; - } - val -= subVal; - if (val < 0) break; - } - val += subVal; - n -= elmWidth; - widths[bar] = elmWidth; - } - widths[bar] = n; - return; -} - -int rss14(struct zint_symbol *symbol, unsigned char source[], int src_len) -{ /* GS1 DataBar-14 */ - int error_number = 0, i, j, mask; - short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112]; - int data_character[4], data_group[4], v_odd[4], v_even[4]; - int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer; - char latch, hrt[15], temp[32]; - int check_digit, count, separator_row; - - separator_row = 0; - - if(src_len > 13) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, src_len); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* make some room for a separator row for composite symbols */ - switch(symbol->symbology) { - case BARCODE_RSS14_CC: - case BARCODE_RSS14STACK_CC: - case BARCODE_RSS14_OMNI_CC: - separator_row = symbol->rows; - symbol->row_height[separator_row] = 1; - symbol->rows += 1; - break; - } - - for(i = 0; i < 112; i++) { - accum[i] = 0; - x_reg[i] = 0; - y_reg[i] = 0; - } - - for(i = 0; i < 4; i++) { - data_character[i] = 0; - data_group[i] = 0; - } - - binary_load(accum, (char*)source, src_len); - strcpy(temp, "10000000000000"); - if(symbol->option_1 == 2) { - /* Add symbol linkage flag */ - binary_load(y_reg, temp, strlen(temp)); - binary_add(accum, y_reg); - for(i = 0; i < 112; i++) { - y_reg[i] = 0; - } - } - - /* Calculate left and right pair values */ - strcpy(temp, "4537077"); - binary_load(x_reg, temp, strlen(temp)); - - for(i = 0; i < 24; i++) { - shiftup(x_reg); - } - - for(i = 24; i >= 0; i--) { - y_reg[i] = islarger(accum, x_reg); - if(y_reg[i] == 1) { - binary_subtract(accum, x_reg); - } - shiftdown(x_reg); - } - - for(i = 0; i < 112; i++) { - left_reg[i] = y_reg[i]; - right_reg[i] = accum[i]; - } - - /* Calculate four data characters */ - strcpy(temp, "1597"); - binary_load(x_reg, temp, strlen(temp)); - for(i = 0; i < 112; i++) { - accum[i] = left_reg[i]; - } - - for(i = 0; i < 24; i++) { - shiftup(x_reg); - } - - for(i = 24; i >= 0; i--) { - y_reg[i] = islarger(accum, x_reg); - if(y_reg[i] == 1) { - binary_subtract(accum, x_reg); - } - shiftdown(x_reg); - } - - data_character[0] = 0; - data_character[1] = 0; - mask = 0x2000; - for(i = 13; i >= 0; i--) { - if(y_reg[i] == 1) { - data_character[0] += mask; - } - if(accum[i] == 1) { - data_character[1] += mask; - } - mask = mask >> 1; - } - strcpy(temp, "1597"); - binary_load(x_reg, temp, strlen(temp)); - for(i = 0; i < 112; i++) { - accum[i] = right_reg[i]; - } - - for(i = 0; i < 24; i++) { - shiftup(x_reg); - } - - for(i = 24; i >= 0; i--) { - y_reg[i] = islarger(accum, x_reg); - if(y_reg[i] == 1) { - binary_subtract(accum, x_reg); - } - shiftdown(x_reg); - } - - data_character[2] = 0; - data_character[3] = 0; - mask = 0x2000; - for(i = 13; i >= 0; i--) { - if(y_reg[i] == 1) { - data_character[2] += mask; - } - if(accum[i] == 1) { - data_character[3] += mask; - } - mask = mask >> 1; - } - - /* Calculate odd and even subset values */ - - if((data_character[0] >= 0) && (data_character[0] <= 160)) { data_group[0] = 0; } - if((data_character[0] >= 161) && (data_character[0] <= 960)) { data_group[0] = 1; } - if((data_character[0] >= 961) && (data_character[0] <= 2014)) { data_group[0] = 2; } - if((data_character[0] >= 2015) && (data_character[0] <= 2714)) { data_group[0] = 3; } - if((data_character[0] >= 2715) && (data_character[0] <= 2840)) { data_group[0] = 4; } - if((data_character[1] >= 0) && (data_character[1] <= 335)) { data_group[1] = 5; } - if((data_character[1] >= 336) && (data_character[1] <= 1035)) { data_group[1] = 6; } - if((data_character[1] >= 1036) && (data_character[1] <= 1515)) { data_group[1] = 7; } - if((data_character[1] >= 1516) && (data_character[1] <= 1596)) { data_group[1] = 8; } - if((data_character[3] >= 0) && (data_character[3] <= 335)) { data_group[3] = 5; } - if((data_character[3] >= 336) && (data_character[3] <= 1035)) { data_group[3] = 6; } - if((data_character[3] >= 1036) && (data_character[3] <= 1515)) { data_group[3] = 7; } - if((data_character[3] >= 1516) && (data_character[3] <= 1596)) { data_group[3] = 8; } - if((data_character[2] >= 0) && (data_character[2] <= 160)) { data_group[2] = 0; } - if((data_character[2] >= 161) && (data_character[2] <= 960)) { data_group[2] = 1; } - if((data_character[2] >= 961) && (data_character[2] <= 2014)) { data_group[2] = 2; } - if((data_character[2] >= 2015) && (data_character[2] <= 2714)) { data_group[2] = 3; } - if((data_character[2] >= 2715) && (data_character[2] <= 2840)) { data_group[2] = 4; } - - v_odd[0] = (data_character[0] - g_sum_table[data_group[0]]) / t_table[data_group[0]]; - v_even[0] = (data_character[0] - g_sum_table[data_group[0]]) % t_table[data_group[0]]; - v_odd[1] = (data_character[1] - g_sum_table[data_group[1]]) % t_table[data_group[1]]; - v_even[1] = (data_character[1] - g_sum_table[data_group[1]]) / t_table[data_group[1]]; - v_odd[3] = (data_character[3] - g_sum_table[data_group[3]]) % t_table[data_group[3]]; - v_even[3] = (data_character[3] - g_sum_table[data_group[3]]) / t_table[data_group[3]]; - v_odd[2] = (data_character[2] - g_sum_table[data_group[2]]) / t_table[data_group[2]]; - v_even[2] = (data_character[2] - g_sum_table[data_group[2]]) % t_table[data_group[2]]; - - - /* Use RSS subset width algorithm */ - for(i = 0; i < 4; i++) { - if((i == 0)||(i == 2)) { - getRSSwidths(v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 1); - data_widths[0][i] = widths[0]; - data_widths[2][i] = widths[1]; - data_widths[4][i] = widths[2]; - data_widths[6][i] = widths[3]; - getRSSwidths(v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 0); - data_widths[1][i] = widths[0]; - data_widths[3][i] = widths[1]; - data_widths[5][i] = widths[2]; - data_widths[7][i] = widths[3]; - } else { - getRSSwidths(v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 0); - data_widths[0][i] = widths[0]; - data_widths[2][i] = widths[1]; - data_widths[4][i] = widths[2]; - data_widths[6][i] = widths[3]; - getRSSwidths(v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 1); - data_widths[1][i] = widths[0]; - data_widths[3][i] = widths[1]; - data_widths[5][i] = widths[2]; - data_widths[7][i] = widths[3]; - } - } - - - checksum = 0; - /* Calculate the checksum */ - for(i = 0; i < 8; i++) { - checksum += checksum_weight[i] * data_widths[i][0]; - checksum += checksum_weight[i+8] * data_widths[i][1]; - checksum += checksum_weight[i+16] * data_widths[i][2]; - checksum += checksum_weight[i+24] * data_widths[i][3]; - } - checksum %= 79; - - /* Calculate the two check characters */ - if(checksum >= 8) { checksum++; } - if(checksum >= 72) { checksum++; } - c_left = checksum / 9; - c_right = checksum % 9; - - /* Put element widths together */ - total_widths[0] = 1; - total_widths[1] = 1; - total_widths[44] = 1; - total_widths[45] = 1; - for(i = 0; i < 8; i++) { - total_widths[i + 2] = data_widths[i][0]; - total_widths[i + 15] = data_widths[7 - i][1]; - total_widths[i + 23] = data_widths[i][3]; - total_widths[i + 36] = data_widths[7 - i][2]; - } - for(i = 0; i < 5; i++) { - total_widths[i + 10] = finder_pattern[i + (5 * c_left)]; - total_widths[i + 31] = finder_pattern[(4 - i) + (5 * c_right)]; - } - - /* Put this data into the symbol */ - if((symbol->symbology == BARCODE_RSS14) || (symbol->symbology == BARCODE_RSS14_CC)) { - writer = 0; - latch = '0'; - for(i = 0; i < 46; i++) { - for(j = 0; j < total_widths[i]; j++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer); } - writer++; - } - if(latch == '1') { - latch = '0'; - } else { - latch = '1'; - } - } - if(symbol->width < writer) { symbol->width = writer; } - if(symbol->symbology == BARCODE_RSS14_CC) { - /* separator pattern for composite symbol */ - for(i = 4; i < 92; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - set_module(symbol, separator_row, i); } - } - latch = '1'; - for(i = 16; i < 32; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - if(latch == '1') { - set_module(symbol, separator_row, i); - latch = '0'; - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } - latch = '1'; - for(i = 63; i < 78; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - if(latch == '1') { - set_module(symbol, separator_row, i); - latch = '0'; - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } - } - symbol->rows = symbol->rows + 1; - - count = 0; - check_digit = 0; - - /* Calculate check digit from Annex A and place human readable text */ - ustrcpy(symbol->text, (unsigned char*)"(01)"); - for(i = 0; i < 14; i++) { - hrt[i] = '0'; - } - for(i = 0; i < src_len; i++) { - hrt[12 - i] = source[src_len - i - 1]; - } - hrt[14] = '\0'; - - for (i = 0; i < 13; i++) { - count += ctoi(hrt[i]); - - if (!(i & 1)) { - count += 2 * (ctoi(hrt[i])); - } - } - - check_digit = 10 - (count%10); - if (check_digit == 10) { check_digit = 0; } - hrt[13] = itoc(check_digit); - - uconcat(symbol->text, (unsigned char*)hrt); - } - - if((symbol->symbology == BARCODE_RSS14STACK) || (symbol->symbology == BARCODE_RSS14STACK_CC)) { - /* top row */ - writer = 0; - latch = '0'; - for(i = 0; i < 23; i++) { - for(j = 0; j < total_widths[i]; j++) { - if(latch == '1') { - set_module(symbol, symbol->rows, writer); - } else { - unset_module(symbol, symbol->rows, writer); - } - writer++; - } - if(latch == '1') { - latch = '0'; - } else { - latch = '1'; - } - } - set_module(symbol, symbol->rows, writer); - unset_module(symbol, symbol->rows, writer + 1); - symbol->row_height[symbol->rows] = 5; - /* bottom row */ - symbol->rows = symbol->rows + 2; - set_module(symbol, symbol->rows, 0); - unset_module(symbol, symbol->rows, 1); - writer = 0; - latch = '1'; - for(i = 23; i < 46; i++) { - for(j = 0; j < total_widths[i]; j++) { - if(latch == '1') { - set_module(symbol, symbol->rows, writer + 2); - } else { - unset_module(symbol, symbol->rows, writer + 2); - } - writer++; - } - if(latch == '1') { - latch = '0'; - } else { - latch = '1'; - } - } - symbol->row_height[symbol->rows] = 7; - /* separator pattern */ - for(i = 4; i < 46; i++) { - if(module_is_set(symbol, symbol->rows - 2, i) == module_is_set(symbol, symbol->rows, i)) { - if(!(module_is_set(symbol, symbol->rows - 2, i))) { - set_module(symbol, symbol->rows - 1, i); - } - } else { - if(!(module_is_set(symbol, symbol->rows - 1, i - 1))) { - set_module(symbol, symbol->rows - 1, i); - } - } - } - symbol->row_height[symbol->rows - 1] = 1; - if(symbol->symbology == BARCODE_RSS14STACK_CC) { - /* separator pattern for composite symbol */ - for(i = 4; i < 46; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - set_module(symbol, separator_row, i); - } - } - latch = '1'; - for(i = 16; i < 32; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - if(latch == '1') { - set_module(symbol, separator_row, i); - latch = '0'; - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } - } - symbol->rows = symbol->rows + 1; - if(symbol->width < 50) { symbol->width = 50; } - } - - if((symbol->symbology == BARCODE_RSS14STACK_OMNI) || (symbol->symbology == BARCODE_RSS14_OMNI_CC)) { - /* top row */ - writer = 0; - latch = '0'; - for(i = 0; i < 23; i++) { - for(j = 0; j < total_widths[i]; j++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } - writer++; - } - latch = (latch == '1' ? '0' : '1'); - } - set_module(symbol, symbol->rows, writer); - unset_module(symbol, symbol->rows, writer + 1); - /* bottom row */ - symbol->rows = symbol->rows + 4; - set_module(symbol, symbol->rows, 0); - unset_module(symbol, symbol->rows, 1); - writer = 0; - latch = '1'; - for(i = 23; i < 46; i++) { - for(j = 0; j < total_widths[i]; j++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer + 2); } else { unset_module(symbol, symbol->rows, writer + 2); } - writer++; - } - if(latch == '1') { - latch = '0'; - } else { - latch = '1'; - } - } - /* middle separator */ - for(i = 5; i < 46; i += 2) { - set_module(symbol, symbol->rows - 2, i); - } - symbol->row_height[symbol->rows - 2] = 1; - /* top separator */ - for(i = 4; i < 46; i++) { - if(!(module_is_set(symbol, symbol->rows - 4, i))) { - set_module(symbol, symbol->rows - 3, i); - } - } - latch = '1'; - for(i = 17; i < 33; i++) { - if(!(module_is_set(symbol, symbol->rows - 4, i))) { - if(latch == '1') { - set_module(symbol, symbol->rows - 3, i); - latch = '0'; - } else { - unset_module(symbol, symbol->rows - 3, i); - latch = '1'; - } - } else { - unset_module(symbol, symbol->rows - 3, i); - latch = '1'; - } - } - symbol->row_height[symbol->rows - 3] = 1; - /* bottom separator */ - for(i = 4; i < 46; i++) { - if(!(module_is_set(symbol, symbol->rows, i))) { - set_module(symbol, symbol->rows - 1, i); - } - } - latch = '1'; - for(i = 16; i < 32; i++) { - if(!(module_is_set(symbol, symbol->rows, i))) { - if(latch == '1') { - set_module(symbol, symbol->rows - 1, i); - latch = '0'; - } else { - unset_module(symbol, symbol->rows - 1, i); - latch = '1'; - } - } else { - unset_module(symbol, symbol->rows - 1, i); - latch = '1'; - } - } - symbol->row_height[symbol->rows - 1] = 1; - if(symbol->width < 50) { symbol->width = 50; } - if(symbol->symbology == BARCODE_RSS14_OMNI_CC) { - /* separator pattern for composite symbol */ - for(i = 4; i < 46; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - set_module(symbol, separator_row, i); - } - } - latch = '1'; - for(i = 16; i < 32; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - if(latch == '1') { - set_module(symbol, separator_row, i); - latch = '0'; - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } else { - unset_module(symbol, separator_row, i); - latch = '1'; - } - } - } - symbol->rows = symbol->rows + 1; - } - - - return error_number; -} - -int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) -{ /* GS1 DataBar Limited */ - int error_number = 0, i, mask; - short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112]; - int left_group, right_group, left_odd, left_even, right_odd, right_even; - int left_character, right_character, left_widths[14], right_widths[14]; - int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count; - char latch, hrt[15], temp[32]; - int separator_row; - - separator_row = 0; - - if(src_len > 13) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - error_number = is_sane(NEON, source, src_len); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - if(src_len == 13) { - if((source[0] != '0') && (source[0] != '1')) { - strcpy(symbol->errtxt, "Input out of range"); - return ERROR_INVALID_DATA1; - } - } - - /* make some room for a separator row for composite symbols */ - if(symbol->symbology == BARCODE_RSS_LTD_CC) { - separator_row = symbol->rows; - symbol->row_height[separator_row] = 1; - symbol->rows += 1; - } - - for(i = 0; i < 112; i++) { - accum[i] = 0; - x_reg[i] = 0; - y_reg[i] = 0; - } - - binary_load(accum, (char*)source, src_len); - if(symbol->option_1 == 2) { - /* Add symbol linkage flag */ - strcpy(temp, "2015133531096"); - binary_load(y_reg, temp, strlen(temp)); - binary_add(accum, y_reg); - for(i = 0; i < 112; i++) { - y_reg[i] = 0; - } - } - - /* Calculate left and right pair values */ - strcpy(temp, "2013571"); - binary_load(x_reg, temp, strlen(temp)); - - for(i = 0; i < 24; i++) { - shiftup(x_reg); - } - - for(i = 24; i >= 0; i--) { - y_reg[i] = islarger(accum, x_reg); - if(y_reg[i] == 1) { - binary_subtract(accum, x_reg); - } - shiftdown(x_reg); - } - - for(i = 0; i < 112; i++) { - left_reg[i] = y_reg[i]; - right_reg[i] = accum[i]; - } - - left_group = 0; - strcpy(temp, "183063"); - binary_load(accum, temp, strlen(temp)); - if(islarger(left_reg, accum)) { left_group = 1; } - strcpy(temp, "820063"); - binary_load(accum, temp, strlen(temp)); - if(islarger(left_reg, accum)) { left_group = 2; } - strcpy(temp, "1000775"); - binary_load(accum, temp, strlen(temp)); - if(islarger(left_reg, accum)) { left_group = 3; } - strcpy(temp, "1491020"); - binary_load(accum, temp, strlen(temp)); - if(islarger(left_reg, accum)) { left_group = 4; } - strcpy(temp, "1979844"); - binary_load(accum, temp, strlen(temp)); - if(islarger(left_reg, accum)) { left_group = 5; } - strcpy(temp, "1996938"); - binary_load(accum, temp, strlen(temp)); - if(islarger(left_reg, accum)) { left_group = 6; } - right_group = 0; - strcpy(temp, "183063"); - binary_load(accum, temp, strlen(temp)); - if(islarger(right_reg, accum)) { right_group = 1; } - strcpy(temp, "820063"); - binary_load(accum, temp, strlen(temp)); - if(islarger(right_reg, accum)) { right_group = 2; } - strcpy(temp, "1000775"); - binary_load(accum, temp, strlen(temp)); - if(islarger(right_reg, accum)) { right_group = 3; } - strcpy(temp, "1491020"); - binary_load(accum, temp, strlen(temp)); - if(islarger(right_reg, accum)) { right_group = 4; } - strcpy(temp, "1979844"); - binary_load(accum, temp, strlen(temp)); - if(islarger(right_reg, accum)) { right_group = 5; } - strcpy(temp, "1996938"); - binary_load(accum, temp, strlen(temp)); - if(islarger(right_reg, accum)) { right_group = 6; } - - switch(left_group) { - case 1: strcpy(temp, "183064"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(left_reg, accum); - break; - case 2: strcpy(temp, "820064"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(left_reg, accum); - break; - case 3: strcpy(temp, "1000776"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(left_reg, accum); - break; - case 4: strcpy(temp, "1491021"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(left_reg, accum); - break; - case 5: strcpy(temp, "1979845"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(left_reg, accum); - break; - case 6: strcpy(temp, "1996939"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(left_reg, accum); - break; - } - - switch(right_group) { - case 1: strcpy(temp, "183064"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(right_reg, accum); - break; - case 2: strcpy(temp, "820064"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(right_reg, accum); - break; - case 3: strcpy(temp, "1000776"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(right_reg, accum); - break; - case 4: strcpy(temp, "1491021"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(right_reg, accum); - break; - case 5: strcpy(temp, "1979845"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(right_reg, accum); - break; - case 6: strcpy(temp, "1996939"); - binary_load(accum, temp, strlen(temp)); - binary_subtract(right_reg, accum); - break; - } - - left_character = 0; - right_character = 0; - mask = 0x800000; - for(i = 23; i >= 0; i--) { - if(left_reg[i] == 1) { - left_character += mask; - } - if(right_reg[i] == 1) { - right_character += mask; - } - mask = mask >> 1; - } - - left_odd = left_character / t_even_ltd[left_group]; - left_even = left_character % t_even_ltd[left_group]; - right_odd = right_character / t_even_ltd[right_group]; - right_even = right_character % t_even_ltd[right_group]; - - getRSSwidths(left_odd, modules_odd_ltd[left_group], 7, widest_odd_ltd[left_group], 1); - left_widths[0] = widths[0]; - left_widths[2] = widths[1]; - left_widths[4] = widths[2]; - left_widths[6] = widths[3]; - left_widths[8] = widths[4]; - left_widths[10] = widths[5]; - left_widths[12] = widths[6]; - getRSSwidths(left_even, modules_even_ltd[left_group], 7, widest_even_ltd[left_group], 0); - left_widths[1] = widths[0]; - left_widths[3] = widths[1]; - left_widths[5] = widths[2]; - left_widths[7] = widths[3]; - left_widths[9] = widths[4]; - left_widths[11] = widths[5]; - left_widths[13] = widths[6]; - getRSSwidths(right_odd, modules_odd_ltd[right_group], 7, widest_odd_ltd[right_group], 1); - right_widths[0] = widths[0]; - right_widths[2] = widths[1]; - right_widths[4] = widths[2]; - right_widths[6] = widths[3]; - right_widths[8] = widths[4]; - right_widths[10] = widths[5]; - right_widths[12] = widths[6]; - getRSSwidths(right_even, modules_even_ltd[right_group], 7, widest_even_ltd[right_group], 0); - right_widths[1] = widths[0]; - right_widths[3] = widths[1]; - right_widths[5] = widths[2]; - right_widths[7] = widths[3]; - right_widths[9] = widths[4]; - right_widths[11] = widths[5]; - right_widths[13] = widths[6]; - - checksum = 0; - /* Calculate the checksum */ - for(i = 0; i < 14; i++) { - checksum += checksum_weight_ltd[i] * left_widths[i]; - checksum += checksum_weight_ltd[i + 14] * right_widths[i]; - } - checksum %= 89; - - for(i = 0; i < 14; i++) { - check_elements[i] = finder_pattern_ltd[i + (checksum * 14)]; - } - - total_widths[0] = 1; - total_widths[1] = 1; - total_widths[44] = 1; - total_widths[45] = 1; - for(i = 0; i < 14; i++) { - total_widths[i + 2] = left_widths[i]; - total_widths[i + 16] = check_elements[i]; - total_widths[i + 30] = right_widths[i]; - } - - writer = 0; - latch = '0'; - for(i = 0; i < 46; i++) { - for(j = 0; j < total_widths[i]; j++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } - writer++; - } - latch = (latch == '1' ? '0' : '1'); - } - if(symbol->width < writer) { symbol->width = writer; } - symbol->rows = symbol->rows + 1; - - /* add separator pattern if composite symbol */ - if(symbol->symbology == BARCODE_RSS_LTD_CC) { - for(i = 4; i < 70; i++) { - if(!(module_is_set(symbol, separator_row + 1, i))) { - set_module(symbol, separator_row, i); - } - } - } - - /* Calculate check digit from Annex A and place human readable text */ - - check_digit = 0; - count = 0; - - ustrcpy(symbol->text, (unsigned char*)"(01)"); - for(i = 0; i < 14; i++) { - hrt[i] = '0'; - } - for(i = 0; i < src_len; i++) { - hrt[12 - i] = source[src_len - i - 1]; - } - - for (i = 0; i < 13; i++) { - count += ctoi(hrt[i]); - - if (!(i & 1)) { - count += 2 * (ctoi(hrt[i])); - } - } - - check_digit = 10 - (count%10); - if (check_digit == 10) { check_digit = 0; } - - hrt[13] = itoc(check_digit); - hrt[14] = '\0'; - - uconcat(symbol->text, (unsigned char*)hrt); - - return error_number; -} - -int general_rules(char field[], char type[]) -{ /* Attempts to apply encoding rules from secions 7.2.5.5.1 to 7.2.5.5.3 - of ISO/IEC 24724:2006 */ - int block[2][200], block_count, i, j, k; - char current, next, last; - - block_count = 0; - - block[0][block_count] = 1; - block[1][block_count] = type[0]; - - for(i = 1; i < strlen(type); i++) { - current = type[i]; - last = type[i - 1]; - - if(current == last) { - block[0][block_count] = block[0][block_count] + 1; - } else { - block_count++; - block[0][block_count] = 1; - block[1][block_count] = type[i]; - } - } - - block_count++; - - for(i = 0; i < block_count; i++) { - } - - for(i = 0; i < block_count; i++) { - current = block[1][i]; - next = (block[1][i + 1] & 0xFF); - - if((current == ISOIEC) && (i != (block_count - 1))) { - if((next == ANY_ENC) && (block[0][i + 1] >= 4)) { - block[1][i + 1] = NUMERIC; - } - if((next == ANY_ENC) && (block[0][i + 1] < 4)) { - block[1][i + 1] = ISOIEC; - } - if((next == ALPHA_OR_ISO) && (block[0][i + 1] >= 5)) { - block[1][i + 1] = ALPHA; - } - if((next == ALPHA_OR_ISO) && (block[0][i + 1] < 5)) { - block[1][i + 1] = ISOIEC; - } - } - - if(current == ALPHA_OR_ISO) { - block[1][i] = ALPHA; - } - - if((current == ALPHA) && (i != (block_count - 1))) { - if((next == ANY_ENC) && (block[0][i + 1] >= 6)) { - block[1][i + 1] = NUMERIC; - } - if((next == ANY_ENC) && (block[0][i + 1] < 6)) { - if((i == block_count - 2) && (block[0][i + 1] >= 4)) { - block[1][i + 1] = NUMERIC; - } else { - block[1][i + 1] = ALPHA; - } - } - } - - if(current == ANY_ENC) { - block[1][i] = NUMERIC; - } - } - - if(block_count > 1) { - i = 1; - while(i < block_count) { - if(block[1][i - 1] == block[1][i]) { - /* bring together */ - block[0][i - 1] = block[0][i - 1] + block[0][i]; - j = i + 1; - - /* decreace the list */ - while(j < block_count) { - block[0][j - 1] = block[0][j]; - block[1][j - 1] = block[1][j]; - j++; - } - block_count--; - i--; - } - i++; - } - } - - for(i = 0; i < block_count - 1; i++) { - if((block[1][i] == NUMERIC) && (block[0][i] & 1)) { - /* Odd size numeric block */ - block[0][i] = block[0][i] - 1; - block[0][i + 1] = block[0][i + 1] + 1; - } - } - - j = 0; - for(i = 0; i < block_count; i++) { - for(k = 0; k < block[0][i]; k++) { - type[j] = block[1][i]; - j++; - } - } - - if((block[1][block_count - 1] == NUMERIC) && (block[0][block_count - 1] & 1)) { - /* If the last block is numeric and an odd size, further - processing needs to be done outside this procedure */ - return 1; - } else { - return 0; - } -} - -int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) -{ /* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */ - int encoding_method, i, mask, j, read_posn, latch, debug = 0, last_mode = ISOIEC; -#ifndef _MSC_VER - char general_field[strlen(source)], general_field_type[strlen(source)]; -#else - char* general_field = (char*)_alloca(strlen(source)); - char* general_field_type = (char*)_alloca(strlen(source)); -#endif - int remainder, d1, d2, value; - char padstring[40]; - - read_posn=0; - value=0; - - /* Decide whether a compressed data field is required and if so what - method to use - method 2 = no compressed data field */ - - if((strlen(source) >= 16) && ((source[0] == '0') && (source[1] == '1'))) { - /* (01) and other AIs */ - encoding_method = 1; - if(debug) printf("Choosing Method 1\n"); - } else { - /* any AIs */ - encoding_method = 2; - if(debug) printf("Choosing Mehod 2\n"); - } - - if(((strlen(source) >= 20) && (encoding_method == 1)) && ((source[2] == '9') && (source[16] == '3'))) { - /* Possibly encoding method > 2 */ - if(debug) printf("Checking for other methods\n"); - - if((strlen(source) >= 26) && (source[17] == '1')) { - /* Methods 3, 7, 9, 11 and 13 */ - - if(source[18] == '0') { - /* (01) and (310x) */ - char weight_str[7]; - float weight; /* In kilos */ - - for(i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; - - if (weight_str[0] == '0') { /* Maximum weight = 99999 */ - - - encoding_method = 7; - - if((source[19] == '3') && (strlen(source) == 26)) { - /* (01) and (3103) */ - weight = atof(weight_str) / 1000.0; - - if(weight <= 32.767) { encoding_method = 3; } - } - - if(strlen(source) == 34){ - if((source[26] == '1') && (source[27] == '1')) { - /* (01), (310x) and (11) - metric weight and production date */ - encoding_method = 7; - } - - if((source[26] == '1') && (source[27] == '3')) { - /* (01), (310x) and (13) - metric weight and packaging date */ - encoding_method = 9; - } - - if((source[26] == '1') && (source[27] == '5')) { - /* (01), (310x) and (15) - metric weight and "best before" date */ - encoding_method = 11; - } - - if((source[26] == '1') && (source[27] == '7')) { - /* (01), (310x) and (17) - metric weight and expiration date */ - encoding_method = 13; - } - } - } - } - if(debug) printf("Now using method %d\n", encoding_method); - } - - if((strlen(source) >= 26) && (source[17] == '2')) { - /* Methods 4, 8, 10, 12 and 14 */ - - if(source[18] == '0') { - /* (01) and (320x) */ - char weight_str[7]; - float weight; /* In pounds */ - - for(i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; - - if (weight_str[0] == '0') { /* Maximum weight = 99999 */ - - encoding_method = 8; - - if(((source[19] == '2') || (source[19] == '3')) && (strlen(source) == 26)) { - /* (01) and (3202)/(3203) */ - - if(source[19] == '3') { - weight = atof(weight_str) / 1000.0; - if(weight <= 22.767) { - encoding_method = 4; - } - } else { - weight = atof(weight_str) / 100.0; - if(weight <= 99.99) { - encoding_method = 4; - } - } - - } - - if(strlen(source) == 34){ - if((source[26] == '1') && (source[27] == '1')) { - /* (01), (320x) and (11) - English weight and production date */ - encoding_method = 8; - } - - if((source[26] == '1') && (source[27] == '3')) { - /* (01), (320x) and (13) - English weight and packaging date */ - encoding_method = 10; - } - - if((source[26] == '1') && (source[27] == '5')) { - /* (01), (320x) and (15) - English weight and "best before" date */ - encoding_method = 12; - } - - if((source[26] == '1') && (source[27] == '7')) { - /* (01), (320x) and (17) - English weight and expiration date */ - encoding_method = 14; - } - } - } - } - if(debug) printf("Now using method %d\n", encoding_method); - - } - - if(source[17] == '9') { - /* Methods 5 and 6 */ - if((source[18] == '2') && ((source[19] >= '0') && (source[19] <= '3'))) { - /* (01) and (392x) */ - encoding_method = 5; - } - if((source[18] == '3') && ((source[19] >= '0') && (source[19] <= '3'))) { - /* (01) and (393x) */ - encoding_method = 6; - } - if(debug) printf("Now using method %d\n", encoding_method); - } - } - - switch(encoding_method) { /* Encoding method - Table 10 */ - case 1: concat(binary_string, "1XX"); read_posn = 16; break; - case 2: concat(binary_string, "00XX"); read_posn = 0; break; - case 3: concat(binary_string, "0100"); read_posn = strlen(source); break; - case 4: concat(binary_string, "0101"); read_posn = strlen(source); break; - case 5: concat(binary_string, "01100XX"); read_posn = 20; break; - case 6: concat(binary_string, "01101XX"); read_posn = 23; break; - case 7: concat(binary_string, "0111000"); read_posn = strlen(source); break; - case 8: concat(binary_string, "0111001"); read_posn = strlen(source); break; - case 9: concat(binary_string, "0111010"); read_posn = strlen(source); break; - case 10: concat(binary_string, "0111011"); read_posn = strlen(source); break; - case 11: concat(binary_string, "0111100"); read_posn = strlen(source); break; - case 12: concat(binary_string, "0111101"); read_posn = strlen(source); break; - case 13: concat(binary_string, "0111110"); read_posn = strlen(source); break; - case 14: concat(binary_string, "0111111"); read_posn = strlen(source); break; - } - if(debug) printf("Setting binary = %s\n", binary_string); - - /* Variable length symbol bit field is just given a place holder (XX) - for the time being */ - - /* Verify that the data to be placed in the compressed data field is all - numeric data before carrying out compression */ - for(i = 0; i < read_posn; i++) { - if((source[i] < '0') || (source[i] > '9')) { - if((source[i] != '[') && (source[i] != ']')) { - /* Something is wrong */ - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - } - } - - /* Now encode the compressed data field */ - - if(debug) printf("Proceeding to encode data\n"); - if(encoding_method == 1) { - /* Encoding method field "1" - general item identification data */ - char group[4]; - int group_val; - - group[0] = source[2]; - group[1] = '\0'; - group_val = atoi(group); - - mask = 0x08; - for(j = 0; j < 4; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - - for(i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - group_val = atoi(group); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - - } - - - if(encoding_method == 3) { - /* Encoding method field "0100" - variable weight item - (0,001 kilogram icrements) */ - char group[4]; - int group_val; - char weight_str[7]; - - for(i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - group_val = atoi(group); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - for(i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; - group_val = atoi(weight_str); - - mask = 0x4000; - for(j = 0; j < 15; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - - - } - - if(encoding_method == 4) { - /* Encoding method field "0101" - variable weight item (0,01 or - 0,001 pound increment) */ - char group[4]; - int group_val; - char weight_str[7]; - - for(i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - group_val = atoi(group); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - for(i = 0; i < 6; i++) { - weight_str[i] = source[20 + i]; - } - weight_str[6] = '\0'; - group_val = atoi(weight_str); - - if(source[19] == '3') { - group_val = group_val + 10000; - } - - mask = 0x4000; - for(j = 0; j < 15; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - - } - - - if((encoding_method >= 7) && (encoding_method <= 14)) { - /* Encoding method fields "0111000" through "0111111" - variable - weight item plus date */ - char group[4]; - int group_val; - char weight_str[8]; - char date_str[4]; - - for(i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - group_val = atoi(group); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - weight_str[0] = source[19]; - - for(i = 0; i < 5; i++) { - weight_str[i + 1] = source[21 + i]; - } - weight_str[6] = '\0'; - group_val = atoi(weight_str); - - mask = 0x80000; - for(j = 0; j < 20; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - - if(strlen(source) == 34) { - /* Date information is included */ - date_str[0] = source[28]; - date_str[1] = source[29]; - date_str[2] = '\0'; - group_val = atoi(date_str) * 384; - - date_str[0] = source[30]; - date_str[1] = source[31]; - group_val += (atoi(date_str) - 1) * 32; - - date_str[0] = source[32]; - date_str[1] = source[33]; - group_val += atoi(date_str); - } else { - group_val = 38400; - } - - mask = 0x8000; - for(j = 0; j < 16; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - - } - - if(encoding_method == 5) { - /* Encoding method field "01100" - variable measure item and price */ - char group[4]; - int group_val; - - for(i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - group_val = atoi(group); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - switch(source[19]) { - case '0': concat(binary_string, "00"); break; - case '1': concat(binary_string, "01"); break; - case '2': concat(binary_string, "10"); break; - case '3': concat(binary_string, "11"); break; - } - } - - if(encoding_method == 6) { - /* Encoding method "01101" - variable measure item and price with ISO 4217 - Currency Code */ - - char group[4]; - int group_val; - char currency_str[5]; - - for(i = 1; i < 5; i++) { - group[0] = source[(i * 3)]; - group[1] = source[(i * 3) + 1]; - group[2] = source[(i * 3) + 2]; - group[3] = '\0'; - group_val = atoi(group); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - switch(source[19]) { - case '0': concat(binary_string, "00"); break; - case '1': concat(binary_string, "01"); break; - case '2': concat(binary_string, "10"); break; - case '3': concat(binary_string, "11"); break; - } - - for(i = 0; i < 3; i++) { - currency_str[i] = source[20 + i]; - } - currency_str[3] = '\0'; - group_val = atoi(currency_str); - - mask = 0x200; - for(j = 0; j < 10; j++) { - concat(binary_string, (group_val & mask) ? "1" : "0"); - mask = mask >> 1; - } - - - } - - /* The compressed data field has been processed if appropriate - the - rest of the data (if any) goes into a general-purpose data compaction field */ - - j = 0; - for(i = read_posn; i < strlen(source); i++) { - general_field[j] = source[i]; - j++; - } - general_field[j] = '\0'; - if(debug) printf("General field data = %s\n", general_field); - - latch = 0; - for(i = 0; i < strlen(general_field); i++) { - /* Table 13 - ISO/IEC 646 encodation */ - if((general_field[i] < ' ') || (general_field[i] > 'z')) { - general_field_type[i] = INVALID_CHAR; latch = 1; - } else { - general_field_type[i] = ISOIEC; - } - - if(general_field[i] == '#') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == '$') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == '@') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == 92) { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == '^') { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - if(general_field[i] == 96) { - general_field_type[i] = INVALID_CHAR; latch = 1; - } - - /* Table 12 - Alphanumeric encodation */ - if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '*') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == ',') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '-') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '.') { - general_field_type[i] = ALPHA_OR_ISO; - } - if(general_field[i] == '/') { - general_field_type[i] = ALPHA_OR_ISO; - } - - /* Numeric encodation */ - if((general_field[i] >= '0') && (general_field[i] <= '9')) { - general_field_type[i] = ANY_ENC; - } - if(general_field[i] == '[') { - /* FNC1 can be encoded in any system */ - general_field_type[i] = ANY_ENC; - } - - } - - general_field_type[strlen(general_field)] = '\0'; - if(debug) printf("General field type: %s\n", general_field_type); - - if(latch == 1) { - /* Invalid characters in input data */ - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - - for(i = 0; i < strlen(general_field); i++) { - if((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) { - general_field_type[i + 1] = ISOIEC; - } - } - - for(i = 0; i < strlen(general_field); i++) { - if((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) { - general_field_type[i + 1] = ALPHA_OR_ISO; - } - } - - latch = general_rules(general_field, general_field_type); - if(debug) printf("General field type: %s\n", general_field_type); - - last_mode = NUMERIC; - - /* Set initial mode if not NUMERIC */ - if(general_field_type[0] == ALPHA) { - concat(binary_string, "0000"); /* Alphanumeric latch */ - last_mode = ALPHA; - } - if(general_field_type[0] == ISOIEC) { - concat(binary_string, "0000"); /* Alphanumeric latch */ - concat(binary_string, "00100"); /* ISO/IEC 646 latch */ - last_mode = ISOIEC; - } - - i = 0; - do { - if(debug) printf("Processing character %d ", i); - switch(general_field_type[i]) { - case NUMERIC: - if(debug) printf("as NUMERIC:"); - - if(last_mode != NUMERIC) { - concat(binary_string, "000"); /* Numeric latch */ - if(debug) printf("\n"); - } - - if(debug) printf(" %c%c > ", general_field[i], general_field[i + 1]); - if(general_field[i] != '[') { - d1 = ctoi(general_field[i]); - } else { - d1 = 10; - } - - if(general_field[i + 1] != '[') { - d2 = ctoi(general_field[i + 1]); - } else { - d2 = 10; - } - - value = (11 * d1) + d2 + 8; - - mask = 0x40; - for(j = 0; j < 7; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - if (debug) { - printf("%d", !!(value & mask)); - } - mask = mask >> 1; - } - - i += 2; - if(debug) printf("\n"); - last_mode = NUMERIC; - break; - - case ALPHA: - if(debug) printf("as ALPHA\n"); - if(i != 0) { - if(last_mode == NUMERIC) { - concat(binary_string, "0000"); /* Alphanumeric latch */ - } - if(last_mode == ISOIEC) { - concat(binary_string, "00100"); /* Alphanumeric latch */ - } - } - - if((general_field[i] >= '0') && (general_field[i] <= '9')) { - - value = general_field[i] - 43; - - mask = 0x10; - for(j = 0; j < 5; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - - value = general_field[i] - 33; - - mask = 0x20; - for(j = 0; j < 6; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - last_mode = ALPHA; - if(general_field[i] == '[') { concat(binary_string, "01111"); last_mode = NUMERIC; } /* FNC1/Numeric latch */ - if(general_field[i] == '*') concat(binary_string, "111010"); /* asterisk */ - if(general_field[i] == ',') concat(binary_string, "111011"); /* comma */ - if(general_field[i] == '-') concat(binary_string, "111100"); /* minus or hyphen */ - if(general_field[i] == '.') concat(binary_string, "111101"); /* period or full stop */ - if(general_field[i] == '/') concat(binary_string, "111110"); /* slash or solidus */ - - i++; - break; - - case ISOIEC: - if(debug) printf("as ISOIEC\n"); - if(i != 0) { - if(last_mode == NUMERIC) { - concat(binary_string, "0000"); /* Alphanumeric latch */ - concat(binary_string, "00100"); /* ISO/IEC 646 latch */ - } - if(last_mode == ALPHA) { - concat(binary_string, "00100"); /* ISO/IEC 646 latch */ - } - } - - if((general_field[i] >= '0') && (general_field[i] <= '9')) { - - value = general_field[i] - 43; - - mask = 0x10; - for(j = 0; j < 5; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - if((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { - - value = general_field[i] - 1; - - mask = 0x40; - for(j = 0; j < 7; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - if((general_field[i] >= 'a') && (general_field[i] <= 'z')) { - - value = general_field[i] - 7; - - mask = 0x40; - for(j = 0; j < 7; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - last_mode = ISOIEC; - if(general_field[i] == '[') { concat(binary_string, "01111"); last_mode = NUMERIC; } /* FNC1/Numeric latch */ - if(general_field[i] == '!') concat(binary_string, "11101000"); /* exclamation mark */ - if(general_field[i] == 34) concat(binary_string, "11101001"); /* quotation mark */ - if(general_field[i] == 37) concat(binary_string, "11101010"); /* percent sign */ - if(general_field[i] == '&') concat(binary_string, "11101011"); /* ampersand */ - if(general_field[i] == 39) concat(binary_string, "11101100"); /* apostrophe */ - if(general_field[i] == '(') concat(binary_string, "11101101"); /* left parenthesis */ - if(general_field[i] == ')') concat(binary_string, "11101110"); /* right parenthesis */ - if(general_field[i] == '*') concat(binary_string, "11101111"); /* asterisk */ - if(general_field[i] == '+') concat(binary_string, "11110000"); /* plus sign */ - if(general_field[i] == ',') concat(binary_string, "11110001"); /* comma */ - if(general_field[i] == '-') concat(binary_string, "11110010"); /* minus or hyphen */ - if(general_field[i] == '.') concat(binary_string, "11110011"); /* period or full stop */ - if(general_field[i] == '/') concat(binary_string, "11110100"); /* slash or solidus */ - if(general_field[i] == ':') concat(binary_string, "11110101"); /* colon */ - if(general_field[i] == ';') concat(binary_string, "11110110"); /* semicolon */ - if(general_field[i] == '<') concat(binary_string, "11110111"); /* less-than sign */ - if(general_field[i] == '=') concat(binary_string, "11111000"); /* equals sign */ - if(general_field[i] == '>') concat(binary_string, "11111001"); /* greater-than sign */ - if(general_field[i] == '?') concat(binary_string, "11111010"); /* question mark */ - if(general_field[i] == '_') concat(binary_string, "11111011"); /* underline or low line */ - if(general_field[i] == ' ') concat(binary_string, "11111100"); /* space */ - - i++; - break; - } - } while (i + latch < strlen(general_field)); - if(debug) printf("Resultant binary = %s\n", binary_string); - if(debug) printf("\tLength: %d\n", (int)strlen(binary_string)); - - remainder = 12 - (strlen(binary_string) % 12); - if(remainder == 12) { remainder = 0; } - if(strlen(binary_string) < 36) { remainder = 36 - strlen(binary_string); } - - if(latch == 1) { - /* There is still one more numeric digit to encode */ - if(debug) printf("Adding extra (odd) numeric digit\n"); - - if(last_mode == NUMERIC) { - if((remainder >= 4) && (remainder <= 6)) { - value = ctoi(general_field[i]); - value++; - - mask = 0x08; - for(j = 0; j < 4; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } else { - d1 = ctoi(general_field[i]); - d2 = 10; - - value = (11 * d1) + d2 + 8; - - mask = 0x40; - for(j = 0; j < 7; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - } else { - value = general_field[i] - 43; - - mask = 0x10; - for(j = 0; j < 5; j++) { - concat(binary_string, (value & mask) ? "1" : "0"); - mask = mask >> 1; - } - } - - remainder = 12 - (strlen(binary_string) % 12); - if(remainder == 12) { remainder = 0; } - if(strlen(binary_string) < 36) { remainder = 36 - strlen(binary_string); } - if(debug) printf("Resultant binary = %s\n", binary_string); - if(debug) printf("\tLength: %d\n", (int)strlen(binary_string)); - } - - if(strlen(binary_string) > 252) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - - /* Now add padding to binary string (7.2.5.5.4) */ - i = remainder; - if((strlen(general_field) != 0) && (last_mode == NUMERIC)) { - strcpy(padstring, "0000"); - i -= 4; - } else { - strcpy(padstring, ""); - } - for(;i > 0;i -= 5) { - concat(padstring, "00100"); - } - - padstring[remainder] = '\0'; - concat(binary_string, padstring); - - /* Patch variable length symbol bit field */ - d1 = ((strlen(binary_string) / 12) + 1) & 1; - if(strlen(binary_string) <= 156) { d2 = 0; } else { d2 = 1; } - - if(encoding_method == 1) { - binary_string[2] = d1 ? '1' : '0'; - binary_string[3] = d2 ? '1' : '0'; - } - if(encoding_method == 2) { - binary_string[3] = d1 ? '1' : '0'; - binary_string[4] = d2 ? '1' : '0'; - } - if((encoding_method == 5) || (encoding_method == 6)) { - binary_string[6] = d1 ? '1' : '0'; - binary_string[7] = d2 ? '1' : '0'; - } - if(debug) printf("Resultant binary = %s\n", binary_string); - if(debug) printf("\tLength: %d\n", (int)strlen(binary_string)); - return 0; -} - -int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) -{ /* GS1 DataBar Expanded */ - int i, j, k, l, data_chars, vs[21], group[21], v_odd[21], v_even[21]; - char substring[21][14], latch; - int char_widths[21][8], checksum, check_widths[8], c_group; - int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer; - int row, elements_in_sub, special_case_row, left_to_right; - int codeblocks, sub_elements[235], stack_rows, current_row, current_block; - int separator_row; -#ifndef _MSC_VER - char reduced[src_len], binary_string[7 * src_len]; -#else - char* reduced = (char*)_alloca(src_len); - char* binary_string = (char*)_alloca(7 * src_len); -#endif - - separator_row = 0; - reader=0; - - if(symbol->input_mode != GS1_MODE) { - /* GS1 data has not been verified yet */ - i = gs1_verify(symbol, source, src_len, reduced); - if(i != 0) { return i; } - } - - if((symbol->symbology == BARCODE_RSS_EXP_CC) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) { - /* make space for a composite separator pattern */ - separator_row = symbol->rows; - symbol->row_height[separator_row] = 1; - symbol->rows += 1; - } - - strcpy(binary_string, ""); - - if(symbol->option_1 == 2) { - concat(binary_string, "1"); - } else { - concat(binary_string, "0"); - } - - i = rss_binary_string(symbol, reduced, binary_string); - if(i != 0) { - return i; - } - - data_chars = strlen(binary_string) / 12; - - for(i = 0; i < data_chars; i++) { - for(j = 0; j < 12; j++) { - substring[i][j] = binary_string[(i * 12) + j]; - } - substring[i][12] = '\0'; - } - - for(i = 0; i < data_chars; i++) { - vs[i] = 0; - if(substring[i][0] == '1') { vs[i] += 2048; } - if(substring[i][1] == '1') { vs[i] += 1024; } - if(substring[i][2] == '1') { vs[i] += 512; } - if(substring[i][3] == '1') { vs[i] += 256; } - if(substring[i][4] == '1') { vs[i] += 128; } - if(substring[i][5] == '1') { vs[i] += 64; } - if(substring[i][6] == '1') { vs[i] += 32; } - if(substring[i][7] == '1') { vs[i] += 16; } - if(substring[i][8] == '1') { vs[i] += 8; } - if(substring[i][9] == '1') { vs[i] += 4; } - if(substring[i][10] == '1') { vs[i] += 2; } - if(substring[i][11] == '1') { vs[i] += 1; } - } - - for(i = 0; i < data_chars; i++) { - if(vs[i] <= 347) { group[i] = 1; } - if((vs[i] >= 348) && (vs[i] <= 1387)) { group[i] = 2; } - if((vs[i] >= 1388) && (vs[i] <= 2947)) { group[i] = 3; } - if((vs[i] >= 2948) && (vs[i] <= 3987)) { group[i] = 4; } - if(vs[i] >= 3988) { group[i] = 5; } - v_odd[i] = (vs[i] - g_sum_exp[group[i] - 1]) / t_even_exp[group[i] - 1]; - v_even[i] = (vs[i] - g_sum_exp[group[i] - 1]) % t_even_exp[group[i] - 1]; - - getRSSwidths(v_odd[i], modules_odd_exp[group[i] - 1], 4, widest_odd_exp[group[i] - 1], 0); - char_widths[i][0] = widths[0]; - char_widths[i][2] = widths[1]; - char_widths[i][4] = widths[2]; - char_widths[i][6] = widths[3]; - getRSSwidths(v_even[i], modules_even_exp[group[i] - 1], 4, widest_even_exp[group[i] - 1], 1); - char_widths[i][1] = widths[0]; - char_widths[i][3] = widths[1]; - char_widths[i][5] = widths[2]; - char_widths[i][7] = widths[3]; - } - - /* 7.2.6 Check character */ - /* The checksum value is equal to the mod 211 residue of the weighted sum of the widths of the - elements in the data characters. */ - checksum = 0; - for(i = 0; i < data_chars; i++) { - row = weight_rows[(((data_chars - 2) / 2) * 21) + i]; - for(j = 0; j < 8; j++) { - checksum += (char_widths[i][j] * checksum_weight_exp[(row * 8) + j]); - - } - } - - check_char = (211 * ((data_chars + 1) - 4)) + (checksum % 211); - - if(check_char <= 347) { c_group = 1; } - if((check_char >= 348) && (check_char <= 1387)) { c_group = 2; } - if((check_char >= 1388) && (check_char <= 2947)) { c_group = 3; } - if((check_char >= 2948) && (check_char <= 3987)) { c_group = 4; } - if(check_char >= 3988) { c_group = 5; } - - c_odd = (check_char - g_sum_exp[c_group - 1]) / t_even_exp[c_group - 1]; - c_even = (check_char - g_sum_exp[c_group - 1]) % t_even_exp[c_group - 1]; - - getRSSwidths(c_odd, modules_odd_exp[c_group - 1], 4, widest_odd_exp[c_group - 1], 0); - check_widths[0] = widths[0]; - check_widths[2] = widths[1]; - check_widths[4] = widths[2]; - check_widths[6] = widths[3]; - getRSSwidths(c_even, modules_even_exp[c_group - 1], 4, widest_even_exp[c_group - 1], 1); - check_widths[1] = widths[0]; - check_widths[3] = widths[1]; - check_widths[5] = widths[2]; - check_widths[7] = widths[3]; - - /* Initialise element array */ - pattern_width = ((((data_chars + 1) / 2) + ((data_chars + 1) & 1)) * 5) + ((data_chars + 1) * 8) + 4; - for(i = 0; i < pattern_width; i++) { - elements[i] = 0; - } - - elements[0] = 1; - elements[1] = 1; - elements[pattern_width - 2] = 1; - elements[pattern_width - 1] = 1; - - /* Put finder patterns in element array */ - for(i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) & 1)); i++) { - k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 1) * 11) + i; - for(j = 0; j < 5; j++) { - elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j]; - } - } - - /* Put check character in element array */ - for(i = 0; i < 8; i++) { - elements[i + 2] = check_widths[i]; - } - - /* Put forward reading data characters in element array */ - for(i = 1; i < data_chars; i += 2) { - for(j = 0; j < 8; j++) { - elements[(((i - 1) / 2) * 21) + 23 + j] = char_widths[i][j]; - } - } - - /* Put reversed data characters in element array */ - for(i = 0; i < data_chars; i += 2) { - for(j = 0; j < 8; j++) { - elements[((i / 2) * 21) + 15 + j] = char_widths[i][7 - j]; - } - } - - if((symbol->symbology == BARCODE_RSS_EXP) || (symbol->symbology == BARCODE_RSS_EXP_CC)) { - /* Copy elements into symbol */ - writer = 0; - latch = '0'; - for(i = 0; i < pattern_width; i++) { - for(j = 0; j < elements[i]; j++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } - writer++; - } - if(latch == '1') { - latch = '0'; - } else { - latch = '1'; - } - } - if(symbol->width < writer) { symbol->width = writer; } - symbol->rows = symbol->rows + 1; - if(symbol->symbology == BARCODE_RSS_EXP_CC) { - for(j = 4; j < (symbol->width - 4); j++) { - if(module_is_set(symbol, separator_row + 1, j)) { - unset_module(symbol, separator_row, j); - } else { - set_module(symbol, separator_row, j); - } - } - /* finder bar adjustment */ - for(j = 0; j < (writer / 49); j++) { - k = (49 * j) + 18; - for(i = 0; i < 15; i++) { - if((!(module_is_set(symbol, separator_row + 1, i + k - 1))) && - (!(module_is_set(symbol, separator_row + 1, i + k))) && - module_is_set(symbol, separator_row, i + k - 1)) { - unset_module(symbol, separator_row, i + k); - } - } - } - } - - /* Add human readable text */ - for(i = 0; i <= src_len; i++) { - if((source[i] != '[') && (source[i] != ']')) { - symbol->text[i] = source[i]; - } else { - if(source[i] == '[') { - symbol->text[i] = '('; - } - if(source[i] == ']') { - symbol->text[i] = ')'; - } - } - } - - } else { - /* RSS Expanded Stacked */ - - codeblocks = (data_chars + 1) / 2; - - if((symbol->option_2 < 1) || (symbol->option_2 > 10)) { - symbol->option_2 = 2; - } - if((symbol->option_1 == 2) && (symbol->option_2 == 1)) { - /* "There shall be a minimum of four symbol characters in the - first row of an RSS Expanded Stacked symbol when it is the linear - component of an EAN.UCC Composite symbol." */ - symbol->option_2 = 2; - } - - stack_rows = codeblocks / symbol->option_2; - if(codeblocks % symbol->option_2 > 0) { - stack_rows++; - } - - current_block = 0; - for(current_row = 1; current_row <= stack_rows; current_row++) { - for(i = 0; i < 235; i++) { - sub_elements[i] = 0; - } - special_case_row = 0; - - /* Row Start */ - sub_elements[0] = 1; - sub_elements[1] = 1; - elements_in_sub = 2; - - /* Row Data */ - reader = 0; - do { - if(((symbol->option_2 & 1) || (current_row & 1)) || - ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) && - (((current_row * symbol->option_2) - codeblocks) & 1))) { - /* left to right */ - left_to_right = 1; - i = 2 + (current_block * 21); - for(j = 0; j < 21; j++) { - sub_elements[j + (reader * 21) + 2] = elements[i + j]; - elements_in_sub++; - } - } else { - /* right to left */ - left_to_right = 0; - if((current_row * symbol->option_2) < codeblocks) { - /* a full row */ - i = 2 + (((current_row * symbol->option_2) - reader - 1) * 21); - for(j = 0; j < 21; j++) { - sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j]; - elements_in_sub++; - } - } else { - /* a partial row */ - k = ((current_row * symbol->option_2) - codeblocks); - l = (current_row * symbol->option_2) - reader - 1; - i = 2 + ((l - k) * 21); - for(j = 0; j < 21; j++) { - sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j]; - elements_in_sub++; - } - } - } - reader++; - current_block++; - } while ((reader < symbol->option_2) && (current_block < codeblocks)); - - /* Row Stop */ - sub_elements[elements_in_sub] = 1; - sub_elements[elements_in_sub + 1] = 1; - elements_in_sub += 2; - - latch = current_row & 1 ? '0' : '1'; - - if ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) && - (((current_row * symbol->option_2) - codeblocks) & 1) ) { - /* Special case bottom row */ - special_case_row = 1; - sub_elements[0] = 2; - latch = '0'; - } - - writer = 0; - for(i = 0; i < elements_in_sub; i++) { - for(j = 0; j < sub_elements[i]; j++) { - if(latch == '1') { set_module(symbol, symbol->rows, writer); } else { unset_module(symbol, symbol->rows, writer); } - writer++; - } - if(latch == '1') { - latch = '0'; - } else { - latch = '1'; - } - } - if(symbol->width < writer) { symbol->width = writer; } - - if(current_row != 1) { - /* middle separator pattern (above current row) */ - for(j = 5; j < (49 * symbol->option_2); j += 2) { - set_module(symbol, symbol->rows - 2, j); - } - symbol->row_height[symbol->rows - 2] = 1; - /* bottom separator pattern (above current row) */ - for(j = 4; j < (writer - 4); j++) { - if(module_is_set(symbol, symbol->rows, j)) { - unset_module(symbol, symbol->rows - 1, j); - } else { - set_module(symbol, symbol->rows - 1, j); - } - } - symbol->row_height[symbol->rows - 1] = 1; - /* finder bar adjustment */ - for(j = 0; j < reader; j++) { - k = (49 * j) + (special_case_row ? 19 : 18); - if(left_to_right) { - for(i = 0; i < 15; i++) { - if((!(module_is_set(symbol, symbol->rows, i + k - 1))) && - (!(module_is_set(symbol, symbol->rows, i + k))) && - module_is_set(symbol, symbol->rows - 1, i + k - 1)) { - unset_module(symbol, symbol->rows - 1, i + k); - } - } - } else { - for(i = 14; i >= 0; i--) { - if((!(module_is_set(symbol, symbol->rows, i + k + 1))) && - (!(module_is_set(symbol, symbol->rows, i + k))) && - module_is_set(symbol, symbol->rows - 1, i + k + 1)) { - unset_module(symbol, symbol->rows - 1, i + k); - } - } - } - } - } - - if(current_row != stack_rows) { - /* top separator pattern (below current row) */ - for(j = 4; j < (writer - 4); j++) { - if(module_is_set(symbol, symbol->rows, j)) { - unset_module(symbol, symbol->rows + 1, j); - } else { - set_module(symbol, symbol->rows + 1, j); - } - } - symbol->row_height[symbol->rows + 1] = 1; - /* finder bar adjustment */ - for(j = 0; j < reader; j++) { - k = (49 * j) + 18; - if(left_to_right) { - for(i = 0; i < 15; i++) { - if((!(module_is_set(symbol, symbol->rows, i + k - 1))) && - (!(module_is_set(symbol, symbol->rows, i + k))) && - module_is_set(symbol, symbol->rows + 1, i + k - 1)) { - unset_module(symbol, symbol->rows + 1, i + k); - } - } - } else{ - for(i = 14; i >= 0; i--) { - if((!(module_is_set(symbol, symbol->rows, i + k + 1))) && - (!(module_is_set(symbol, symbol->rows, i + k))) && - module_is_set(symbol, symbol->rows + 1, i + k + 1)) { - unset_module(symbol, symbol->rows + 1, i + k); - } - } - } - } - } - - symbol->rows = symbol->rows + 4; - } - symbol->rows = symbol->rows - 3; - if(symbol->symbology == BARCODE_RSS_EXPSTACK_CC) { - for(j = 4; j < (symbol->width - 4); j++) { - if(module_is_set(symbol, separator_row + 1, j)) { - unset_module(symbol, separator_row, j); - } else { - set_module(symbol, separator_row, j); - } - } - /* finder bar adjustment */ - for(j = 0; j < reader; j++) { - k = (49 * j) + 18; - for(i = 0; i < 15; i++) { - if((!(module_is_set(symbol, separator_row + 1, i + k - 1))) && - (!(module_is_set(symbol, separator_row + 1, i + k))) && - module_is_set(symbol, separator_row, i + k - 1)) { - unset_module(symbol, separator_row, i + k); - } - } - } - } - - } - - return 0; -} diff --git a/3rdparty/zint-2.4.4/backend/rss.h b/3rdparty/zint-2.4.4/backend/rss.h deleted file mode 100644 index f1463a9..0000000 --- a/3rdparty/zint-2.4.4/backend/rss.h +++ /dev/null @@ -1,225 +0,0 @@ -/* rss.h - Data tables for Reduced Space Symbology */ - -/* - libzint - the open source barcode library - Copyright (C) 2007 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define NUMERIC 110 -#define ALPHA 97 -#define ISOIEC 105 -#define INVALID_CHAR 100 -#define ANY_ENC 120 -#define ALPHA_OR_ISO 121 - -/* RSS-14 Tables */ -static int g_sum_table[9] = { 0, 161, 961, 2015, 2715, 0, 336, 1036, 1516}; -static int t_table[9] = { 1, 10, 34, 70, 126, 4, 20, 48, 81}; -static int modules_odd[9] = { 12, 10, 8, 6, 4, 5, 7, 9, 11 }; -static int modules_even[9] = { 4, 6, 8, 10, 12, 10, 8, 6, 4 }; -static int widest_odd[9] = { 8, 6, 4, 3, 1, 2, 4, 6, 8 }; -static int widest_even[9] = { 1, 3, 5, 6, 8, 7, 5, 3, 1 }; -static int widths[8]; -static int finder_pattern[45] = { - 3, 8, 2, 1, 1, - 3, 5, 5, 1, 1, - 3, 3, 7, 1, 1, - 3, 1, 9, 1, 1, - 2, 7, 4, 1, 1, - 2, 5, 6, 1, 1, - 2, 3, 8, 1, 1, - 1, 5, 7, 1, 1, - 1, 3, 9, 1, 1 -}; -static int checksum_weight[32] = { /* Table 5 */ - 1, 3, 9, 27, 2, 6, 18, 54, - 4, 12, 36, 29, 8, 24, 72, 58, - 16, 48, 65, 37, 32, 17, 51, 74, - 64, 34, 23, 69, 49, 68, 46, 59 -}; - -/* RSS Limited Tables */ -static int t_even_ltd[7] = { 28, 728, 6454, 203, 2408, 1, 16632 }; -static int modules_odd_ltd[7] = { 17, 13, 9, 15, 11, 19, 7 }; -static int modules_even_ltd[7] = { 9, 13, 17, 11, 15, 7, 19 }; -static int widest_odd_ltd[7] = { 6, 5, 3, 5, 4, 8, 1 }; -static int widest_even_ltd[7] = { 3, 4, 6, 4, 5, 1, 8 }; -static int checksum_weight_ltd[28] = { /* Table 7 */ - 1, 3, 9, 27, 81, 65, 17, 51, 64, 14, 42, 37, 22, 66, - 20, 60, 2, 6, 18, 54, 73, 41, 34, 13, 39, 28, 84, 74 -}; -static int finder_pattern_ltd[1232] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, - 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, - 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 3, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, - 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, - 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, - 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, - 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, - 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, - 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, - 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, - 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, - 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, - 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, - 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, - 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, - 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, - 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, - 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, - 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, - 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, - 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, - 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, - 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1 -}; - -/* RSS Expanded Tables */ -static int g_sum_exp[5] = { 0, 348, 1388, 2948, 3988 }; -static int t_even_exp[5] = { 4, 20, 52, 104, 204 }; -static int modules_odd_exp[5] = { 12, 10, 8, 6, 4 }; -static int modules_even_exp[5] = { 5, 7, 9, 11, 13 }; -static int widest_odd_exp[5] = { 7, 5, 4, 3, 1 }; -static int widest_even_exp[5] = { 2, 4, 5, 6, 8 }; -static int checksum_weight_exp[184] = { /* Table 14 */ - 1, 3, 9, 27, 81, 32, 96, 77, - 20, 60, 180, 118, 143, 7, 21, 63, - 189, 145, 13, 39, 117, 140, 209, 205, - 193, 157, 49, 147, 19, 57, 171, 91, - 62, 186, 136, 197, 169, 85, 44, 132, - 185, 133, 188, 142, 4, 12, 36, 108, - 113, 128, 173, 97, 80, 29, 87, 50, - 150, 28, 84, 41, 123, 158, 52, 156, - 46, 138, 203, 187, 139, 206, 196, 166, - 76, 17, 51, 153, 37, 111, 122, 155, - 43, 129, 176, 106, 107, 110, 119, 146, - 16, 48, 144, 10, 30, 90, 59, 177, - 109, 116, 137, 200, 178, 112, 125, 164, - 70, 210, 208, 202, 184, 130, 179, 115, - 134, 191, 151, 31, 93, 68, 204, 190, - 148, 22, 66, 198, 172, 94, 71, 2, - 6, 18, 54, 162, 64, 192, 154, 40, - 120, 149, 25, 75, 14, 42, 126, 167, - 79, 26, 78, 23, 69, 207, 199, 175, - 103, 98, 83, 38, 114, 131, 182, 124, - 161, 61, 183, 127, 170, 88, 53, 159, - 55, 165, 73, 8, 24, 72, 5, 15, - 45, 135, 194, 160, 58, 174, 100, 89 -}; -static int finder_pattern_exp[60] = { /* Table 15 */ - 1, 8, 4, 1, 1, - 1, 1, 4, 8, 1, - 3, 6, 4, 1, 1, - 1, 1, 4, 6, 3, - 3, 4, 6, 1, 1, - 1, 1, 6, 4, 3, - 3, 2, 8, 1, 1, - 1, 1, 8, 2, 3, - 2, 6, 5, 1, 1, - 1, 1, 5, 6, 2, - 2, 2, 9, 1, 1, - 1, 1, 9, 2, 2 -}; -static int finder_sequence[198] = { /* Table 16 */ - 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 6, 3, 8, 0, 0, 0, 0, 0, 0, 0, - 1, 10, 3, 8, 5, 0, 0, 0, 0, 0, 0, - 1, 10, 3, 8, 7, 12, 0, 0, 0, 0, 0, - 1, 10, 3, 8, 9, 12, 11, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 10, 9, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 0, - 1, 2, 3, 4, 5, 8, 7, 10, 9, 12, 11 -}; -static int weight_rows[210] = { - 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 10, 3, 4, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 3, 4, 13, 14, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 3, 4, 13, 14, 11, 12, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 3, 4, 13, 14, 15, 16, 21, 22, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 15, 16, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 21, 22, 19, 20 -}; diff --git a/3rdparty/zint-2.4.4/backend/sjis.h b/3rdparty/zint-2.4.4/backend/sjis.h deleted file mode 100644 index a75d80b..0000000 --- a/3rdparty/zint-2.4.4/backend/sjis.h +++ /dev/null @@ -1,6875 +0,0 @@ -/* sjis.h - Unicode to Shift JIS lookup table - - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -/* Derived from : -## Shift_JIS (JIS X 0208:1997 Appendix 1) vs Unicode mapping table -## -## Date: 06 Mar 2002 06:01:22 GMT -## License: -## Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved. -## Copyright (C) 2001 I'O, All Rights Reserved. -## You can use, modify, distribute this table freely. -*/ - -unsigned long int sjis_lookup[] = { - 0x005C,0x815F, // REVERSE SOLIDUS - 0x00A2,0x8191, // CENT SIGN - 0x00A3,0x8192, // POUND SIGN - 0x00A7,0x8198, // SECTION SIGN - 0x00A8,0x814E, // DIAERESIS - 0x00AC,0x81CA, // NOT SIGN - 0x00B0,0x818B, // DEGREE SIGN - 0x00B1,0x817D, // PLUS-MINUS SIGN - 0x00B4,0x814C, // ACUTE ACCENT - 0x00B6,0x81F7, // PILCROW SIGN - 0x00D7,0x817E, // MULTIPLICATION SIGN - 0x00F7,0x8180, // DIVISION SIGN - 0x0391,0x839F, // GREEK CAPITAL LETTER ALPHA - 0x0392,0x83A0, // GREEK CAPITAL LETTER BETA - 0x0393,0x83A1, // GREEK CAPITAL LETTER GAMMA - 0x0394,0x83A2, // GREEK CAPITAL LETTER DELTA - 0x0395,0x83A3, // GREEK CAPITAL LETTER EPSILON - 0x0396,0x83A4, // GREEK CAPITAL LETTER ZETA - 0x0397,0x83A5, // GREEK CAPITAL LETTER ETA - 0x0398,0x83A6, // GREEK CAPITAL LETTER THETA - 0x0399,0x83A7, // GREEK CAPITAL LETTER IOTA - 0x039A,0x83A8, // GREEK CAPITAL LETTER KAPPA - 0x039B,0x83A9, // GREEK CAPITAL LETTER LAMDA - 0x039C,0x83AA, // GREEK CAPITAL LETTER MU - 0x039D,0x83AB, // GREEK CAPITAL LETTER NU - 0x039E,0x83AC, // GREEK CAPITAL LETTER XI - 0x039F,0x83AD, // GREEK CAPITAL LETTER OMICRON - 0x03A0,0x83AE, // GREEK CAPITAL LETTER PI - 0x03A1,0x83AF, // GREEK CAPITAL LETTER RHO - 0x03A3,0x83B0, // GREEK CAPITAL LETTER SIGMA - 0x03A4,0x83B1, // GREEK CAPITAL LETTER TAU - 0x03A5,0x83B2, // GREEK CAPITAL LETTER UPSILON - 0x03A6,0x83B3, // GREEK CAPITAL LETTER PHI - 0x03A7,0x83B4, // GREEK CAPITAL LETTER CHI - 0x03A8,0x83B5, // GREEK CAPITAL LETTER PSI - 0x03A9,0x83B6, // GREEK CAPITAL LETTER OMEGA - 0x03B1,0x83BF, // GREEK SMALL LETTER ALPHA - 0x03B2,0x83C0, // GREEK SMALL LETTER BETA - 0x03B3,0x83C1, // GREEK SMALL LETTER GAMMA - 0x03B4,0x83C2, // GREEK SMALL LETTER DELTA - 0x03B5,0x83C3, // GREEK SMALL LETTER EPSILON - 0x03B6,0x83C4, // GREEK SMALL LETTER ZETA - 0x03B7,0x83C5, // GREEK SMALL LETTER ETA - 0x03B8,0x83C6, // GREEK SMALL LETTER THETA - 0x03B9,0x83C7, // GREEK SMALL LETTER IOTA - 0x03BA,0x83C8, // GREEK SMALL LETTER KAPPA - 0x03BB,0x83C9, // GREEK SMALL LETTER LAMDA - 0x03BC,0x83CA, // GREEK SMALL LETTER MU - 0x03BD,0x83CB, // GREEK SMALL LETTER NU - 0x03BE,0x83CC, // GREEK SMALL LETTER XI - 0x03BF,0x83CD, // GREEK SMALL LETTER OMICRON - 0x03C0,0x83CE, // GREEK SMALL LETTER PI - 0x03C1,0x83CF, // GREEK SMALL LETTER RHO - 0x03C3,0x83D0, // GREEK SMALL LETTER SIGMA - 0x03C4,0x83D1, // GREEK SMALL LETTER TAU - 0x03C5,0x83D2, // GREEK SMALL LETTER UPSILON - 0x03C6,0x83D3, // GREEK SMALL LETTER PHI - 0x03C7,0x83D4, // GREEK SMALL LETTER CHI - 0x03C8,0x83D5, // GREEK SMALL LETTER PSI - 0x03C9,0x83D6, // GREEK SMALL LETTER OMEGA - 0x0401,0x8446, // CYRILLIC CAPITAL LETTER IO - 0x0410,0x8440, // CYRILLIC CAPITAL LETTER A - 0x0411,0x8441, // CYRILLIC CAPITAL LETTER BE - 0x0412,0x8442, // CYRILLIC CAPITAL LETTER VE - 0x0413,0x8443, // CYRILLIC CAPITAL LETTER GHE - 0x0414,0x8444, // CYRILLIC CAPITAL LETTER DE - 0x0415,0x8445, // CYRILLIC CAPITAL LETTER IE - 0x0416,0x8447, // CYRILLIC CAPITAL LETTER ZHE - 0x0417,0x8448, // CYRILLIC CAPITAL LETTER ZE - 0x0418,0x8449, // CYRILLIC CAPITAL LETTER I - 0x0419,0x844A, // CYRILLIC CAPITAL LETTER SHORT I - 0x041A,0x844B, // CYRILLIC CAPITAL LETTER KA - 0x041B,0x844C, // CYRILLIC CAPITAL LETTER EL - 0x041C,0x844D, // CYRILLIC CAPITAL LETTER EM - 0x041D,0x844E, // CYRILLIC CAPITAL LETTER EN - 0x041E,0x844F, // CYRILLIC CAPITAL LETTER O - 0x041F,0x8450, // CYRILLIC CAPITAL LETTER PE - 0x0420,0x8451, // CYRILLIC CAPITAL LETTER ER - 0x0421,0x8452, // CYRILLIC CAPITAL LETTER ES - 0x0422,0x8453, // CYRILLIC CAPITAL LETTER TE - 0x0423,0x8454, // CYRILLIC CAPITAL LETTER U - 0x0424,0x8455, // CYRILLIC CAPITAL LETTER EF - 0x0425,0x8456, // CYRILLIC CAPITAL LETTER HA - 0x0426,0x8457, // CYRILLIC CAPITAL LETTER TSE - 0x0427,0x8458, // CYRILLIC CAPITAL LETTER CHE - 0x0428,0x8459, // CYRILLIC CAPITAL LETTER SHA - 0x0429,0x845A, // CYRILLIC CAPITAL LETTER SHCHA - 0x042B,0x845C, // CYRILLIC CAPITAL LETTER YERU - 0x042C,0x845D, // CYRILLIC CAPITAL LETTER SOFT SIGN - 0x042D,0x845E, // CYRILLIC CAPITAL LETTER E - 0x042E,0x845F, // CYRILLIC CAPITAL LETTER YU - 0x042F,0x8460, // CYRILLIC CAPITAL LETTER YA - 0x0430,0x8470, // CYRILLIC SMALL LETTER A - 0x0431,0x8471, // CYRILLIC SMALL LETTER BE - 0x0432,0x8472, // CYRILLIC SMALL LETTER VE - 0x0433,0x8473, // CYRILLIC SMALL LETTER GHE - 0x0434,0x8474, // CYRILLIC SMALL LETTER DE - 0x0435,0x8475, // CYRILLIC SMALL LETTER IE - 0x0436,0x8477, // CYRILLIC SMALL LETTER ZHE - 0x0437,0x8478, // CYRILLIC SMALL LETTER ZE - 0x0438,0x8479, // CYRILLIC SMALL LETTER I - 0x0439,0x847A, // CYRILLIC SMALL LETTER SHORT I - 0x043A,0x847B, // CYRILLIC SMALL LETTER KA - 0x043B,0x847C, // CYRILLIC SMALL LETTER EL - 0x043C,0x847D, // CYRILLIC SMALL LETTER EM - 0x043D,0x847E, // CYRILLIC SMALL LETTER EN - 0x043E,0x8480, // CYRILLIC SMALL LETTER O - 0x043F,0x8481, // CYRILLIC SMALL LETTER PE - 0x0440,0x8482, // CYRILLIC SMALL LETTER ER - 0x0441,0x8483, // CYRILLIC SMALL LETTER ES - 0x0442,0x8484, // CYRILLIC SMALL LETTER TE - 0x0443,0x8485, // CYRILLIC SMALL LETTER U - 0x0444,0x8486, // CYRILLIC SMALL LETTER EF - 0x0445,0x8487, // CYRILLIC SMALL LETTER HA - 0x0446,0x8488, // CYRILLIC SMALL LETTER TSE - 0x0447,0x8489, // CYRILLIC SMALL LETTER CHE - 0x0448,0x848A, // CYRILLIC SMALL LETTER SHA - 0x0449,0x848B, // CYRILLIC SMALL LETTER SHCHA - 0x044A,0x848C, // CYRILLIC SMALL LETTER HARD SIGN - 0x044B,0x848D, // CYRILLIC SMALL LETTER YERU - 0x044C,0x848E, // CYRILLIC SMALL LETTER SOFT SIGN - 0x044D,0x848F, // CYRILLIC SMALL LETTER E - 0x044E,0x8490, // CYRILLIC SMALL LETTER YU - 0x044F,0x8491, // CYRILLIC SMALL LETTER YA - 0x0451,0x8476, // CYRILLIC SMALL LETTER IO - 0x2010,0x815D, // HYPHEN - 0x2014,0x815C, // EM DASH - 0x2016,0x8161, // DOUBLE VERTICAL LINE - 0x2018,0x8165, // LEFT SINGLE QUOTATION MARK - 0x2019,0x8166, // RIGHT SINGLE QUOTATION MARK - 0x201C,0x8167, // LEFT DOUBLE QUOTATION MARK - 0x201D,0x8168, // RIGHT DOUBLE QUOTATION MARK - 0x2020,0x81F5, // DAGGER - 0x2021,0x81F6, // DOUBLE DAGGER - 0x2025,0x8164, // TWO DOT LEADER - 0x2026,0x8163, // HORIZONTAL ELLIPSIS - 0x2030,0x81F1, // PER MILLE SIGN - 0x2032,0x818C, // PRIME - 0x2033,0x818D, // DOUBLE PRIME - 0x203B,0x81A6, // REFERENCE MARK - 0x2103,0x818E, // DEGREE CELSIUS - 0x212B,0x81F0, // ANGSTROM SIGN - 0x2190,0x81A9, // LEFTWARDS ARROW - 0x2191,0x81AA, // UPWARDS ARROW - 0x2192,0x81A8, // RIGHTWARDS ARROW - 0x2193,0x81AB, // DOWNWARDS ARROW - 0x21D2,0x81CB, // RIGHTWARDS DOUBLE ARROW - 0x21D4,0x81CC, // LEFT RIGHT DOUBLE ARROW - 0x2200,0x81CD, // FOR ALL - 0x2202,0x81DD, // PARTIAL DIFFERENTIAL - 0x2203,0x81CE, // THERE EXISTS - 0x2207,0x81DE, // NABLA - 0x2208,0x81B8, // ELEMENT OF - 0x220B,0x81B9, // CONTAINS AS MEMBER - 0x2212,0x817C, // MINUS SIGN - 0x221A,0x81E3, // SQUARE ROOT - 0x221D,0x81E5, // PROPORTIONAL TO - 0x221E,0x8187, // INFINITY - 0x2220,0x81DA, // ANGLE - 0x2227,0x81C8, // LOGICAL AND - 0x2228,0x81C9, // LOGICAL OR - 0x2229,0x81BF, // INTERSECTION - 0x222A,0x81BE, // UNION - 0x222B,0x81E7, // INTEGRAL - 0x222C,0x81E8, // DOUBLE INTEGRAL - 0x2234,0x8188, // THEREFORE - 0x2235,0x81E6, // BECAUSE - 0x223D,0x81E4, // REVERSED TILDE - 0x2252,0x81E0, // APPROXIMATELY EQUAL TO OR THE IMAGE OF - 0x2260,0x8182, // NOT EQUAL TO - 0x2261,0x81DF, // IDENTICAL TO - 0x2266,0x8185, // LESS-THAN OVER EQUAL TO - 0x2267,0x8186, // GREATER-THAN OVER EQUAL TO - 0x226A,0x81E1, // MUCH LESS-THAN - 0x226B,0x81E2, // MUCH GREATER-THAN - 0x2282,0x81BC, // SUBSET OF - 0x2283,0x81BD, // SUPERSET OF - 0x2286,0x81BA, // SUBSET OF OR EQUAL TO - 0x2287,0x81BB, // SUPERSET OF OR EQUAL TO - 0x22A5,0x81DB, // UP TACK - 0x2312,0x81DC, // ARC - 0x2500,0x849F, // BOX DRAWINGS LIGHT HORIZONTAL - 0x2501,0x84AA, // BOX DRAWINGS HEAVY HORIZONTAL - 0x2502,0x84A0, // BOX DRAWINGS LIGHT VERTICAL - 0x2503,0x84AB, // BOX DRAWINGS HEAVY VERTICAL - 0x250C,0x84A1, // BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x250F,0x84AC, // BOX DRAWINGS HEAVY DOWN AND RIGHT - 0x2510,0x84A2, // BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2513,0x84AD, // BOX DRAWINGS HEAVY DOWN AND LEFT - 0x2514,0x84A4, // BOX DRAWINGS LIGHT UP AND RIGHT - 0x2517,0x84AF, // BOX DRAWINGS HEAVY UP AND RIGHT - 0x2518,0x84A3, // BOX DRAWINGS LIGHT UP AND LEFT - 0x251B,0x84AE, // BOX DRAWINGS HEAVY UP AND LEFT - 0x251C,0x84A5, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x251D,0x84BA, // BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY - 0x2520,0x84B5, // BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT - 0x2523,0x84B0, // BOX DRAWINGS HEAVY VERTICAL AND RIGHT - 0x2524,0x84A7, // BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x2525,0x84BC, // BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY - 0x2528,0x84B7, // BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT - 0x252B,0x84B2, // BOX DRAWINGS HEAVY VERTICAL AND LEFT - 0x252C,0x84A6, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x252F,0x84B6, // BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY - 0x2530,0x84BB, // BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT - 0x2533,0x84B1, // BOX DRAWINGS HEAVY DOWN AND HORIZONTAL - 0x2534,0x84A8, // BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x2537,0x84B8, // BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY - 0x2538,0x84BD, // BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT - 0x253B,0x84B3, // BOX DRAWINGS HEAVY UP AND HORIZONTAL - 0x253C,0x84A9, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x253F,0x84B9, // BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY - 0x2542,0x84BE, // BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT - 0x254B,0x84B4, // BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL - 0x25A0,0x81A1, // BLACK SQUARE - 0x25A1,0x81A0, // WHITE SQUARE - 0x25B2,0x81A3, // BLACK UP-POINTING TRIANGLE - 0x25B3,0x81A2, // WHITE UP-POINTING TRIANGLE - 0x25BC,0x81A5, // BLACK DOWN-POINTING TRIANGLE - 0x25BD,0x81A4, // WHITE DOWN-POINTING TRIANGLE - 0x25C6,0x819F, // BLACK DIAMOND - 0x25C7,0x819E, // WHITE DIAMOND - 0x25CB,0x819B, // WHITE CIRCLE - 0x25CE,0x819D, // BULLSEYE - 0x25CF,0x819C, // BLACK CIRCLE - 0x25EF,0x81FC, // LARGE CIRCLE - 0x2605,0x819A, // BLACK STAR - 0x2606,0x8199, // WHITE STAR - 0x2640,0x818A, // FEMALE SIGN - 0x2642,0x8189, // MALE SIGN - 0x266A,0x81F4, // EIGHTH NOTE - 0x266D,0x81F3, // MUSIC FLAT SIGN - 0x266F,0x81F2, // MUSIC SHARP SIGN - 0x3000,0x8140, // IDEOGRAPHIC SPACE - 0x3001,0x8141, // IDEOGRAPHIC COMMA - 0x3002,0x8142, // IDEOGRAPHIC FULL STOP - 0x3003,0x8156, // DITTO MARK - 0x3005,0x8158, // IDEOGRAPHIC ITERATION MARK - 0x3006,0x8159, // IDEOGRAPHIC CLOSING MARK - 0x3007,0x815A, // IDEOGRAPHIC NUMBER ZERO - 0x3008,0x8171, // LEFT ANGLE BRACKET - 0x3009,0x8172, // RIGHT ANGLE BRACKET - 0x300A,0x8173, // LEFT DOUBLE ANGLE BRACKET - 0x300B,0x8174, // RIGHT DOUBLE ANGLE BRACKET - 0x300C,0x8175, // LEFT CORNER BRACKET - 0x300D,0x8176, // RIGHT CORNER BRACKET - 0x300E,0x8177, // LEFT WHITE CORNER BRACKET - 0x300F,0x8178, // RIGHT WHITE CORNER BRACKET - 0x3010,0x8179, // LEFT BLACK LENTICULAR BRACKET - 0x3011,0x817A, // RIGHT BLACK LENTICULAR BRACKET - 0x3012,0x81A7, // POSTAL MARK - 0x3013,0x81AC, // GETA MARK - 0x3014,0x816B, // LEFT TORTOISE SHELL BRACKET - 0x3015,0x816C, // RIGHT TORTOISE SHELL BRACKET - 0x301C,0x8160, // WAVE DASH - 0x3041,0x829F, // HIRAGANA LETTER SMALL A - 0x3042,0x82A0, // HIRAGANA LETTER A - 0x3043,0x82A1, // HIRAGANA LETTER SMALL I - 0x3044,0x82A2, // HIRAGANA LETTER I - 0x3045,0x82A3, // HIRAGANA LETTER SMALL U - 0x3046,0x82A4, // HIRAGANA LETTER U - 0x3047,0x82A5, // HIRAGANA LETTER SMALL E - 0x3048,0x82A6, // HIRAGANA LETTER E - 0x3049,0x82A7, // HIRAGANA LETTER SMALL O - 0x304A,0x82A8, // HIRAGANA LETTER O - 0x304B,0x82A9, // HIRAGANA LETTER KA - 0x304C,0x82AA, // HIRAGANA LETTER GA - 0x304D,0x82AB, // HIRAGANA LETTER KI - 0x304E,0x82AC, // HIRAGANA LETTER GI - 0x304F,0x82AD, // HIRAGANA LETTER KU - 0x3050,0x82AE, // HIRAGANA LETTER GU - 0x3051,0x82AF, // HIRAGANA LETTER KE - 0x3052,0x82B0, // HIRAGANA LETTER GE - 0x3053,0x82B1, // HIRAGANA LETTER KO - 0x3054,0x82B2, // HIRAGANA LETTER GO - 0x3055,0x82B3, // HIRAGANA LETTER SA - 0x3056,0x82B4, // HIRAGANA LETTER ZA - 0x3057,0x82B5, // HIRAGANA LETTER SI - 0x3058,0x82B6, // HIRAGANA LETTER ZI - 0x3059,0x82B7, // HIRAGANA LETTER SU - 0x305A,0x82B8, // HIRAGANA LETTER ZU - 0x305B,0x82B9, // HIRAGANA LETTER SE - 0x305C,0x82BA, // HIRAGANA LETTER ZE - 0x305D,0x82BB, // HIRAGANA LETTER SO - 0x305E,0x82BC, // HIRAGANA LETTER ZO - 0x305F,0x82BD, // HIRAGANA LETTER TA - 0x3060,0x82BE, // HIRAGANA LETTER DA - 0x3061,0x82BF, // HIRAGANA LETTER TI - 0x3062,0x82C0, // HIRAGANA LETTER DI - 0x3063,0x82C1, // HIRAGANA LETTER SMALL TU - 0x3064,0x82C2, // HIRAGANA LETTER TU - 0x3065,0x82C3, // HIRAGANA LETTER DU - 0x3066,0x82C4, // HIRAGANA LETTER TE - 0x3067,0x82C5, // HIRAGANA LETTER DE - 0x3068,0x82C6, // HIRAGANA LETTER TO - 0x3069,0x82C7, // HIRAGANA LETTER DO - 0x306A,0x82C8, // HIRAGANA LETTER NA - 0x306B,0x82C9, // HIRAGANA LETTER NI - 0x306C,0x82CA, // HIRAGANA LETTER NU - 0x306D,0x82CB, // HIRAGANA LETTER NE - 0x306E,0x82CC, // HIRAGANA LETTER NO - 0x306F,0x82CD, // HIRAGANA LETTER HA - 0x3070,0x82CE, // HIRAGANA LETTER BA - 0x3071,0x82CF, // HIRAGANA LETTER PA - 0x3072,0x82D0, // HIRAGANA LETTER HI - 0x3073,0x82D1, // HIRAGANA LETTER BI - 0x3074,0x82D2, // HIRAGANA LETTER PI - 0x3075,0x82D3, // HIRAGANA LETTER HU - 0x3076,0x82D4, // HIRAGANA LETTER BU - 0x3077,0x82D5, // HIRAGANA LETTER PU - 0x3078,0x82D6, // HIRAGANA LETTER HE - 0x3079,0x82D7, // HIRAGANA LETTER BE - 0x307A,0x82D8, // HIRAGANA LETTER PE - 0x307B,0x82D9, // HIRAGANA LETTER HO - 0x307C,0x82DA, // HIRAGANA LETTER BO - 0x307D,0x82DB, // HIRAGANA LETTER PO - 0x307E,0x82DC, // HIRAGANA LETTER MA - 0x307F,0x82DD, // HIRAGANA LETTER MI - 0x3080,0x82DE, // HIRAGANA LETTER MU - 0x3081,0x82DF, // HIRAGANA LETTER ME - 0x3082,0x82E0, // HIRAGANA LETTER MO - 0x3083,0x82E1, // HIRAGANA LETTER SMALL YA - 0x3084,0x82E2, // HIRAGANA LETTER YA - 0x3085,0x82E3, // HIRAGANA LETTER SMALL YU - 0x3086,0x82E4, // HIRAGANA LETTER YU - 0x3087,0x82E5, // HIRAGANA LETTER SMALL YO - 0x3088,0x82E6, // HIRAGANA LETTER YO - 0x3089,0x82E7, // HIRAGANA LETTER RA - 0x308A,0x82E8, // HIRAGANA LETTER RI - 0x308B,0x82E9, // HIRAGANA LETTER RU - 0x308C,0x82EA, // HIRAGANA LETTER RE - 0x308D,0x82EB, // HIRAGANA LETTER RO - 0x308E,0x82EC, // HIRAGANA LETTER SMALL WA - 0x308F,0x82ED, // HIRAGANA LETTER WA - 0x3090,0x82EE, // HIRAGANA LETTER WI - 0x3091,0x82EF, // HIRAGANA LETTER WE - 0x3092,0x82F0, // HIRAGANA LETTER WO - 0x3093,0x82F1, // HIRAGANA LETTER N - 0x309B,0x814A, // KATAKANA-HIRAGANA VOICED SOUND MARK - 0x309C,0x814B, // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK - 0x309D,0x8154, // HIRAGANA ITERATION MARK - 0x309E,0x8155, // HIRAGANA VOICED ITERATION MARK - 0x30A1,0x8340, // KATAKANA LETTER SMALL A - 0x30A2,0x8341, // KATAKANA LETTER A - 0x30A3,0x8342, // KATAKANA LETTER SMALL I - 0x30A4,0x8343, // KATAKANA LETTER I - 0x30A5,0x8344, // KATAKANA LETTER SMALL U - 0x30A6,0x8345, // KATAKANA LETTER U - 0x30A7,0x8346, // KATAKANA LETTER SMALL E - 0x30A8,0x8347, // KATAKANA LETTER E - 0x30A9,0x8348, // KATAKANA LETTER SMALL O - 0x30AA,0x8349, // KATAKANA LETTER O - 0x30AB,0x834A, // KATAKANA LETTER KA - 0x30AC,0x834B, // KATAKANA LETTER GA - 0x30AD,0x834C, // KATAKANA LETTER KI - 0x30AE,0x834D, // KATAKANA LETTER GI - 0x30AF,0x834E, // KATAKANA LETTER KU - 0x30B0,0x834F, // KATAKANA LETTER GU - 0x30B1,0x8350, // KATAKANA LETTER KE - 0x30B2,0x8351, // KATAKANA LETTER GE - 0x30B3,0x8352, // KATAKANA LETTER KO - 0x30B4,0x8353, // KATAKANA LETTER GO - 0x30B5,0x8354, // KATAKANA LETTER SA - 0x30B6,0x8355, // KATAKANA LETTER ZA - 0x30B7,0x8356, // KATAKANA LETTER SI - 0x30B8,0x8357, // KATAKANA LETTER ZI - 0x30B9,0x8358, // KATAKANA LETTER SU - 0x30BA,0x8359, // KATAKANA LETTER ZU - 0x30BB,0x835A, // KATAKANA LETTER SE - 0x30BD,0x835C, // KATAKANA LETTER SO - 0x30BE,0x835D, // KATAKANA LETTER ZO - 0x30BF,0x835E, // KATAKANA LETTER TA - 0x30C0,0x835F, // KATAKANA LETTER DA - 0x30C1,0x8360, // KATAKANA LETTER TI - 0x30C2,0x8361, // KATAKANA LETTER DI - 0x30C3,0x8362, // KATAKANA LETTER SMALL TU - 0x30C4,0x8363, // KATAKANA LETTER TU - 0x30C5,0x8364, // KATAKANA LETTER DU - 0x30C6,0x8365, // KATAKANA LETTER TE - 0x30C7,0x8366, // KATAKANA LETTER DE - 0x30C8,0x8367, // KATAKANA LETTER TO - 0x30C9,0x8368, // KATAKANA LETTER DO - 0x30CA,0x8369, // KATAKANA LETTER NA - 0x30CB,0x836A, // KATAKANA LETTER NI - 0x30CC,0x836B, // KATAKANA LETTER NU - 0x30CD,0x836C, // KATAKANA LETTER NE - 0x30CE,0x836D, // KATAKANA LETTER NO - 0x30CF,0x836E, // KATAKANA LETTER HA - 0x30D0,0x836F, // KATAKANA LETTER BA - 0x30D1,0x8370, // KATAKANA LETTER PA - 0x30D2,0x8371, // KATAKANA LETTER HI - 0x30D3,0x8372, // KATAKANA LETTER BI - 0x30D4,0x8373, // KATAKANA LETTER PI - 0x30D5,0x8374, // KATAKANA LETTER HU - 0x30D6,0x8375, // KATAKANA LETTER BU - 0x30D7,0x8376, // KATAKANA LETTER PU - 0x30D8,0x8377, // KATAKANA LETTER HE - 0x30D9,0x8378, // KATAKANA LETTER BE - 0x30DA,0x8379, // KATAKANA LETTER PE - 0x30DB,0x837A, // KATAKANA LETTER HO - 0x30DC,0x837B, // KATAKANA LETTER BO - 0x30DD,0x837C, // KATAKANA LETTER PO - 0x30DE,0x837D, // KATAKANA LETTER MA - 0x30DF,0x837E, // KATAKANA LETTER MI - 0x30E0,0x8380, // KATAKANA LETTER MU - 0x30E1,0x8381, // KATAKANA LETTER ME - 0x30E2,0x8382, // KATAKANA LETTER MO - 0x30E3,0x8383, // KATAKANA LETTER SMALL YA - 0x30E4,0x8384, // KATAKANA LETTER YA - 0x30E5,0x8385, // KATAKANA LETTER SMALL YU - 0x30E6,0x8386, // KATAKANA LETTER YU - 0x30E7,0x8387, // KATAKANA LETTER SMALL YO - 0x30E8,0x8388, // KATAKANA LETTER YO - 0x30E9,0x8389, // KATAKANA LETTER RA - 0x30EA,0x838A, // KATAKANA LETTER RI - 0x30EB,0x838B, // KATAKANA LETTER RU - 0x30EC,0x838C, // KATAKANA LETTER RE - 0x30ED,0x838D, // KATAKANA LETTER RO - 0x30EE,0x838E, // KATAKANA LETTER SMALL WA - 0x30EF,0x838F, // KATAKANA LETTER WA - 0x30F0,0x8390, // KATAKANA LETTER WI - 0x30F1,0x8391, // KATAKANA LETTER WE - 0x30F2,0x8392, // KATAKANA LETTER WO - 0x30F3,0x8393, // KATAKANA LETTER N - 0x30F4,0x8394, // KATAKANA LETTER VU - 0x30F5,0x8395, // KATAKANA LETTER SMALL KA - 0x30F6,0x8396, // KATAKANA LETTER SMALL KE - 0x30FB,0x8145, // KATAKANA MIDDLE DOT - 0x30FD,0x8152, // KATAKANA ITERATION MARK - 0x30FE,0x8153, // KATAKANA VOICED ITERATION MARK - 0x4E00,0x88EA, // - 0x4E01,0x929A, // - 0x4E03,0x8EB5, // - 0x4E07,0x969C, // - 0x4E08,0x8FE4, // - 0x4E09,0x8E4F, // - 0x4E0A,0x8FE3, // - 0x4E0B,0x89BA, // - 0x4E0D,0x9573, // - 0x4E0E,0x975E, // - 0x4E10,0x98A0, // - 0x4E11,0x894E, // - 0x4E14,0x8A8E, // - 0x4E15,0x98A1, // - 0x4E16,0x90A2, // - 0x4E17,0x99C0, // - 0x4E18,0x8B75, // - 0x4E19,0x95B8, // - 0x4E1E,0x8FE5, // - 0x4E21,0x97BC, // - 0x4E26,0x95C0, // - 0x4E2A,0x98A2, // - 0x4E2D,0x9286, // - 0x4E31,0x98A3, // - 0x4E32,0x8BF8, // - 0x4E36,0x98A4, // - 0x4E38,0x8ADB, // - 0x4E39,0x924F, // - 0x4E3B,0x8EE5, // - 0x4E3C,0x98A5, // - 0x4E3F,0x98A6, // - 0x4E42,0x98A7, // - 0x4E43,0x9454, // - 0x4E45,0x8B76, // - 0x4E4B,0x9456, // - 0x4E4D,0x93E1, // - 0x4E4E,0x8CC1, // - 0x4E4F,0x9652, // - 0x4E55,0xE568, // - 0x4E56,0x98A8, // - 0x4E57,0x8FE6, // - 0x4E58,0x98A9, // - 0x4E59,0x89B3, // - 0x4E5D,0x8BE3, // - 0x4E5E,0x8CEE, // - 0x4E5F,0x96E7, // - 0x4E62,0x9BA4, // - 0x4E71,0x9790, // - 0x4E73,0x93FB, // - 0x4E7E,0x8AA3, // - 0x4E80,0x8B54, // - 0x4E82,0x98AA, // - 0x4E85,0x98AB, // - 0x4E86,0x97B9, // - 0x4E88,0x975C, // - 0x4E89,0x9188, // - 0x4E8A,0x98AD, // - 0x4E8B,0x8E96, // - 0x4E8C,0x93F1, // - 0x4E8E,0x98B0, // - 0x4E91,0x895D, // - 0x4E92,0x8CDD, // - 0x4E94,0x8CDC, // - 0x4E95,0x88E4, // - 0x4E98,0x986A, // - 0x4E99,0x9869, // - 0x4E9B,0x8DB1, // - 0x4E9C,0x889F, // - 0x4E9E,0x98B1, // - 0x4E9F,0x98B2, // - 0x4EA0,0x98B3, // - 0x4EA1,0x9653, // - 0x4EA2,0x98B4, // - 0x4EA4,0x8CF0, // - 0x4EA5,0x88E5, // - 0x4EA6,0x9692, // - 0x4EA8,0x8B9C, // - 0x4EAB,0x8B9D, // - 0x4EAC,0x8B9E, // - 0x4EAD,0x92E0, // - 0x4EAE,0x97BA, // - 0x4EB0,0x98B5, // - 0x4EB3,0x98B6, // - 0x4EB6,0x98B7, // - 0x4EBA,0x906C, // - 0x4EC0,0x8F59, // - 0x4EC1,0x906D, // - 0x4EC2,0x98BC, // - 0x4EC4,0x98BA, // - 0x4EC6,0x98BB, // - 0x4EC7,0x8B77, // - 0x4ECA,0x8DA1, // - 0x4ECB,0x89EE, // - 0x4ECD,0x98B9, // - 0x4ECE,0x98B8, // - 0x4ECF,0x95A7, // - 0x4ED4,0x8E65, // - 0x4ED5,0x8E64, // - 0x4ED6,0x91BC, // - 0x4ED7,0x98BD, // - 0x4ED8,0x9574, // - 0x4ED9,0x90E5, // - 0x4EDD,0x8157, // - 0x4EDE,0x98BE, // - 0x4EDF,0x98C0, // - 0x4EE3,0x91E3, // - 0x4EE4,0x97DF, // - 0x4EE5,0x88C8, // - 0x4EED,0x98BF, // - 0x4EEE,0x89BC, // - 0x4EF0,0x8BC2, // - 0x4EF2,0x9287, // - 0x4EF6,0x8C8F, // - 0x4EF7,0x98C1, // - 0x4EFB,0x9443, // - 0x4F01,0x8AE9, // - 0x4F09,0x98C2, // - 0x4F0A,0x88C9, // - 0x4F0D,0x8CDE, // - 0x4F0E,0x8AEA, // - 0x4F0F,0x959A, // - 0x4F10,0x94B0, // - 0x4F11,0x8B78, // - 0x4F1A,0x89EF, // - 0x4F1C,0x98E5, // - 0x4F1D,0x9360, // - 0x4F2F,0x948C, // - 0x4F30,0x98C4, // - 0x4F34,0x94BA, // - 0x4F36,0x97E0, // - 0x4F38,0x904C, // - 0x4F3A,0x8E66, // - 0x4F3C,0x8E97, // - 0x4F3D,0x89BE, // - 0x4F43,0x92CF, // - 0x4F46,0x9241, // - 0x4F47,0x98C8, // - 0x4F4D,0x88CA, // - 0x4F4E,0x92E1, // - 0x4F4F,0x8F5A, // - 0x4F50,0x8DB2, // - 0x4F51,0x9743, // - 0x4F53,0x91CC, // - 0x4F55,0x89BD, // - 0x4F57,0x98C7, // - 0x4F59,0x975D, // - 0x4F5A,0x98C3, // - 0x4F5B,0x98C5, // - 0x4F5C,0x8DEC, // - 0x4F5D,0x98C6, // - 0x4F5E,0x9B43, // - 0x4F69,0x98CE, // - 0x4F6F,0x98D1, // - 0x4F70,0x98CF, // - 0x4F73,0x89C0, // - 0x4F75,0x95B9, // - 0x4F76,0x98C9, // - 0x4F7B,0x98CD, // - 0x4F7C,0x8CF1, // - 0x4F7F,0x8E67, // - 0x4F83,0x8AA4, // - 0x4F86,0x98D2, // - 0x4F88,0x98CA, // - 0x4F8B,0x97E1, // - 0x4F8D,0x8E98, // - 0x4F8F,0x98CB, // - 0x4F91,0x98D0, // - 0x4F96,0x98D3, // - 0x4F98,0x98CC, // - 0x4F9B,0x8B9F, // - 0x4F9D,0x88CB, // - 0x4FA0,0x8BA0, // - 0x4FA1,0x89BF, // - 0x4FAB,0x9B44, // - 0x4FAD,0x9699, // - 0x4FAE,0x958E, // - 0x4FAF,0x8CF2, // - 0x4FB5,0x904E, // - 0x4FB6,0x97B5, // - 0x4FBF,0x95D6, // - 0x4FC2,0x8C57, // - 0x4FC3,0x91A3, // - 0x4FC4,0x89E2, // - 0x4FCA,0x8F72, // - 0x4FCE,0x98D7, // - 0x4FD0,0x98DC, // - 0x4FD1,0x98DA, // - 0x4FD4,0x98D5, // - 0x4FD7,0x91AD, // - 0x4FD8,0x98D8, // - 0x4FDA,0x98DB, // - 0x4FDB,0x98D9, // - 0x4FDD,0x95DB, // - 0x4FDF,0x98D6, // - 0x4FE1,0x904D, // - 0x4FE3,0x9693, // - 0x4FE4,0x98DD, // - 0x4FE5,0x98DE, // - 0x4FEE,0x8F43, // - 0x4FEF,0x98EB, // - 0x4FF3,0x946F, // - 0x4FF5,0x9555, // - 0x4FF6,0x98E6, // - 0x4FF8,0x95EE, // - 0x4FFA,0x89B4, // - 0x4FFE,0x98EA, // - 0x5005,0x98E4, // - 0x5006,0x98ED, // - 0x5009,0x9171, // - 0x500B,0x8CC2, // - 0x500D,0x947B, // - 0x500F,0xE0C5, // - 0x5011,0x98EC, // - 0x5012,0x937C, // - 0x5014,0x98E1, // - 0x5016,0x8CF4, // - 0x5019,0x8CF3, // - 0x501A,0x98DF, // - 0x501F,0x8ED8, // - 0x5021,0x98E7, // - 0x5023,0x95ED, // - 0x5024,0x926C, // - 0x5025,0x98E3, // - 0x5026,0x8C91, // - 0x5028,0x98E0, // - 0x5029,0x98E8, // - 0x502A,0x98E2, // - 0x502B,0x97CF, // - 0x502C,0x98E9, // - 0x502D,0x9860, // - 0x5036,0x8BE4, // - 0x5039,0x8C90, // - 0x5043,0x98EE, // - 0x5047,0x98EF, // - 0x5048,0x98F3, // - 0x5049,0x88CC, // - 0x504F,0x95CE, // - 0x5050,0x98F2, // - 0x5055,0x98F1, // - 0x5056,0x98F5, // - 0x505A,0x98F4, // - 0x505C,0x92E2, // - 0x5065,0x8C92, // - 0x506C,0x98F6, // - 0x5072,0x8EC3, // - 0x5074,0x91A4, // - 0x5075,0x92E3, // - 0x5076,0x8BF4, // - 0x5078,0x98F7, // - 0x507D,0x8B55, // - 0x5080,0x98F8, // - 0x5085,0x98FA, // - 0x508D,0x9654, // - 0x5091,0x8C86, // - 0x5098,0x8E50, // - 0x5099,0x94F5, // - 0x509A,0x98F9, // - 0x50AC,0x8DC3, // - 0x50AD,0x9762, // - 0x50B2,0x98FC, // - 0x50B3,0x9942, // - 0x50B4,0x98FB, // - 0x50B5,0x8DC2, // - 0x50B7,0x8F9D, // - 0x50BE,0x8C58, // - 0x50C2,0x9943, // - 0x50C5,0x8BCD, // - 0x50C9,0x9940, // - 0x50CA,0x9941, // - 0x50CD,0x93AD, // - 0x50CF,0x919C, // - 0x50D1,0x8BA1, // - 0x50D5,0x966C, // - 0x50D6,0x9944, // - 0x50DA,0x97BB, // - 0x50DE,0x9945, // - 0x50E3,0x9948, // - 0x50E5,0x9946, // - 0x50E7,0x916D, // - 0x50ED,0x9947, // - 0x50EE,0x9949, // - 0x50F5,0x994B, // - 0x50F9,0x994A, // - 0x50FB,0x95C6, // - 0x5100,0x8B56, // - 0x5101,0x994D, // - 0x5102,0x994E, // - 0x5104,0x89AD, // - 0x5109,0x994C, // - 0x5112,0x8EF2, // - 0x5114,0x9951, // - 0x5115,0x9950, // - 0x5116,0x994F, // - 0x5118,0x98D4, // - 0x511A,0x9952, // - 0x511F,0x8F9E, // - 0x5121,0x9953, // - 0x512A,0x9744, // - 0x5132,0x96D7, // - 0x5137,0x9955, // - 0x513A,0x9954, // - 0x513B,0x9957, // - 0x513C,0x9956, // - 0x513F,0x9958, // - 0x5140,0x9959, // - 0x5141,0x88F2, // - 0x5143,0x8CB3, // - 0x5144,0x8C5A, // - 0x5146,0x929B, // - 0x5147,0x8BA2, // - 0x5148,0x90E6, // - 0x5149,0x8CF5, // - 0x514B,0x8D8E, // - 0x514D,0x96C6, // - 0x514E,0x9365, // - 0x5150,0x8E99, // - 0x5152,0x995A, // - 0x5154,0x995C, // - 0x515A,0x937D, // - 0x515C,0x8A95, // - 0x5162,0x995D, // - 0x5165,0x93FC, // - 0x5168,0x9153, // - 0x5169,0x995F, // - 0x516A,0x9960, // - 0x516B,0x94AA, // - 0x516C,0x8CF6, // - 0x516D,0x985A, // - 0x516E,0x9961, // - 0x5171,0x8BA4, // - 0x5175,0x95BA, // - 0x5176,0x91B4, // - 0x5177,0x8BEF, // - 0x5178,0x9354, // - 0x517C,0x8C93, // - 0x5180,0x9962, // - 0x5182,0x9963, // - 0x5185,0x93E0, // - 0x5186,0x897E, // - 0x5189,0x9966, // - 0x518A,0x8DFB, // - 0x518C,0x9965, // - 0x518D,0x8DC4, // - 0x518F,0x9967, // - 0x5190,0xE3EC, // - 0x5191,0x9968, // - 0x5192,0x9660, // - 0x5193,0x9969, // - 0x5195,0x996A, // - 0x5196,0x996B, // - 0x5197,0x8FE7, // - 0x5199,0x8ECA, // - 0x51A0,0x8AA5, // - 0x51A2,0x996E, // - 0x51A4,0x996C, // - 0x51A5,0x96BB, // - 0x51A6,0x996D, // - 0x51A8,0x9579, // - 0x51A9,0x996F, // - 0x51AA,0x9970, // - 0x51AB,0x9971, // - 0x51AC,0x937E, // - 0x51B0,0x9975, // - 0x51B1,0x9973, // - 0x51B2,0x9974, // - 0x51B3,0x9972, // - 0x51B4,0x8DE1, // - 0x51B5,0x9976, // - 0x51B6,0x96E8, // - 0x51B7,0x97E2, // - 0x51BD,0x9977, // - 0x51C4,0x90A6, // - 0x51C5,0x9978, // - 0x51C6,0x8F79, // - 0x51C9,0x9979, // - 0x51CB,0x929C, // - 0x51CC,0x97BD, // - 0x51CD,0x9380, // - 0x51D6,0x99C3, // - 0x51DB,0x997A, // - 0x51DC,0xEAA3, // - 0x51DD,0x8BC3, // - 0x51E0,0x997B, // - 0x51E1,0x967D, // - 0x51E6,0x8F88, // - 0x51E7,0x91FA, // - 0x51E9,0x997D, // - 0x51EA,0x93E2, // - 0x51ED,0x997E, // - 0x51F0,0x9980, // - 0x51F1,0x8A4D, // - 0x51F5,0x9981, // - 0x51F6,0x8BA5, // - 0x51F8,0x93CA, // - 0x51F9,0x899A, // - 0x51FA,0x8F6F, // - 0x51FD,0x949F, // - 0x51FE,0x9982, // - 0x5200,0x9381, // - 0x5203,0x906E, // - 0x5204,0x9983, // - 0x5206,0x95AA, // - 0x5207,0x90D8, // - 0x5208,0x8AA0, // - 0x520A,0x8AA7, // - 0x520B,0x9984, // - 0x520E,0x9986, // - 0x5211,0x8C59, // - 0x5214,0x9985, // - 0x5217,0x97F1, // - 0x521D,0x8F89, // - 0x5224,0x94BB, // - 0x5225,0x95CA, // - 0x5227,0x9987, // - 0x5229,0x9798, // - 0x522A,0x9988, // - 0x522E,0x9989, // - 0x5230,0x939E, // - 0x5233,0x998A, // - 0x5236,0x90A7, // - 0x5237,0x8DFC, // - 0x5238,0x8C94, // - 0x5239,0x998B, // - 0x523A,0x8E68, // - 0x523B,0x8D8F, // - 0x5243,0x92E4, // - 0x5244,0x998D, // - 0x5247,0x91A5, // - 0x524A,0x8DED, // - 0x524B,0x998E, // - 0x524C,0x998F, // - 0x524D,0x914F, // - 0x524F,0x998C, // - 0x5254,0x9991, // - 0x5256,0x9655, // - 0x525B,0x8D84, // - 0x525E,0x9990, // - 0x5263,0x8C95, // - 0x5264,0x8DDC, // - 0x5265,0x948D, // - 0x5269,0x9994, // - 0x526A,0x9992, // - 0x526F,0x959B, // - 0x5270,0x8FE8, // - 0x5271,0x999B, // - 0x5272,0x8A84, // - 0x5273,0x9995, // - 0x5274,0x9993, // - 0x5275,0x916E, // - 0x527D,0x9997, // - 0x527F,0x9996, // - 0x5283,0x8A63, // - 0x5287,0x8C80, // - 0x5288,0x999C, // - 0x5289,0x97AB, // - 0x528D,0x9998, // - 0x5291,0x999D, // - 0x5292,0x999A, // - 0x5294,0x9999, // - 0x529B,0x97CD, // - 0x529F,0x8CF7, // - 0x52A0,0x89C1, // - 0x52A3,0x97F2, // - 0x52A9,0x8F95, // - 0x52AA,0x9377, // - 0x52AB,0x8D85, // - 0x52AC,0x99A0, // - 0x52AD,0x99A1, // - 0x52B1,0x97E3, // - 0x52B4,0x984A, // - 0x52B5,0x99A3, // - 0x52B9,0x8CF8, // - 0x52BC,0x99A2, // - 0x52BE,0x8A4E, // - 0x52C1,0x99A4, // - 0x52C3,0x9675, // - 0x52C5,0x92BA, // - 0x52C7,0x9745, // - 0x52C9,0x95D7, // - 0x52CD,0x99A5, // - 0x52D2,0xE8D3, // - 0x52D5,0x93AE, // - 0x52D7,0x99A6, // - 0x52D8,0x8AA8, // - 0x52D9,0x96B1, // - 0x52DD,0x8F9F, // - 0x52DE,0x99A7, // - 0x52DF,0x95E5, // - 0x52E0,0x99AB, // - 0x52E2,0x90A8, // - 0x52E3,0x99A8, // - 0x52E4,0x8BCE, // - 0x52E6,0x99A9, // - 0x52E7,0x8AA9, // - 0x52F2,0x8C4D, // - 0x52F3,0x99AC, // - 0x52F5,0x99AD, // - 0x52F8,0x99AE, // - 0x52F9,0x99AF, // - 0x52FA,0x8ED9, // - 0x52FE,0x8CF9, // - 0x52FF,0x96DC, // - 0x5301,0x96E6, // - 0x5302,0x93F5, // - 0x5305,0x95EF, // - 0x5306,0x99B0, // - 0x5308,0x99B1, // - 0x530D,0x99B3, // - 0x530F,0x99B5, // - 0x5310,0x99B4, // - 0x5315,0x99B6, // - 0x5316,0x89BB, // - 0x5317,0x966B, // - 0x5319,0x8DFA, // - 0x531A,0x99B7, // - 0x531D,0x9178, // - 0x5320,0x8FA0, // - 0x5321,0x8BA7, // - 0x5323,0x99B8, // - 0x532A,0x94D9, // - 0x532F,0x99B9, // - 0x5331,0x99BA, // - 0x5333,0x99BB, // - 0x5338,0x99BC, // - 0x5339,0x9543, // - 0x533A,0x8BE6, // - 0x533B,0x88E3, // - 0x533F,0x93BD, // - 0x5340,0x99BD, // - 0x5341,0x8F5C, // - 0x5343,0x90E7, // - 0x5345,0x99BF, // - 0x5346,0x99BE, // - 0x5347,0x8FA1, // - 0x5348,0x8CDF, // - 0x5349,0x99C1, // - 0x534A,0x94BC, // - 0x534D,0x99C2, // - 0x5351,0x94DA, // - 0x5352,0x91B2, // - 0x5353,0x91EC, // - 0x5354,0x8BA6, // - 0x5357,0x93EC, // - 0x5358,0x9250, // - 0x535A,0x948E, // - 0x535C,0x966D, // - 0x535E,0x99C4, // - 0x5360,0x90E8, // - 0x5366,0x8C54, // - 0x5369,0x99C5, // - 0x536E,0x99C6, // - 0x536F,0x894B, // - 0x5370,0x88F3, // - 0x5371,0x8AEB, // - 0x5373,0x91A6, // - 0x5374,0x8B70, // - 0x5375,0x9791, // - 0x5377,0x99C9, // - 0x5378,0x89B5, // - 0x537B,0x99C8, // - 0x537F,0x8BA8, // - 0x5382,0x99CA, // - 0x5384,0x96EF, // - 0x5396,0x99CB, // - 0x5398,0x97D0, // - 0x539A,0x8CFA, // - 0x539F,0x8CB4, // - 0x53A0,0x99CC, // - 0x53A5,0x99CE, // - 0x53A6,0x99CD, // - 0x53A8,0x907E, // - 0x53A9,0x8958, // - 0x53AD,0x897D, // - 0x53AE,0x99CF, // - 0x53B0,0x99D0, // - 0x53B3,0x8CB5, // - 0x53B6,0x99D1, // - 0x53BB,0x8B8E, // - 0x53C2,0x8E51, // - 0x53C3,0x99D2, // - 0x53C8,0x9694, // - 0x53C9,0x8DB3, // - 0x53CA,0x8B79, // - 0x53CB,0x9746, // - 0x53CC,0x916F, // - 0x53CD,0x94BD, // - 0x53CE,0x8EFB, // - 0x53D4,0x8F66, // - 0x53D6,0x8EE6, // - 0x53D7,0x8EF3, // - 0x53D9,0x8F96, // - 0x53DB,0x94BE, // - 0x53DF,0x99D5, // - 0x53E1,0x8962, // - 0x53E2,0x9170, // - 0x53E3,0x8CFB, // - 0x53E4,0x8CC3, // - 0x53E5,0x8BE5, // - 0x53E8,0x99D9, // - 0x53E9,0x9240, // - 0x53EA,0x91FC, // - 0x53EB,0x8BA9, // - 0x53EC,0x8FA2, // - 0x53ED,0x99DA, // - 0x53EE,0x99D8, // - 0x53EF,0x89C2, // - 0x53F0,0x91E4, // - 0x53F1,0x8EB6, // - 0x53F2,0x8E6A, // - 0x53F3,0x8945, // - 0x53F6,0x8A90, // - 0x53F7,0x8D86, // - 0x53F8,0x8E69, // - 0x53FA,0x99DB, // - 0x5401,0x99DC, // - 0x5403,0x8B68, // - 0x5404,0x8A65, // - 0x5408,0x8D87, // - 0x5409,0x8B67, // - 0x540A,0x92DD, // - 0x540B,0x8944, // - 0x540C,0x93AF, // - 0x540D,0x96BC, // - 0x540E,0x8D40, // - 0x540F,0x9799, // - 0x5410,0x9366, // - 0x5411,0x8CFC, // - 0x541B,0x8C4E, // - 0x541D,0x99E5, // - 0x541F,0x8BE1, // - 0x5420,0x9669, // - 0x5426,0x94DB, // - 0x5429,0x99E4, // - 0x542B,0x8ADC, // - 0x542C,0x99DF, // - 0x542D,0x99E0, // - 0x542E,0x99E2, // - 0x5436,0x99E3, // - 0x5438,0x8B7A, // - 0x5439,0x9081, // - 0x543B,0x95AB, // - 0x543C,0x99E1, // - 0x543D,0x99DD, // - 0x543E,0x8CE1, // - 0x5440,0x99DE, // - 0x5442,0x9843, // - 0x5446,0x95F0, // - 0x5448,0x92E6, // - 0x5449,0x8CE0, // - 0x544A,0x8D90, // - 0x544E,0x99E6, // - 0x5451,0x93DB, // - 0x545F,0x99EA, // - 0x5468,0x8EFC, // - 0x546A,0x8EF4, // - 0x5470,0x99ED, // - 0x5471,0x99EB, // - 0x5473,0x96A1, // - 0x5475,0x99E8, // - 0x5476,0x99F1, // - 0x5477,0x99EC, // - 0x547B,0x99EF, // - 0x547C,0x8CC4, // - 0x547D,0x96BD, // - 0x5480,0x99F0, // - 0x5484,0x99F2, // - 0x5486,0x99F4, // - 0x548B,0x8DEE, // - 0x548C,0x9861, // - 0x548E,0x99E9, // - 0x548F,0x99E7, // - 0x5490,0x99F3, // - 0x5492,0x99EE, // - 0x54A2,0x99F6, // - 0x54A4,0x9A42, // - 0x54A5,0x99F8, // - 0x54A8,0x99FC, // - 0x54AB,0x9A40, // - 0x54AC,0x99F9, // - 0x54AF,0x9A5D, // - 0x54B2,0x8DE7, // - 0x54B3,0x8A50, // - 0x54B8,0x99F7, // - 0x54BC,0x9A44, // - 0x54BD,0x88F4, // - 0x54BE,0x9A43, // - 0x54C0,0x88A3, // - 0x54C1,0x9569, // - 0x54C2,0x9A41, // - 0x54C4,0x99FA, // - 0x54C7,0x99F5, // - 0x54C8,0x99FB, // - 0x54C9,0x8DC6, // - 0x54D8,0x9A45, // - 0x54E1,0x88F5, // - 0x54E2,0x9A4E, // - 0x54E5,0x9A46, // - 0x54E6,0x9A47, // - 0x54E8,0x8FA3, // - 0x54E9,0x9689, // - 0x54ED,0x9A4C, // - 0x54EE,0x9A4B, // - 0x54F2,0x934E, // - 0x54FA,0x9A4D, // - 0x54FD,0x9A4A, // - 0x5504,0x8953, // - 0x5506,0x8DB4, // - 0x5507,0x904F, // - 0x550F,0x9A48, // - 0x5510,0x9382, // - 0x5514,0x9A49, // - 0x5516,0x88A0, // - 0x552E,0x9A53, // - 0x552F,0x9742, // - 0x5531,0x8FA5, // - 0x5533,0x9A59, // - 0x5538,0x9A58, // - 0x5539,0x9A4F, // - 0x553E,0x91C1, // - 0x5540,0x9A50, // - 0x5544,0x91ED, // - 0x5545,0x9A55, // - 0x5546,0x8FA4, // - 0x554C,0x9A52, // - 0x554F,0x96E2, // - 0x5556,0x9A56, // - 0x5557,0x9A57, // - 0x555C,0x9A54, // - 0x555D,0x9A5A, // - 0x5563,0x9A51, // - 0x557B,0x9A60, // - 0x557C,0x9A65, // - 0x557E,0x9A61, // - 0x5580,0x9A5C, // - 0x5583,0x9A66, // - 0x5584,0x9150, // - 0x5587,0x9A68, // - 0x5589,0x8D41, // - 0x558A,0x9A5E, // - 0x558B,0x929D, // - 0x5598,0x9A62, // - 0x559A,0x8AAB, // - 0x559C,0x8AEC, // - 0x559D,0x8A85, // - 0x559E,0x9A63, // - 0x559F,0x9A5F, // - 0x55A7,0x8C96, // - 0x55A8,0x9A69, // - 0x55A9,0x9A67, // - 0x55AA,0x9172, // - 0x55AB,0x8B69, // - 0x55AC,0x8BAA, // - 0x55AE,0x9A64, // - 0x55B0,0x8BF2, // - 0x55B6,0x8963, // - 0x55C4,0x9A6D, // - 0x55C5,0x9A6B, // - 0x55C7,0x9AA5, // - 0x55D4,0x9A70, // - 0x55DA,0x9A6A, // - 0x55DC,0x9A6E, // - 0x55DF,0x9A6C, // - 0x55E3,0x8E6B, // - 0x55E4,0x9A6F, // - 0x55F7,0x9A72, // - 0x55F9,0x9A77, // - 0x55FD,0x9A75, // - 0x55FE,0x9A74, // - 0x5606,0x9251, // - 0x5609,0x89C3, // - 0x5614,0x9A71, // - 0x5616,0x9A73, // - 0x5617,0x8FA6, // - 0x5618,0x8952, // - 0x561B,0x9A76, // - 0x5629,0x89DC, // - 0x562F,0x9A82, // - 0x5631,0x8FFA, // - 0x5632,0x9A7D, // - 0x5634,0x9A7B, // - 0x5636,0x9A7C, // - 0x5638,0x9A7E, // - 0x5642,0x895C, // - 0x564C,0x9158, // - 0x564E,0x9A78, // - 0x5650,0x9A79, // - 0x565B,0x8A9A, // - 0x5664,0x9A81, // - 0x5668,0x8AED, // - 0x566A,0x9A84, // - 0x566B,0x9A80, // - 0x566C,0x9A83, // - 0x5674,0x95AC, // - 0x5678,0x93D3, // - 0x567A,0x94B6, // - 0x5680,0x9A86, // - 0x5686,0x9A85, // - 0x5687,0x8A64, // - 0x568A,0x9A87, // - 0x568F,0x9A8A, // - 0x5694,0x9A89, // - 0x56A0,0x9A88, // - 0x56A2,0x9458, // - 0x56A5,0x9A8B, // - 0x56AE,0x9A8C, // - 0x56B4,0x9A8E, // - 0x56B6,0x9A8D, // - 0x56BC,0x9A90, // - 0x56C0,0x9A93, // - 0x56C1,0x9A91, // - 0x56C2,0x9A8F, // - 0x56C3,0x9A92, // - 0x56C8,0x9A94, // - 0x56CE,0x9A95, // - 0x56D1,0x9A96, // - 0x56D3,0x9A97, // - 0x56D7,0x9A98, // - 0x56D8,0x9964, // - 0x56DA,0x8EFA, // - 0x56DB,0x8E6C, // - 0x56DE,0x89F1, // - 0x56E0,0x88F6, // - 0x56E3,0x9263, // - 0x56EE,0x9A99, // - 0x56F0,0x8DA2, // - 0x56F2,0x88CD, // - 0x56F3,0x907D, // - 0x56F9,0x9A9A, // - 0x56FA,0x8CC5, // - 0x56FD,0x8D91, // - 0x56FF,0x9A9C, // - 0x5700,0x9A9B, // - 0x5703,0x95DE, // - 0x5704,0x9A9D, // - 0x5708,0x9A9F, // - 0x5709,0x9A9E, // - 0x570B,0x9AA0, // - 0x570D,0x9AA1, // - 0x570F,0x8C97, // - 0x5712,0x8980, // - 0x5713,0x9AA2, // - 0x5716,0x9AA4, // - 0x5718,0x9AA3, // - 0x571C,0x9AA6, // - 0x571F,0x9379, // - 0x5726,0x9AA7, // - 0x5727,0x88B3, // - 0x5728,0x8DDD, // - 0x572D,0x8C5C, // - 0x5730,0x926E, // - 0x5737,0x9AA8, // - 0x5738,0x9AA9, // - 0x573B,0x9AAB, // - 0x5740,0x9AAC, // - 0x5742,0x8DE2, // - 0x5747,0x8BCF, // - 0x574A,0x9656, // - 0x574E,0x9AAA, // - 0x574F,0x9AAD, // - 0x5750,0x8DBF, // - 0x5751,0x8D42, // - 0x5761,0x9AB1, // - 0x5764,0x8DA3, // - 0x5766,0x9252, // - 0x5769,0x9AAE, // - 0x576A,0x92D8, // - 0x577F,0x9AB2, // - 0x5782,0x9082, // - 0x5788,0x9AB0, // - 0x5789,0x9AB3, // - 0x578B,0x8C5E, // - 0x5793,0x9AB4, // - 0x57A0,0x9AB5, // - 0x57A2,0x8D43, // - 0x57A3,0x8A5F, // - 0x57A4,0x9AB7, // - 0x57AA,0x9AB8, // - 0x57B0,0x9AB9, // - 0x57B3,0x9AB6, // - 0x57C0,0x9AAF, // - 0x57C3,0x9ABA, // - 0x57C6,0x9ABB, // - 0x57CB,0x9684, // - 0x57CE,0x8FE9, // - 0x57D2,0x9ABD, // - 0x57D3,0x9ABE, // - 0x57D4,0x9ABC, // - 0x57D6,0x9AC0, // - 0x57DC,0x9457, // - 0x57DF,0x88E6, // - 0x57E0,0x9575, // - 0x57E3,0x9AC1, // - 0x57F4,0x8FFB, // - 0x57F7,0x8EB7, // - 0x57F9,0x947C, // - 0x57FA,0x8AEE, // - 0x57FC,0x8DE9, // - 0x5800,0x9678, // - 0x5802,0x93B0, // - 0x5805,0x8C98, // - 0x5806,0x91CD, // - 0x580A,0x9ABF, // - 0x580B,0x9AC2, // - 0x5815,0x91C2, // - 0x5819,0x9AC3, // - 0x581D,0x9AC4, // - 0x5821,0x9AC6, // - 0x5824,0x92E7, // - 0x582A,0x8AAC, // - 0x582F,0xEA9F, // - 0x5830,0x8981, // - 0x5831,0x95F1, // - 0x5834,0x8FEA, // - 0x5835,0x9367, // - 0x583A,0x8DE4, // - 0x583D,0x9ACC, // - 0x5840,0x95BB, // - 0x5841,0x97DB, // - 0x584A,0x89F2, // - 0x584B,0x9AC8, // - 0x5851,0x9159, // - 0x5852,0x9ACB, // - 0x5854,0x9383, // - 0x5857,0x9368, // - 0x5858,0x9384, // - 0x5859,0x94B7, // - 0x585A,0x92CB, // - 0x585E,0x8DC7, // - 0x5862,0x9AC7, // - 0x5869,0x8996, // - 0x586B,0x9355, // - 0x5870,0x9AC9, // - 0x5872,0x9AC5, // - 0x5875,0x906F, // - 0x5879,0x9ACD, // - 0x587E,0x8F6D, // - 0x5883,0x8BAB, // - 0x5885,0x9ACE, // - 0x5893,0x95E6, // - 0x5897,0x919D, // - 0x589C,0x92C4, // - 0x589F,0x9AD0, // - 0x58A8,0x966E, // - 0x58AB,0x9AD1, // - 0x58AE,0x9AD6, // - 0x58B3,0x95AD, // - 0x58B8,0x9AD5, // - 0x58B9,0x9ACF, // - 0x58BA,0x9AD2, // - 0x58BB,0x9AD4, // - 0x58BE,0x8DA4, // - 0x58C1,0x95C7, // - 0x58C5,0x9AD7, // - 0x58C7,0x9264, // - 0x58CA,0x89F3, // - 0x58CC,0x8FEB, // - 0x58D1,0x9AD9, // - 0x58D3,0x9AD8, // - 0x58D5,0x8D88, // - 0x58D7,0x9ADA, // - 0x58D8,0x9ADC, // - 0x58D9,0x9ADB, // - 0x58DC,0x9ADE, // - 0x58DE,0x9AD3, // - 0x58DF,0x9AE0, // - 0x58E4,0x9ADF, // - 0x58E5,0x9ADD, // - 0x58EB,0x8E6D, // - 0x58EC,0x9070, // - 0x58EE,0x9173, // - 0x58EF,0x9AE1, // - 0x58F0,0x90BA, // - 0x58F1,0x88EB, // - 0x58F2,0x9484, // - 0x58F7,0x92D9, // - 0x58F9,0x9AE3, // - 0x58FA,0x9AE2, // - 0x58FB,0x9AE4, // - 0x58FC,0x9AE5, // - 0x58FD,0x9AE6, // - 0x5902,0x9AE7, // - 0x5909,0x95CF, // - 0x590A,0x9AE8, // - 0x590F,0x89C4, // - 0x5910,0x9AE9, // - 0x5916,0x8A4F, // - 0x5918,0x99C7, // - 0x5919,0x8F67, // - 0x591A,0x91BD, // - 0x591B,0x9AEA, // - 0x591C,0x96E9, // - 0x5922,0x96B2, // - 0x5925,0x9AEC, // - 0x5927,0x91E5, // - 0x5929,0x9356, // - 0x592A,0x91BE, // - 0x592B,0x9576, // - 0x592C,0x9AED, // - 0x592D,0x9AEE, // - 0x592E,0x899B, // - 0x5931,0x8EB8, // - 0x5932,0x9AEF, // - 0x5937,0x88CE, // - 0x5938,0x9AF0, // - 0x593E,0x9AF1, // - 0x5944,0x8982, // - 0x5947,0x8AEF, // - 0x5948,0x93DE, // - 0x5949,0x95F2, // - 0x594E,0x9AF5, // - 0x594F,0x9174, // - 0x5950,0x9AF4, // - 0x5951,0x8C5F, // - 0x5954,0x967A, // - 0x5955,0x9AF3, // - 0x5957,0x9385, // - 0x5958,0x9AF7, // - 0x595A,0x9AF6, // - 0x5960,0x9AF9, // - 0x5962,0x9AF8, // - 0x5965,0x899C, // - 0x5967,0x9AFA, // - 0x5968,0x8FA7, // - 0x5969,0x9AFC, // - 0x596A,0x9244, // - 0x596C,0x9AFB, // - 0x596E,0x95B1, // - 0x5973,0x8F97, // - 0x5974,0x937A, // - 0x5978,0x9B40, // - 0x597D,0x8D44, // - 0x5981,0x9B41, // - 0x5982,0x9440, // - 0x5983,0x94DC, // - 0x5984,0x96CF, // - 0x598A,0x9444, // - 0x598D,0x9B4A, // - 0x5993,0x8B57, // - 0x5996,0x9764, // - 0x5999,0x96AD, // - 0x599B,0x9BAA, // - 0x599D,0x9B42, // - 0x59A3,0x9B45, // - 0x59A5,0x91C3, // - 0x59A8,0x9657, // - 0x59AC,0x9369, // - 0x59B2,0x9B46, // - 0x59B9,0x9685, // - 0x59BB,0x8DC8, // - 0x59BE,0x8FA8, // - 0x59C6,0x9B47, // - 0x59C9,0x8E6F, // - 0x59CB,0x8E6E, // - 0x59D0,0x88B7, // - 0x59D1,0x8CC6, // - 0x59D3,0x90A9, // - 0x59D4,0x88CF, // - 0x59D9,0x9B4B, // - 0x59DA,0x9B4C, // - 0x59DC,0x9B49, // - 0x59E5,0x8957, // - 0x59E6,0x8AAD, // - 0x59E8,0x9B48, // - 0x59EA,0x96C3, // - 0x59EB,0x9550, // - 0x59F6,0x88A6, // - 0x59FB,0x88F7, // - 0x59FF,0x8E70, // - 0x5A01,0x88D0, // - 0x5A03,0x88A1, // - 0x5A09,0x9B51, // - 0x5A11,0x9B4F, // - 0x5A18,0x96BA, // - 0x5A1A,0x9B52, // - 0x5A1C,0x9B50, // - 0x5A1F,0x9B4E, // - 0x5A20,0x9050, // - 0x5A25,0x9B4D, // - 0x5A29,0x95D8, // - 0x5A2F,0x8CE2, // - 0x5A35,0x9B56, // - 0x5A36,0x9B57, // - 0x5A3C,0x8FA9, // - 0x5A40,0x9B53, // - 0x5A41,0x984B, // - 0x5A46,0x946B, // - 0x5A49,0x9B55, // - 0x5A5A,0x8DA5, // - 0x5A62,0x9B58, // - 0x5A66,0x9577, // - 0x5A6A,0x9B59, // - 0x5A6C,0x9B54, // - 0x5A7F,0x96B9, // - 0x5A92,0x947D, // - 0x5A9A,0x9B5A, // - 0x5A9B,0x9551, // - 0x5ABD,0x9B5F, // - 0x5ABE,0x9B5C, // - 0x5AC1,0x89C5, // - 0x5AC2,0x9B5E, // - 0x5AC9,0x8EB9, // - 0x5ACB,0x9B5D, // - 0x5ACC,0x8C99, // - 0x5AD0,0x9B6B, // - 0x5AD6,0x9B64, // - 0x5AD7,0x9B61, // - 0x5AE1,0x9284, // - 0x5AE3,0x9B60, // - 0x5AE6,0x9B62, // - 0x5AE9,0x9B63, // - 0x5AFA,0x9B65, // - 0x5AFB,0x9B66, // - 0x5B09,0x8AF0, // - 0x5B0B,0x9B68, // - 0x5B0C,0x9B67, // - 0x5B16,0x9B69, // - 0x5B22,0x8FEC, // - 0x5B2A,0x9B6C, // - 0x5B2C,0x92DA, // - 0x5B30,0x8964, // - 0x5B32,0x9B6A, // - 0x5B36,0x9B6D, // - 0x5B3E,0x9B6E, // - 0x5B40,0x9B71, // - 0x5B43,0x9B6F, // - 0x5B45,0x9B70, // - 0x5B50,0x8E71, // - 0x5B51,0x9B72, // - 0x5B54,0x8D45, // - 0x5B55,0x9B73, // - 0x5B57,0x8E9A, // - 0x5B58,0x91B6, // - 0x5B5A,0x9B74, // - 0x5B5B,0x9B75, // - 0x5B5C,0x8E79, // - 0x5B5D,0x8D46, // - 0x5B5F,0x96D0, // - 0x5B63,0x8B47, // - 0x5B64,0x8CC7, // - 0x5B65,0x9B76, // - 0x5B66,0x8A77, // - 0x5B69,0x9B77, // - 0x5B6B,0x91B7, // - 0x5B70,0x9B78, // - 0x5B71,0x9BA1, // - 0x5B73,0x9B79, // - 0x5B75,0x9B7A, // - 0x5B78,0x9B7B, // - 0x5B7A,0x9B7D, // - 0x5B80,0x9B7E, // - 0x5B83,0x9B80, // - 0x5B85,0x91EE, // - 0x5B87,0x8946, // - 0x5B88,0x8EE7, // - 0x5B89,0x88C0, // - 0x5B8B,0x9176, // - 0x5B8C,0x8AAE, // - 0x5B8D,0x8EB3, // - 0x5B8F,0x8D47, // - 0x5B95,0x9386, // - 0x5B97,0x8F40, // - 0x5B98,0x8AAF, // - 0x5B99,0x9288, // - 0x5B9A,0x92E8, // - 0x5B9B,0x88B6, // - 0x5B9C,0x8B58, // - 0x5B9D,0x95F3, // - 0x5B9F,0x8EC0, // - 0x5BA2,0x8B71, // - 0x5BA3,0x90E9, // - 0x5BA4,0x8EBA, // - 0x5BA5,0x9747, // - 0x5BA6,0x9B81, // - 0x5BAE,0x8B7B, // - 0x5BB0,0x8DC9, // - 0x5BB3,0x8A51, // - 0x5BB4,0x8983, // - 0x5BB5,0x8FAA, // - 0x5BB6,0x89C6, // - 0x5BB8,0x9B82, // - 0x5BB9,0x9765, // - 0x5BBF,0x8F68, // - 0x5BC2,0x8EE2, // - 0x5BC3,0x9B83, // - 0x5BC4,0x8AF1, // - 0x5BC5,0x93D0, // - 0x5BC6,0x96A7, // - 0x5BC7,0x9B84, // - 0x5BC9,0x9B85, // - 0x5BCC,0x9578, // - 0x5BD0,0x9B87, // - 0x5BD2,0x8AA6, // - 0x5BD3,0x8BF5, // - 0x5BD4,0x9B86, // - 0x5BDB,0x8AB0, // - 0x5BDD,0x9051, // - 0x5BDE,0x9B8B, // - 0x5BDF,0x8E40, // - 0x5BE1,0x89C7, // - 0x5BE2,0x9B8A, // - 0x5BE4,0x9B88, // - 0x5BE5,0x9B8C, // - 0x5BE6,0x9B89, // - 0x5BE7,0x944A, // - 0x5BE8,0x9ECB, // - 0x5BE9,0x9052, // - 0x5BEB,0x9B8D, // - 0x5BEE,0x97BE, // - 0x5BF0,0x9B8E, // - 0x5BF3,0x9B90, // - 0x5BF5,0x929E, // - 0x5BF6,0x9B8F, // - 0x5BF8,0x90A1, // - 0x5BFA,0x8E9B, // - 0x5BFE,0x91CE, // - 0x5BFF,0x8EF5, // - 0x5C01,0x9595, // - 0x5C02,0x90EA, // - 0x5C04,0x8ECB, // - 0x5C05,0x9B91, // - 0x5C06,0x8FAB, // - 0x5C07,0x9B92, // - 0x5C08,0x9B93, // - 0x5C09,0x88D1, // - 0x5C0A,0x91B8, // - 0x5C0B,0x9071, // - 0x5C0D,0x9B94, // - 0x5C0E,0x93B1, // - 0x5C0F,0x8FAC, // - 0x5C11,0x8FAD, // - 0x5C13,0x9B95, // - 0x5C16,0x90EB, // - 0x5C1A,0x8FAE, // - 0x5C20,0x9B96, // - 0x5C22,0x9B97, // - 0x5C24,0x96DE, // - 0x5C28,0x9B98, // - 0x5C2D,0x8BC4, // - 0x5C31,0x8F41, // - 0x5C38,0x9B99, // - 0x5C39,0x9B9A, // - 0x5C3A,0x8EDA, // - 0x5C3B,0x904B, // - 0x5C3C,0x93F2, // - 0x5C3D,0x9073, // - 0x5C3E,0x94F6, // - 0x5C3F,0x9441, // - 0x5C40,0x8BC7, // - 0x5C41,0x9B9B, // - 0x5C45,0x8B8F, // - 0x5C46,0x9B9C, // - 0x5C48,0x8BFC, // - 0x5C4A,0x93CD, // - 0x5C4B,0x89AE, // - 0x5C4D,0x8E72, // - 0x5C4E,0x9B9D, // - 0x5C4F,0x9BA0, // - 0x5C50,0x9B9F, // - 0x5C51,0x8BFB, // - 0x5C53,0x9B9E, // - 0x5C55,0x9357, // - 0x5C5E,0x91AE, // - 0x5C60,0x936A, // - 0x5C61,0x8EC6, // - 0x5C64,0x9177, // - 0x5C65,0x979A, // - 0x5C6C,0x9BA2, // - 0x5C6E,0x9BA3, // - 0x5C6F,0x93D4, // - 0x5C71,0x8E52, // - 0x5C76,0x9BA5, // - 0x5C79,0x9BA6, // - 0x5C8C,0x9BA7, // - 0x5C90,0x8AF2, // - 0x5C91,0x9BA8, // - 0x5C94,0x9BA9, // - 0x5CA1,0x89AA, // - 0x5CA8,0x915A, // - 0x5CA9,0x8AE2, // - 0x5CAB,0x9BAB, // - 0x5CAC,0x96A6, // - 0x5CB1,0x91D0, // - 0x5CB3,0x8A78, // - 0x5CB6,0x9BAD, // - 0x5CB7,0x9BAF, // - 0x5CB8,0x8ADD, // - 0x5CBB,0x9BAC, // - 0x5CBC,0x9BAE, // - 0x5CBE,0x9BB1, // - 0x5CC5,0x9BB0, // - 0x5CC7,0x9BB2, // - 0x5CD9,0x9BB3, // - 0x5CE0,0x93BB, // - 0x5CE1,0x8BAC, // - 0x5CE8,0x89E3, // - 0x5CE9,0x9BB4, // - 0x5CEA,0x9BB9, // - 0x5CED,0x9BB7, // - 0x5CEF,0x95F5, // - 0x5CF0,0x95F4, // - 0x5CF6,0x9387, // - 0x5CFA,0x9BB6, // - 0x5CFB,0x8F73, // - 0x5CFD,0x9BB5, // - 0x5D07,0x9092, // - 0x5D0B,0x9BBA, // - 0x5D0E,0x8DE8, // - 0x5D11,0x9BC0, // - 0x5D14,0x9BC1, // - 0x5D15,0x9BBB, // - 0x5D16,0x8A52, // - 0x5D17,0x9BBC, // - 0x5D18,0x9BC5, // - 0x5D19,0x9BC4, // - 0x5D1A,0x9BC3, // - 0x5D1B,0x9BBF, // - 0x5D1F,0x9BBE, // - 0x5D22,0x9BC2, // - 0x5D29,0x95F6, // - 0x5D4B,0x9BC9, // - 0x5D4C,0x9BC6, // - 0x5D4E,0x9BC8, // - 0x5D50,0x9792, // - 0x5D52,0x9BC7, // - 0x5D5C,0x9BBD, // - 0x5D69,0x9093, // - 0x5D6C,0x9BCA, // - 0x5D6F,0x8DB5, // - 0x5D73,0x9BCB, // - 0x5D76,0x9BCC, // - 0x5D82,0x9BCF, // - 0x5D84,0x9BCE, // - 0x5D87,0x9BCD, // - 0x5D8B,0x9388, // - 0x5D8C,0x9BB8, // - 0x5D90,0x9BD5, // - 0x5D9D,0x9BD1, // - 0x5DA2,0x9BD0, // - 0x5DAC,0x9BD2, // - 0x5DAE,0x9BD3, // - 0x5DB7,0x9BD6, // - 0x5DBA,0x97E4, // - 0x5DBC,0x9BD7, // - 0x5DBD,0x9BD4, // - 0x5DC9,0x9BD8, // - 0x5DCC,0x8ADE, // - 0x5DCD,0x9BD9, // - 0x5DD2,0x9BDB, // - 0x5DD3,0x9BDA, // - 0x5DD6,0x9BDC, // - 0x5DDB,0x9BDD, // - 0x5DDD,0x90EC, // - 0x5DDE,0x8F42, // - 0x5DE1,0x8F84, // - 0x5DE3,0x9183, // - 0x5DE5,0x8D48, // - 0x5DE6,0x8DB6, // - 0x5DE7,0x8D49, // - 0x5DE8,0x8B90, // - 0x5DEB,0x9BDE, // - 0x5DEE,0x8DB7, // - 0x5DF1,0x8CC8, // - 0x5DF2,0x9BDF, // - 0x5DF3,0x96A4, // - 0x5DF4,0x9462, // - 0x5DF5,0x9BE0, // - 0x5DF7,0x8D4A, // - 0x5DFB,0x8AAA, // - 0x5DFD,0x9246, // - 0x5DFE,0x8BD0, // - 0x5E02,0x8E73, // - 0x5E03,0x957A, // - 0x5E06,0x94BF, // - 0x5E0B,0x9BE1, // - 0x5E0C,0x8AF3, // - 0x5E11,0x9BE4, // - 0x5E16,0x929F, // - 0x5E19,0x9BE3, // - 0x5E1A,0x9BE2, // - 0x5E1B,0x9BE5, // - 0x5E1D,0x92E9, // - 0x5E25,0x9083, // - 0x5E2B,0x8E74, // - 0x5E2D,0x90C8, // - 0x5E2F,0x91D1, // - 0x5E30,0x8B41, // - 0x5E33,0x92A0, // - 0x5E36,0x9BE6, // - 0x5E37,0x9BE7, // - 0x5E38,0x8FED, // - 0x5E3D,0x9658, // - 0x5E40,0x9BEA, // - 0x5E43,0x9BE9, // - 0x5E44,0x9BE8, // - 0x5E45,0x959D, // - 0x5E47,0x9BF1, // - 0x5E4C,0x9679, // - 0x5E4E,0x9BEB, // - 0x5E54,0x9BED, // - 0x5E55,0x968B, // - 0x5E57,0x9BEC, // - 0x5E5F,0x9BEE, // - 0x5E61,0x94A6, // - 0x5E62,0x9BEF, // - 0x5E63,0x95BC, // - 0x5E64,0x9BF0, // - 0x5E72,0x8AB1, // - 0x5E73,0x95BD, // - 0x5E74,0x944E, // - 0x5E75,0x9BF2, // - 0x5E76,0x9BF3, // - 0x5E78,0x8D4B, // - 0x5E79,0x8AB2, // - 0x5E7A,0x9BF4, // - 0x5E7B,0x8CB6, // - 0x5E7C,0x9763, // - 0x5E7D,0x9748, // - 0x5E7E,0x8AF4, // - 0x5E7F,0x9BF6, // - 0x5E81,0x92A1, // - 0x5E83,0x8D4C, // - 0x5E84,0x8FAF, // - 0x5E87,0x94DD, // - 0x5E8A,0x8FB0, // - 0x5E8F,0x8F98, // - 0x5E95,0x92EA, // - 0x5E96,0x95F7, // - 0x5E97,0x9358, // - 0x5E9A,0x8D4D, // - 0x5E9C,0x957B, // - 0x5EA0,0x9BF7, // - 0x5EA6,0x9378, // - 0x5EA7,0x8DC0, // - 0x5EAB,0x8CC9, // - 0x5EAD,0x92EB, // - 0x5EB5,0x88C1, // - 0x5EB6,0x8F8E, // - 0x5EB7,0x8D4E, // - 0x5EB8,0x9766, // - 0x5EC1,0x9BF8, // - 0x5EC2,0x9BF9, // - 0x5EC3,0x9470, // - 0x5EC8,0x9BFA, // - 0x5EC9,0x97F5, // - 0x5ECA,0x984C, // - 0x5ECF,0x9BFC, // - 0x5ED0,0x9BFB, // - 0x5ED3,0x8A66, // - 0x5ED6,0x9C40, // - 0x5EDA,0x9C43, // - 0x5EDB,0x9C44, // - 0x5EDD,0x9C42, // - 0x5EDF,0x955F, // - 0x5EE0,0x8FB1, // - 0x5EE1,0x9C46, // - 0x5EE2,0x9C45, // - 0x5EE3,0x9C41, // - 0x5EE8,0x9C47, // - 0x5EE9,0x9C48, // - 0x5EEC,0x9C49, // - 0x5EF0,0x9C4C, // - 0x5EF1,0x9C4A, // - 0x5EF3,0x9C4B, // - 0x5EF4,0x9C4D, // - 0x5EF6,0x8984, // - 0x5EF7,0x92EC, // - 0x5EF8,0x9C4E, // - 0x5EFA,0x8C9A, // - 0x5EFB,0x89F4, // - 0x5EFC,0x9455, // - 0x5EFE,0x9C4F, // - 0x5EFF,0x93F9, // - 0x5F01,0x95D9, // - 0x5F03,0x9C50, // - 0x5F04,0x984D, // - 0x5F09,0x9C51, // - 0x5F0A,0x95BE, // - 0x5F0B,0x9C54, // - 0x5F0C,0x989F, // - 0x5F0D,0x98AF, // - 0x5F0F,0x8EAE, // - 0x5F10,0x93F3, // - 0x5F11,0x9C55, // - 0x5F13,0x8B7C, // - 0x5F14,0x92A2, // - 0x5F15,0x88F8, // - 0x5F16,0x9C56, // - 0x5F17,0x95A4, // - 0x5F18,0x8D4F, // - 0x5F1B,0x926F, // - 0x5F1F,0x92ED, // - 0x5F25,0x96ED, // - 0x5F26,0x8CB7, // - 0x5F27,0x8CCA, // - 0x5F29,0x9C57, // - 0x5F2D,0x9C58, // - 0x5F2F,0x9C5E, // - 0x5F31,0x8EE3, // - 0x5F35,0x92A3, // - 0x5F37,0x8BAD, // - 0x5F38,0x9C59, // - 0x5F3C,0x954A, // - 0x5F3E,0x9265, // - 0x5F41,0x9C5A, // - 0x5F4A,0x8BAE, // - 0x5F4C,0x9C5C, // - 0x5F4E,0x9C5D, // - 0x5F51,0x9C5F, // - 0x5F53,0x9396, // - 0x5F56,0x9C60, // - 0x5F57,0x9C61, // - 0x5F59,0x9C62, // - 0x5F5C,0x9C53, // - 0x5F5D,0x9C52, // - 0x5F61,0x9C63, // - 0x5F62,0x8C60, // - 0x5F66,0x9546, // - 0x5F69,0x8DCA, // - 0x5F6A,0x9556, // - 0x5F6B,0x92A4, // - 0x5F6C,0x956A, // - 0x5F6D,0x9C64, // - 0x5F70,0x8FB2, // - 0x5F71,0x8965, // - 0x5F73,0x9C65, // - 0x5F77,0x9C66, // - 0x5F79,0x96F0, // - 0x5F7C,0x94DE, // - 0x5F7F,0x9C69, // - 0x5F80,0x899D, // - 0x5F81,0x90AA, // - 0x5F82,0x9C68, // - 0x5F83,0x9C67, // - 0x5F84,0x8C61, // - 0x5F85,0x91D2, // - 0x5F87,0x9C6D, // - 0x5F88,0x9C6B, // - 0x5F8A,0x9C6A, // - 0x5F8B,0x97A5, // - 0x5F8C,0x8CE3, // - 0x5F90,0x8F99, // - 0x5F91,0x9C6C, // - 0x5F92,0x936B, // - 0x5F93,0x8F5D, // - 0x5F97,0x93BE, // - 0x5F98,0x9C70, // - 0x5F99,0x9C6F, // - 0x5F9E,0x9C6E, // - 0x5FA0,0x9C71, // - 0x5FA1,0x8CE4, // - 0x5FA8,0x9C72, // - 0x5FA9,0x959C, // - 0x5FAA,0x8F7A, // - 0x5FAD,0x9C73, // - 0x5FAE,0x94F7, // - 0x5FB3,0x93BF, // - 0x5FB4,0x92A5, // - 0x5FB9,0x934F, // - 0x5FBC,0x9C74, // - 0x5FBD,0x8B4A, // - 0x5FC3,0x9053, // - 0x5FC5,0x954B, // - 0x5FCC,0x8AF5, // - 0x5FCD,0x9445, // - 0x5FD6,0x9C75, // - 0x5FD7,0x8E75, // - 0x5FD8,0x9659, // - 0x5FD9,0x965A, // - 0x5FDC,0x899E, // - 0x5FDD,0x9C7A, // - 0x5FE0,0x9289, // - 0x5FE4,0x9C77, // - 0x5FEB,0x89F5, // - 0x5FF0,0x9CAB, // - 0x5FF1,0x9C79, // - 0x5FF5,0x944F, // - 0x5FF8,0x9C78, // - 0x5FFB,0x9C76, // - 0x5FFD,0x8D9A, // - 0x5FFF,0x9C7C, // - 0x600E,0x9C83, // - 0x600F,0x9C89, // - 0x6010,0x9C81, // - 0x6012,0x937B, // - 0x6015,0x9C86, // - 0x6016,0x957C, // - 0x6019,0x9C80, // - 0x601B,0x9C85, // - 0x601C,0x97E5, // - 0x601D,0x8E76, // - 0x6020,0x91D3, // - 0x6021,0x9C7D, // - 0x6025,0x8B7D, // - 0x6026,0x9C88, // - 0x6027,0x90AB, // - 0x6028,0x8985, // - 0x6029,0x9C82, // - 0x602A,0x89F6, // - 0x602B,0x9C87, // - 0x602F,0x8BAF, // - 0x6031,0x9C84, // - 0x603A,0x9C8A, // - 0x6041,0x9C8C, // - 0x6042,0x9C96, // - 0x6043,0x9C94, // - 0x6046,0x9C91, // - 0x604A,0x9C90, // - 0x604B,0x97F6, // - 0x604D,0x9C92, // - 0x6050,0x8BB0, // - 0x6052,0x8D50, // - 0x6055,0x8F9A, // - 0x6059,0x9C99, // - 0x605A,0x9C8B, // - 0x605F,0x9C8F, // - 0x6060,0x9C7E, // - 0x6062,0x89F8, // - 0x6063,0x9C93, // - 0x6064,0x9C95, // - 0x6065,0x9270, // - 0x6068,0x8DA6, // - 0x6069,0x89B6, // - 0x606A,0x9C8D, // - 0x606B,0x9C98, // - 0x606C,0x9C97, // - 0x606D,0x8BB1, // - 0x606F,0x91A7, // - 0x6070,0x8A86, // - 0x6075,0x8C62, // - 0x6077,0x9C8E, // - 0x6081,0x9C9A, // - 0x6083,0x9C9D, // - 0x6084,0x9C9F, // - 0x6089,0x8EBB, // - 0x608B,0x9CA5, // - 0x608C,0x92EE, // - 0x608D,0x9C9B, // - 0x6092,0x9CA3, // - 0x6094,0x89F7, // - 0x6096,0x9CA1, // - 0x6097,0x9CA2, // - 0x609A,0x9C9E, // - 0x609B,0x9CA0, // - 0x609F,0x8CE5, // - 0x60A0,0x9749, // - 0x60A3,0x8AB3, // - 0x60A6,0x8978, // - 0x60A7,0x9CA4, // - 0x60A9,0x9459, // - 0x60AA,0x88AB, // - 0x60B2,0x94DF, // - 0x60B3,0x9C7B, // - 0x60B4,0x9CAA, // - 0x60B5,0x9CAE, // - 0x60B6,0x96E3, // - 0x60B8,0x9CA7, // - 0x60BC,0x9389, // - 0x60BD,0x9CAC, // - 0x60C5,0x8FEE, // - 0x60C6,0x9CAD, // - 0x60C7,0x93D5, // - 0x60D1,0x9866, // - 0x60D3,0x9CA9, // - 0x60D8,0x9CAF, // - 0x60DA,0x8D9B, // - 0x60DC,0x90C9, // - 0x60DF,0x88D2, // - 0x60E0,0x9CA8, // - 0x60E1,0x9CA6, // - 0x60E3,0x9179, // - 0x60E7,0x9C9C, // - 0x60E8,0x8E53, // - 0x60F0,0x91C4, // - 0x60F1,0x9CBB, // - 0x60F3,0x917A, // - 0x60F4,0x9CB6, // - 0x60F6,0x9CB3, // - 0x60F7,0x9CB4, // - 0x60F9,0x8EE4, // - 0x60FA,0x9CB7, // - 0x60FB,0x9CBA, // - 0x6100,0x9CB5, // - 0x6101,0x8F44, // - 0x6103,0x9CB8, // - 0x6106,0x9CB2, // - 0x6108,0x96FA, // - 0x6109,0x96F9, // - 0x610D,0x9CBC, // - 0x610E,0x9CBD, // - 0x610F,0x88D3, // - 0x6115,0x9CB1, // - 0x611A,0x8BF0, // - 0x611B,0x88A4, // - 0x611F,0x8AB4, // - 0x6121,0x9CB9, // - 0x6127,0x9CC1, // - 0x6128,0x9CC0, // - 0x612C,0x9CC5, // - 0x6134,0x9CC6, // - 0x613C,0x9CC4, // - 0x613D,0x9CC7, // - 0x613E,0x9CBF, // - 0x613F,0x9CC3, // - 0x6142,0x9CC8, // - 0x6144,0x9CC9, // - 0x6147,0x9CBE, // - 0x6148,0x8E9C, // - 0x614A,0x9CC2, // - 0x614B,0x91D4, // - 0x614C,0x8D51, // - 0x614D,0x9CB0, // - 0x614E,0x9054, // - 0x6153,0x9CD6, // - 0x6155,0x95E7, // - 0x6158,0x9CCC, // - 0x6159,0x9CCD, // - 0x615A,0x9CCE, // - 0x615D,0x9CD5, // - 0x615F,0x9CD4, // - 0x6162,0x969D, // - 0x6163,0x8AB5, // - 0x6165,0x9CD2, // - 0x6167,0x8C64, // - 0x6168,0x8A53, // - 0x616B,0x9CCF, // - 0x616E,0x97B6, // - 0x616F,0x9CD1, // - 0x6170,0x88D4, // - 0x6171,0x9CD3, // - 0x6173,0x9CCA, // - 0x6174,0x9CD0, // - 0x6175,0x9CD7, // - 0x6176,0x8C63, // - 0x6177,0x9CCB, // - 0x617E,0x977C, // - 0x6182,0x974A, // - 0x6187,0x9CDA, // - 0x618A,0x9CDE, // - 0x618E,0x919E, // - 0x6190,0x97F7, // - 0x6191,0x9CDF, // - 0x6194,0x9CDC, // - 0x6196,0x9CD9, // - 0x6199,0x9CD8, // - 0x619A,0x9CDD, // - 0x61A4,0x95AE, // - 0x61A7,0x93B2, // - 0x61A9,0x8C65, // - 0x61AB,0x9CE0, // - 0x61AC,0x9CDB, // - 0x61AE,0x9CE1, // - 0x61B2,0x8C9B, // - 0x61B6,0x89AF, // - 0x61BA,0x9CE9, // - 0x61BE,0x8AB6, // - 0x61C3,0x9CE7, // - 0x61C6,0x9CE8, // - 0x61C7,0x8DA7, // - 0x61C8,0x9CE6, // - 0x61C9,0x9CE4, // - 0x61CA,0x9CE3, // - 0x61CB,0x9CEA, // - 0x61CC,0x9CE2, // - 0x61CD,0x9CEC, // - 0x61D0,0x89F9, // - 0x61E3,0x9CEE, // - 0x61E6,0x9CED, // - 0x61F2,0x92A6, // - 0x61F4,0x9CF1, // - 0x61F6,0x9CEF, // - 0x61F7,0x9CE5, // - 0x61F8,0x8C9C, // - 0x61FA,0x9CF0, // - 0x61FC,0x9CF4, // - 0x61FD,0x9CF3, // - 0x61FE,0x9CF5, // - 0x61FF,0x9CF2, // - 0x6200,0x9CF6, // - 0x6208,0x9CF7, // - 0x6209,0x9CF8, // - 0x620A,0x95E8, // - 0x620C,0x9CFA, // - 0x620D,0x9CF9, // - 0x620E,0x8F5E, // - 0x6210,0x90AC, // - 0x6211,0x89E4, // - 0x6212,0x89FA, // - 0x6214,0x9CFB, // - 0x6216,0x88BD, // - 0x621A,0x90CA, // - 0x621B,0x9CFC, // - 0x621D,0xE6C1, // - 0x621E,0x9D40, // - 0x621F,0x8C81, // - 0x6221,0x9D41, // - 0x6226,0x90ED, // - 0x622A,0x9D42, // - 0x622E,0x9D43, // - 0x622F,0x8B59, // - 0x6230,0x9D44, // - 0x6232,0x9D45, // - 0x6233,0x9D46, // - 0x6234,0x91D5, // - 0x6238,0x8CCB, // - 0x623B,0x96DF, // - 0x6240,0x8F8A, // - 0x6241,0x9D47, // - 0x6247,0x90EE, // - 0x6248,0xE7BB, // - 0x6249,0x94E0, // - 0x624B,0x8EE8, // - 0x624D,0x8DCB, // - 0x624E,0x9D48, // - 0x6253,0x91C5, // - 0x6255,0x95A5, // - 0x6258,0x91EF, // - 0x625B,0x9D4B, // - 0x625E,0x9D49, // - 0x6260,0x9D4C, // - 0x6263,0x9D4A, // - 0x6268,0x9D4D, // - 0x626E,0x95AF, // - 0x6271,0x88B5, // - 0x6276,0x957D, // - 0x6279,0x94E1, // - 0x627C,0x9D4E, // - 0x627E,0x9D51, // - 0x627F,0x8FB3, // - 0x6280,0x8B5A, // - 0x6282,0x9D4F, // - 0x6283,0x9D56, // - 0x6284,0x8FB4, // - 0x6289,0x9D50, // - 0x628A,0x9463, // - 0x6291,0x977D, // - 0x6292,0x9D52, // - 0x6293,0x9D53, // - 0x6294,0x9D57, // - 0x6295,0x938A, // - 0x6296,0x9D54, // - 0x6297,0x8D52, // - 0x6298,0x90DC, // - 0x629B,0x9D65, // - 0x629C,0x94B2, // - 0x629E,0x91F0, // - 0x62AB,0x94E2, // - 0x62AC,0x9DAB, // - 0x62B1,0x95F8, // - 0x62B5,0x92EF, // - 0x62B9,0x9695, // - 0x62BB,0x9D5A, // - 0x62BC,0x899F, // - 0x62BD,0x928A, // - 0x62C2,0x9D63, // - 0x62C5,0x9253, // - 0x62C6,0x9D5D, // - 0x62C7,0x9D64, // - 0x62C8,0x9D5F, // - 0x62C9,0x9D66, // - 0x62CA,0x9D62, // - 0x62CC,0x9D61, // - 0x62CD,0x948F, // - 0x62D0,0x89FB, // - 0x62D1,0x9D59, // - 0x62D2,0x8B91, // - 0x62D3,0x91F1, // - 0x62D4,0x9D55, // - 0x62D7,0x9D58, // - 0x62D8,0x8D53, // - 0x62D9,0x90D9, // - 0x62DB,0x8FB5, // - 0x62DC,0x9D60, // - 0x62DD,0x9471, // - 0x62E0,0x8B92, // - 0x62E1,0x8A67, // - 0x62EC,0x8A87, // - 0x62ED,0x9040, // - 0x62EE,0x9D68, // - 0x62EF,0x9D6D, // - 0x62F1,0x9D69, // - 0x62F3,0x8C9D, // - 0x62F5,0x9D6E, // - 0x62F6,0x8E41, // - 0x62F7,0x8D89, // - 0x62FE,0x8F45, // - 0x62FF,0x9D5C, // - 0x6301,0x8E9D, // - 0x6302,0x9D6B, // - 0x6307,0x8E77, // - 0x6308,0x9D6C, // - 0x6309,0x88C2, // - 0x630C,0x9D67, // - 0x6311,0x92A7, // - 0x6319,0x8B93, // - 0x631F,0x8BB2, // - 0x6327,0x9D6A, // - 0x6328,0x88A5, // - 0x632B,0x8DC1, // - 0x632F,0x9055, // - 0x633A,0x92F0, // - 0x633D,0x94D2, // - 0x633E,0x9D70, // - 0x633F,0x917D, // - 0x6349,0x91A8, // - 0x634C,0x8E4A, // - 0x634D,0x9D71, // - 0x634F,0x9D73, // - 0x6350,0x9D6F, // - 0x6355,0x95DF, // - 0x6357,0x92BB, // - 0x635C,0x917B, // - 0x6367,0x95F9, // - 0x6368,0x8ECC, // - 0x6369,0x9D80, // - 0x636B,0x9D7E, // - 0x636E,0x9098, // - 0x6372,0x8C9E, // - 0x6376,0x9D78, // - 0x6377,0x8FB7, // - 0x637A,0x93E6, // - 0x637B,0x9450, // - 0x6380,0x9D76, // - 0x6383,0x917C, // - 0x6388,0x8EF6, // - 0x6389,0x9D7B, // - 0x638C,0x8FB6, // - 0x638E,0x9D75, // - 0x638F,0x9D7A, // - 0x6392,0x9472, // - 0x6396,0x9D74, // - 0x6398,0x8C40, // - 0x639B,0x8A7C, // - 0x639F,0x9D7C, // - 0x63A0,0x97A9, // - 0x63A1,0x8DCC, // - 0x63A2,0x9254, // - 0x63A3,0x9D79, // - 0x63A5,0x90DA, // - 0x63A7,0x8D54, // - 0x63A8,0x9084, // - 0x63A9,0x8986, // - 0x63AB,0x9D77, // - 0x63AC,0x8B64, // - 0x63B2,0x8C66, // - 0x63B4,0x92CD, // - 0x63B5,0x9D7D, // - 0x63BB,0x917E, // - 0x63BE,0x9D81, // - 0x63C0,0x9D83, // - 0x63C3,0x91B5, // - 0x63C4,0x9D89, // - 0x63C6,0x9D84, // - 0x63C9,0x9D86, // - 0x63CF,0x9560, // - 0x63D0,0x92F1, // - 0x63D2,0x9D87, // - 0x63D6,0x974B, // - 0x63DA,0x9767, // - 0x63DB,0x8AB7, // - 0x63E1,0x88AC, // - 0x63E3,0x9D85, // - 0x63E9,0x9D82, // - 0x63EE,0x8AF6, // - 0x63F4,0x8987, // - 0x63F6,0x9D88, // - 0x63FA,0x9768, // - 0x6406,0x9D8C, // - 0x640D,0x91B9, // - 0x640F,0x9D93, // - 0x6413,0x9D8D, // - 0x6416,0x9D8A, // - 0x6417,0x9D91, // - 0x641C,0x9D72, // - 0x6426,0x9D8E, // - 0x6428,0x9D92, // - 0x642C,0x94C0, // - 0x642D,0x938B, // - 0x6434,0x9D8B, // - 0x6436,0x9D8F, // - 0x643A,0x8C67, // - 0x643E,0x8DEF, // - 0x6442,0x90DB, // - 0x644E,0x9D97, // - 0x6458,0x9345, // - 0x6467,0x9D94, // - 0x6469,0x9680, // - 0x646F,0x9D95, // - 0x6476,0x9D96, // - 0x6478,0x96CC, // - 0x647A,0x90A0, // - 0x6483,0x8C82, // - 0x6488,0x9D9D, // - 0x6492,0x8E54, // - 0x6493,0x9D9A, // - 0x6495,0x9D99, // - 0x649A,0x9451, // - 0x649E,0x93B3, // - 0x64A4,0x9350, // - 0x64A5,0x9D9B, // - 0x64A9,0x9D9C, // - 0x64AB,0x958F, // - 0x64AD,0x9464, // - 0x64AE,0x8E42, // - 0x64B0,0x90EF, // - 0x64B2,0x966F, // - 0x64B9,0x8A68, // - 0x64BB,0x9DA3, // - 0x64BC,0x9D9E, // - 0x64C1,0x9769, // - 0x64C2,0x9DA5, // - 0x64C5,0x9DA1, // - 0x64C7,0x9DA2, // - 0x64CD,0x9180, // - 0x64D2,0x9DA0, // - 0x64D4,0x9D5E, // - 0x64D8,0x9DA4, // - 0x64DA,0x9D9F, // - 0x64E0,0x9DA9, // - 0x64E1,0x9DAA, // - 0x64E2,0x9346, // - 0x64E3,0x9DAC, // - 0x64E6,0x8E43, // - 0x64E7,0x9DA7, // - 0x64EF,0x9DAD, // - 0x64F1,0x9DA6, // - 0x64F2,0x9DB1, // - 0x64F4,0x9DB0, // - 0x64F6,0x9DAF, // - 0x64FA,0x9DB2, // - 0x64FD,0x9DB4, // - 0x64FE,0x8FEF, // - 0x6500,0x9DB3, // - 0x6505,0x9DB7, // - 0x6518,0x9DB5, // - 0x651C,0x9DB6, // - 0x651D,0x9D90, // - 0x6523,0x9DB9, // - 0x6524,0x9DB8, // - 0x652A,0x9D98, // - 0x652B,0x9DBA, // - 0x652C,0x9DAE, // - 0x652F,0x8E78, // - 0x6534,0x9DBB, // - 0x6535,0x9DBC, // - 0x6536,0x9DBE, // - 0x6537,0x9DBD, // - 0x6538,0x9DBF, // - 0x6539,0x89FC, // - 0x653B,0x8D55, // - 0x653E,0x95FA, // - 0x653F,0x90AD, // - 0x6545,0x8CCC, // - 0x6548,0x9DC1, // - 0x654D,0x9DC4, // - 0x654F,0x9571, // - 0x6551,0x8B7E, // - 0x6555,0x9DC3, // - 0x6556,0x9DC2, // - 0x6557,0x9473, // - 0x6558,0x9DC5, // - 0x6559,0x8BB3, // - 0x655D,0x9DC7, // - 0x655E,0x9DC6, // - 0x6562,0x8AB8, // - 0x6563,0x8E55, // - 0x6566,0x93D6, // - 0x656C,0x8C68, // - 0x6570,0x9094, // - 0x6572,0x9DC8, // - 0x6574,0x90AE, // - 0x6575,0x9347, // - 0x6577,0x957E, // - 0x6578,0x9DC9, // - 0x6582,0x9DCA, // - 0x6583,0x9DCB, // - 0x6587,0x95B6, // - 0x6588,0x9B7C, // - 0x6589,0x90C4, // - 0x658C,0x956B, // - 0x658E,0x8DD6, // - 0x6590,0x94E3, // - 0x6591,0x94C1, // - 0x6597,0x936C, // - 0x6599,0x97BF, // - 0x659B,0x9DCD, // - 0x659C,0x8ECE, // - 0x659F,0x9DCE, // - 0x65A1,0x88B4, // - 0x65A4,0x8BD2, // - 0x65A5,0x90CB, // - 0x65A7,0x9580, // - 0x65AB,0x9DCF, // - 0x65AC,0x8E61, // - 0x65AD,0x9266, // - 0x65AF,0x8E7A, // - 0x65B0,0x9056, // - 0x65B7,0x9DD0, // - 0x65B9,0x95FB, // - 0x65BC,0x8997, // - 0x65BD,0x8E7B, // - 0x65C1,0x9DD3, // - 0x65C3,0x9DD1, // - 0x65C4,0x9DD4, // - 0x65C5,0x97B7, // - 0x65C6,0x9DD2, // - 0x65CB,0x90F9, // - 0x65CC,0x9DD5, // - 0x65CF,0x91B0, // - 0x65D2,0x9DD6, // - 0x65D7,0x8AF8, // - 0x65D9,0x9DD8, // - 0x65DB,0x9DD7, // - 0x65E0,0x9DD9, // - 0x65E1,0x9DDA, // - 0x65E2,0x8AF9, // - 0x65E5,0x93FA, // - 0x65E6,0x9255, // - 0x65E7,0x8B8C, // - 0x65E8,0x8E7C, // - 0x65E9,0x9181, // - 0x65EC,0x8F7B, // - 0x65ED,0x88AE, // - 0x65F1,0x9DDB, // - 0x65FA,0x89A0, // - 0x65FB,0x9DDF, // - 0x6602,0x8D56, // - 0x6603,0x9DDE, // - 0x6606,0x8DA9, // - 0x6607,0x8FB8, // - 0x660A,0x9DDD, // - 0x660C,0x8FB9, // - 0x660E,0x96BE, // - 0x660F,0x8DA8, // - 0x6613,0x88D5, // - 0x6614,0x90CC, // - 0x661C,0x9DE4, // - 0x661F,0x90AF, // - 0x6620,0x8966, // - 0x6625,0x8F74, // - 0x6627,0x9686, // - 0x6628,0x8DF0, // - 0x662D,0x8FBA, // - 0x662F,0x90A5, // - 0x6634,0x9DE3, // - 0x6635,0x9DE1, // - 0x6636,0x9DE2, // - 0x663C,0x928B, // - 0x663F,0x9E45, // - 0x6641,0x9DE8, // - 0x6642,0x8E9E, // - 0x6643,0x8D57, // - 0x6644,0x9DE6, // - 0x6649,0x9DE7, // - 0x664B,0x9057, // - 0x664F,0x9DE5, // - 0x6652,0x8E4E, // - 0x665D,0x9DEA, // - 0x665E,0x9DE9, // - 0x665F,0x9DEE, // - 0x6662,0x9DEF, // - 0x6664,0x9DEB, // - 0x6666,0x8A41, // - 0x6667,0x9DEC, // - 0x6668,0x9DED, // - 0x6669,0x94D3, // - 0x666E,0x9581, // - 0x666F,0x8C69, // - 0x6670,0x9DF0, // - 0x6674,0x90B0, // - 0x6676,0x8FBB, // - 0x667A,0x9271, // - 0x6681,0x8BC5, // - 0x6683,0x9DF1, // - 0x6684,0x9DF5, // - 0x6687,0x89C9, // - 0x6688,0x9DF2, // - 0x6689,0x9DF4, // - 0x668E,0x9DF3, // - 0x6691,0x8F8B, // - 0x6696,0x9267, // - 0x6697,0x88C3, // - 0x6698,0x9DF6, // - 0x669D,0x9DF7, // - 0x66A2,0x92A8, // - 0x66A6,0x97EF, // - 0x66AB,0x8E62, // - 0x66AE,0x95E9, // - 0x66B4,0x965C, // - 0x66B8,0x9E41, // - 0x66B9,0x9DF9, // - 0x66BC,0x9DFC, // - 0x66BE,0x9DFB, // - 0x66C1,0x9DF8, // - 0x66C4,0x9E40, // - 0x66C7,0x93DC, // - 0x66C9,0x9DFA, // - 0x66D6,0x9E42, // - 0x66D9,0x8F8C, // - 0x66DA,0x9E43, // - 0x66DC,0x976A, // - 0x66DD,0x9498, // - 0x66E0,0x9E44, // - 0x66E6,0x9E46, // - 0x66E9,0x9E47, // - 0x66F0,0x9E48, // - 0x66F2,0x8BC8, // - 0x66F3,0x8967, // - 0x66F4,0x8D58, // - 0x66F5,0x9E49, // - 0x66F7,0x9E4A, // - 0x66F8,0x8F91, // - 0x66F9,0x9182, // - 0x66FC,0x99D6, // - 0x66FD,0x915D, // - 0x66FE,0x915C, // - 0x66FF,0x91D6, // - 0x6700,0x8DC5, // - 0x6703,0x98F0, // - 0x6708,0x8C8E, // - 0x6709,0x974C, // - 0x670B,0x95FC, // - 0x670D,0x959E, // - 0x670F,0x9E4B, // - 0x6714,0x8DF1, // - 0x6715,0x92BD, // - 0x6716,0x9E4C, // - 0x6717,0x984E, // - 0x671B,0x965D, // - 0x671D,0x92A9, // - 0x671E,0x9E4D, // - 0x671F,0x8AFA, // - 0x6726,0x9E4E, // - 0x6727,0x9E4F, // - 0x6728,0x96D8, // - 0x672A,0x96A2, // - 0x672B,0x9696, // - 0x672C,0x967B, // - 0x672D,0x8E44, // - 0x672E,0x9E51, // - 0x6731,0x8EE9, // - 0x6734,0x9670, // - 0x6736,0x9E53, // - 0x6737,0x9E56, // - 0x6738,0x9E55, // - 0x673A,0x8AF7, // - 0x673D,0x8B80, // - 0x673F,0x9E52, // - 0x6741,0x9E54, // - 0x6746,0x9E57, // - 0x6749,0x9099, // - 0x674E,0x979B, // - 0x674F,0x88C7, // - 0x6750,0x8DDE, // - 0x6751,0x91BA, // - 0x6753,0x8EDB, // - 0x6756,0x8FF1, // - 0x6759,0x9E5A, // - 0x675C,0x936D, // - 0x675E,0x9E58, // - 0x675F,0x91A9, // - 0x6760,0x9E59, // - 0x6761,0x8FF0, // - 0x6762,0x96DB, // - 0x6764,0x9E5C, // - 0x6765,0x9788, // - 0x676A,0x9E61, // - 0x676D,0x8D59, // - 0x676F,0x9474, // - 0x6770,0x9E5E, // - 0x6771,0x938C, // - 0x6772,0x9DDC, // - 0x6773,0x9DE0, // - 0x6775,0x8B6E, // - 0x6777,0x9466, // - 0x677C,0x9E60, // - 0x677E,0x8FBC, // - 0x677F,0x94C2, // - 0x6785,0x9E66, // - 0x6787,0x94F8, // - 0x6789,0x9E5D, // - 0x678B,0x9E63, // - 0x678C,0x9E62, // - 0x6790,0x90CD, // - 0x6795,0x968D, // - 0x6797,0x97D1, // - 0x679A,0x9687, // - 0x679C,0x89CA, // - 0x679D,0x8E7D, // - 0x67A0,0x9867, // - 0x67A1,0x9E65, // - 0x67A2,0x9095, // - 0x67A6,0x9E64, // - 0x67A9,0x9E5F, // - 0x67AF,0x8CCD, // - 0x67B3,0x9E6B, // - 0x67B4,0x9E69, // - 0x67B6,0x89CB, // - 0x67B7,0x9E67, // - 0x67B8,0x9E6D, // - 0x67B9,0x9E73, // - 0x67C1,0x91C6, // - 0x67C4,0x95BF, // - 0x67C6,0x9E75, // - 0x67CA,0x9541, // - 0x67CE,0x9E74, // - 0x67CF,0x9490, // - 0x67D0,0x965E, // - 0x67D1,0x8AB9, // - 0x67D3,0x90F5, // - 0x67D4,0x8F5F, // - 0x67D8,0x92D1, // - 0x67DA,0x974D, // - 0x67DD,0x9E70, // - 0x67DE,0x9E6F, // - 0x67E2,0x9E71, // - 0x67E4,0x9E6E, // - 0x67E7,0x9E76, // - 0x67E9,0x9E6C, // - 0x67EC,0x9E6A, // - 0x67EE,0x9E72, // - 0x67EF,0x9E68, // - 0x67F1,0x928C, // - 0x67F3,0x96F6, // - 0x67F4,0x8EC4, // - 0x67F5,0x8DF2, // - 0x67FB,0x8DB8, // - 0x67FE,0x968F, // - 0x67FF,0x8A60, // - 0x6802,0x92CC, // - 0x6803,0x93C8, // - 0x6804,0x8968, // - 0x6813,0x90F0, // - 0x6816,0x90B2, // - 0x6817,0x8C49, // - 0x681E,0x9E78, // - 0x6821,0x8D5A, // - 0x6822,0x8A9C, // - 0x6829,0x9E7A, // - 0x682A,0x8A94, // - 0x682B,0x9E81, // - 0x6832,0x9E7D, // - 0x6834,0x90F1, // - 0x6838,0x8A6A, // - 0x6839,0x8DAA, // - 0x683C,0x8A69, // - 0x683D,0x8DCD, // - 0x6840,0x9E7B, // - 0x6841,0x8C85, // - 0x6842,0x8C6A, // - 0x6843,0x938D, // - 0x6846,0x9E79, // - 0x6848,0x88C4, // - 0x684D,0x9E7C, // - 0x684E,0x9E7E, // - 0x6850,0x8BCB, // - 0x6851,0x8C4B, // - 0x6853,0x8ABA, // - 0x6854,0x8B6A, // - 0x6859,0x9E82, // - 0x685C,0x8DF7, // - 0x685D,0x9691, // - 0x685F,0x8E56, // - 0x6863,0x9E83, // - 0x6867,0x954F, // - 0x6874,0x9E8F, // - 0x6876,0x89B1, // - 0x6877,0x9E84, // - 0x687E,0x9E95, // - 0x687F,0x9E85, // - 0x6881,0x97C0, // - 0x6883,0x9E8C, // - 0x6885,0x947E, // - 0x688D,0x9E94, // - 0x688F,0x9E87, // - 0x6893,0x88B2, // - 0x6894,0x9E89, // - 0x689B,0x9E8B, // - 0x689D,0x9E8A, // - 0x689F,0x9E86, // - 0x68A0,0x9E91, // - 0x68A2,0x8FBD, // - 0x68A6,0x9AEB, // - 0x68A7,0x8CE6, // - 0x68A8,0x979C, // - 0x68AD,0x9E88, // - 0x68AF,0x92F2, // - 0x68B0,0x8A42, // - 0x68B1,0x8DAB, // - 0x68B3,0x9E80, // - 0x68B5,0x9E90, // - 0x68B6,0x8A81, // - 0x68B9,0x9E8E, // - 0x68BA,0x9E92, // - 0x68BC,0x938E, // - 0x68C4,0x8AFC, // - 0x68C6,0x9EB0, // - 0x68C9,0x96C7, // - 0x68CA,0x9E97, // - 0x68CB,0x8AFB, // - 0x68CD,0x9E9E, // - 0x68D2,0x965F, // - 0x68D4,0x9E9F, // - 0x68D5,0x9EA1, // - 0x68D7,0x9EA5, // - 0x68D8,0x9E99, // - 0x68DA,0x9249, // - 0x68DF,0x938F, // - 0x68E0,0x9EA9, // - 0x68E1,0x9E9C, // - 0x68E3,0x9EA6, // - 0x68E7,0x9EA0, // - 0x68EE,0x9058, // - 0x68EF,0x9EAA, // - 0x68F2,0x90B1, // - 0x68F9,0x9EA8, // - 0x68FA,0x8ABB, // - 0x6900,0x986F, // - 0x6901,0x9E96, // - 0x6904,0x9EA4, // - 0x6905,0x88D6, // - 0x6908,0x9E98, // - 0x690B,0x96B8, // - 0x690C,0x9E9D, // - 0x690D,0x9041, // - 0x690E,0x92C5, // - 0x690F,0x9E93, // - 0x6912,0x9EA3, // - 0x6919,0x909A, // - 0x691A,0x9EAD, // - 0x691B,0x8A91, // - 0x691C,0x8C9F, // - 0x6921,0x9EAF, // - 0x6922,0x9E9A, // - 0x6923,0x9EAE, // - 0x6925,0x9EA7, // - 0x6926,0x9E9B, // - 0x6928,0x9EAB, // - 0x692A,0x9EAC, // - 0x6930,0x9EBD, // - 0x6934,0x93CC, // - 0x6936,0x9EA2, // - 0x6939,0x9EB9, // - 0x693D,0x9EBB, // - 0x693F,0x92D6, // - 0x694A,0x976B, // - 0x6953,0x9596, // - 0x6954,0x9EB6, // - 0x6955,0x91C8, // - 0x6959,0x9EBC, // - 0x695A,0x915E, // - 0x695C,0x9EB3, // - 0x695D,0x9EC0, // - 0x695E,0x9EBF, // - 0x6960,0x93ED, // - 0x6961,0x9EBE, // - 0x6962,0x93E8, // - 0x696A,0x9EC2, // - 0x696B,0x9EB5, // - 0x696D,0x8BC6, // - 0x696E,0x9EB8, // - 0x696F,0x8F7C, // - 0x6973,0x9480, // - 0x6974,0x9EBA, // - 0x6975,0x8BC9, // - 0x6977,0x9EB2, // - 0x6978,0x9EB4, // - 0x6979,0x9EB1, // - 0x697C,0x984F, // - 0x697D,0x8A79, // - 0x697E,0x9EB7, // - 0x6981,0x9EC1, // - 0x6982,0x8A54, // - 0x698A,0x8DE5, // - 0x698E,0x897C, // - 0x6991,0x9ED2, // - 0x6994,0x9850, // - 0x6995,0x9ED5, // - 0x699B,0x9059, // - 0x699C,0x9ED4, // - 0x69A0,0x9ED3, // - 0x69A7,0x9ED0, // - 0x69AE,0x9EC4, // - 0x69B1,0x9EE1, // - 0x69B2,0x9EC3, // - 0x69B4,0x9ED6, // - 0x69BB,0x9ECE, // - 0x69BE,0x9EC9, // - 0x69BF,0x9EC6, // - 0x69C1,0x9EC7, // - 0x69C3,0x9ECF, // - 0x69C7,0xEAA0, // - 0x69CA,0x9ECC, // - 0x69CB,0x8D5C, // - 0x69CC,0x92C6, // - 0x69CD,0x9184, // - 0x69CE,0x9ECA, // - 0x69D0,0x9EC5, // - 0x69D3,0x9EC8, // - 0x69D8,0x976C, // - 0x69D9,0x968A, // - 0x69DD,0x9ECD, // - 0x69DE,0x9ED7, // - 0x69E7,0x9EDF, // - 0x69E8,0x9ED8, // - 0x69EB,0x9EE5, // - 0x69ED,0x9EE3, // - 0x69F2,0x9EDE, // - 0x69F9,0x9EDD, // - 0x69FB,0x92CE, // - 0x69FD,0x9185, // - 0x69FF,0x9EDB, // - 0x6A02,0x9ED9, // - 0x6A05,0x9EE0, // - 0x6A0A,0x9EE6, // - 0x6A0B,0x94F3, // - 0x6A0C,0x9EEC, // - 0x6A12,0x9EE7, // - 0x6A13,0x9EEA, // - 0x6A14,0x9EE4, // - 0x6A17,0x9294, // - 0x6A19,0x9557, // - 0x6A1B,0x9EDA, // - 0x6A1E,0x9EE2, // - 0x6A1F,0x8FBE, // - 0x6A21,0x96CD, // - 0x6A22,0x9EF6, // - 0x6A23,0x9EE9, // - 0x6A29,0x8CA0, // - 0x6A2A,0x89A1, // - 0x6A2B,0x8A7E, // - 0x6A2E,0x9ED1, // - 0x6A35,0x8FBF, // - 0x6A36,0x9EEE, // - 0x6A38,0x9EF5, // - 0x6A39,0x8EF7, // - 0x6A3A,0x8A92, // - 0x6A3D,0x924D, // - 0x6A44,0x9EEB, // - 0x6A47,0x9EF0, // - 0x6A48,0x9EF4, // - 0x6A4B,0x8BB4, // - 0x6A58,0x8B6B, // - 0x6A59,0x9EF2, // - 0x6A5F,0x8B40, // - 0x6A61,0x93C9, // - 0x6A62,0x9EF1, // - 0x6A66,0x9EF3, // - 0x6A72,0x9EED, // - 0x6A78,0x9EEF, // - 0x6A7F,0x8A80, // - 0x6A80,0x9268, // - 0x6A84,0x9EFA, // - 0x6A8D,0x9EF8, // - 0x6A8E,0x8CE7, // - 0x6A90,0x9EF7, // - 0x6A97,0x9F40, // - 0x6A9C,0x9E77, // - 0x6AA0,0x9EF9, // - 0x6AA2,0x9EFB, // - 0x6AA3,0x9EFC, // - 0x6AAA,0x9F4B, // - 0x6AAC,0x9F47, // - 0x6AAE,0x9E8D, // - 0x6AB3,0x9F46, // - 0x6AB8,0x9F45, // - 0x6ABB,0x9F42, // - 0x6AC1,0x9EE8, // - 0x6AC2,0x9F44, // - 0x6AC3,0x9F43, // - 0x6AD1,0x9F49, // - 0x6AD3,0x9845, // - 0x6ADA,0x9F4C, // - 0x6ADB,0x8BF9, // - 0x6ADE,0x9F48, // - 0x6ADF,0x9F4A, // - 0x6AE8,0x94A5, // - 0x6AEA,0x9F4D, // - 0x6AFA,0x9F51, // - 0x6AFB,0x9F4E, // - 0x6B04,0x9793, // - 0x6B05,0x9F4F, // - 0x6B0A,0x9EDC, // - 0x6B12,0x9F52, // - 0x6B16,0x9F53, // - 0x6B1D,0x8954, // - 0x6B1F,0x9F55, // - 0x6B20,0x8C87, // - 0x6B21,0x8E9F, // - 0x6B23,0x8BD3, // - 0x6B27,0x89A2, // - 0x6B32,0x977E, // - 0x6B37,0x9F57, // - 0x6B38,0x9F56, // - 0x6B39,0x9F59, // - 0x6B3A,0x8B5C, // - 0x6B3D,0x8BD4, // - 0x6B3E,0x8ABC, // - 0x6B43,0x9F5C, // - 0x6B49,0x9F5D, // - 0x6B4C,0x89CC, // - 0x6B4E,0x9256, // - 0x6B50,0x9F5E, // - 0x6B53,0x8ABD, // - 0x6B54,0x9F60, // - 0x6B59,0x9F5F, // - 0x6B5B,0x9F61, // - 0x6B5F,0x9F62, // - 0x6B61,0x9F63, // - 0x6B62,0x8E7E, // - 0x6B63,0x90B3, // - 0x6B64,0x8D9F, // - 0x6B66,0x9590, // - 0x6B69,0x95E0, // - 0x6B6A,0x9863, // - 0x6B6F,0x8E95, // - 0x6B73,0x8DCE, // - 0x6B74,0x97F0, // - 0x6B78,0x9F64, // - 0x6B79,0x9F65, // - 0x6B7B,0x8E80, // - 0x6B7F,0x9F66, // - 0x6B80,0x9F67, // - 0x6B83,0x9F69, // - 0x6B84,0x9F68, // - 0x6B86,0x9677, // - 0x6B89,0x8F7D, // - 0x6B8A,0x8EEA, // - 0x6B8B,0x8E63, // - 0x6B8D,0x9F6A, // - 0x6B95,0x9F6C, // - 0x6B96,0x9042, // - 0x6B98,0x9F6B, // - 0x6B9E,0x9F6D, // - 0x6BA4,0x9F6E, // - 0x6BAA,0x9F6F, // - 0x6BAB,0x9F70, // - 0x6BAF,0x9F71, // - 0x6BB1,0x9F73, // - 0x6BB2,0x9F72, // - 0x6BB3,0x9F74, // - 0x6BB4,0x89A3, // - 0x6BB5,0x9269, // - 0x6BB7,0x9F75, // - 0x6BBA,0x8E45, // - 0x6BBB,0x8A6B, // - 0x6BBC,0x9F76, // - 0x6BBF,0x9361, // - 0x6BC0,0x9ACA, // - 0x6BC5,0x8B42, // - 0x6BC6,0x9F77, // - 0x6BCB,0x9F78, // - 0x6BCD,0x95EA, // - 0x6BCE,0x9688, // - 0x6BD2,0x93C5, // - 0x6BD3,0x9F79, // - 0x6BD4,0x94E4, // - 0x6BD8,0x94F9, // - 0x6BDB,0x96D1, // - 0x6BDF,0x9F7A, // - 0x6BEB,0x9F7C, // - 0x6BEC,0x9F7B, // - 0x6BEF,0x9F7E, // - 0x6BF3,0x9F7D, // - 0x6C08,0x9F81, // - 0x6C0F,0x8E81, // - 0x6C11,0x96AF, // - 0x6C13,0x9F82, // - 0x6C14,0x9F83, // - 0x6C17,0x8B43, // - 0x6C1B,0x9F84, // - 0x6C23,0x9F86, // - 0x6C24,0x9F85, // - 0x6C34,0x9085, // - 0x6C37,0x9558, // - 0x6C38,0x8969, // - 0x6C3E,0x94C3, // - 0x6C40,0x92F3, // - 0x6C41,0x8F60, // - 0x6C42,0x8B81, // - 0x6C4E,0x94C4, // - 0x6C50,0x8EAC, // - 0x6C55,0x9F88, // - 0x6C57,0x8ABE, // - 0x6C5A,0x8998, // - 0x6C5D,0x93F0, // - 0x6C5E,0x9F87, // - 0x6C5F,0x8D5D, // - 0x6C60,0x9272, // - 0x6C62,0x9F89, // - 0x6C68,0x9F91, // - 0x6C6A,0x9F8A, // - 0x6C70,0x91BF, // - 0x6C72,0x8B82, // - 0x6C73,0x9F92, // - 0x6C7A,0x8C88, // - 0x6C7D,0x8B44, // - 0x6C7E,0x9F90, // - 0x6C81,0x9F8E, // - 0x6C82,0x9F8B, // - 0x6C83,0x9780, // - 0x6C88,0x92BE, // - 0x6C8C,0x93D7, // - 0x6C8D,0x9F8C, // - 0x6C90,0x9F94, // - 0x6C92,0x9F93, // - 0x6C93,0x8C42, // - 0x6C96,0x89AB, // - 0x6C99,0x8DB9, // - 0x6C9A,0x9F8D, // - 0x6C9B,0x9F8F, // - 0x6CA1,0x9676, // - 0x6CA2,0x91F2, // - 0x6CAB,0x9697, // - 0x6CAE,0x9F9C, // - 0x6CB1,0x9F9D, // - 0x6CB3,0x89CD, // - 0x6CB8,0x95A6, // - 0x6CB9,0x96FB, // - 0x6CBA,0x9F9F, // - 0x6CBB,0x8EA1, // - 0x6CBC,0x8FC0, // - 0x6CBD,0x9F98, // - 0x6CBE,0x9F9E, // - 0x6CBF,0x8988, // - 0x6CC1,0x8BB5, // - 0x6CC4,0x9F95, // - 0x6CC5,0x9F9A, // - 0x6CC9,0x90F2, // - 0x6CCA,0x9491, // - 0x6CCC,0x94E5, // - 0x6CD3,0x9F97, // - 0x6CD5,0x9640, // - 0x6CD7,0x9F99, // - 0x6CD9,0x9FA2, // - 0x6CDB,0x9FA0, // - 0x6CDD,0x9F9B, // - 0x6CE1,0x9641, // - 0x6CE2,0x9467, // - 0x6CE3,0x8B83, // - 0x6CE5,0x9344, // - 0x6CE8,0x928D, // - 0x6CEA,0x9FA3, // - 0x6CEF,0x9FA1, // - 0x6CF0,0x91D7, // - 0x6CF1,0x9F96, // - 0x6CF3,0x896A, // - 0x6D0B,0x976D, // - 0x6D0C,0x9FAE, // - 0x6D12,0x9FAD, // - 0x6D17,0x90F4, // - 0x6D19,0x9FAA, // - 0x6D1B,0x978C, // - 0x6D1E,0x93B4, // - 0x6D1F,0x9FA4, // - 0x6D25,0x92C3, // - 0x6D29,0x896B, // - 0x6D2A,0x8D5E, // - 0x6D2B,0x9FA7, // - 0x6D32,0x8F46, // - 0x6D33,0x9FAC, // - 0x6D35,0x9FAB, // - 0x6D36,0x9FA6, // - 0x6D38,0x9FA9, // - 0x6D3B,0x8A88, // - 0x6D3D,0x9FA8, // - 0x6D3E,0x9468, // - 0x6D41,0x97AC, // - 0x6D44,0x8FF2, // - 0x6D45,0x90F3, // - 0x6D59,0x9FB4, // - 0x6D5A,0x9FB2, // - 0x6D5C,0x956C, // - 0x6D63,0x9FAF, // - 0x6D64,0x9FB1, // - 0x6D66,0x8959, // - 0x6D69,0x8D5F, // - 0x6D6A,0x9851, // - 0x6D6C,0x8A5C, // - 0x6D6E,0x9582, // - 0x6D74,0x9781, // - 0x6D77,0x8A43, // - 0x6D78,0x905A, // - 0x6D79,0x9FB3, // - 0x6D85,0x9FB8, // - 0x6D88,0x8FC1, // - 0x6D8C,0x974F, // - 0x6D8E,0x9FB5, // - 0x6D93,0x9FB0, // - 0x6D95,0x9FB6, // - 0x6D99,0x97DC, // - 0x6D9B,0x9393, // - 0x6D9C,0x93C0, // - 0x6DAF,0x8A55, // - 0x6DB2,0x8974, // - 0x6DB5,0x9FBC, // - 0x6DB8,0x9FBF, // - 0x6DBC,0x97C1, // - 0x6DC0,0x9784, // - 0x6DC5,0x9FC6, // - 0x6DC6,0x9FC0, // - 0x6DC7,0x9FBD, // - 0x6DCB,0x97D2, // - 0x6DCC,0x9FC3, // - 0x6DD1,0x8F69, // - 0x6DD2,0x9FC5, // - 0x6DD5,0x9FCA, // - 0x6DD8,0x9391, // - 0x6DD9,0x9FC8, // - 0x6DDE,0x9FC2, // - 0x6DE1,0x9257, // - 0x6DE4,0x9FC9, // - 0x6DE6,0x9FBE, // - 0x6DE8,0x9FC4, // - 0x6DEA,0x9FCB, // - 0x6DEB,0x88FA, // - 0x6DEC,0x9FC1, // - 0x6DEE,0x9FCC, // - 0x6DF3,0x8F7E, // - 0x6DF5,0x95A3, // - 0x6DF7,0x8DAC, // - 0x6DF9,0x9FB9, // - 0x6DFA,0x9FC7, // - 0x6DFB,0x9359, // - 0x6E05,0x90B4, // - 0x6E07,0x8A89, // - 0x6E08,0x8DCF, // - 0x6E09,0x8FC2, // - 0x6E0A,0x9FBB, // - 0x6E0B,0x8F61, // - 0x6E13,0x8C6B, // - 0x6E15,0x9FBA, // - 0x6E19,0x9FD0, // - 0x6E1A,0x8F8D, // - 0x6E1B,0x8CB8, // - 0x6E1D,0x9FDF, // - 0x6E1F,0x9FD9, // - 0x6E20,0x8B94, // - 0x6E21,0x936E, // - 0x6E23,0x9FD4, // - 0x6E24,0x9FDD, // - 0x6E25,0x88AD, // - 0x6E26,0x8951, // - 0x6E29,0x89B7, // - 0x6E2B,0x9FD6, // - 0x6E2C,0x91AA, // - 0x6E2D,0x9FCD, // - 0x6E2E,0x9FCF, // - 0x6E2F,0x8D60, // - 0x6E38,0x9FE0, // - 0x6E3A,0x9FDB, // - 0x6E3E,0x9FD3, // - 0x6E43,0x9FDA, // - 0x6E4A,0x96A9, // - 0x6E4D,0x9FD8, // - 0x6E4E,0x9FDC, // - 0x6E56,0x8CCE, // - 0x6E58,0x8FC3, // - 0x6E5B,0x9258, // - 0x6E5F,0x9FD2, // - 0x6E67,0x974E, // - 0x6E6B,0x9FD5, // - 0x6E6E,0x9FCE, // - 0x6E6F,0x9392, // - 0x6E72,0x9FD1, // - 0x6E76,0x9FD7, // - 0x6E7E,0x9870, // - 0x6E7F,0x8EBC, // - 0x6E80,0x969E, // - 0x6E82,0x9FE1, // - 0x6E8C,0x94AC, // - 0x6E8F,0x9FED, // - 0x6E90,0x8CB9, // - 0x6E96,0x8F80, // - 0x6E98,0x9FE3, // - 0x6E9C,0x97AD, // - 0x6E9D,0x8D61, // - 0x6E9F,0x9FF0, // - 0x6EA2,0x88EC, // - 0x6EA5,0x9FEE, // - 0x6EAA,0x9FE2, // - 0x6EAF,0x9FE8, // - 0x6EB2,0x9FEA, // - 0x6EB6,0x976E, // - 0x6EB7,0x9FE5, // - 0x6EBA,0x934D, // - 0x6EBD,0x9FE7, // - 0x6EC2,0x9FEF, // - 0x6EC4,0x9FE9, // - 0x6EC5,0x96C5, // - 0x6EC9,0x9FE4, // - 0x6ECB,0x8EA0, // - 0x6ECC,0x9FFC, // - 0x6ED1,0x8A8A, // - 0x6ED3,0x9FE6, // - 0x6ED4,0x9FEB, // - 0x6ED5,0x9FEC, // - 0x6EDD,0x91EA, // - 0x6EDE,0x91D8, // - 0x6EEC,0x9FF4, // - 0x6EEF,0x9FFA, // - 0x6EF2,0x9FF8, // - 0x6EF4,0x9348, // - 0x6EF7,0xE042, // - 0x6EF8,0x9FF5, // - 0x6EFE,0x9FF6, // - 0x6EFF,0x9FDE, // - 0x6F01,0x8B99, // - 0x6F02,0x9559, // - 0x6F06,0x8EBD, // - 0x6F09,0x8D97, // - 0x6F0F,0x9852, // - 0x6F11,0x9FF2, // - 0x6F13,0xE041, // - 0x6F14,0x8989, // - 0x6F15,0x9186, // - 0x6F20,0x9499, // - 0x6F22,0x8ABF, // - 0x6F23,0x97F8, // - 0x6F2B,0x969F, // - 0x6F2C,0x92D0, // - 0x6F31,0x9FF9, // - 0x6F32,0x9FFB, // - 0x6F38,0x9151, // - 0x6F3E,0xE040, // - 0x6F3F,0x9FF7, // - 0x6F41,0x9FF1, // - 0x6F45,0x8AC1, // - 0x6F54,0x8C89, // - 0x6F58,0xE04E, // - 0x6F5B,0xE049, // - 0x6F5C,0x90F6, // - 0x6F5F,0x8A83, // - 0x6F64,0x8F81, // - 0x6F66,0xE052, // - 0x6F6D,0xE04B, // - 0x6F6E,0x92AA, // - 0x6F6F,0xE048, // - 0x6F70,0x92D7, // - 0x6F74,0xE06B, // - 0x6F78,0xE045, // - 0x6F7A,0xE044, // - 0x6F7C,0xE04D, // - 0x6F80,0xE047, // - 0x6F81,0xE046, // - 0x6F82,0xE04C, // - 0x6F84,0x909F, // - 0x6F86,0xE043, // - 0x6F8E,0xE04F, // - 0x6F91,0xE050, // - 0x6F97,0x8AC0, // - 0x6FA1,0xE055, // - 0x6FA3,0xE054, // - 0x6FA4,0xE056, // - 0x6FAA,0xE059, // - 0x6FB1,0x9362, // - 0x6FB3,0xE053, // - 0x6FB9,0xE057, // - 0x6FC0,0x8C83, // - 0x6FC1,0x91F7, // - 0x6FC2,0xE051, // - 0x6FC3,0x945A, // - 0x6FC6,0xE058, // - 0x6FD4,0xE05D, // - 0x6FD8,0xE05E, // - 0x6FDB,0xE061, // - 0x6FDF,0xE05A, // - 0x6FE0,0x8D8A, // - 0x6FE1,0x9447, // - 0x6FE4,0x9FB7, // - 0x6FEB,0x9794, // - 0x6FEC,0xE05C, // - 0x6FEE,0xE060, // - 0x6FEF,0x91F3, // - 0x6FF1,0xE05F, // - 0x6FF3,0xE04A, // - 0x6FF6,0xE889, // - 0x6FFA,0xE064, // - 0x6FFE,0xE068, // - 0x7001,0xE066, // - 0x7009,0xE062, // - 0x700B,0xE063, // - 0x700F,0xE067, // - 0x7011,0xE065, // - 0x7015,0x956D, // - 0x7018,0xE06D, // - 0x701A,0xE06A, // - 0x701B,0xE069, // - 0x701D,0xE06C, // - 0x701E,0x93D2, // - 0x701F,0xE06E, // - 0x7026,0x9295, // - 0x7027,0x91EB, // - 0x702C,0x90A3, // - 0x7030,0xE06F, // - 0x7032,0xE071, // - 0x703E,0xE070, // - 0x704C,0x9FF3, // - 0x7051,0xE072, // - 0x7058,0x93E5, // - 0x7063,0xE073, // - 0x706B,0x89CE, // - 0x706F,0x9394, // - 0x7070,0x8A44, // - 0x7078,0x8B84, // - 0x707C,0x8EDC, // - 0x707D,0x8DD0, // - 0x7089,0x9846, // - 0x708A,0x9086, // - 0x708E,0x898A, // - 0x7092,0xE075, // - 0x7099,0xE074, // - 0x70AC,0xE078, // - 0x70AD,0x9259, // - 0x70AE,0xE07B, // - 0x70AF,0xE076, // - 0x70B3,0xE07A, // - 0x70B8,0xE079, // - 0x70B9,0x935F, // - 0x70BA,0x88D7, // - 0x70C8,0x97F3, // - 0x70CB,0xE07D, // - 0x70CF,0x8947, // - 0x70D9,0xE080, // - 0x70DD,0xE07E, // - 0x70DF,0xE07C, // - 0x70F1,0xE077, // - 0x70F9,0x9642, // - 0x70FD,0xE082, // - 0x7109,0xE081, // - 0x7114,0x898B, // - 0x7119,0xE084, // - 0x711A,0x95B0, // - 0x711C,0xE083, // - 0x7121,0x96B3, // - 0x7126,0x8FC5, // - 0x7136,0x9152, // - 0x713C,0x8FC4, // - 0x7149,0x97F9, // - 0x714C,0xE08A, // - 0x714E,0x90F7, // - 0x7155,0xE086, // - 0x7156,0xE08B, // - 0x7159,0x898C, // - 0x7162,0xE089, // - 0x7164,0x9481, // - 0x7165,0xE085, // - 0x7166,0xE088, // - 0x7167,0x8FC6, // - 0x7169,0x94CF, // - 0x716C,0xE08C, // - 0x716E,0x8ECF, // - 0x717D,0x90F8, // - 0x7184,0xE08F, // - 0x7188,0xE087, // - 0x718A,0x8C46, // - 0x718F,0xE08D, // - 0x7194,0x976F, // - 0x7195,0xE090, // - 0x7199,0xEAA4, // - 0x719F,0x8F6E, // - 0x71A8,0xE091, // - 0x71AC,0xE092, // - 0x71B1,0x944D, // - 0x71B9,0xE094, // - 0x71BE,0xE095, // - 0x71C3,0x9452, // - 0x71C8,0x9395, // - 0x71C9,0xE097, // - 0x71CE,0xE099, // - 0x71D0,0x97D3, // - 0x71D2,0xE096, // - 0x71D4,0xE098, // - 0x71D5,0x898D, // - 0x71D7,0xE093, // - 0x71DF,0x9A7A, // - 0x71E0,0xE09A, // - 0x71E5,0x9187, // - 0x71E6,0x8E57, // - 0x71E7,0xE09C, // - 0x71EC,0xE09B, // - 0x71ED,0x9043, // - 0x71EE,0x99D7, // - 0x71F5,0xE09D, // - 0x71F9,0xE09F, // - 0x71FB,0xE08E, // - 0x71FC,0xE09E, // - 0x71FF,0xE0A0, // - 0x7206,0x949A, // - 0x720D,0xE0A1, // - 0x7210,0xE0A2, // - 0x721B,0xE0A3, // - 0x7228,0xE0A4, // - 0x722A,0x92DC, // - 0x722C,0xE0A6, // - 0x722D,0xE0A5, // - 0x7230,0xE0A7, // - 0x7232,0xE0A8, // - 0x7235,0x8EDD, // - 0x7236,0x9583, // - 0x723A,0x96EA, // - 0x723B,0xE0A9, // - 0x723C,0xE0AA, // - 0x723D,0x9175, // - 0x723E,0x8EA2, // - 0x723F,0xE0AB, // - 0x7240,0xE0AC, // - 0x7246,0xE0AD, // - 0x7247,0x95D0, // - 0x7248,0x94C5, // - 0x724B,0xE0AE, // - 0x724C,0x9476, // - 0x7252,0x92AB, // - 0x7258,0xE0AF, // - 0x7259,0x89E5, // - 0x725B,0x8B8D, // - 0x725D,0x96C4, // - 0x725F,0x96B4, // - 0x7261,0x89B2, // - 0x7262,0x9853, // - 0x7267,0x9671, // - 0x7269,0x95A8, // - 0x7272,0x90B5, // - 0x7274,0xE0B0, // - 0x7279,0x93C1, // - 0x727D,0x8CA1, // - 0x727E,0xE0B1, // - 0x7280,0x8DD2, // - 0x7281,0xE0B3, // - 0x7282,0xE0B2, // - 0x7287,0xE0B4, // - 0x7292,0xE0B5, // - 0x7296,0xE0B6, // - 0x72A0,0x8B5D, // - 0x72A2,0xE0B7, // - 0x72A7,0xE0B8, // - 0x72AC,0x8CA2, // - 0x72AF,0x94C6, // - 0x72B2,0xE0BA, // - 0x72B6,0x8FF3, // - 0x72B9,0xE0B9, // - 0x72C2,0x8BB6, // - 0x72C3,0xE0BB, // - 0x72C4,0xE0BD, // - 0x72C6,0xE0BC, // - 0x72CE,0xE0BE, // - 0x72D0,0x8CCF, // - 0x72D2,0xE0BF, // - 0x72D7,0x8BE7, // - 0x72D9,0x915F, // - 0x72DB,0x8D9D, // - 0x72E0,0xE0C1, // - 0x72E1,0xE0C2, // - 0x72E2,0xE0C0, // - 0x72E9,0x8EEB, // - 0x72EC,0x93C6, // - 0x72ED,0x8BB7, // - 0x72F7,0xE0C4, // - 0x72F8,0x924B, // - 0x72F9,0xE0C3, // - 0x72FC,0x9854, // - 0x72FD,0x9482, // - 0x730A,0xE0C7, // - 0x7316,0xE0C9, // - 0x7317,0xE0C6, // - 0x731B,0x96D2, // - 0x731C,0xE0C8, // - 0x731D,0xE0CA, // - 0x731F,0x97C2, // - 0x7325,0xE0CE, // - 0x7329,0xE0CD, // - 0x732A,0x9296, // - 0x732B,0x944C, // - 0x732E,0x8CA3, // - 0x732F,0xE0CC, // - 0x7334,0xE0CB, // - 0x7336,0x9750, // - 0x7337,0x9751, // - 0x733E,0xE0CF, // - 0x733F,0x898E, // - 0x7344,0x8D96, // - 0x7345,0x8E82, // - 0x734E,0xE0D0, // - 0x734F,0xE0D1, // - 0x7357,0xE0D3, // - 0x7363,0x8F62, // - 0x7368,0xE0D5, // - 0x736A,0xE0D4, // - 0x7370,0xE0D6, // - 0x7372,0x8A6C, // - 0x7375,0xE0D8, // - 0x7378,0xE0D7, // - 0x737A,0xE0DA, // - 0x737B,0xE0D9, // - 0x7384,0x8CBA, // - 0x7387,0x97A6, // - 0x7389,0x8BCA, // - 0x738B,0x89A4, // - 0x7396,0x8BE8, // - 0x73A9,0x8ADF, // - 0x73B2,0x97E6, // - 0x73B3,0xE0DC, // - 0x73BB,0xE0DE, // - 0x73C0,0xE0DF, // - 0x73C2,0x89CF, // - 0x73C8,0xE0DB, // - 0x73CA,0x8E58, // - 0x73CD,0x92BF, // - 0x73CE,0xE0DD, // - 0x73DE,0xE0E2, // - 0x73E0,0x8EEC, // - 0x73E5,0xE0E0, // - 0x73EA,0x8C5D, // - 0x73ED,0x94C7, // - 0x73EE,0xE0E1, // - 0x73F1,0xE0FC, // - 0x73F8,0xE0E7, // - 0x73FE,0x8CBB, // - 0x7403,0x8B85, // - 0x7405,0xE0E4, // - 0x7406,0x979D, // - 0x7409,0x97AE, // - 0x7422,0x91F4, // - 0x7425,0xE0E6, // - 0x7432,0xE0E8, // - 0x7433,0x97D4, // - 0x7434,0x8BD5, // - 0x7435,0x94FA, // - 0x7436,0x9469, // - 0x743A,0xE0E9, // - 0x743F,0xE0EB, // - 0x7441,0xE0EE, // - 0x7455,0xE0EA, // - 0x7459,0xE0ED, // - 0x745A,0x8CE8, // - 0x745B,0x896C, // - 0x745C,0xE0EF, // - 0x745E,0x9090, // - 0x745F,0xE0EC, // - 0x7460,0x97DA, // - 0x7463,0xE0F2, // - 0x7464,0xEAA2, // - 0x7469,0xE0F0, // - 0x746A,0xE0F3, // - 0x746F,0xE0E5, // - 0x7470,0xE0F1, // - 0x7473,0x8DBA, // - 0x7476,0xE0F4, // - 0x747E,0xE0F5, // - 0x7483,0x979E, // - 0x748B,0xE0F6, // - 0x749E,0xE0F7, // - 0x74A2,0xE0E3, // - 0x74A7,0xE0F8, // - 0x74B0,0x8AC2, // - 0x74BD,0x8EA3, // - 0x74CA,0xE0F9, // - 0x74CF,0xE0FA, // - 0x74D4,0xE0FB, // - 0x74DC,0x895A, // - 0x74E0,0xE140, // - 0x74E2,0x955A, // - 0x74E3,0xE141, // - 0x74E6,0x8AA2, // - 0x74E7,0xE142, // - 0x74E9,0xE143, // - 0x74EE,0xE144, // - 0x74F0,0xE146, // - 0x74F1,0xE147, // - 0x74F2,0xE145, // - 0x74F6,0x9572, // - 0x74F7,0xE149, // - 0x74F8,0xE148, // - 0x7503,0xE14B, // - 0x7504,0xE14A, // - 0x7505,0xE14C, // - 0x750C,0xE14D, // - 0x750D,0xE14F, // - 0x750E,0xE14E, // - 0x7511,0x8D99, // - 0x7513,0xE151, // - 0x7515,0xE150, // - 0x7518,0x8AC3, // - 0x751A,0x9072, // - 0x751E,0xE152, // - 0x751F,0x90B6, // - 0x7523,0x8E59, // - 0x7525,0x8999, // - 0x7526,0xE153, // - 0x7528,0x9770, // - 0x752B,0x95E1, // - 0x752C,0xE154, // - 0x7530,0x9363, // - 0x7531,0x9752, // - 0x7532,0x8D62, // - 0x7533,0x905C, // - 0x7537,0x926A, // - 0x7538,0x99B2, // - 0x753A,0x92AC, // - 0x753B,0x89E6, // - 0x753C,0xE155, // - 0x7544,0xE156, // - 0x7549,0xE159, // - 0x754A,0xE158, // - 0x754B,0x9DC0, // - 0x754C,0x8A45, // - 0x754D,0xE157, // - 0x754F,0x88D8, // - 0x7551,0x94A8, // - 0x7554,0x94C8, // - 0x7559,0x97AF, // - 0x755A,0xE15C, // - 0x755B,0xE15A, // - 0x755C,0x927B, // - 0x755D,0x90A4, // - 0x7560,0x94A9, // - 0x7562,0x954C, // - 0x7564,0xE15E, // - 0x7565,0x97AA, // - 0x7566,0x8C6C, // - 0x7567,0xE15F, // - 0x7569,0xE15D, // - 0x756A,0x94D4, // - 0x756B,0xE160, // - 0x756D,0xE161, // - 0x7570,0x88D9, // - 0x7573,0x8FF4, // - 0x7574,0xE166, // - 0x7576,0xE163, // - 0x7577,0x93EB, // - 0x7578,0xE162, // - 0x757F,0x8B45, // - 0x7582,0xE169, // - 0x7586,0xE164, // - 0x7587,0xE165, // - 0x7589,0xE168, // - 0x758A,0xE167, // - 0x758B,0x9544, // - 0x758E,0x9161, // - 0x758F,0x9160, // - 0x7591,0x8B5E, // - 0x7594,0xE16A, // - 0x759A,0xE16B, // - 0x759D,0xE16C, // - 0x75A3,0xE16E, // - 0x75A5,0xE16D, // - 0x75AB,0x8975, // - 0x75B1,0xE176, // - 0x75B2,0x94E6, // - 0x75B3,0xE170, // - 0x75B5,0xE172, // - 0x75B8,0xE174, // - 0x75B9,0x905D, // - 0x75BC,0xE175, // - 0x75BD,0xE173, // - 0x75BE,0x8EBE, // - 0x75C2,0xE16F, // - 0x75C3,0xE171, // - 0x75C5,0x9561, // - 0x75C7,0x8FC7, // - 0x75CA,0xE178, // - 0x75CD,0xE177, // - 0x75D2,0xE179, // - 0x75D4,0x8EA4, // - 0x75D5,0x8DAD, // - 0x75D8,0x9397, // - 0x75D9,0xE17A, // - 0x75DB,0x92C9, // - 0x75DE,0xE17C, // - 0x75E2,0x979F, // - 0x75E3,0xE17B, // - 0x75E9,0x9189, // - 0x75F0,0xE182, // - 0x75F2,0xE184, // - 0x75F3,0xE185, // - 0x75F4,0x9273, // - 0x75FA,0xE183, // - 0x75FC,0xE180, // - 0x75FE,0xE17D, // - 0x75FF,0xE17E, // - 0x7601,0xE181, // - 0x7609,0xE188, // - 0x760B,0xE186, // - 0x760D,0xE187, // - 0x761F,0xE189, // - 0x7620,0xE18B, // - 0x7621,0xE18C, // - 0x7622,0xE18D, // - 0x7624,0xE18E, // - 0x7627,0xE18A, // - 0x7630,0xE190, // - 0x7634,0xE18F, // - 0x763B,0xE191, // - 0x7642,0x97C3, // - 0x7646,0xE194, // - 0x7647,0xE192, // - 0x7648,0xE193, // - 0x764C,0x8AE0, // - 0x7652,0x96FC, // - 0x7656,0x95C8, // - 0x7658,0xE196, // - 0x765C,0xE195, // - 0x7661,0xE197, // - 0x7662,0xE198, // - 0x7667,0xE19C, // - 0x7668,0xE199, // - 0x7669,0xE19A, // - 0x766A,0xE19B, // - 0x766C,0xE19D, // - 0x7670,0xE19E, // - 0x7672,0xE19F, // - 0x7676,0xE1A0, // - 0x7678,0xE1A1, // - 0x767A,0x94AD, // - 0x767B,0x936F, // - 0x767C,0xE1A2, // - 0x767D,0x9492, // - 0x767E,0x9553, // - 0x7680,0xE1A3, // - 0x7683,0xE1A4, // - 0x7684,0x9349, // - 0x7686,0x8A46, // - 0x7687,0x8D63, // - 0x7688,0xE1A5, // - 0x768B,0xE1A6, // - 0x768E,0xE1A7, // - 0x7690,0x8E48, // - 0x7693,0xE1A9, // - 0x7696,0xE1A8, // - 0x7699,0xE1AA, // - 0x769A,0xE1AB, // - 0x76AE,0x94E7, // - 0x76B0,0xE1AC, // - 0x76B4,0xE1AD, // - 0x76B7,0xEA89, // - 0x76B8,0xE1AE, // - 0x76B9,0xE1AF, // - 0x76BA,0xE1B0, // - 0x76BF,0x8E4D, // - 0x76C2,0xE1B1, // - 0x76C3,0x9475, // - 0x76C6,0x967E, // - 0x76C8,0x896D, // - 0x76CA,0x8976, // - 0x76CD,0xE1B2, // - 0x76D2,0xE1B4, // - 0x76D6,0xE1B3, // - 0x76D7,0x9390, // - 0x76DB,0x90B7, // - 0x76DC,0x9F58, // - 0x76DE,0xE1B5, // - 0x76DF,0x96BF, // - 0x76E1,0xE1B6, // - 0x76E3,0x8AC4, // - 0x76E4,0x94D5, // - 0x76E5,0xE1B7, // - 0x76E7,0xE1B8, // - 0x76EA,0xE1B9, // - 0x76EE,0x96DA, // - 0x76F2,0x96D3, // - 0x76F4,0x92BC, // - 0x76F8,0x918A, // - 0x76FB,0xE1BB, // - 0x76FE,0x8F82, // - 0x7701,0x8FC8, // - 0x7704,0xE1BE, // - 0x7707,0xE1BD, // - 0x7708,0xE1BC, // - 0x7709,0x94FB, // - 0x770B,0x8AC5, // - 0x770C,0x8CA7, // - 0x771B,0xE1C4, // - 0x771E,0xE1C1, // - 0x771F,0x905E, // - 0x7720,0x96B0, // - 0x7724,0xE1C0, // - 0x7725,0xE1C2, // - 0x7726,0xE1C3, // - 0x7729,0xE1BF, // - 0x7737,0xE1C5, // - 0x7738,0xE1C6, // - 0x773A,0x92AD, // - 0x773C,0x8AE1, // - 0x7740,0x9285, // - 0x7747,0xE1C7, // - 0x775A,0xE1C8, // - 0x775B,0xE1CB, // - 0x7761,0x9087, // - 0x7763,0x93C2, // - 0x7765,0xE1CC, // - 0x7766,0x9672, // - 0x7768,0xE1C9, // - 0x776B,0xE1CA, // - 0x7779,0xE1CF, // - 0x777E,0xE1CE, // - 0x777F,0xE1CD, // - 0x778B,0xE1D1, // - 0x778E,0xE1D0, // - 0x7791,0xE1D2, // - 0x779E,0xE1D4, // - 0x77A0,0xE1D3, // - 0x77A5,0x95CB, // - 0x77AC,0x8F75, // - 0x77AD,0x97C4, // - 0x77B0,0xE1D5, // - 0x77B3,0x93B5, // - 0x77B6,0xE1D6, // - 0x77B9,0xE1D7, // - 0x77BB,0xE1DB, // - 0x77BC,0xE1D9, // - 0x77BD,0xE1DA, // - 0x77BF,0xE1D8, // - 0x77C7,0xE1DC, // - 0x77CD,0xE1DD, // - 0x77D7,0xE1DE, // - 0x77DA,0xE1DF, // - 0x77DB,0x96B5, // - 0x77DC,0xE1E0, // - 0x77E2,0x96EE, // - 0x77E3,0xE1E1, // - 0x77E5,0x926D, // - 0x77E7,0x948A, // - 0x77E9,0x8BE9, // - 0x77ED,0x925A, // - 0x77EE,0xE1E2, // - 0x77EF,0x8BB8, // - 0x77F3,0x90CE, // - 0x77FC,0xE1E3, // - 0x7802,0x8DBB, // - 0x780C,0xE1E4, // - 0x7812,0xE1E5, // - 0x7814,0x8CA4, // - 0x7815,0x8DD3, // - 0x7820,0xE1E7, // - 0x7825,0x9375, // - 0x7826,0x8DD4, // - 0x7827,0x8B6D, // - 0x7832,0x9643, // - 0x7834,0x946A, // - 0x783A,0x9376, // - 0x783F,0x8D7B, // - 0x7845,0xE1E9, // - 0x785D,0x8FC9, // - 0x786B,0x97B0, // - 0x786C,0x8D64, // - 0x786F,0x8CA5, // - 0x7872,0x94A1, // - 0x7874,0xE1EB, // - 0x787C,0xE1ED, // - 0x7881,0x8CE9, // - 0x7886,0xE1EC, // - 0x7887,0x92F4, // - 0x788C,0xE1EF, // - 0x788D,0x8A56, // - 0x788E,0xE1EA, // - 0x7891,0x94E8, // - 0x7893,0x894F, // - 0x7895,0x8DEA, // - 0x7897,0x9871, // - 0x789A,0xE1EE, // - 0x78A3,0xE1F0, // - 0x78A7,0x95C9, // - 0x78A9,0x90D7, // - 0x78AA,0xE1F2, // - 0x78AF,0xE1F3, // - 0x78B5,0xE1F1, // - 0x78BA,0x8A6D, // - 0x78BC,0xE1F9, // - 0x78BE,0xE1F8, // - 0x78C1,0x8EA5, // - 0x78C5,0xE1FA, // - 0x78C6,0xE1F5, // - 0x78CA,0xE1FB, // - 0x78CB,0xE1F6, // - 0x78D0,0x94D6, // - 0x78D1,0xE1F4, // - 0x78D4,0xE1F7, // - 0x78DA,0xE241, // - 0x78E7,0xE240, // - 0x78E8,0x9681, // - 0x78EC,0xE1FC, // - 0x78EF,0x88E9, // - 0x78F4,0xE243, // - 0x78FD,0xE242, // - 0x7901,0x8FCA, // - 0x7907,0xE244, // - 0x790E,0x9162, // - 0x7911,0xE246, // - 0x7912,0xE245, // - 0x7919,0xE247, // - 0x7926,0xE1E6, // - 0x792A,0xE1E8, // - 0x792B,0xE249, // - 0x792C,0xE248, // - 0x793A,0x8EA6, // - 0x793C,0x97E7, // - 0x793E,0x8ED0, // - 0x7940,0xE24A, // - 0x7941,0x8C56, // - 0x7947,0x8B5F, // - 0x7948,0x8B46, // - 0x7949,0x8E83, // - 0x7950,0x9753, // - 0x7953,0xE250, // - 0x7955,0xE24F, // - 0x7956,0x9163, // - 0x7957,0xE24C, // - 0x795A,0xE24E, // - 0x795D,0x8F6A, // - 0x795E,0x905F, // - 0x795F,0xE24D, // - 0x7960,0xE24B, // - 0x7962,0x9449, // - 0x7965,0x8FCB, // - 0x796D,0x8DD5, // - 0x7977,0x9398, // - 0x797A,0xE251, // - 0x797F,0xE252, // - 0x7980,0xE268, // - 0x7981,0x8BD6, // - 0x7984,0x985C, // - 0x7985,0x9154, // - 0x798A,0xE253, // - 0x798D,0x89D0, // - 0x798E,0x92F5, // - 0x798F,0x959F, // - 0x799D,0xE254, // - 0x79A6,0x8B9A, // - 0x79A7,0xE255, // - 0x79AA,0xE257, // - 0x79AE,0xE258, // - 0x79B0,0x9448, // - 0x79B3,0xE259, // - 0x79B9,0xE25A, // - 0x79BD,0x8BD7, // - 0x79BE,0x89D1, // - 0x79BF,0x93C3, // - 0x79C0,0x8F47, // - 0x79C1,0x8E84, // - 0x79C9,0xE25C, // - 0x79CB,0x8F48, // - 0x79D1,0x89C8, // - 0x79D2,0x9562, // - 0x79D5,0xE25D, // - 0x79D8,0x94E9, // - 0x79DF,0x9164, // - 0x79E1,0xE260, // - 0x79E3,0xE261, // - 0x79E4,0x9489, // - 0x79E6,0x9060, // - 0x79E7,0xE25E, // - 0x79E9,0x9281, // - 0x79EC,0xE25F, // - 0x79F0,0x8FCC, // - 0x79FB,0x88DA, // - 0x7A00,0x8B48, // - 0x7A08,0xE262, // - 0x7A0B,0x92F6, // - 0x7A0D,0xE263, // - 0x7A0E,0x90C5, // - 0x7A14,0x96AB, // - 0x7A17,0x9542, // - 0x7A18,0xE264, // - 0x7A19,0xE265, // - 0x7A1A,0x9274, // - 0x7A1C,0x97C5, // - 0x7A1F,0xE267, // - 0x7A20,0xE266, // - 0x7A2E,0x8EED, // - 0x7A31,0xE269, // - 0x7A32,0x88EE, // - 0x7A37,0xE26C, // - 0x7A3B,0xE26A, // - 0x7A3C,0x89D2, // - 0x7A3D,0x8C6D, // - 0x7A3E,0xE26B, // - 0x7A3F,0x8D65, // - 0x7A40,0x8D92, // - 0x7A42,0x95E4, // - 0x7A43,0xE26D, // - 0x7A46,0x9673, // - 0x7A49,0xE26F, // - 0x7A4D,0x90CF, // - 0x7A4E,0x896E, // - 0x7A4F,0x89B8, // - 0x7A50,0x88AA, // - 0x7A57,0xE26E, // - 0x7A61,0xE270, // - 0x7A62,0xE271, // - 0x7A63,0x8FF5, // - 0x7A69,0xE272, // - 0x7A6B,0x8A6E, // - 0x7A70,0xE274, // - 0x7A74,0x8C8A, // - 0x7A76,0x8B86, // - 0x7A79,0xE275, // - 0x7A7A,0x8BF3, // - 0x7A7D,0xE276, // - 0x7A7F,0x90FA, // - 0x7A81,0x93CB, // - 0x7A83,0x90DE, // - 0x7A84,0x8DF3, // - 0x7A88,0xE277, // - 0x7A92,0x9282, // - 0x7A93,0x918B, // - 0x7A95,0xE279, // - 0x7A96,0xE27B, // - 0x7A97,0xE278, // - 0x7A98,0xE27A, // - 0x7A9F,0x8C41, // - 0x7AA9,0xE27C, // - 0x7AAA,0x8C45, // - 0x7AAE,0x8B87, // - 0x7AAF,0x9771, // - 0x7AB0,0xE27E, // - 0x7AB6,0xE280, // - 0x7ABA,0x894D, // - 0x7ABF,0xE283, // - 0x7AC3,0x8A96, // - 0x7AC4,0xE282, // - 0x7AC5,0xE281, // - 0x7AC7,0xE285, // - 0x7AC8,0xE27D, // - 0x7ACA,0xE286, // - 0x7ACB,0x97A7, // - 0x7ACD,0xE287, // - 0x7ACF,0xE288, // - 0x7AD2,0x9AF2, // - 0x7AD3,0xE28A, // - 0x7AD5,0xE289, // - 0x7AD9,0xE28B, // - 0x7ADA,0xE28C, // - 0x7ADC,0x97B3, // - 0x7ADD,0xE28D, // - 0x7ADF,0xE8ED, // - 0x7AE0,0x8FCD, // - 0x7AE1,0xE28E, // - 0x7AE2,0xE28F, // - 0x7AE3,0x8F76, // - 0x7AE5,0x93B6, // - 0x7AE6,0xE290, // - 0x7AEA,0x9247, // - 0x7AED,0xE291, // - 0x7AF0,0xE292, // - 0x7AF6,0x8BA3, // - 0x7AF8,0x995E, // - 0x7AF9,0x927C, // - 0x7AFA,0x8EB1, // - 0x7AFF,0x8AC6, // - 0x7B02,0xE293, // - 0x7B04,0xE2A0, // - 0x7B06,0xE296, // - 0x7B08,0x8B88, // - 0x7B0A,0xE295, // - 0x7B0B,0xE2A2, // - 0x7B0F,0xE294, // - 0x7B11,0x8FCE, // - 0x7B18,0xE298, // - 0x7B19,0xE299, // - 0x7B1B,0x934A, // - 0x7B1E,0xE29A, // - 0x7B20,0x8A7D, // - 0x7B25,0x9079, // - 0x7B26,0x9584, // - 0x7B28,0xE29C, // - 0x7B2C,0x91E6, // - 0x7B33,0xE297, // - 0x7B35,0xE29B, // - 0x7B36,0xE29D, // - 0x7B39,0x8DF9, // - 0x7B45,0xE2A4, // - 0x7B46,0x954D, // - 0x7B48,0x94A4, // - 0x7B49,0x9399, // - 0x7B4B,0x8BD8, // - 0x7B4C,0xE2A3, // - 0x7B4D,0xE2A1, // - 0x7B4F,0x94B3, // - 0x7B50,0xE29E, // - 0x7B51,0x927D, // - 0x7B52,0x939B, // - 0x7B54,0x939A, // - 0x7B56,0x8DF4, // - 0x7B5D,0xE2B6, // - 0x7B65,0xE2A6, // - 0x7B67,0xE2A8, // - 0x7B6C,0xE2AB, // - 0x7B6E,0xE2AC, // - 0x7B70,0xE2A9, // - 0x7B71,0xE2AA, // - 0x7B74,0xE2A7, // - 0x7B75,0xE2A5, // - 0x7B7A,0xE29F, // - 0x7B86,0x95CD, // - 0x7B87,0x89D3, // - 0x7B8B,0xE2B3, // - 0x7B8D,0xE2B0, // - 0x7B8F,0xE2B5, // - 0x7B92,0xE2B4, // - 0x7B94,0x9493, // - 0x7B95,0x96A5, // - 0x7B97,0x8E5A, // - 0x7B98,0xE2AE, // - 0x7B99,0xE2B7, // - 0x7B9A,0xE2B2, // - 0x7B9C,0xE2B1, // - 0x7B9D,0xE2AD, // - 0x7B9F,0xE2AF, // - 0x7BA1,0x8AC7, // - 0x7BAA,0x925C, // - 0x7BAD,0x90FB, // - 0x7BB1,0x94A0, // - 0x7BB4,0xE2BC, // - 0x7BB8,0x94A2, // - 0x7BC0,0x90DF, // - 0x7BC1,0xE2B9, // - 0x7BC4,0x94CD, // - 0x7BC6,0xE2BD, // - 0x7BC7,0x95D1, // - 0x7BC9,0x927A, // - 0x7BCB,0xE2B8, // - 0x7BCC,0xE2BA, // - 0x7BCF,0xE2BB, // - 0x7BDD,0xE2BE, // - 0x7BE0,0x8EC2, // - 0x7BE4,0x93C4, // - 0x7BE5,0xE2C3, // - 0x7BE6,0xE2C2, // - 0x7BE9,0xE2BF, // - 0x7BED,0x9855, // - 0x7BF3,0xE2C8, // - 0x7BF6,0xE2CC, // - 0x7BF7,0xE2C9, // - 0x7C00,0xE2C5, // - 0x7C07,0xE2C6, // - 0x7C0D,0xE2CB, // - 0x7C11,0xE2C0, // - 0x7C12,0x99D3, // - 0x7C13,0xE2C7, // - 0x7C14,0xE2C1, // - 0x7C17,0xE2CA, // - 0x7C1F,0xE2D0, // - 0x7C21,0x8AC8, // - 0x7C23,0xE2CD, // - 0x7C27,0xE2CE, // - 0x7C2A,0xE2CF, // - 0x7C2B,0xE2D2, // - 0x7C37,0xE2D1, // - 0x7C38,0x94F4, // - 0x7C3D,0xE2D3, // - 0x7C3E,0x97FA, // - 0x7C3F,0x95EB, // - 0x7C40,0xE2D8, // - 0x7C43,0xE2D5, // - 0x7C4C,0xE2D4, // - 0x7C4D,0x90D0, // - 0x7C4F,0xE2D7, // - 0x7C50,0xE2D9, // - 0x7C54,0xE2D6, // - 0x7C56,0xE2DD, // - 0x7C58,0xE2DA, // - 0x7C5F,0xE2DB, // - 0x7C60,0xE2C4, // - 0x7C64,0xE2DC, // - 0x7C65,0xE2DE, // - 0x7C6C,0xE2DF, // - 0x7C73,0x95C4, // - 0x7C75,0xE2E0, // - 0x7C7E,0x96E0, // - 0x7C81,0x8BCC, // - 0x7C82,0x8C48, // - 0x7C83,0xE2E1, // - 0x7C89,0x95B2, // - 0x7C8B,0x9088, // - 0x7C8D,0x96AE, // - 0x7C90,0xE2E2, // - 0x7C92,0x97B1, // - 0x7C95,0x9494, // - 0x7C97,0x9165, // - 0x7C98,0x9453, // - 0x7C9B,0x8F6C, // - 0x7C9F,0x88BE, // - 0x7CA1,0xE2E7, // - 0x7CA2,0xE2E5, // - 0x7CA4,0xE2E3, // - 0x7CA5,0x8A9F, // - 0x7CA7,0x8FCF, // - 0x7CA8,0xE2E8, // - 0x7CAB,0xE2E6, // - 0x7CAD,0xE2E4, // - 0x7CAE,0xE2EC, // - 0x7CB1,0xE2EB, // - 0x7CB2,0xE2EA, // - 0x7CB3,0xE2E9, // - 0x7CB9,0xE2ED, // - 0x7CBD,0xE2EE, // - 0x7CBE,0x90B8, // - 0x7CC0,0xE2EF, // - 0x7CC2,0xE2F1, // - 0x7CC5,0xE2F0, // - 0x7CCA,0x8CD0, // - 0x7CCE,0x9157, // - 0x7CD2,0xE2F3, // - 0x7CD6,0x939C, // - 0x7CD8,0xE2F2, // - 0x7CDC,0xE2F4, // - 0x7CDE,0x95B3, // - 0x7CDF,0x918C, // - 0x7CE0,0x8D66, // - 0x7CE2,0xE2F5, // - 0x7CE7,0x97C6, // - 0x7CEF,0xE2F7, // - 0x7CF2,0xE2F8, // - 0x7CF4,0xE2F9, // - 0x7CF6,0xE2FA, // - 0x7CF8,0x8E85, // - 0x7CFA,0xE2FB, // - 0x7CFB,0x8C6E, // - 0x7CFE,0x8B8A, // - 0x7D00,0x8B49, // - 0x7D02,0xE340, // - 0x7D04,0x96F1, // - 0x7D05,0x8D67, // - 0x7D06,0xE2FC, // - 0x7D0A,0xE343, // - 0x7D0B,0x96E4, // - 0x7D10,0x9552, // - 0x7D14,0x8F83, // - 0x7D15,0xE342, // - 0x7D17,0x8ED1, // - 0x7D18,0x8D68, // - 0x7D19,0x8E86, // - 0x7D1A,0x8B89, // - 0x7D1B,0x95B4, // - 0x7D1C,0xE341, // - 0x7D20,0x9166, // - 0x7D21,0x9661, // - 0x7D22,0x8DF5, // - 0x7D2B,0x8E87, // - 0x7D2C,0x92DB, // - 0x7D2E,0xE346, // - 0x7D2F,0x97DD, // - 0x7D30,0x8DD7, // - 0x7D32,0xE347, // - 0x7D33,0x9061, // - 0x7D35,0xE349, // - 0x7D39,0x8FD0, // - 0x7D3A,0x8DAE, // - 0x7D3F,0xE348, // - 0x7D42,0x8F49, // - 0x7D43,0x8CBC, // - 0x7D44,0x9167, // - 0x7D45,0xE344, // - 0x7D46,0xE34A, // - 0x7D4B,0xE345, // - 0x7D4C,0x8C6F, // - 0x7D4E,0xE34D, // - 0x7D4F,0xE351, // - 0x7D50,0x8C8B, // - 0x7D56,0xE34C, // - 0x7D5B,0xE355, // - 0x7D5E,0x8D69, // - 0x7D61,0x978D, // - 0x7D62,0x88BA, // - 0x7D63,0xE352, // - 0x7D66,0x8B8B, // - 0x7D68,0xE34F, // - 0x7D6E,0xE350, // - 0x7D71,0x939D, // - 0x7D72,0xE34E, // - 0x7D73,0xE34B, // - 0x7D75,0x8A47, // - 0x7D76,0x90E2, // - 0x7D79,0x8CA6, // - 0x7D7D,0xE357, // - 0x7D89,0xE354, // - 0x7D8F,0xE356, // - 0x7D93,0xE353, // - 0x7D99,0x8C70, // - 0x7D9A,0x91B1, // - 0x7D9B,0xE358, // - 0x7D9C,0x918E, // - 0x7D9F,0xE365, // - 0x7DA2,0xE361, // - 0x7DAB,0xE35F, // - 0x7DAC,0x8EF8, // - 0x7DAD,0x88DB, // - 0x7DAE,0xE35A, // - 0x7DAF,0xE362, // - 0x7DB0,0xE366, // - 0x7DB1,0x8D6A, // - 0x7DB2,0x96D4, // - 0x7DB4,0x92D4, // - 0x7DB5,0xE35C, // - 0x7DB8,0xE364, // - 0x7DBA,0xE359, // - 0x7DBB,0x925D, // - 0x7DBD,0xE35E, // - 0x7DBE,0x88BB, // - 0x7DBF,0x96C8, // - 0x7DC7,0xE35D, // - 0x7DCA,0x8BD9, // - 0x7DCB,0x94EA, // - 0x7DCF,0x918D, // - 0x7DD1,0x97CE, // - 0x7DD2,0x8F8F, // - 0x7DD5,0xE38E, // - 0x7DD8,0xE367, // - 0x7DDA,0x90FC, // - 0x7DDC,0xE363, // - 0x7DDD,0xE368, // - 0x7DDE,0xE36A, // - 0x7DE0,0x92F7, // - 0x7DE1,0xE36D, // - 0x7DE4,0xE369, // - 0x7DE8,0x95D2, // - 0x7DE9,0x8AC9, // - 0x7DEC,0x96C9, // - 0x7DEF,0x88DC, // - 0x7DF2,0xE36C, // - 0x7DF4,0x97FB, // - 0x7DFB,0xE36B, // - 0x7E01,0x898F, // - 0x7E04,0x93EA, // - 0x7E05,0xE36E, // - 0x7E09,0xE375, // - 0x7E0A,0xE36F, // - 0x7E0B,0xE376, // - 0x7E12,0xE372, // - 0x7E1B,0x949B, // - 0x7E1E,0x8EC8, // - 0x7E1F,0xE374, // - 0x7E21,0xE371, // - 0x7E22,0xE377, // - 0x7E23,0xE370, // - 0x7E26,0x8F63, // - 0x7E2B,0x9644, // - 0x7E2E,0x8F6B, // - 0x7E31,0xE373, // - 0x7E32,0xE380, // - 0x7E35,0xE37B, // - 0x7E37,0xE37E, // - 0x7E39,0xE37C, // - 0x7E3A,0xE381, // - 0x7E3B,0xE37A, // - 0x7E3D,0xE360, // - 0x7E3E,0x90D1, // - 0x7E41,0x94C9, // - 0x7E43,0xE37D, // - 0x7E46,0xE378, // - 0x7E4A,0x9140, // - 0x7E4B,0x8C71, // - 0x7E4D,0x8F4A, // - 0x7E54,0x9044, // - 0x7E55,0x9155, // - 0x7E56,0xE384, // - 0x7E59,0xE386, // - 0x7E5A,0xE387, // - 0x7E5D,0xE383, // - 0x7E5E,0xE385, // - 0x7E66,0xE379, // - 0x7E67,0xE382, // - 0x7E69,0xE38A, // - 0x7E6A,0xE389, // - 0x7E6D,0x969A, // - 0x7E70,0x8C4A, // - 0x7E79,0xE388, // - 0x7E7B,0xE38C, // - 0x7E7C,0xE38B, // - 0x7E7D,0xE38F, // - 0x7E7F,0xE391, // - 0x7E83,0xE38D, // - 0x7E88,0xE392, // - 0x7E89,0xE393, // - 0x7E8C,0xE394, // - 0x7E8E,0xE39A, // - 0x7E8F,0x935A, // - 0x7E90,0xE396, // - 0x7E92,0xE395, // - 0x7E93,0xE397, // - 0x7E94,0xE398, // - 0x7E96,0xE399, // - 0x7E9B,0xE39B, // - 0x7E9C,0xE39C, // - 0x7F36,0x8ACA, // - 0x7F38,0xE39D, // - 0x7F3A,0xE39E, // - 0x7F45,0xE39F, // - 0x7F4C,0xE3A0, // - 0x7F4D,0xE3A1, // - 0x7F4E,0xE3A2, // - 0x7F50,0xE3A3, // - 0x7F51,0xE3A4, // - 0x7F54,0xE3A6, // - 0x7F55,0xE3A5, // - 0x7F58,0xE3A7, // - 0x7F5F,0xE3A8, // - 0x7F60,0xE3A9, // - 0x7F67,0xE3AC, // - 0x7F68,0xE3AA, // - 0x7F69,0xE3AB, // - 0x7F6A,0x8DDF, // - 0x7F6B,0x8C72, // - 0x7F6E,0x9275, // - 0x7F70,0x94B1, // - 0x7F72,0x8F90, // - 0x7F75,0x946C, // - 0x7F77,0x94EB, // - 0x7F78,0xE3AD, // - 0x7F79,0x9CEB, // - 0x7F82,0xE3AE, // - 0x7F83,0xE3B0, // - 0x7F85,0x9785, // - 0x7F86,0xE3AF, // - 0x7F87,0xE3B2, // - 0x7F88,0xE3B1, // - 0x7F8A,0x9772, // - 0x7F8C,0xE3B3, // - 0x7F8E,0x94FC, // - 0x7F94,0xE3B4, // - 0x7F9A,0xE3B7, // - 0x7F9D,0xE3B6, // - 0x7F9E,0xE3B5, // - 0x7FA3,0xE3B8, // - 0x7FA4,0x8C51, // - 0x7FA8,0x9141, // - 0x7FA9,0x8B60, // - 0x7FAE,0xE3BC, // - 0x7FAF,0xE3B9, // - 0x7FB2,0xE3BA, // - 0x7FB6,0xE3BD, // - 0x7FB8,0xE3BE, // - 0x7FB9,0xE3BB, // - 0x7FBD,0x8948, // - 0x7FC1,0x89A5, // - 0x7FC5,0xE3C0, // - 0x7FC6,0xE3C1, // - 0x7FCA,0xE3C2, // - 0x7FCC,0x9782, // - 0x7FD2,0x8F4B, // - 0x7FD4,0xE3C4, // - 0x7FD5,0xE3C3, // - 0x7FE0,0x9089, // - 0x7FE1,0xE3C5, // - 0x7FE6,0xE3C6, // - 0x7FE9,0xE3C7, // - 0x7FEB,0x8AE3, // - 0x7FF0,0x8ACB, // - 0x7FF3,0xE3C8, // - 0x7FF9,0xE3C9, // - 0x7FFB,0x967C, // - 0x7FFC,0x9783, // - 0x8000,0x9773, // - 0x8001,0x9856, // - 0x8003,0x8D6C, // - 0x8004,0xE3CC, // - 0x8005,0x8ED2, // - 0x8006,0xE3CB, // - 0x800B,0xE3CD, // - 0x800C,0x8EA7, // - 0x8010,0x91CF, // - 0x8012,0xE3CE, // - 0x8015,0x8D6B, // - 0x8017,0x96D5, // - 0x8018,0xE3CF, // - 0x8019,0xE3D0, // - 0x801C,0xE3D1, // - 0x8021,0xE3D2, // - 0x8028,0xE3D3, // - 0x8033,0x8EA8, // - 0x8036,0x96EB, // - 0x803B,0xE3D5, // - 0x803D,0x925E, // - 0x803F,0xE3D4, // - 0x8046,0xE3D7, // - 0x804A,0xE3D6, // - 0x8052,0xE3D8, // - 0x8056,0x90B9, // - 0x8058,0xE3D9, // - 0x805A,0xE3DA, // - 0x805E,0x95B7, // - 0x805F,0xE3DB, // - 0x8061,0x918F, // - 0x8062,0xE3DC, // - 0x8068,0xE3DD, // - 0x806F,0x97FC, // - 0x8070,0xE3E0, // - 0x8072,0xE3DF, // - 0x8073,0xE3DE, // - 0x8074,0x92AE, // - 0x8076,0xE3E1, // - 0x8077,0x9045, // - 0x8079,0xE3E2, // - 0x807D,0xE3E3, // - 0x807E,0x9857, // - 0x807F,0xE3E4, // - 0x8084,0xE3E5, // - 0x8085,0xE3E7, // - 0x8086,0xE3E6, // - 0x8087,0x94A3, // - 0x8089,0x93F7, // - 0x808B,0x985D, // - 0x808C,0x94A7, // - 0x8093,0xE3E9, // - 0x8096,0x8FD1, // - 0x8098,0x9549, // - 0x809A,0xE3EA, // - 0x809B,0xE3E8, // - 0x809D,0x8ACC, // - 0x80A1,0x8CD2, // - 0x80A2,0x8E88, // - 0x80A5,0x94EC, // - 0x80A9,0x8CA8, // - 0x80AA,0x9662, // - 0x80AC,0xE3ED, // - 0x80AD,0xE3EB, // - 0x80AF,0x8D6D, // - 0x80B1,0x8D6E, // - 0x80B2,0x88E7, // - 0x80B4,0x8DE6, // - 0x80BA,0x9478, // - 0x80C3,0x88DD, // - 0x80C4,0xE3F2, // - 0x80C6,0x925F, // - 0x80CC,0x9477, // - 0x80CE,0x91D9, // - 0x80D6,0xE3F4, // - 0x80D9,0xE3F0, // - 0x80DA,0xE3F3, // - 0x80DB,0xE3EE, // - 0x80DD,0xE3F1, // - 0x80DE,0x9645, // - 0x80E1,0x8CD3, // - 0x80E4,0x88FB, // - 0x80E5,0xE3EF, // - 0x80EF,0xE3F6, // - 0x80F1,0xE3F7, // - 0x80F4,0x93B7, // - 0x80F8,0x8BB9, // - 0x80FC,0xE445, // - 0x80FD,0x945C, // - 0x8102,0x8E89, // - 0x8105,0x8BBA, // - 0x8106,0x90C6, // - 0x8107,0x9865, // - 0x8108,0x96AC, // - 0x8109,0xE3F5, // - 0x810A,0x90D2, // - 0x811A,0x8B72, // - 0x811B,0xE3F8, // - 0x8123,0xE3FA, // - 0x8129,0xE3F9, // - 0x812F,0xE3FB, // - 0x8131,0x9245, // - 0x8133,0x945D, // - 0x8139,0x92AF, // - 0x813E,0xE442, // - 0x8146,0xE441, // - 0x814B,0xE3FC, // - 0x814E,0x9074, // - 0x8150,0x9585, // - 0x8151,0xE444, // - 0x8153,0xE443, // - 0x8154,0x8D6F, // - 0x8155,0x9872, // - 0x815F,0xE454, // - 0x8165,0xE448, // - 0x8166,0xE449, // - 0x816B,0x8EEE, // - 0x816E,0xE447, // - 0x8170,0x8D98, // - 0x8171,0xE446, // - 0x8174,0xE44A, // - 0x8178,0x92B0, // - 0x8179,0x95A0, // - 0x817A,0x9142, // - 0x817F,0x91DA, // - 0x8180,0xE44E, // - 0x8182,0xE44F, // - 0x8183,0xE44B, // - 0x8188,0xE44C, // - 0x818A,0xE44D, // - 0x818F,0x8D70, // - 0x8193,0xE455, // - 0x8195,0xE451, // - 0x819A,0x9586, // - 0x819C,0x968C, // - 0x819D,0x9547, // - 0x81A0,0xE450, // - 0x81A3,0xE453, // - 0x81A4,0xE452, // - 0x81A8,0x9663, // - 0x81A9,0xE456, // - 0x81B0,0xE457, // - 0x81B3,0x9156, // - 0x81B5,0xE458, // - 0x81B8,0xE45A, // - 0x81BA,0xE45E, // - 0x81BE,0xE459, // - 0x81BF,0x945E, // - 0x81C0,0xE45C, // - 0x81C2,0xE45D, // - 0x81C6,0x89B0, // - 0x81C8,0xE464, // - 0x81C9,0xE45F, // - 0x81CD,0xE460, // - 0x81D1,0xE461, // - 0x81D3,0x919F, // - 0x81D8,0xE463, // - 0x81D9,0xE462, // - 0x81DA,0xE465, // - 0x81DF,0xE466, // - 0x81E0,0xE467, // - 0x81E3,0x9062, // - 0x81E5,0x89E7, // - 0x81E7,0xE468, // - 0x81E8,0x97D5, // - 0x81EA,0x8EA9, // - 0x81ED,0x8F4C, // - 0x81F3,0x8E8A, // - 0x81F4,0x9276, // - 0x81FA,0xE469, // - 0x81FB,0xE46A, // - 0x81FC,0x8950, // - 0x81FE,0xE46B, // - 0x8201,0xE46C, // - 0x8202,0xE46D, // - 0x8205,0xE46E, // - 0x8207,0xE46F, // - 0x8208,0x8BBB, // - 0x8209,0x9DA8, // - 0x820A,0xE470, // - 0x820C,0x90E3, // - 0x820D,0xE471, // - 0x820E,0x8EC9, // - 0x8210,0xE472, // - 0x8212,0x98AE, // - 0x8216,0xE473, // - 0x8217,0x95DC, // - 0x8218,0x8ADA, // - 0x821B,0x9143, // - 0x821C,0x8F77, // - 0x821E,0x9591, // - 0x821F,0x8F4D, // - 0x8229,0xE474, // - 0x822A,0x8D71, // - 0x822B,0xE475, // - 0x822C,0x94CA, // - 0x822E,0xE484, // - 0x8233,0xE477, // - 0x8235,0x91C7, // - 0x8236,0x9495, // - 0x8237,0x8CBD, // - 0x8238,0xE476, // - 0x8239,0x9144, // - 0x8240,0xE478, // - 0x8247,0x92F8, // - 0x8258,0xE47A, // - 0x8259,0xE479, // - 0x825A,0xE47C, // - 0x825D,0xE47B, // - 0x825F,0xE47D, // - 0x8262,0xE480, // - 0x8264,0xE47E, // - 0x8266,0x8ACD, // - 0x8268,0xE481, // - 0x826A,0xE482, // - 0x826B,0xE483, // - 0x826E,0x8DAF, // - 0x826F,0x97C7, // - 0x8271,0xE485, // - 0x8272,0x9046, // - 0x8276,0x8990, // - 0x8277,0xE486, // - 0x8278,0xE487, // - 0x827E,0xE488, // - 0x828B,0x88F0, // - 0x828D,0xE489, // - 0x8292,0xE48A, // - 0x8299,0x9587, // - 0x829D,0x8EC5, // - 0x829F,0xE48C, // - 0x82A5,0x8A48, // - 0x82A6,0x88B0, // - 0x82AB,0xE48B, // - 0x82AC,0xE48E, // - 0x82AD,0x946D, // - 0x82AF,0x9063, // - 0x82B1,0x89D4, // - 0x82B3,0x9646, // - 0x82B8,0x8C7C, // - 0x82B9,0x8BDA, // - 0x82BB,0xE48D, // - 0x82BD,0x89E8, // - 0x82C5,0x8AA1, // - 0x82D1,0x8991, // - 0x82D2,0xE492, // - 0x82D3,0x97E8, // - 0x82D4,0x91DB, // - 0x82D7,0x9563, // - 0x82D9,0xE49E, // - 0x82DB,0x89D5, // - 0x82DC,0xE49C, // - 0x82DE,0xE49A, // - 0x82DF,0xE491, // - 0x82E1,0xE48F, // - 0x82E3,0xE490, // - 0x82E5,0x8EE1, // - 0x82E6,0x8BEA, // - 0x82E7,0x9297, // - 0x82EB,0x93CF, // - 0x82F1,0x8970, // - 0x82F3,0xE494, // - 0x82F4,0xE493, // - 0x82F9,0xE499, // - 0x82FA,0xE495, // - 0x82FB,0xE498, // - 0x8302,0x96CE, // - 0x8303,0xE497, // - 0x8304,0x89D6, // - 0x8305,0x8A9D, // - 0x8306,0xE49B, // - 0x8309,0xE49D, // - 0x830E,0x8C73, // - 0x8316,0xE4A1, // - 0x8317,0xE4AA, // - 0x8318,0xE4AB, // - 0x831C,0x88A9, // - 0x8323,0xE4B2, // - 0x8328,0x88EF, // - 0x832B,0xE4A9, // - 0x832F,0xE4A8, // - 0x8331,0xE4A3, // - 0x8332,0xE4A2, // - 0x8334,0xE4A0, // - 0x8335,0xE49F, // - 0x8336,0x9283, // - 0x8338,0x91F9, // - 0x8339,0xE4A5, // - 0x8340,0xE4A4, // - 0x8345,0xE4A7, // - 0x8349,0x9190, // - 0x834A,0x8C74, // - 0x834F,0x8960, // - 0x8350,0xE4A6, // - 0x8352,0x8D72, // - 0x8358,0x9191, // - 0x8373,0xE4B8, // - 0x8375,0xE4B9, // - 0x8377,0x89D7, // - 0x837B,0x89AC, // - 0x837C,0xE4B6, // - 0x8385,0xE4AC, // - 0x8387,0xE4B4, // - 0x8389,0xE4BB, // - 0x838A,0xE4B5, // - 0x838E,0xE4B3, // - 0x8393,0xE496, // - 0x8396,0xE4B1, // - 0x839A,0xE4AD, // - 0x839E,0x8ACE, // - 0x839F,0xE4AF, // - 0x83A0,0xE4BA, // - 0x83A2,0xE4B0, // - 0x83A8,0xE4BC, // - 0x83AA,0xE4AE, // - 0x83AB,0x949C, // - 0x83B1,0x9789, // - 0x83B5,0xE4B7, // - 0x83BD,0xE4CD, // - 0x83C1,0xE4C5, // - 0x83C5,0x909B, // - 0x83CA,0x8B65, // - 0x83CC,0x8BDB, // - 0x83CE,0xE4C0, // - 0x83D3,0x89D9, // - 0x83D6,0x8FD2, // - 0x83D8,0xE4C3, // - 0x83DC,0x8DD8, // - 0x83DF,0x9370, // - 0x83E0,0xE4C8, // - 0x83E9,0x95EC, // - 0x83EB,0xE4BF, // - 0x83EF,0x89D8, // - 0x83F0,0x8CD4, // - 0x83F1,0x9548, // - 0x83F2,0xE4C9, // - 0x83F4,0xE4BD, // - 0x83F7,0xE4C6, // - 0x83FB,0xE4D0, // - 0x83FD,0xE4C1, // - 0x8403,0xE4C2, // - 0x8404,0x93B8, // - 0x8407,0xE4C7, // - 0x840B,0xE4C4, // - 0x840C,0x9647, // - 0x840D,0xE4CA, // - 0x840E,0x88DE, // - 0x8413,0xE4BE, // - 0x8420,0xE4CC, // - 0x8422,0xE4CB, // - 0x8429,0x948B, // - 0x842A,0xE4D2, // - 0x842C,0xE4DD, // - 0x8431,0x8A9E, // - 0x8435,0xE4E0, // - 0x8438,0xE4CE, // - 0x843C,0xE4D3, // - 0x843D,0x978E, // - 0x8446,0xE4DC, // - 0x8449,0x9774, // - 0x844E,0x97A8, // - 0x8457,0x9298, // - 0x845B,0x8A8B, // - 0x8461,0x9592, // - 0x8462,0xE4E2, // - 0x8463,0x939F, // - 0x8466,0x88AF, // - 0x8469,0xE4DB, // - 0x846B,0xE4D7, // - 0x846C,0x9192, // - 0x846D,0xE4D1, // - 0x846E,0xE4D9, // - 0x846F,0xE4DE, // - 0x8471,0x944B, // - 0x8475,0x88A8, // - 0x8477,0xE4D6, // - 0x8479,0xE4DF, // - 0x847A,0x9598, // - 0x8482,0xE4DA, // - 0x8484,0xE4D5, // - 0x848B,0x8FD3, // - 0x8490,0x8F4E, // - 0x8494,0x8EAA, // - 0x8499,0x96D6, // - 0x849C,0x9566, // - 0x849F,0xE4E5, // - 0x84A1,0xE4EE, // - 0x84AD,0xE4D8, // - 0x84B2,0x8A97, // - 0x84B8,0x8FF6, // - 0x84B9,0xE4E3, // - 0x84BB,0xE4E8, // - 0x84BC,0x9193, // - 0x84BF,0xE4E4, // - 0x84C1,0xE4EB, // - 0x84C4,0x927E, // - 0x84C6,0xE4EC, // - 0x84C9,0x9775, // - 0x84CA,0xE4E1, // - 0x84CB,0x8A57, // - 0x84CD,0xE4E7, // - 0x84D0,0xE4EA, // - 0x84D1,0x96AA, // - 0x84D6,0xE4ED, // - 0x84D9,0xE4E6, // - 0x84DA,0xE4E9, // - 0x84EC,0x9648, // - 0x84EE,0x9840, // - 0x84F4,0xE4F1, // - 0x84FC,0xE4F8, // - 0x84FF,0xE4F0, // - 0x8500,0x8EC1, // - 0x8506,0xE4CF, // - 0x8511,0x95CC, // - 0x8513,0x96A0, // - 0x8514,0xE4F7, // - 0x8515,0xE4F6, // - 0x8517,0xE4F2, // - 0x8518,0xE4F3, // - 0x851A,0x8955, // - 0x851F,0xE4F5, // - 0x8521,0xE4EF, // - 0x8526,0x92D3, // - 0x852C,0xE4F4, // - 0x852D,0x88FC, // - 0x8535,0x91A0, // - 0x853D,0x95C1, // - 0x8540,0xE4F9, // - 0x8541,0xE540, // - 0x8543,0x94D7, // - 0x8548,0xE4FC, // - 0x8549,0x8FD4, // - 0x854A,0x8EC7, // - 0x854B,0xE542, // - 0x854E,0x8BBC, // - 0x8555,0xE543, // - 0x8557,0x9599, // - 0x8558,0xE4FB, // - 0x855A,0xE4D4, // - 0x8563,0xE4FA, // - 0x8568,0x986E, // - 0x8569,0x93A0, // - 0x856A,0x9593, // - 0x856D,0xE54A, // - 0x8577,0xE550, // - 0x857E,0xE551, // - 0x8580,0xE544, // - 0x8584,0x9496, // - 0x8587,0xE54E, // - 0x8588,0xE546, // - 0x858A,0xE548, // - 0x8590,0xE552, // - 0x8591,0xE547, // - 0x8594,0xE54B, // - 0x8597,0x8992, // - 0x8599,0x93E3, // - 0x859B,0xE54C, // - 0x859C,0xE54F, // - 0x85A4,0xE545, // - 0x85A6,0x9145, // - 0x85A8,0xE549, // - 0x85A9,0x8E46, // - 0x85AA,0x9064, // - 0x85AB,0x8C4F, // - 0x85AC,0x96F2, // - 0x85AE,0x96F7, // - 0x85AF,0x8F92, // - 0x85B9,0xE556, // - 0x85BA,0xE554, // - 0x85C1,0x986D, // - 0x85C9,0xE553, // - 0x85CD,0x9795, // - 0x85CF,0xE555, // - 0x85D0,0xE557, // - 0x85D5,0xE558, // - 0x85DD,0xE559, // - 0x85E4,0x93A1, // - 0x85E5,0xE55A, // - 0x85E9,0x94CB, // - 0x85EA,0xE54D, // - 0x85F7,0x8F93, // - 0x85F9,0xE55C, // - 0x85FA,0xE561, // - 0x85FB,0x9194, // - 0x85FE,0xE560, // - 0x8602,0xE541, // - 0x8606,0xE562, // - 0x8607,0x9168, // - 0x860A,0xE55D, // - 0x860B,0xE55F, // - 0x8613,0xE55E, // - 0x8616,0x9F50, // - 0x8617,0x9F41, // - 0x861A,0xE564, // - 0x8622,0xE563, // - 0x862D,0x9796, // - 0x862F,0xE1BA, // - 0x8630,0xE565, // - 0x863F,0xE566, // - 0x864D,0xE567, // - 0x864E,0x8CD5, // - 0x8650,0x8B73, // - 0x8654,0xE569, // - 0x8655,0x997C, // - 0x865A,0x8B95, // - 0x865C,0x97B8, // - 0x865E,0x8BF1, // - 0x865F,0xE56A, // - 0x8667,0xE56B, // - 0x866B,0x928E, // - 0x8671,0xE56C, // - 0x8679,0x93F8, // - 0x867B,0x88B8, // - 0x868A,0x89E1, // - 0x868B,0xE571, // - 0x868C,0xE572, // - 0x8693,0xE56D, // - 0x8695,0x8E5C, // - 0x86A3,0xE56E, // - 0x86A4,0x9461, // - 0x86A9,0xE56F, // - 0x86AA,0xE570, // - 0x86AB,0xE57A, // - 0x86AF,0xE574, // - 0x86B0,0xE577, // - 0x86B6,0xE573, // - 0x86C4,0xE575, // - 0x86C6,0xE576, // - 0x86C7,0x8ED6, // - 0x86C9,0xE578, // - 0x86CB,0x9260, // - 0x86CD,0x8C75, // - 0x86CE,0x8A61, // - 0x86D4,0xE57B, // - 0x86D9,0x8A5E, // - 0x86DB,0xE581, // - 0x86DE,0xE57C, // - 0x86DF,0xE580, // - 0x86E4,0x94B8, // - 0x86E9,0xE57D, // - 0x86EC,0xE57E, // - 0x86ED,0x9567, // - 0x86EE,0x94D8, // - 0x86EF,0xE582, // - 0x86F8,0x91FB, // - 0x86F9,0xE58C, // - 0x86FB,0xE588, // - 0x86FE,0x89E9, // - 0x8700,0xE586, // - 0x8702,0x9649, // - 0x8703,0xE587, // - 0x8706,0xE584, // - 0x8708,0xE585, // - 0x8709,0xE58A, // - 0x870A,0xE58D, // - 0x870D,0xE58B, // - 0x8711,0xE589, // - 0x8712,0xE583, // - 0x8718,0x9277, // - 0x871A,0xE594, // - 0x871C,0x96A8, // - 0x8725,0xE592, // - 0x8729,0xE593, // - 0x8734,0xE58E, // - 0x8737,0xE590, // - 0x873B,0xE591, // - 0x873F,0xE58F, // - 0x8749,0x90E4, // - 0x874B,0x9858, // - 0x874C,0xE598, // - 0x874E,0xE599, // - 0x8753,0xE59F, // - 0x8755,0x9049, // - 0x8757,0xE59B, // - 0x8759,0xE59E, // - 0x875F,0xE596, // - 0x8760,0xE595, // - 0x8763,0xE5A0, // - 0x8766,0x89DA, // - 0x8768,0xE59C, // - 0x876A,0xE5A1, // - 0x876E,0xE59D, // - 0x8774,0xE59A, // - 0x8776,0x92B1, // - 0x8778,0xE597, // - 0x877F,0x9488, // - 0x8782,0xE5A5, // - 0x878D,0x975A, // - 0x879F,0xE5A4, // - 0x87A2,0xE5A3, // - 0x87AB,0xE5AC, // - 0x87AF,0xE5A6, // - 0x87B3,0xE5AE, // - 0x87BA,0x9786, // - 0x87BB,0xE5B1, // - 0x87BD,0xE5A8, // - 0x87C0,0xE5A9, // - 0x87C4,0xE5AD, // - 0x87C6,0xE5B0, // - 0x87C7,0xE5AF, // - 0x87CB,0xE5A7, // - 0x87D0,0xE5AA, // - 0x87D2,0xE5BB, // - 0x87E0,0xE5B4, // - 0x87EF,0xE5B2, // - 0x87F2,0xE5B3, // - 0x87F6,0xE5B8, // - 0x87F7,0xE5B9, // - 0x87F9,0x8A49, // - 0x87FB,0x8B61, // - 0x87FE,0xE5B7, // - 0x8805,0xE5A2, // - 0x880D,0xE5B6, // - 0x880E,0xE5BA, // - 0x880F,0xE5B5, // - 0x8811,0xE5BC, // - 0x8815,0xE5BE, // - 0x8816,0xE5BD, // - 0x8821,0xE5C0, // - 0x8822,0xE5BF, // - 0x8823,0xE579, // - 0x8827,0xE5C4, // - 0x8831,0xE5C1, // - 0x8836,0xE5C2, // - 0x8839,0xE5C3, // - 0x883B,0xE5C5, // - 0x8840,0x8C8C, // - 0x8842,0xE5C7, // - 0x8844,0xE5C6, // - 0x8846,0x8F4F, // - 0x884C,0x8D73, // - 0x884D,0x9FA5, // - 0x8852,0xE5C8, // - 0x8853,0x8F70, // - 0x8857,0x8A58, // - 0x8859,0xE5C9, // - 0x885B,0x8971, // - 0x885D,0x8FD5, // - 0x885E,0xE5CA, // - 0x8861,0x8D74, // - 0x8862,0xE5CB, // - 0x8863,0x88DF, // - 0x8868,0x955C, // - 0x886B,0xE5CC, // - 0x8870,0x908A, // - 0x8872,0xE5D3, // - 0x8875,0xE5D0, // - 0x8877,0x928F, // - 0x887D,0xE5D1, // - 0x887E,0xE5CE, // - 0x887F,0x8BDC, // - 0x8881,0xE5CD, // - 0x8882,0xE5D4, // - 0x8888,0x8C55, // - 0x888B,0x91DC, // - 0x888D,0xE5DA, // - 0x8892,0xE5D6, // - 0x8896,0x91B3, // - 0x8897,0xE5D5, // - 0x8899,0xE5D8, // - 0x889E,0xE5CF, // - 0x88A2,0xE5D9, // - 0x88A4,0xE5DB, // - 0x88AB,0x94ED, // - 0x88AE,0xE5D7, // - 0x88B0,0xE5DC, // - 0x88B1,0xE5DE, // - 0x88B4,0x8CD1, // - 0x88B5,0xE5D2, // - 0x88B7,0x88BF, // - 0x88BF,0xE5DD, // - 0x88C1,0x8DD9, // - 0x88C2,0x97F4, // - 0x88C3,0xE5DF, // - 0x88C4,0xE5E0, // - 0x88C5,0x9195, // - 0x88CF,0x97A0, // - 0x88D4,0xE5E1, // - 0x88D5,0x9754, // - 0x88D8,0xE5E2, // - 0x88D9,0xE5E3, // - 0x88DC,0x95E2, // - 0x88DD,0xE5E4, // - 0x88DF,0x8DBE, // - 0x88E1,0x97A1, // - 0x88E8,0xE5E9, // - 0x88F2,0xE5EA, // - 0x88F3,0x8FD6, // - 0x88F4,0xE5E8, // - 0x88F8,0x9787, // - 0x88F9,0xE5E5, // - 0x88FC,0xE5E7, // - 0x88FD,0x90BB, // - 0x88FE,0x909E, // - 0x8902,0xE5E6, // - 0x8904,0xE5EB, // - 0x8907,0x95A1, // - 0x890A,0xE5ED, // - 0x890C,0xE5EC, // - 0x8910,0x8A8C, // - 0x8912,0x964A, // - 0x8913,0xE5EE, // - 0x891D,0xE5FA, // - 0x891E,0xE5F0, // - 0x8925,0xE5F1, // - 0x892A,0xE5F2, // - 0x892B,0xE5F3, // - 0x8936,0xE5F7, // - 0x8938,0xE5F8, // - 0x893B,0xE5F6, // - 0x8941,0xE5F4, // - 0x8943,0xE5EF, // - 0x8944,0xE5F5, // - 0x894C,0xE5F9, // - 0x894D,0xE8B5, // - 0x8956,0x89A6, // - 0x895E,0xE5FC, // - 0x895F,0x8BDD, // - 0x8960,0xE5FB, // - 0x8964,0xE641, // - 0x8966,0xE640, // - 0x896A,0xE643, // - 0x896D,0xE642, // - 0x896F,0xE644, // - 0x8972,0x8F50, // - 0x8974,0xE645, // - 0x8977,0xE646, // - 0x897E,0xE647, // - 0x897F,0x90BC, // - 0x8981,0x9776, // - 0x8983,0xE648, // - 0x8986,0x95A2, // - 0x8987,0x9465, // - 0x8988,0xE649, // - 0x898A,0xE64A, // - 0x898B,0x8CA9, // - 0x898F,0x8B4B, // - 0x8993,0xE64B, // - 0x8996,0x8E8B, // - 0x8997,0x9460, // - 0x8998,0xE64C, // - 0x899A,0x8A6F, // - 0x89A1,0xE64D, // - 0x89A6,0xE64F, // - 0x89A7,0x9797, // - 0x89A9,0xE64E, // - 0x89AA,0x9065, // - 0x89AC,0xE650, // - 0x89AF,0xE651, // - 0x89B2,0xE652, // - 0x89B3,0x8ACF, // - 0x89BA,0xE653, // - 0x89BD,0xE654, // - 0x89BF,0xE655, // - 0x89C0,0xE656, // - 0x89D2,0x8A70, // - 0x89DA,0xE657, // - 0x89DC,0xE658, // - 0x89DD,0xE659, // - 0x89E3,0x89F0, // - 0x89E6,0x9047, // - 0x89E7,0xE65A, // - 0x89F8,0xE65C, // - 0x8A00,0x8CBE, // - 0x8A02,0x92F9, // - 0x8A03,0xE65D, // - 0x8A08,0x8C76, // - 0x8A0A,0x9075, // - 0x8A0C,0xE660, // - 0x8A0E,0x93A2, // - 0x8A10,0xE65F, // - 0x8A13,0x8C50, // - 0x8A16,0xE65E, // - 0x8A17,0x91F5, // - 0x8A18,0x8B4C, // - 0x8A1B,0xE661, // - 0x8A1D,0xE662, // - 0x8A1F,0x8FD7, // - 0x8A23,0x8C8D, // - 0x8A25,0xE663, // - 0x8A2A,0x964B, // - 0x8A2D,0x90DD, // - 0x8A31,0x8B96, // - 0x8A33,0x96F3, // - 0x8A34,0x9169, // - 0x8A36,0xE664, // - 0x8A3A,0x9066, // - 0x8A3B,0x9290, // - 0x8A3C,0x8FD8, // - 0x8A41,0xE665, // - 0x8A46,0xE668, // - 0x8A48,0xE669, // - 0x8A50,0x8DBC, // - 0x8A51,0x91C0, // - 0x8A52,0xE667, // - 0x8A54,0x8FD9, // - 0x8A55,0x955D, // - 0x8A5B,0xE666, // - 0x8A5E,0x8E8C, // - 0x8A60,0x8972, // - 0x8A62,0xE66D, // - 0x8A63,0x8C77, // - 0x8A66,0x8E8E, // - 0x8A69,0x8E8D, // - 0x8A6B,0x986C, // - 0x8A6C,0xE66C, // - 0x8A6D,0xE66B, // - 0x8A6E,0x9146, // - 0x8A70,0x8B6C, // - 0x8A71,0x9862, // - 0x8A72,0x8A59, // - 0x8A73,0x8FDA, // - 0x8A7C,0xE66A, // - 0x8A82,0xE66F, // - 0x8A84,0xE670, // - 0x8A85,0xE66E, // - 0x8A87,0x8CD6, // - 0x8A89,0x975F, // - 0x8A8C,0x8E8F, // - 0x8A8D,0x9446, // - 0x8A91,0xE673, // - 0x8A93,0x90BE, // - 0x8A95,0x9261, // - 0x8A98,0x9755, // - 0x8A9A,0xE676, // - 0x8A9E,0x8CEA, // - 0x8AA0,0x90BD, // - 0x8AA1,0xE672, // - 0x8AA3,0xE677, // - 0x8AA4,0x8CEB, // - 0x8AA5,0xE674, // - 0x8AA6,0xE675, // - 0x8AA8,0xE671, // - 0x8AAC,0x90E0, // - 0x8AAD,0x93C7, // - 0x8AB0,0x924E, // - 0x8AB2,0x89DB, // - 0x8AB9,0x94EE, // - 0x8ABC,0x8B62, // - 0x8ABF,0x92B2, // - 0x8AC2,0xE67A, // - 0x8AC4,0xE678, // - 0x8AC7,0x926B, // - 0x8ACB,0x90BF, // - 0x8ACC,0x8AD0, // - 0x8ACD,0xE679, // - 0x8ACF,0x907A, // - 0x8AD2,0x97C8, // - 0x8AD6,0x985F, // - 0x8ADA,0xE67B, // - 0x8ADB,0xE687, // - 0x8ADC,0x92B3, // - 0x8ADE,0xE686, // - 0x8AE0,0xE683, // - 0x8AE1,0xE68B, // - 0x8AE2,0xE684, // - 0x8AE4,0xE680, // - 0x8AE6,0x92FA, // - 0x8AE7,0xE67E, // - 0x8AEB,0xE67C, // - 0x8AED,0x9740, // - 0x8AEE,0x8E90, // - 0x8AF1,0xE681, // - 0x8AF3,0xE67D, // - 0x8AF7,0xE685, // - 0x8AF8,0x8F94, // - 0x8AFA,0x8CBF, // - 0x8AFE,0x91F8, // - 0x8B00,0x9664, // - 0x8B01,0x8979, // - 0x8B02,0x88E0, // - 0x8B04,0x93A3, // - 0x8B07,0xE689, // - 0x8B0C,0xE688, // - 0x8B0E,0x93E4, // - 0x8B10,0xE68D, // - 0x8B14,0xE682, // - 0x8B16,0xE68C, // - 0x8B17,0xE68E, // - 0x8B19,0x8CAA, // - 0x8B1A,0xE68A, // - 0x8B1B,0x8D75, // - 0x8B1D,0x8ED3, // - 0x8B20,0xE68F, // - 0x8B21,0x9777, // - 0x8B26,0xE692, // - 0x8B28,0xE695, // - 0x8B2B,0xE693, // - 0x8B2C,0x9554, // - 0x8B33,0xE690, // - 0x8B39,0x8BDE, // - 0x8B3E,0xE694, // - 0x8B41,0xE696, // - 0x8B49,0xE69A, // - 0x8B4C,0xE697, // - 0x8B4E,0xE699, // - 0x8B4F,0xE698, // - 0x8B56,0xE69B, // - 0x8B58,0x8EAF, // - 0x8B5A,0xE69D, // - 0x8B5B,0xE69C, // - 0x8B5C,0x9588, // - 0x8B5F,0xE69F, // - 0x8B66,0x8C78, // - 0x8B6B,0xE69E, // - 0x8B6C,0xE6A0, // - 0x8B6F,0xE6A1, // - 0x8B70,0x8B63, // - 0x8B71,0xE3BF, // - 0x8B72,0x8FF7, // - 0x8B74,0xE6A2, // - 0x8B77,0x8CEC, // - 0x8B7D,0xE6A3, // - 0x8B80,0xE6A4, // - 0x8B83,0x8E5D, // - 0x8B8A,0x9DCC, // - 0x8B8C,0xE6A5, // - 0x8B8E,0xE6A6, // - 0x8B90,0x8F51, // - 0x8B92,0xE6A7, // - 0x8B93,0xE6A8, // - 0x8B96,0xE6A9, // - 0x8B99,0xE6AA, // - 0x8B9A,0xE6AB, // - 0x8C37,0x924A, // - 0x8C3A,0xE6AC, // - 0x8C3F,0xE6AE, // - 0x8C41,0xE6AD, // - 0x8C46,0x93A4, // - 0x8C48,0xE6AF, // - 0x8C4A,0x964C, // - 0x8C4C,0xE6B0, // - 0x8C4E,0xE6B1, // - 0x8C50,0xE6B2, // - 0x8C55,0xE6B3, // - 0x8C5A,0x93D8, // - 0x8C61,0x8FDB, // - 0x8C62,0xE6B4, // - 0x8C6A,0x8D8B, // - 0x8C6B,0x98AC, // - 0x8C6C,0xE6B5, // - 0x8C78,0xE6B6, // - 0x8C79,0x955E, // - 0x8C7A,0xE6B7, // - 0x8C7C,0xE6BF, // - 0x8C82,0xE6B8, // - 0x8C85,0xE6BA, // - 0x8C89,0xE6B9, // - 0x8C8A,0xE6BB, // - 0x8C8C,0x9665, // - 0x8C8D,0xE6BC, // - 0x8C8E,0xE6BD, // - 0x8C94,0xE6BE, // - 0x8C98,0xE6C0, // - 0x8C9D,0x8A4C, // - 0x8C9E,0x92E5, // - 0x8CA0,0x9589, // - 0x8CA1,0x8DE0, // - 0x8CA2,0x8D76, // - 0x8CA7,0x956E, // - 0x8CA8,0x89DD, // - 0x8CA9,0x94CC, // - 0x8CAA,0xE6C3, // - 0x8CAB,0x8AD1, // - 0x8CAC,0x90D3, // - 0x8CAD,0xE6C2, // - 0x8CAE,0xE6C7, // - 0x8CAF,0x9299, // - 0x8CB0,0x96E1, // - 0x8CB2,0xE6C5, // - 0x8CB3,0xE6C6, // - 0x8CB4,0x8B4D, // - 0x8CB6,0xE6C8, // - 0x8CB7,0x9483, // - 0x8CB8,0x91DD, // - 0x8CBB,0x94EF, // - 0x8CBC,0x935C, // - 0x8CBD,0xE6C4, // - 0x8CBF,0x9666, // - 0x8CC0,0x89EA, // - 0x8CC1,0xE6CA, // - 0x8CC2,0x9847, // - 0x8CC3,0x92C0, // - 0x8CC4,0x9864, // - 0x8CC7,0x8E91, // - 0x8CC8,0xE6C9, // - 0x8CCA,0x91AF, // - 0x8CCD,0xE6DA, // - 0x8CCE,0x9147, // - 0x8CD1,0x93F6, // - 0x8CD3,0x956F, // - 0x8CDA,0xE6CD, // - 0x8CDB,0x8E5E, // - 0x8CDC,0x8E92, // - 0x8CDE,0x8FDC, // - 0x8CE0,0x9485, // - 0x8CE2,0x8CAB, // - 0x8CE3,0xE6CC, // - 0x8CE4,0xE6CB, // - 0x8CE6,0x958A, // - 0x8CEA,0x8EBF, // - 0x8CED,0x9371, // - 0x8CFA,0xE6CF, // - 0x8CFB,0xE6D0, // - 0x8CFC,0x8D77, // - 0x8CFD,0xE6CE, // - 0x8D04,0xE6D1, // - 0x8D05,0xE6D2, // - 0x8D07,0xE6D4, // - 0x8D08,0x91A1, // - 0x8D0A,0xE6D3, // - 0x8D0B,0x8AE4, // - 0x8D0D,0xE6D6, // - 0x8D0F,0xE6D5, // - 0x8D10,0xE6D7, // - 0x8D13,0xE6D9, // - 0x8D14,0xE6DB, // - 0x8D16,0xE6DC, // - 0x8D64,0x90D4, // - 0x8D66,0x8ECD, // - 0x8D67,0xE6DD, // - 0x8D6B,0x8A71, // - 0x8D6D,0xE6DE, // - 0x8D70,0x9196, // - 0x8D71,0xE6DF, // - 0x8D73,0xE6E0, // - 0x8D74,0x958B, // - 0x8D77,0x8B4E, // - 0x8D81,0xE6E1, // - 0x8D85,0x92B4, // - 0x8D8A,0x897A, // - 0x8D99,0xE6E2, // - 0x8DA3,0x8EEF, // - 0x8DA8,0x9096, // - 0x8DB3,0x91AB, // - 0x8DBA,0xE6E5, // - 0x8DBE,0xE6E4, // - 0x8DC2,0xE6E3, // - 0x8DCB,0xE6EB, // - 0x8DCC,0xE6E9, // - 0x8DCF,0xE6E6, // - 0x8DD6,0xE6E8, // - 0x8DDA,0xE6E7, // - 0x8DDB,0xE6EA, // - 0x8DDD,0x8B97, // - 0x8DDF,0xE6EE, // - 0x8DE1,0x90D5, // - 0x8DE3,0xE6EF, // - 0x8DE8,0x8CD7, // - 0x8DEA,0xE6EC, // - 0x8DEB,0xE6ED, // - 0x8DEF,0x9848, // - 0x8DF3,0x92B5, // - 0x8DF5,0x9148, // - 0x8DFC,0xE6F0, // - 0x8DFF,0xE6F3, // - 0x8E08,0xE6F1, // - 0x8E09,0xE6F2, // - 0x8E0A,0x9778, // - 0x8E0F,0x93A5, // - 0x8E10,0xE6F6, // - 0x8E1D,0xE6F4, // - 0x8E1E,0xE6F5, // - 0x8E1F,0xE6F7, // - 0x8E2A,0xE748, // - 0x8E30,0xE6FA, // - 0x8E34,0xE6FB, // - 0x8E35,0xE6F9, // - 0x8E42,0xE6F8, // - 0x8E44,0x92FB, // - 0x8E47,0xE740, // - 0x8E48,0xE744, // - 0x8E49,0xE741, // - 0x8E4A,0xE6FC, // - 0x8E4C,0xE742, // - 0x8E50,0xE743, // - 0x8E55,0xE74A, // - 0x8E59,0xE745, // - 0x8E5F,0x90D6, // - 0x8E60,0xE747, // - 0x8E63,0xE749, // - 0x8E64,0xE746, // - 0x8E72,0xE74C, // - 0x8E74,0x8F52, // - 0x8E76,0xE74B, // - 0x8E7C,0xE74D, // - 0x8E81,0xE74E, // - 0x8E84,0xE751, // - 0x8E85,0xE750, // - 0x8E87,0xE74F, // - 0x8E8A,0xE753, // - 0x8E8B,0xE752, // - 0x8E8D,0x96F4, // - 0x8E91,0xE755, // - 0x8E93,0xE754, // - 0x8E94,0xE756, // - 0x8E99,0xE757, // - 0x8EA1,0xE759, // - 0x8EAA,0xE758, // - 0x8EAB,0x9067, // - 0x8EAC,0xE75A, // - 0x8EAF,0x8BEB, // - 0x8EB1,0xE75D, // - 0x8EBE,0xE75E, // - 0x8EC5,0xE75F, // - 0x8EC6,0xE75C, // - 0x8EC8,0xE760, // - 0x8ECA,0x8ED4, // - 0x8ECB,0xE761, // - 0x8ECC,0x8B4F, // - 0x8ECD,0x8C52, // - 0x8ED2,0x8CAC, // - 0x8EDB,0xE762, // - 0x8EDF,0x93EE, // - 0x8EE2,0x935D, // - 0x8EE3,0xE763, // - 0x8EEB,0xE766, // - 0x8EF8,0x8EB2, // - 0x8EFB,0xE765, // - 0x8EFC,0xE764, // - 0x8EFD,0x8C79, // - 0x8EFE,0xE767, // - 0x8F03,0x8A72, // - 0x8F05,0xE769, // - 0x8F09,0x8DDA, // - 0x8F0A,0xE768, // - 0x8F0C,0xE771, // - 0x8F12,0xE76B, // - 0x8F13,0xE76D, // - 0x8F14,0x95E3, // - 0x8F15,0xE76A, // - 0x8F19,0xE76C, // - 0x8F1B,0xE770, // - 0x8F1C,0xE76E, // - 0x8F1D,0x8B50, // - 0x8F1F,0xE76F, // - 0x8F26,0xE772, // - 0x8F29,0x9479, // - 0x8F2A,0x97D6, // - 0x8F2F,0x8F53, // - 0x8F33,0xE773, // - 0x8F38,0x9741, // - 0x8F39,0xE775, // - 0x8F3B,0xE774, // - 0x8F3E,0xE778, // - 0x8F3F,0x9760, // - 0x8F42,0xE777, // - 0x8F44,0x8A8D, // - 0x8F45,0xE776, // - 0x8F46,0xE77B, // - 0x8F49,0xE77A, // - 0x8F4C,0xE779, // - 0x8F4D,0x9351, // - 0x8F4E,0xE77C, // - 0x8F57,0xE77D, // - 0x8F5C,0xE77E, // - 0x8F5F,0x8D8C, // - 0x8F61,0x8C44, // - 0x8F62,0xE780, // - 0x8F63,0xE781, // - 0x8F64,0xE782, // - 0x8F9B,0x9068, // - 0x8F9C,0xE783, // - 0x8F9E,0x8EAB, // - 0x8F9F,0xE784, // - 0x8FA3,0xE785, // - 0x8FA7,0x999F, // - 0x8FA8,0x999E, // - 0x8FAD,0xE786, // - 0x8FAE,0xE390, // - 0x8FAF,0xE787, // - 0x8FB0,0x9243, // - 0x8FB1,0x904A, // - 0x8FB2,0x945F, // - 0x8FB7,0xE788, // - 0x8FBA,0x95D3, // - 0x8FBB,0x92D2, // - 0x8FBC,0x8D9E, // - 0x8FBF,0x9248, // - 0x8FC2,0x8949, // - 0x8FC4,0x9698, // - 0x8FC5,0x9076, // - 0x8FCE,0x8C7D, // - 0x8FD1,0x8BDF, // - 0x8FD4,0x95D4, // - 0x8FDA,0xE789, // - 0x8FE2,0xE78B, // - 0x8FE5,0xE78A, // - 0x8FE6,0x89DE, // - 0x8FE9,0x93F4, // - 0x8FEA,0xE78C, // - 0x8FEB,0x9497, // - 0x8FED,0x9352, // - 0x8FEF,0xE78D, // - 0x8FF0,0x8F71, // - 0x8FF4,0xE78F, // - 0x8FF7,0x96C0, // - 0x8FF8,0xE79E, // - 0x8FF9,0xE791, // - 0x8FFA,0xE792, // - 0x8FFD,0x92C7, // - 0x9000,0x91DE, // - 0x9001,0x9197, // - 0x9003,0x93A6, // - 0x9005,0xE790, // - 0x9006,0x8B74, // - 0x900B,0xE799, // - 0x900D,0xE796, // - 0x900E,0xE7A3, // - 0x900F,0x93A7, // - 0x9010,0x9280, // - 0x9011,0xE793, // - 0x9013,0x92FC, // - 0x9014,0x9372, // - 0x9015,0xE794, // - 0x9016,0xE798, // - 0x9017,0x9080, // - 0x9019,0x9487, // - 0x901A,0x92CA, // - 0x901D,0x90C0, // - 0x901E,0xE797, // - 0x901F,0x91AC, // - 0x9020,0x91A2, // - 0x9021,0xE795, // - 0x9022,0x88A7, // - 0x9023,0x9841, // - 0x9027,0xE79A, // - 0x902E,0x91DF, // - 0x9031,0x8F54, // - 0x9032,0x9069, // - 0x9035,0xE79C, // - 0x9036,0xE79B, // - 0x9038,0x88ED, // - 0x9039,0xE79D, // - 0x903C,0x954E, // - 0x903E,0xE7A5, // - 0x9041,0x93D9, // - 0x9042,0x908B, // - 0x9045,0x9278, // - 0x9047,0x8BF6, // - 0x9049,0xE7A4, // - 0x904A,0x9756, // - 0x904B,0x895E, // - 0x904D,0x95D5, // - 0x904E,0x89DF, // - 0x904F,0xE79F, // - 0x9050,0xE7A0, // - 0x9051,0xE7A1, // - 0x9052,0xE7A2, // - 0x9053,0x93B9, // - 0x9054,0x9242, // - 0x9055,0x88E1, // - 0x9056,0xE7A6, // - 0x9058,0xE7A7, // - 0x9059,0xEAA1, // - 0x905C,0x91BB, // - 0x905E,0xE7A8, // - 0x9060,0x8993, // - 0x9061,0x916B, // - 0x9063,0x8CAD, // - 0x9065,0x9779, // - 0x9068,0xE7A9, // - 0x9069,0x934B, // - 0x906D,0x9198, // - 0x906E,0x8ED5, // - 0x906F,0xE7AA, // - 0x9072,0xE7AD, // - 0x9075,0x8F85, // - 0x9076,0xE7AB, // - 0x9077,0x914A, // - 0x9078,0x9149, // - 0x907A,0x88E2, // - 0x907C,0x97C9, // - 0x907D,0xE7AF, // - 0x907F,0x94F0, // - 0x9080,0xE7B1, // - 0x9081,0xE7B0, // - 0x9082,0xE7AE, // - 0x9083,0xE284, // - 0x9084,0x8AD2, // - 0x9087,0xE78E, // - 0x9089,0xE7B3, // - 0x908A,0xE7B2, // - 0x908F,0xE7B4, // - 0x9091,0x9757, // - 0x90A3,0x93DF, // - 0x90A6,0x964D, // - 0x90A8,0xE7B5, // - 0x90AA,0x8ED7, // - 0x90AF,0xE7B6, // - 0x90B1,0xE7B7, // - 0x90B5,0xE7B8, // - 0x90B8,0x9340, // - 0x90C1,0x88E8, // - 0x90CA,0x8D78, // - 0x90CE,0x9859, // - 0x90DB,0xE7BC, // - 0x90E1,0x8C53, // - 0x90E2,0xE7B9, // - 0x90E4,0xE7BA, // - 0x90E8,0x9594, // - 0x90ED,0x8A73, // - 0x90F5,0x9758, // - 0x90F7,0x8BBD, // - 0x90FD,0x9373, // - 0x9102,0xE7BD, // - 0x9112,0xE7BE, // - 0x9119,0xE7BF, // - 0x912D,0x9341, // - 0x9130,0xE7C1, // - 0x9132,0xE7C0, // - 0x9149,0x93D1, // - 0x914A,0xE7C2, // - 0x914B,0x8F55, // - 0x914C,0x8EDE, // - 0x914D,0x947A, // - 0x914E,0x9291, // - 0x9152,0x8EF0, // - 0x9154,0x908C, // - 0x9156,0xE7C3, // - 0x9158,0xE7C4, // - 0x9162,0x907C, // - 0x9163,0xE7C5, // - 0x9165,0xE7C6, // - 0x9169,0xE7C7, // - 0x916A,0x978F, // - 0x916C,0x8F56, // - 0x9172,0xE7C9, // - 0x9173,0xE7C8, // - 0x9175,0x8D79, // - 0x9177,0x8D93, // - 0x9178,0x8E5F, // - 0x9182,0xE7CC, // - 0x9187,0x8F86, // - 0x9189,0xE7CB, // - 0x918B,0xE7CA, // - 0x918D,0x91E7, // - 0x9190,0x8CED, // - 0x9192,0x90C1, // - 0x9197,0x94AE, // - 0x919C,0x8F58, // - 0x91A2,0xE7CD, // - 0x91A4,0x8FDD, // - 0x91AA,0xE7D0, // - 0x91AB,0xE7CE, // - 0x91AF,0xE7CF, // - 0x91B4,0xE7D2, // - 0x91B5,0xE7D1, // - 0x91B8,0x8FF8, // - 0x91BA,0xE7D3, // - 0x91C0,0xE7D4, // - 0x91C1,0xE7D5, // - 0x91C6,0x94CE, // - 0x91C7,0x8DD1, // - 0x91C8,0x8EDF, // - 0x91C9,0xE7D6, // - 0x91CB,0xE7D7, // - 0x91CC,0x97A2, // - 0x91CD,0x8F64, // - 0x91CE,0x96EC, // - 0x91CF,0x97CA, // - 0x91D0,0xE7D8, // - 0x91D1,0x8BE0, // - 0x91D6,0xE7D9, // - 0x91D8,0x9342, // - 0x91DB,0xE7DC, // - 0x91DC,0x8A98, // - 0x91DD,0x906A, // - 0x91DF,0xE7DA, // - 0x91E1,0xE7DB, // - 0x91E3,0x92DE, // - 0x91E6,0x9674, // - 0x91E7,0x8BFA, // - 0x91F5,0xE7DE, // - 0x91F6,0xE7DF, // - 0x91FC,0xE7DD, // - 0x91FF,0xE7E1, // - 0x920D,0x93DD, // - 0x920E,0x8A62, // - 0x9211,0xE7E5, // - 0x9214,0xE7E2, // - 0x9215,0xE7E4, // - 0x921E,0xE7E0, // - 0x9229,0xE86E, // - 0x922C,0xE7E3, // - 0x9234,0x97E9, // - 0x9237,0x8CD8, // - 0x923F,0xE7ED, // - 0x9244,0x9353, // - 0x9245,0xE7E8, // - 0x9248,0xE7EB, // - 0x9249,0xE7E9, // - 0x924B,0xE7EE, // - 0x9250,0xE7EF, // - 0x9257,0xE7E7, // - 0x925A,0xE7F4, // - 0x925B,0x8994, // - 0x925E,0xE7E6, // - 0x9262,0x94AB, // - 0x9264,0xE7EA, // - 0x9266,0x8FDE, // - 0x9271,0x8D7A, // - 0x927E,0x9667, // - 0x9280,0x8BE2, // - 0x9283,0x8F65, // - 0x9285,0x93BA, // - 0x9291,0x914C, // - 0x9293,0xE7F2, // - 0x9295,0xE7EC, // - 0x9296,0xE7F1, // - 0x9298,0x96C1, // - 0x929A,0x92B6, // - 0x929B,0xE7F3, // - 0x929C,0xE7F0, // - 0x92AD,0x914B, // - 0x92B7,0xE7F7, // - 0x92B9,0xE7F6, // - 0x92CF,0xE7F5, // - 0x92D2,0x964E, // - 0x92E4,0x8F9B, // - 0x92E9,0xE7F8, // - 0x92EA,0x95DD, // - 0x92ED,0x8973, // - 0x92F2,0x9565, // - 0x92F3,0x9292, // - 0x92F8,0x8B98, // - 0x92FA,0xE7FA, // - 0x92FC,0x8D7C, // - 0x9306,0x8E4B, // - 0x930F,0xE7F9, // - 0x9310,0x908D, // - 0x9318,0x908E, // - 0x9319,0xE840, // - 0x931A,0xE842, // - 0x9320,0x8FF9, // - 0x9322,0xE841, // - 0x9323,0xE843, // - 0x9326,0x8BD1, // - 0x9328,0x9564, // - 0x932B,0x8EE0, // - 0x932C,0x9842, // - 0x932E,0xE7FC, // - 0x932F,0x8DF6, // - 0x9332,0x985E, // - 0x9335,0xE845, // - 0x933A,0xE844, // - 0x933B,0xE846, // - 0x9344,0xE7FB, // - 0x934B,0x93E7, // - 0x934D,0x9374, // - 0x9354,0x92D5, // - 0x9356,0xE84B, // - 0x935B,0x9262, // - 0x935C,0xE847, // - 0x9360,0xE848, // - 0x936C,0x8C4C, // - 0x936E,0xE84A, // - 0x9375,0x8CAE, // - 0x937C,0xE849, // - 0x937E,0x8FDF, // - 0x938C,0x8A99, // - 0x9394,0xE84F, // - 0x9396,0x8DBD, // - 0x9397,0x9199, // - 0x939A,0x92C8, // - 0x93A7,0x8A5A, // - 0x93AC,0xE84D, // - 0x93AD,0xE84E, // - 0x93AE,0x92C1, // - 0x93B0,0xE84C, // - 0x93B9,0xE850, // - 0x93C3,0xE856, // - 0x93C8,0xE859, // - 0x93D0,0xE858, // - 0x93D1,0x934C, // - 0x93D6,0xE851, // - 0x93D7,0xE852, // - 0x93D8,0xE855, // - 0x93DD,0xE857, // - 0x93E1,0x8BBE, // - 0x93E4,0xE85A, // - 0x93E5,0xE854, // - 0x93E8,0xE853, // - 0x9403,0xE85E, // - 0x9407,0xE85F, // - 0x9410,0xE860, // - 0x9413,0xE85D, // - 0x9414,0xE85C, // - 0x9418,0x8FE0, // - 0x9419,0x93A8, // - 0x9421,0xE864, // - 0x942B,0xE862, // - 0x9435,0xE863, // - 0x9436,0xE861, // - 0x9438,0x91F6, // - 0x943A,0xE865, // - 0x9441,0xE866, // - 0x9444,0xE868, // - 0x9451,0x8AD3, // - 0x9452,0xE867, // - 0x9453,0x96F8, // - 0x945A,0xE873, // - 0x945B,0xE869, // - 0x945E,0xE86C, // - 0x9460,0xE86A, // - 0x9462,0xE86B, // - 0x946A,0xE86D, // - 0x9470,0xE86F, // - 0x9475,0xE870, // - 0x9477,0xE871, // - 0x947C,0xE874, // - 0x947D,0xE872, // - 0x947E,0xE875, // - 0x947F,0xE877, // - 0x9481,0xE876, // - 0x9577,0x92B7, // - 0x9580,0x96E5, // - 0x9582,0xE878, // - 0x9583,0x914D, // - 0x9587,0xE879, // - 0x9589,0x95C2, // - 0x958A,0xE87A, // - 0x958B,0x8A4A, // - 0x9591,0x8AD5, // - 0x9593,0x8AD4, // - 0x9594,0xE87B, // - 0x9596,0xE87C, // - 0x9598,0xE87D, // - 0x9599,0xE87E, // - 0x95A0,0xE880, // - 0x95A2,0x8AD6, // - 0x95A3,0x8A74, // - 0x95A4,0x8D7D, // - 0x95A5,0x94B4, // - 0x95A7,0xE882, // - 0x95A8,0xE881, // - 0x95AD,0xE883, // - 0x95B2,0x897B, // - 0x95B9,0xE886, // - 0x95BB,0xE885, // - 0x95BC,0xE884, // - 0x95BE,0xE887, // - 0x95C3,0xE88A, // - 0x95C7,0x88C5, // - 0x95CA,0xE888, // - 0x95CC,0xE88C, // - 0x95CD,0xE88B, // - 0x95D4,0xE88E, // - 0x95D5,0xE88D, // - 0x95D6,0xE88F, // - 0x95D8,0x93AC, // - 0x95DC,0xE890, // - 0x95E1,0xE891, // - 0x95E2,0xE893, // - 0x95E5,0xE892, // - 0x961C,0x958C, // - 0x9621,0xE894, // - 0x9628,0xE895, // - 0x962A,0x8DE3, // - 0x962E,0xE896, // - 0x962F,0xE897, // - 0x9632,0x9668, // - 0x963B,0x916A, // - 0x963F,0x88A2, // - 0x9640,0x91C9, // - 0x9642,0xE898, // - 0x9644,0x958D, // - 0x964B,0xE89B, // - 0x964C,0xE899, // - 0x964D,0x8D7E, // - 0x964F,0xE89A, // - 0x9650,0x8CC0, // - 0x965B,0x95C3, // - 0x965C,0xE89D, // - 0x965D,0xE89F, // - 0x965E,0xE89E, // - 0x965F,0xE8A0, // - 0x9662,0x8940, // - 0x9663,0x9077, // - 0x9664,0x8F9C, // - 0x9665,0x8AD7, // - 0x9666,0xE8A1, // - 0x966A,0x9486, // - 0x966C,0xE8A3, // - 0x9670,0x8941, // - 0x9672,0xE8A2, // - 0x9673,0x92C2, // - 0x9675,0x97CB, // - 0x9676,0x93A9, // - 0x9677,0xE89C, // - 0x9678,0x97A4, // - 0x967A,0x8CAF, // - 0x967D,0x977A, // - 0x9685,0x8BF7, // - 0x9686,0x97B2, // - 0x9688,0x8C47, // - 0x968A,0x91E0, // - 0x968B,0xE440, // - 0x968D,0xE8A4, // - 0x968E,0x8A4B, // - 0x968F,0x908F, // - 0x9694,0x8A75, // - 0x9695,0xE8A6, // - 0x9697,0xE8A7, // - 0x9698,0xE8A5, // - 0x9699,0x8C84, // - 0x969B,0x8DDB, // - 0x969C,0x8FE1, // - 0x96A0,0x8942, // - 0x96A3,0x97D7, // - 0x96A7,0xE8A9, // - 0x96A8,0xE7AC, // - 0x96AA,0xE8A8, // - 0x96B0,0xE8AC, // - 0x96B1,0xE8AA, // - 0x96B2,0xE8AB, // - 0x96B4,0xE8AD, // - 0x96B6,0xE8AE, // - 0x96B7,0x97EA, // - 0x96B8,0xE8AF, // - 0x96B9,0xE8B0, // - 0x96BB,0x90C7, // - 0x96BC,0x94B9, // - 0x96C0,0x909D, // - 0x96C1,0x8AE5, // - 0x96C4,0x9759, // - 0x96C5,0x89EB, // - 0x96C6,0x8F57, // - 0x96C7,0x8CD9, // - 0x96C9,0xE8B3, // - 0x96CB,0xE8B2, // - 0x96CC,0x8E93, // - 0x96CD,0xE8B4, // - 0x96CE,0xE8B1, // - 0x96D1,0x8E47, // - 0x96D5,0xE8B8, // - 0x96D6,0xE5AB, // - 0x96D9,0x99D4, // - 0x96DB,0x9097, // - 0x96DC,0xE8B6, // - 0x96E2,0x97A3, // - 0x96E3,0x93EF, // - 0x96E8,0x894A, // - 0x96EA,0x90E1, // - 0x96EB,0x8EB4, // - 0x96F0,0x95B5, // - 0x96F2,0x895F, // - 0x96F6,0x97EB, // - 0x96F7,0x978B, // - 0x96F9,0xE8B9, // - 0x96FB,0x9364, // - 0x9700,0x8EF9, // - 0x9704,0xE8BA, // - 0x9706,0xE8BB, // - 0x9707,0x906B, // - 0x9708,0xE8BC, // - 0x970A,0x97EC, // - 0x970D,0xE8B7, // - 0x970E,0xE8BE, // - 0x970F,0xE8C0, // - 0x9711,0xE8BF, // - 0x9713,0xE8BD, // - 0x9716,0xE8C1, // - 0x9719,0xE8C2, // - 0x971C,0x919A, // - 0x971E,0x89E0, // - 0x9724,0xE8C3, // - 0x9727,0x96B6, // - 0x972A,0xE8C4, // - 0x9730,0xE8C5, // - 0x9732,0x9849, // - 0x9738,0x9E50, // - 0x9739,0xE8C6, // - 0x973D,0xE8C7, // - 0x973E,0xE8C8, // - 0x9742,0xE8CC, // - 0x9744,0xE8C9, // - 0x9746,0xE8CA, // - 0x9748,0xE8CB, // - 0x9749,0xE8CD, // - 0x9752,0x90C2, // - 0x9756,0x96F5, // - 0x9759,0x90C3, // - 0x975C,0xE8CE, // - 0x975E,0x94F1, // - 0x9760,0xE8CF, // - 0x9761,0xEA72, // - 0x9762,0x96CA, // - 0x9764,0xE8D0, // - 0x9766,0xE8D1, // - 0x9768,0xE8D2, // - 0x9769,0x8A76, // - 0x976B,0xE8D4, // - 0x976D,0x9078, // - 0x9771,0xE8D5, // - 0x9774,0x8C43, // - 0x9779,0xE8D6, // - 0x977A,0xE8DA, // - 0x977C,0xE8D8, // - 0x9781,0xE8D9, // - 0x9784,0x8A93, // - 0x9785,0xE8D7, // - 0x9786,0xE8DB, // - 0x978B,0xE8DC, // - 0x978D,0x88C6, // - 0x978F,0xE8DD, // - 0x9790,0xE8DE, // - 0x9798,0x8FE2, // - 0x979C,0xE8DF, // - 0x97A0,0x8B66, // - 0x97A3,0xE8E2, // - 0x97A6,0xE8E1, // - 0x97A8,0xE8E0, // - 0x97AB,0xE691, // - 0x97AD,0x95DA, // - 0x97B3,0xE8E3, // - 0x97B4,0xE8E4, // - 0x97C3,0xE8E5, // - 0x97C6,0xE8E6, // - 0x97C8,0xE8E7, // - 0x97CB,0xE8E8, // - 0x97D3,0x8AD8, // - 0x97DC,0xE8E9, // - 0x97ED,0xE8EA, // - 0x97EE,0x9442, // - 0x97F2,0xE8EC, // - 0x97F3,0x89B9, // - 0x97F5,0xE8EF, // - 0x97F6,0xE8EE, // - 0x97FB,0x8943, // - 0x97FF,0x8BBF, // - 0x9801,0x95C5, // - 0x9802,0x92B8, // - 0x9803,0x8DA0, // - 0x9805,0x8D80, // - 0x9806,0x8F87, // - 0x9808,0x907B, // - 0x980C,0xE8F1, // - 0x980F,0xE8F0, // - 0x9810,0x9761, // - 0x9811,0x8AE6, // - 0x9812,0x94D0, // - 0x9813,0x93DA, // - 0x9817,0x909C, // - 0x9818,0x97CC, // - 0x981A,0x8C7A, // - 0x9821,0xE8F4, // - 0x9824,0xE8F3, // - 0x982C,0x966A, // - 0x982D,0x93AA, // - 0x9834,0x896F, // - 0x9837,0xE8F5, // - 0x9838,0xE8F2, // - 0x983B,0x9570, // - 0x983C,0x978A, // - 0x983D,0xE8F6, // - 0x9846,0xE8F7, // - 0x984B,0xE8F9, // - 0x984C,0x91E8, // - 0x984D,0x8A7A, // - 0x984E,0x8A7B, // - 0x984F,0xE8F8, // - 0x9854,0x8AE7, // - 0x9855,0x8CB0, // - 0x9858,0x8AE8, // - 0x985B,0x935E, // - 0x985E,0x97DE, // - 0x9867,0x8CDA, // - 0x986B,0xE8FA, // - 0x986F,0xE8FB, // - 0x9870,0xE8FC, // - 0x9871,0xE940, // - 0x9873,0xE942, // - 0x9874,0xE941, // - 0x98A8,0x9597, // - 0x98AA,0xE943, // - 0x98AF,0xE944, // - 0x98B1,0xE945, // - 0x98B6,0xE946, // - 0x98C3,0xE948, // - 0x98C4,0xE947, // - 0x98C6,0xE949, // - 0x98DB,0x94F2, // - 0x98DC,0xE3CA, // - 0x98DF,0x9048, // - 0x98E2,0x8B51, // - 0x98E9,0xE94A, // - 0x98EB,0xE94B, // - 0x98ED,0x99AA, // - 0x98EE,0x9F5A, // - 0x98EF,0x94D1, // - 0x98F2,0x88F9, // - 0x98F4,0x88B9, // - 0x98FC,0x8E94, // - 0x98FD,0x964F, // - 0x98FE,0x8FFC, // - 0x9903,0xE94C, // - 0x9905,0x96DD, // - 0x9909,0xE94D, // - 0x990A,0x977B, // - 0x990C,0x8961, // - 0x9910,0x8E60, // - 0x9912,0xE94E, // - 0x9913,0x89EC, // - 0x9914,0xE94F, // - 0x9918,0xE950, // - 0x991D,0xE952, // - 0x991E,0xE953, // - 0x9920,0xE955, // - 0x9921,0xE951, // - 0x9924,0xE954, // - 0x9928,0x8AD9, // - 0x992C,0xE956, // - 0x992E,0xE957, // - 0x993D,0xE958, // - 0x993E,0xE959, // - 0x9942,0xE95A, // - 0x9945,0xE95C, // - 0x994B,0xE95E, // - 0x994C,0xE961, // - 0x9950,0xE95D, // - 0x9951,0xE95F, // - 0x9952,0xE960, // - 0x9955,0xE962, // - 0x9957,0x8BC0, // - 0x9996,0x8EF1, // - 0x9997,0xE963, // - 0x9998,0xE964, // - 0x9999,0x8D81, // - 0x99A5,0xE965, // - 0x99A8,0x8A5D, // - 0x99AC,0x946E, // - 0x99AD,0xE966, // - 0x99AE,0xE967, // - 0x99B3,0x9279, // - 0x99B4,0x93E9, // - 0x99BC,0xE968, // - 0x99C1,0x949D, // - 0x99C4,0x91CA, // - 0x99C5,0x8977, // - 0x99C6,0x8BEC, // - 0x99C8,0x8BED, // - 0x99D0,0x9293, // - 0x99D1,0xE96D, // - 0x99D2,0x8BEE, // - 0x99D5,0x89ED, // - 0x99D8,0xE96C, // - 0x99DB,0xE96A, // - 0x99DD,0xE96B, // - 0x99DF,0xE969, // - 0x99E2,0xE977, // - 0x99ED,0xE96E, // - 0x99EE,0xE96F, // - 0x99F1,0xE970, // - 0x99F2,0xE971, // - 0x99F8,0xE973, // - 0x99FB,0xE972, // - 0x99FF,0x8F78, // - 0x9A01,0xE974, // - 0x9A05,0xE976, // - 0x9A0E,0x8B52, // - 0x9A0F,0xE975, // - 0x9A12,0x919B, // - 0x9A13,0x8CB1, // - 0x9A19,0xE978, // - 0x9A28,0x91CB, // - 0x9A2B,0xE979, // - 0x9A30,0x93AB, // - 0x9A37,0xE97A, // - 0x9A3E,0xE980, // - 0x9A40,0xE97D, // - 0x9A42,0xE97C, // - 0x9A43,0xE97E, // - 0x9A45,0xE97B, // - 0x9A4D,0xE982, // - 0x9A55,0xE981, // - 0x9A57,0xE984, // - 0x9A5A,0x8BC1, // - 0x9A5B,0xE983, // - 0x9A5F,0xE985, // - 0x9A62,0xE986, // - 0x9A64,0xE988, // - 0x9A65,0xE987, // - 0x9A69,0xE989, // - 0x9A6A,0xE98B, // - 0x9A6B,0xE98A, // - 0x9AA8,0x8D9C, // - 0x9AAD,0xE98C, // - 0x9AB0,0xE98D, // - 0x9ABC,0xE98E, // - 0x9AC0,0xE98F, // - 0x9AC4,0x9091, // - 0x9ACF,0xE990, // - 0x9AD1,0xE991, // - 0x9AD3,0xE992, // - 0x9AD4,0xE993, // - 0x9AD8,0x8D82, // - 0x9ADE,0xE994, // - 0x9ADF,0xE995, // - 0x9AE2,0xE996, // - 0x9AE3,0xE997, // - 0x9AE6,0xE998, // - 0x9AEA,0x94AF, // - 0x9AEB,0xE99A, // - 0x9AED,0x9545, // - 0x9AEE,0xE99B, // - 0x9AEF,0xE999, // - 0x9AF1,0xE99D, // - 0x9AF4,0xE99C, // - 0x9AF7,0xE99E, // - 0x9AFB,0xE99F, // - 0x9B06,0xE9A0, // - 0x9B18,0xE9A1, // - 0x9B1A,0xE9A2, // - 0x9B1F,0xE9A3, // - 0x9B22,0xE9A4, // - 0x9B23,0xE9A5, // - 0x9B25,0xE9A6, // - 0x9B27,0xE9A7, // - 0x9B28,0xE9A8, // - 0x9B29,0xE9A9, // - 0x9B2A,0xE9AA, // - 0x9B2E,0xE9AB, // - 0x9B2F,0xE9AC, // - 0x9B31,0x9F54, // - 0x9B32,0xE9AD, // - 0x9B3B,0xE2F6, // - 0x9B3C,0x8B53, // - 0x9B41,0x8A40, // - 0x9B42,0x8DB0, // - 0x9B43,0xE9AF, // - 0x9B44,0xE9AE, // - 0x9B45,0x96A3, // - 0x9B4D,0xE9B1, // - 0x9B4E,0xE9B2, // - 0x9B4F,0xE9B0, // - 0x9B51,0xE9B3, // - 0x9B54,0x9682, // - 0x9B58,0xE9B4, // - 0x9B5A,0x8B9B, // - 0x9B6F,0x9844, // - 0x9B74,0xE9B5, // - 0x9B83,0xE9B7, // - 0x9B8E,0x88BC, // - 0x9B91,0xE9B8, // - 0x9B92,0x95A9, // - 0x9B93,0xE9B6, // - 0x9B96,0xE9B9, // - 0x9B97,0xE9BA, // - 0x9B9F,0xE9BB, // - 0x9BA0,0xE9BC, // - 0x9BA8,0xE9BD, // - 0x9BAA,0x968E, // - 0x9BAB,0x8E4C, // - 0x9BAD,0x8DF8, // - 0x9BAE,0x914E, // - 0x9BB4,0xE9BE, // - 0x9BB9,0xE9C1, // - 0x9BC0,0xE9BF, // - 0x9BC6,0xE9C2, // - 0x9BC9,0x8CEF, // - 0x9BCA,0xE9C0, // - 0x9BCF,0xE9C3, // - 0x9BD1,0xE9C4, // - 0x9BD2,0xE9C5, // - 0x9BD4,0xE9C9, // - 0x9BD6,0x8E49, // - 0x9BDB,0x91E2, // - 0x9BE1,0xE9CA, // - 0x9BE2,0xE9C7, // - 0x9BE3,0xE9C6, // - 0x9BE4,0xE9C8, // - 0x9BE8,0x8C7E, // - 0x9BF0,0xE9CE, // - 0x9BF1,0xE9CD, // - 0x9BF2,0xE9CC, // - 0x9BF5,0x88B1, // - 0x9C04,0xE9D8, // - 0x9C06,0xE9D4, // - 0x9C08,0xE9D5, // - 0x9C09,0xE9D1, // - 0x9C0A,0xE9D7, // - 0x9C0C,0xE9D3, // - 0x9C0D,0x8A82, // - 0x9C10,0x986B, // - 0x9C12,0xE9D6, // - 0x9C13,0xE9D2, // - 0x9C14,0xE9D0, // - 0x9C15,0xE9CF, // - 0x9C1B,0xE9DA, // - 0x9C21,0xE9DD, // - 0x9C24,0xE9DC, // - 0x9C25,0xE9DB, // - 0x9C2D,0x9568, // - 0x9C2E,0xE9D9, // - 0x9C2F,0x88F1, // - 0x9C30,0xE9DE, // - 0x9C32,0xE9E0, // - 0x9C39,0x8A8F, // - 0x9C3A,0xE9CB, // - 0x9C3B,0x8956, // - 0x9C3E,0xE9E2, // - 0x9C46,0xE9E1, // - 0x9C47,0xE9DF, // - 0x9C48,0x924C, // - 0x9C52,0x9690, // - 0x9C57,0x97D8, // - 0x9C5A,0xE9E3, // - 0x9C60,0xE9E4, // - 0x9C67,0xE9E5, // - 0x9C76,0xE9E6, // - 0x9C78,0xE9E7, // - 0x9CE5,0x92B9, // - 0x9CE7,0xE9E8, // - 0x9CE9,0x94B5, // - 0x9CEB,0xE9ED, // - 0x9CEC,0xE9E9, // - 0x9CF0,0xE9EA, // - 0x9CF3,0x9650, // - 0x9CF4,0x96C2, // - 0x9CF6,0x93CE, // - 0x9D03,0xE9EE, // - 0x9D06,0xE9EF, // - 0x9D07,0x93BC, // - 0x9D08,0xE9EC, // - 0x9D09,0xE9EB, // - 0x9D0E,0x89A8, // - 0x9D12,0xE9F7, // - 0x9D15,0xE9F6, // - 0x9D1B,0x8995, // - 0x9D1F,0xE9F4, // - 0x9D23,0xE9F3, // - 0x9D26,0xE9F1, // - 0x9D28,0x8A9B, // - 0x9D2A,0xE9F0, // - 0x9D2B,0x8EB0, // - 0x9D2C,0x89A7, // - 0x9D3B,0x8D83, // - 0x9D3E,0xE9FA, // - 0x9D3F,0xE9F9, // - 0x9D41,0xE9F8, // - 0x9D44,0xE9F5, // - 0x9D46,0xE9FB, // - 0x9D48,0xE9FC, // - 0x9D50,0xEA44, // - 0x9D51,0xEA43, // - 0x9D59,0xEA45, // - 0x9D5C,0x894C, // - 0x9D5D,0xEA40, // - 0x9D5E,0xEA41, // - 0x9D60,0x8D94, // - 0x9D61,0x96B7, // - 0x9D64,0xEA42, // - 0x9D6C,0x9651, // - 0x9D6F,0xEA4A, // - 0x9D72,0xEA46, // - 0x9D7A,0xEA4B, // - 0x9D87,0xEA48, // - 0x9D89,0xEA47, // - 0x9D8F,0x8C7B, // - 0x9D9A,0xEA4C, // - 0x9DA4,0xEA4D, // - 0x9DA9,0xEA4E, // - 0x9DAB,0xEA49, // - 0x9DAF,0xE9F2, // - 0x9DB2,0xEA4F, // - 0x9DB4,0x92DF, // - 0x9DB8,0xEA53, // - 0x9DBA,0xEA54, // - 0x9DBB,0xEA52, // - 0x9DC1,0xEA51, // - 0x9DC2,0xEA57, // - 0x9DC4,0xEA50, // - 0x9DC6,0xEA55, // - 0x9DCF,0xEA56, // - 0x9DD3,0xEA59, // - 0x9DD9,0xEA58, // - 0x9DED,0xEA5C, // - 0x9DEF,0xEA5D, // - 0x9DF2,0x9868, // - 0x9DF8,0xEA5A, // - 0x9DF9,0x91E9, // - 0x9DFA,0x8DEB, // - 0x9DFD,0xEA5E, // - 0x9E1A,0xEA5F, // - 0x9E1B,0xEA60, // - 0x9E1E,0xEA61, // - 0x9E75,0xEA62, // - 0x9E78,0x8CB2, // - 0x9E79,0xEA63, // - 0x9E7D,0xEA64, // - 0x9E7F,0x8EAD, // - 0x9E81,0xEA65, // - 0x9E88,0xEA66, // - 0x9E8B,0xEA67, // - 0x9E8C,0xEA68, // - 0x9E91,0xEA6B, // - 0x9E92,0xEA69, // - 0x9E95,0xEA6A, // - 0x9E97,0x97ED, // - 0x9E9D,0xEA6C, // - 0x9E9F,0x97D9, // - 0x9EA5,0xEA6D, // - 0x9EA6,0x949E, // - 0x9EA9,0xEA6E, // - 0x9EAA,0xEA70, // - 0x9EAD,0xEA71, // - 0x9EB8,0xEA6F, // - 0x9EB9,0x8D8D, // - 0x9EBA,0x96CB, // - 0x9EBB,0x9683, // - 0x9EBC,0x9BF5, // - 0x9EBE,0x9F80, // - 0x9EBF,0x969B, // - 0x9EC4,0x89A9, // - 0x9ECC,0xEA73, // - 0x9ECD,0x8B6F, // - 0x9ECE,0xEA74, // - 0x9ECF,0xEA75, // - 0x9ED0,0xEA76, // - 0x9ED2,0x8D95, // - 0x9ED4,0xEA77, // - 0x9ED8,0xE0D2, // - 0x9ED9,0x96D9, // - 0x9EDB,0x91E1, // - 0x9EDC,0xEA78, // - 0x9EDD,0xEA7A, // - 0x9EDE,0xEA79, // - 0x9EE0,0xEA7B, // - 0x9EE5,0xEA7C, // - 0x9EE8,0xEA7D, // - 0x9EEF,0xEA7E, // - 0x9EF4,0xEA80, // - 0x9EF6,0xEA81, // - 0x9EF7,0xEA82, // - 0x9EF9,0xEA83, // - 0x9EFB,0xEA84, // - 0x9EFC,0xEA85, // - 0x9EFD,0xEA86, // - 0x9F07,0xEA87, // - 0x9F08,0xEA88, // - 0x9F0E,0x9343, // - 0x9F13,0x8CDB, // - 0x9F15,0xEA8A, // - 0x9F20,0x916C, // - 0x9F21,0xEA8B, // - 0x9F2C,0xEA8C, // - 0x9F3B,0x9540, // - 0x9F3E,0xEA8D, // - 0x9F4A,0xEA8E, // - 0x9F4B,0xE256, // - 0x9F4E,0xE6D8, // - 0x9F4F,0xE8EB, // - 0x9F52,0xEA8F, // - 0x9F54,0xEA90, // - 0x9F5F,0xEA92, // - 0x9F60,0xEA93, // - 0x9F61,0xEA94, // - 0x9F62,0x97EE, // - 0x9F63,0xEA91, // - 0x9F66,0xEA95, // - 0x9F67,0xEA96, // - 0x9F6A,0xEA98, // - 0x9F6C,0xEA97, // - 0x9F72,0xEA9A, // - 0x9F76,0xEA9B, // - 0x9F77,0xEA99, // - 0x9F8D,0x97B4, // - 0x9F95,0xEA9C, // - 0x9F9C,0xEA9D, // - 0x9F9D,0xE273, // - 0x9FA0,0xEA9E, // - 0xFF01,0x8149, // FULLWIDTH EXCLAMATION MARK - 0xFF03,0x8194, // FULLWIDTH NUMBER SIGN - 0xFF04,0x8190, // FULLWIDTH DOLLAR SIGN - 0xFF05,0x8193, // FULLWIDTH PERCENT SIGN - 0xFF06,0x8195, // FULLWIDTH AMPERSAND - 0xFF07,0x81AD, // FULLWIDTH APOSTROPHE - 0xFF08,0x8169, // FULLWIDTH LEFT PARENTHESIS - 0xFF09,0x816A, // FULLWIDTH RIGHT PARENTHESIS - 0xFF0A,0x8196, // FULLWIDTH ASTERISK - 0xFF0B,0x817B, // FULLWIDTH PLUS SIGN - 0xFF0C,0x8143, // FULLWIDTH COMMA - 0xFF0E,0x8144, // FULLWIDTH FULL STOP - 0xFF0F,0x815E, // FULLWIDTH SOLIDUS - 0xFF10,0x824F, // FULLWIDTH DIGIT ZERO - 0xFF11,0x8250, // FULLWIDTH DIGIT ONE - 0xFF12,0x8251, // FULLWIDTH DIGIT TWO - 0xFF13,0x8252, // FULLWIDTH DIGIT THREE - 0xFF14,0x8253, // FULLWIDTH DIGIT FOUR - 0xFF15,0x8254, // FULLWIDTH DIGIT FIVE - 0xFF16,0x8255, // FULLWIDTH DIGIT SIX - 0xFF17,0x8256, // FULLWIDTH DIGIT SEVEN - 0xFF18,0x8257, // FULLWIDTH DIGIT EIGHT - 0xFF19,0x8258, // FULLWIDTH DIGIT NINE - 0xFF1A,0x8146, // FULLWIDTH COLON - 0xFF1B,0x8147, // FULLWIDTH SEMICOLON - 0xFF1C,0x8183, // FULLWIDTH LESS-THAN SIGN - 0xFF1D,0x8181, // FULLWIDTH EQUALS SIGN - 0xFF1E,0x8184, // FULLWIDTH GREATER-THAN SIGN - 0xFF1F,0x8148, // FULLWIDTH QUESTION MARK - 0xFF20,0x8197, // FULLWIDTH COMMERCIAL AT - 0xFF21,0x8260, // FULLWIDTH LATIN CAPITAL LETTER A - 0xFF22,0x8261, // FULLWIDTH LATIN CAPITAL LETTER B - 0xFF23,0x8262, // FULLWIDTH LATIN CAPITAL LETTER C - 0xFF24,0x8263, // FULLWIDTH LATIN CAPITAL LETTER D - 0xFF25,0x8264, // FULLWIDTH LATIN CAPITAL LETTER E - 0xFF26,0x8265, // FULLWIDTH LATIN CAPITAL LETTER F - 0xFF27,0x8266, // FULLWIDTH LATIN CAPITAL LETTER G - 0xFF28,0x8267, // FULLWIDTH LATIN CAPITAL LETTER H - 0xFF29,0x8268, // FULLWIDTH LATIN CAPITAL LETTER I - 0xFF2A,0x8269, // FULLWIDTH LATIN CAPITAL LETTER J - 0xFF2B,0x826A, // FULLWIDTH LATIN CAPITAL LETTER K - 0xFF2C,0x826B, // FULLWIDTH LATIN CAPITAL LETTER L - 0xFF2D,0x826C, // FULLWIDTH LATIN CAPITAL LETTER M - 0xFF2E,0x826D, // FULLWIDTH LATIN CAPITAL LETTER N - 0xFF2F,0x826E, // FULLWIDTH LATIN CAPITAL LETTER O - 0xFF30,0x826F, // FULLWIDTH LATIN CAPITAL LETTER P - 0xFF31,0x8270, // FULLWIDTH LATIN CAPITAL LETTER Q - 0xFF32,0x8271, // FULLWIDTH LATIN CAPITAL LETTER R - 0xFF33,0x8272, // FULLWIDTH LATIN CAPITAL LETTER S - 0xFF34,0x8273, // FULLWIDTH LATIN CAPITAL LETTER T - 0xFF35,0x8274, // FULLWIDTH LATIN CAPITAL LETTER U - 0xFF36,0x8275, // FULLWIDTH LATIN CAPITAL LETTER V - 0xFF37,0x8276, // FULLWIDTH LATIN CAPITAL LETTER W - 0xFF38,0x8277, // FULLWIDTH LATIN CAPITAL LETTER X - 0xFF39,0x8278, // FULLWIDTH LATIN CAPITAL LETTER Y - 0xFF3A,0x8279, // FULLWIDTH LATIN CAPITAL LETTER Z - 0xFF3B,0x816D, // FULLWIDTH LEFT SQUARE BRACKET - 0xFF3D,0x816E, // FULLWIDTH RIGHT SQUARE BRACKET - 0xFF3E,0x814F, // FULLWIDTH CIRCUMFLEX ACCENT - 0xFF3F,0x8151, // FULLWIDTH LOW LINE - 0xFF40,0x814D, // FULLWIDTH GRAVE ACCENT - 0xFF41,0x8281, // FULLWIDTH LATIN SMALL LETTER A - 0xFF42,0x8282, // FULLWIDTH LATIN SMALL LETTER B - 0xFF43,0x8283, // FULLWIDTH LATIN SMALL LETTER C - 0xFF44,0x8284, // FULLWIDTH LATIN SMALL LETTER D - 0xFF45,0x8285, // FULLWIDTH LATIN SMALL LETTER E - 0xFF46,0x8286, // FULLWIDTH LATIN SMALL LETTER F - 0xFF47,0x8287, // FULLWIDTH LATIN SMALL LETTER G - 0xFF48,0x8288, // FULLWIDTH LATIN SMALL LETTER H - 0xFF49,0x8289, // FULLWIDTH LATIN SMALL LETTER I - 0xFF4A,0x828A, // FULLWIDTH LATIN SMALL LETTER J - 0xFF4B,0x828B, // FULLWIDTH LATIN SMALL LETTER K - 0xFF4C,0x828C, // FULLWIDTH LATIN SMALL LETTER L - 0xFF4D,0x828D, // FULLWIDTH LATIN SMALL LETTER M - 0xFF4E,0x828E, // FULLWIDTH LATIN SMALL LETTER N - 0xFF4F,0x828F, // FULLWIDTH LATIN SMALL LETTER O - 0xFF50,0x8290, // FULLWIDTH LATIN SMALL LETTER P - 0xFF51,0x8291, // FULLWIDTH LATIN SMALL LETTER Q - 0xFF52,0x8292, // FULLWIDTH LATIN SMALL LETTER R - 0xFF53,0x8293, // FULLWIDTH LATIN SMALL LETTER S - 0xFF54,0x8294, // FULLWIDTH LATIN SMALL LETTER T - 0xFF55,0x8295, // FULLWIDTH LATIN SMALL LETTER U - 0xFF56,0x8296, // FULLWIDTH LATIN SMALL LETTER V - 0xFF57,0x8297, // FULLWIDTH LATIN SMALL LETTER W - 0xFF58,0x8298, // FULLWIDTH LATIN SMALL LETTER X - 0xFF59,0x8299, // FULLWIDTH LATIN SMALL LETTER Y - 0xFF5A,0x829A, // FULLWIDTH LATIN SMALL LETTER Z - 0xFF5B,0x816F, // FULLWIDTH LEFT CURLY BRACKET - 0xFF5C,0x8162, // FULLWIDTH VERTICAL LINE - 0xFF5D,0x8170, // FULLWIDTH RIGHT CURLY BRACKET - 0xFFE3,0x8150, // FULLWIDTH MACRON - 0xFFE5,0x818F // FULLWIDTH YEN SIGN -}; \ No newline at end of file diff --git a/3rdparty/zint-2.4.4/backend/svg.c b/3rdparty/zint-2.4.4/backend/svg.c deleted file mode 100644 index 5cbba13..0000000 --- a/3rdparty/zint-2.4.4/backend/svg.c +++ /dev/null @@ -1,614 +0,0 @@ -/* svg.c - Scalable Vector Graphics */ - -/* - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#include "common.h" - -#define SSET "0123456789ABCDEF" - -int svg_plot(struct zint_symbol *symbol) -{ - int i, block_width, latch, r, this_row; - float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0; - FILE *fsvg; - int fgred, fggrn, fgblu, bgred, bggrn, bgblu; - float /*red_ink,*/ green_ink, blue_ink, red_paper, green_paper , blue_paper; - int error_number = 0; - int textoffset, xoffset, yoffset, textdone, main_width; - char textpart[10], addon[6]; - int large_bar_count, comp_offset; - float addon_text_posn; - float scaler = symbol->scale; - float default_text_posn; - int plot_text = 1; - const char *locale = NULL; - - row_height=0; - textdone = 0; - main_width = symbol->width; - strcpy(addon, ""); - comp_offset = 0; - addon_text_posn = 0.0; - - if((symbol->output_options & BARCODE_STDOUT) != 0) { - fsvg = stdout; - } else { - fsvg = fopen(symbol->outfile, "w"); - } - if(fsvg == NULL) { - strcpy(symbol->errtxt, "Could not open output file"); - return ERROR_FILE_ACCESS; - } - - /* sort out colour options */ - to_upper((unsigned char*)symbol->fgcolour); - to_upper((unsigned char*)symbol->bgcolour); - - if(strlen(symbol->fgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - if(strlen(symbol->bgcolour) != 6) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - error_number = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour)); - if (error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Malformed foreground colour target"); - return ERROR_INVALID_OPTION; - } - error_number = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour)); - if (error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Malformed background colour target"); - return ERROR_INVALID_OPTION; - } - locale = setlocale(LC_ALL, "C"); - - fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); -// red_ink = fgred / 256.0; - green_ink = fggrn / 256.0; - blue_ink = fgblu / 256.0; - red_paper = bgred / 256.0; - green_paper = bggrn / 256.0; - blue_paper = bgblu / 256.0; - - if (symbol->height == 0) { - symbol->height = 50; - } - - large_bar_count = 0; - preset_height = 0.0; - for(i = 0; i < symbol->rows; i++) { - preset_height += symbol->row_height[i]; - if(symbol->row_height[i] == 0) { - large_bar_count++; - } - } - large_bar_height = (symbol->height - preset_height) / large_bar_count; - - if (large_bar_count == 0) { - symbol->height = preset_height; - } - - while(!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { - comp_offset++; - } - - /* Certain symbols need whitespace otherwise characters get chopped off the sides */ - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) - || (symbol->symbology == BARCODE_ISBNX)) { - switch(ustrlen(symbol->text)) { - case 13: /* EAN 13 */ - case 16: - case 19: - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - } - main_width = 96 + comp_offset; - break; - default: - main_width = 68 + comp_offset; - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_width = 96 + comp_offset; - } - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - if(symbol->whitespace_width == 0) { - symbol->whitespace_width = 10; - main_width = 51 + comp_offset; - } - } - - latch = 0; - r = 0; - /* Isolate add-on text */ - if(is_extendable(symbol->symbology)) { - for(i = 0; i < ustrlen(symbol->text); i++) { - if (latch == 1) { - addon[r] = symbol->text[i]; - r++; - } - if (symbol->text[i] == '+') { - latch = 1; - } - } - } - addon[r] = '\0'; - - if((symbol->show_hrt == 0) || (ustrlen(symbol->text) == 0)) { - plot_text = 0; - } - if(plot_text) { - textoffset = 9; - } else { - textoffset = 0; - } - xoffset = symbol->border_width + symbol->whitespace_width; - yoffset = symbol->border_width; - - /* Start writing the header */ - fprintf(fsvg, "\n"); - fprintf(fsvg, "\n"); - if(symbol->symbology != BARCODE_MAXICODE) { - fprintf(fsvg, "width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler)); - } else { - fprintf(fsvg, "\n"); - if(ustrlen(symbol->text) != 0) { - fprintf(fsvg, " %s\n", symbol->text); - } else { - fprintf(fsvg, " Zint Generated Symbol\n"); - } - fprintf(fsvg, " \n"); - fprintf(fsvg, "\n \n", symbol->fgcolour); - - if(symbol->symbology != BARCODE_MAXICODE) { - fprintf(fsvg, " \n", roundup((symbol->width + xoffset + xoffset) * scaler), roundup((symbol->height + textoffset + yoffset + yoffset) * scaler), symbol->bgcolour); - } else { - fprintf(fsvg, " \n", roundup((74.0 + xoffset + xoffset) * scaler), roundup((72.0 + yoffset + yoffset) * scaler), symbol->bgcolour); - } - - if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - default_text_posn = (symbol->height + textoffset + symbol->border_width + symbol->border_width) * scaler; - } else { - default_text_posn = (symbol->height + textoffset + symbol->border_width) * scaler; - } - - if(symbol->symbology == BARCODE_MAXICODE) { - /* Maxicode uses hexagons */ - float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; - - - textoffset = 0.0; - if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - fprintf(fsvg, " \n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); - fprintf(fsvg, " \n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); - } - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); - fprintf(fsvg, " \n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); - } - fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, symbol->fgcolour); - fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, symbol->bgcolour); - fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, symbol->fgcolour); - fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, symbol->bgcolour); - fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, symbol->fgcolour); - fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, symbol->bgcolour); - for(r = 0; r < symbol->rows; r++) { - for(i = 0; i < symbol->width; i++) { - if(module_is_set(symbol, r, i)) { - /* Dump a hexagon */ - my = r * 2.135 + 1.43; - ay = my + 1.0 + yoffset; - by = my + 0.5 + yoffset; - cy = my - 0.5 + yoffset; - dy = my - 1.0 + yoffset; - ey = my - 0.5 + yoffset; - fy = my + 0.5 + yoffset; - if(r & 1) { - mx = (2.46 * i) + 1.23 + 1.23; - } else { - mx = (2.46 * i) + 1.23; - } - ax = mx + xoffset; - bx = mx + 0.86 + xoffset; - cx = mx + 0.86 + xoffset; - dx = mx + xoffset; - ex = mx - 0.86 + xoffset; - fx = mx - 0.86 + xoffset; - fprintf(fsvg, " \n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); - } - } - } - } - - if(symbol->symbology != BARCODE_MAXICODE) { - /* everything else uses rectangles (or squares) */ - /* Works from the bottom of the symbol up */ - int addon_latch = 0; - - for(r = 0; r < symbol->rows; r++) { - this_row = r; - if(symbol->row_height[this_row] == 0) { - row_height = large_bar_height; - } else { - row_height = symbol->row_height[this_row]; - } - row_posn = 0; - for(i = 0; i < r; i++) { - if(symbol->row_height[i] == 0) { - row_posn += large_bar_height; - } else { - row_posn += symbol->row_height[i]; - } - } - row_posn += yoffset; - - i = 0; - if(module_is_set(symbol, this_row, 0)) { - latch = 1; - } else { - latch = 0; - } - - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); - if((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { - addon_text_posn = (row_posn + 8.0) * scaler; - addon_latch = 1; - } - if(latch == 1) { - /* a bar */ - if(addon_latch == 0) { - fprintf(fsvg, " \n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler); - } else { - fprintf(fsvg, " \n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); - } - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - - } while (i < symbol->width); - } - } - /* That's done the actual data area, everything else is human-friendly */ - - xoffset += comp_offset; - row_posn = (row_posn + large_bar_height) * scaler; - - if(plot_text) { - if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || - (symbol->symbology == BARCODE_ISBNX)) { - /* guard bar extensions and text formatting for EAN8 and EAN13 */ - switch(ustrlen(symbol->text)) { - case 8: /* EAN-8 */ - case 11: - case 14: - fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i]; - } - textpart[4] = '\0'; - textpos = 17; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - for(i = 0; i < 4; i++) { - textpart[i] = symbol->text[i + 4]; - } - textpart[4] = '\0'; - textpos = 50; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 86; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - case 5: - textpos = xoffset + 100; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - } - - break; - case 13: /* EAN 13 */ - case 16: - case 19: - fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = -7; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - textpos = 24; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 7]; - } - textpart[6] = '\0'; - textpos = 71; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 114; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - case 5: - textpos = xoffset + 128; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - } - break; - - } - } - - if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { - /* guard bar extensions and text formatting for UPCA */ - latch = 1; - - i = 0 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); - if(latch == 1) { - /* a bar */ - fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - } while (i < 11 + comp_offset); - fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - latch = 1; - i = 85 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); - if(latch == 1) { - /* a bar */ - fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); - latch = 0; - } else { - /* a space */ - latch = 1; - } - i += block_width; - } while (i < 96 + comp_offset); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = -5; - fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[5] = '\0'; - textpos = 27; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - for(i = 0; i < 5; i++) { - textpart[i] = symbol->text[i + 6]; - } - textpart[6] = '\0'; - textpos = 68; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - textpart[0] = symbol->text[11]; - textpart[1] = '\0'; - textpos = 100; - fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 116; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - case 5: - textpos = xoffset + 130; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - } - - } - - if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { - /* guard bar extensions and text formatting for UPCE */ - fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - fprintf(fsvg, " \n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); - textpart[0] = symbol->text[0]; - textpart[1] = '\0'; - textpos = -5; - fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - for(i = 0; i < 6; i++) { - textpart[i] = symbol->text[i + 1]; - } - textpart[6] = '\0'; - textpos = 24; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - textpart[0] = symbol->text[7]; - textpart[1] = '\0'; - textpos = 55; - fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", textpart); - fprintf(fsvg, " \n"); - textdone = 1; - switch(strlen(addon)) { - case 2: - textpos = xoffset + 70; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - case 5: - textpos = xoffset + 84; - fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", addon); - fprintf(fsvg, " \n"); - break; - } - - } - } /* if (plot_text) */ - - xoffset -= comp_offset; - - switch(symbol->symbology) { - case BARCODE_MAXICODE: - /* Do nothing! (It's already been done) */ - break; - default: - if((symbol->output_options & BARCODE_BIND) != 0) { - if((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { - /* row binding */ - for(r = 1; r < symbol->rows; r++) { - fprintf(fsvg, " \n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); - } - } - } - if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { - fprintf(fsvg, " \n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); - fprintf(fsvg, " \n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); - } - if((symbol->output_options & BARCODE_BOX) != 0) { - /* side bars */ - fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); - fprintf(fsvg, " \n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); - } - break; - } - - /* Put the human readable text at the bottom */ - if(plot_text && (textdone == 0)) { - textpos = symbol->width / 2.0; - fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); - fprintf(fsvg, " %s\n", symbol->text); - fprintf(fsvg, " \n"); - } - fprintf(fsvg, " \n"); - fprintf(fsvg, "\n"); - - fclose(fsvg); - - if (locale) - setlocale(LC_ALL, locale); - - return error_number; -} - diff --git a/3rdparty/zint-2.4.4/backend/telepen.c b/3rdparty/zint-2.4.4/backend/telepen.c deleted file mode 100644 index 5ee4a5d..0000000 --- a/3rdparty/zint-2.4.4/backend/telepen.c +++ /dev/null @@ -1,157 +0,0 @@ -/* telepen.c - Handles Telepen and Telepen numeric */ - -/* - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define SODIUM "0123456789X" - -#include -#include -#include -#include "common.h" - -static char *TeleTable[] = -{ - "1111111111111111", "1131313111", "33313111", "1111313131", "3111313111", "11333131", "13133131", "111111313111", - "31333111", "1131113131", "33113131", "1111333111", "3111113131", "1113133111", "1311133111", "111111113131", - "3131113111", "11313331", "333331", "111131113111", "31113331", "1133113111", "1313113111", "1111113331", - "31131331", "113111113111", "3311113111", "1111131331", "311111113111", "1113111331", "1311111331", "11111111113111", - "31313311", "1131311131", "33311131", "1111313311", "3111311131", "11333311", "13133311", "111111311131", - "31331131", "1131113311", "33113311", "1111331131", "3111113311", "1113131131", "1311131131", "111111113311", - "3131111131", "1131131311", "33131311", "111131111131", "3111131311", "1133111131", "1313111131", "111111131311", - "3113111311", "113111111131", "3311111131", "111113111311", "311111111131", "111311111311", "131111111311", "11111111111131", - "3131311111", "11313133", "333133", "111131311111", "31113133", "1133311111", "1313311111", "1111113133", - "313333", "113111311111", "3311311111", "11113333", "311111311111", "11131333", "13111333", "11111111311111", - "31311133", "1131331111", "33331111", " 1111311133", "3111331111", "11331133", "13131133", "111111331111", - "3113131111", "1131111133", "33111133", "111113131111", "3111111133", "111311131111", "131111131111", "111111111133", - "31311313", "113131111111", "3331111111", "1111311313", "311131111111", "11331313", "13131313", "11111131111111", - "3133111111", "1131111313", "33111313", "111133111111", "3111111313", "111313111111", "131113111111", "111111111313", - "313111111111", "1131131113", "33131113", "11113111111111","3111131113", "113311111111", "131311111111", "111111131113", - "3113111113", "11311111111111","331111111111","111113111113", "31111111111111","111311111113","131111111113"}; - -int telepen(struct zint_symbol *symbol, unsigned char source[], int src_len) -{ - int i, count, check_digit; - int error_number; - char dest[512]; /*14 + 30 * 14 + 14 + 14 + 1 ~ 512 */ - - error_number = 0; - - count = 0; - - if(src_len > 30) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - /* Start character */ - strcpy(dest, TeleTable['_']); - - for(i = 0; i < src_len; i++) { - if(source[i] > 126) { - /* Cannot encode extended ASCII */ - strcpy(symbol->errtxt, "Invalid characters in input data"); - return ERROR_INVALID_DATA1; - } - concat(dest, TeleTable[source[i]]); - count += source[i]; - } - - check_digit = 127 - (count % 127); - if(check_digit == 127) { check_digit = 0; } - concat(dest, TeleTable[check_digit]); - - /* Stop character */ - concat(dest, TeleTable['z']); - - expand(symbol, dest); - for(i = 0; i < src_len; i++) { - if(source[i] == '\0') { - symbol->text[i] = ' '; - } else { - symbol->text[i] = source[i]; - } - } - symbol->text[src_len] = '\0'; - return error_number; -} - -int telepen_num(struct zint_symbol *symbol, unsigned char source[], int src_len) -{ - int i, count, check_digit, glyph; - int error_number, temp_length = src_len; - char dest[1024]; /* 14 + 60 * 14 + 14 + 14 + 1 ~ 1024 */ - unsigned char temp[64]; - - error_number = 0; - count = 0; - - if(temp_length > 60) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - ustrcpy(temp, source); - to_upper(temp); - error_number = is_sane(NEON, temp, temp_length); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - - /* Add a leading zero if required */ - if (temp_length & 1) - { - memmove(temp + 1, temp, temp_length); - temp[0] = '0'; - - temp[++temp_length] = '\0'; - } - - /* Start character */ - strcpy(dest, TeleTable['_']); - - for (i = 0; i < temp_length; i += 2) - { - if(temp[i] == 'X') { - strcpy(symbol->errtxt, "Invalid position of X in Telepen data"); - return ERROR_INVALID_DATA1; - } - - if(temp[i + 1] == 'X') { - glyph = ctoi(temp[i]) + 17; - count += glyph; - } else { - glyph = (10 * ctoi(temp[i])) + ctoi(temp[i + 1]); - glyph += 27; - count += glyph; - } - concat(dest, TeleTable[glyph]); - } - - check_digit = 127 - (count % 127); - if(check_digit == 127) { check_digit = 0; } - concat(dest, TeleTable[check_digit]); - - /* Stop character */ - concat(dest, TeleTable['z']); - - expand(symbol, dest); - ustrcpy(symbol->text, temp); - return error_number; -} - diff --git a/3rdparty/zint-2.4.4/backend/upcean.c b/3rdparty/zint-2.4.4/backend/upcean.c deleted file mode 100644 index f403f3d..0000000 --- a/3rdparty/zint-2.4.4/backend/upcean.c +++ /dev/null @@ -1,796 +0,0 @@ -/* upcean.c - Handles UPC, EAN and ISBN - - libzint - the open source barcode library - Copyright (C) 2008 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#define SODIUM "0123456789+" -#define EAN2 102 -#define EAN5 105 - -#include -#include -#include -#include "common.h" - -/* UPC and EAN tables checked against EN 797:1996 */ - -static char *UPCParity0[10] = {"BBBAAA", "BBABAA", "BBAABA", "BBAAAB", "BABBAA", "BAABBA", "BAAABB", - "BABABA", "BABAAB", "BAABAB"}; /* Number set for UPC-E symbol (EN Table 4) */ -static char *UPCParity1[10] = {"AAABBB", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA", - "ABABAB", "ABABBA", "ABBABA"}; /* Not covered by BS EN 797:1995 */ -static char *EAN2Parity[4] = {"AA", "AB", "BA", "BB"}; /* Number sets for 2-digit add-on (EN Table 6) */ -static char *EAN5Parity[10] = {"BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA", - "ABAAB", "AABAB"}; /* Number set for 5-digit add-on (EN Table 7) */ -static char *EAN13Parity[10] = {"AAAAA", "ABABB", "ABBAB", "ABBBA", "BAABB", "BBAAB", "BBBAA", "BABAB", - "BABBA", "BBABA"}; /* Left hand of the EAN-13 symbol (EN Table 3) */ -static char *EANsetA[10] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213", - "3112"}; /* Representation set A and C (EN Table 1) */ -static char *EANsetB[10] = {"1123", "1222", "2212", "1141", "2311", "1321", "4111", "2131", "3121", - "2113"}; /* Representation set B (EN Table 1) */ - -char upc_check(char source[]) -{ /* Calculate the correct check digit for a UPC barcode */ - unsigned int i, count, check_digit; - - count = 0; - - for (i = 0; i < strlen(source); i++) { - count += ctoi(source[i]); - - if (!(i & 1)) { - count += 2 * (ctoi(source[i])); - } - } - - check_digit = 10 - (count%10); - if (check_digit == 10) { check_digit = 0; } - return itoc(check_digit); -} - -void upca_draw(char source[], char dest[]) -{ /* UPC A is usually used for 12 digit numbers, but this function takes a source of any length */ - unsigned int i, half_way; - - half_way = strlen(source) / 2; - - /* start character */ - concat (dest, "111"); - - for(i = 0; i <= strlen(source); i++) - { - if (i == half_way) - { - /* middle character - separates manufacturer no. from product no. */ - /* also inverts right hand characters */ - concat(dest, "11111"); - } - - lookup(NEON, EANsetA, source[i], dest); - } - - /* stop character */ - concat (dest, "111"); -} - -void upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) -{ /* Make a UPC A barcode when we haven't been given the check digit */ - int length; - char gtin[15]; - - strcpy(gtin, (char*)source); - length = strlen(gtin); - gtin[length] = upc_check(gtin); - gtin[length + 1] = '\0'; - upca_draw(gtin, dest); - ustrcpy(symbol->text, (unsigned char*)gtin); -} - -void upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) -{ /* UPC E is a zero-compressed version of UPC A */ - int i, num_system; - char emode, equivalent[12], check_digit, parity[8], temp[8]; - char hrt[9]; - - /* Two number systems can be used - system 0 and system 1 */ - if(ustrlen(source) == 7) { - switch(source[0]) { - case '0': num_system = 0; break; - case '1': num_system = 1; break; - default: num_system = 0; source[0] = '0'; break; - } - strcpy(temp, (char*)source); - strcpy(hrt, (char*)source); - for(i = 1; i <= 7; i++) { - source[i - 1] = temp[i]; - } - } - else { - num_system = 0; - hrt[0] = '0'; - hrt[1] = '\0'; - concat(hrt, (char*)source); - } - - /* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */ - emode = source[5]; - for(i = 0; i < 11; i++) { - equivalent[i] = '0'; - } - if(num_system == 1) { equivalent[0] = temp[0]; } - equivalent[1] = source[0]; - equivalent[2] = source[1]; - equivalent[11] = '\0'; - - switch(emode) - { - case '0': - case '1': - case '2': - equivalent[3] = emode; - equivalent[8] = source[2]; - equivalent[9] = source[3]; - equivalent[10] = source[4]; - break; - case '3': - equivalent[3] = source[2]; - equivalent[9] = source[3]; - equivalent[10] = source[4]; - if(((source[2] == '0') || (source[2] == '1')) || (source[2] == '2')) { - /* Note 1 - "X3 shall not be equal to 0, 1 or 2" */ - strcpy(symbol->errtxt, "Invalid UPC-E data"); - } - break; - case '4': - equivalent[3] = source[2]; - equivalent[4] = source[3]; - equivalent[10] = source[4]; - if(source[3] == '0') { - /* Note 2 - "X4 shall not be equal to 0" */ - strcpy(symbol->errtxt, "Invalid UPC-E data"); - } - break; - case '5': - case '6': - case '7': - case '8': - case '9': - equivalent[3] = source[2]; - equivalent[4] = source[3]; - equivalent[5] = source[4]; - equivalent[10] = emode; - if(source[4] == '0') { - /* Note 3 - "X5 shall not be equal to 0" */ - strcpy(symbol->errtxt, "Invalid UPC-E data"); - } - break; - } - - /* Get the check digit from the expanded UPCA code */ - - check_digit = upc_check(equivalent); - - /* Use the number system and check digit information to choose a parity scheme */ - if(num_system == 1) { - strcpy(parity, UPCParity1[ctoi(check_digit)]); - } else { - strcpy(parity, UPCParity0[ctoi(check_digit)]); - } - - /* Take all this information and make the barcode pattern */ - - /* start character */ - concat (dest, "111"); - - for(i = 0; i <= ustrlen(source); i++) { - switch(parity[i]) { - case 'A': lookup(NEON, EANsetA, source[i], dest); break; - case 'B': lookup(NEON, EANsetB, source[i], dest); break; - } - } - - /* stop character */ - concat (dest, "111111"); - - hrt[7] = check_digit; - hrt[8] = '\0'; - ustrcpy(symbol->text, (unsigned char*)hrt); -} - - -void add_on(unsigned char source[], char dest[], int mode) -{ /* EAN-2 and EAN-5 add-on codes */ - char parity[6]; - int i, code_type; - - /* If an add-on then append with space */ - if (mode != 0) - { - concat(dest, "9"); - } - - /* Start character */ - concat (dest, "112"); - - /* Determine EAN2 or EAN5 add-on */ - if(ustrlen(source) == 2) - { - code_type = EAN2; - } - else - { - code_type = EAN5; - } - - /* Calculate parity for EAN2 */ - if(code_type == EAN2) - { - int code_value, parity_bit; - - code_value = (10 * ctoi(source[0])) + ctoi(source[1]); - parity_bit = code_value%4; - strcpy(parity, EAN2Parity[parity_bit]); - } - - if(code_type == EAN5) - { - int values[6], parity_sum, parity_bit; - - for(i = 0; i < 6; i++) - { - values[i] = ctoi(source[i]); - } - - parity_sum = (3 * (values[0] + values[2] + values[4])); - parity_sum += (9 * (values[1] + values[3])); - - parity_bit = parity_sum%10; - strcpy(parity, EAN5Parity[parity_bit]); - } - - for(i = 0; i < ustrlen(source); i++) - { - switch(parity[i]) { - case 'A': lookup(NEON, EANsetA, source[i], dest); break; - case 'B': lookup(NEON, EANsetB, source[i], dest); break; - } - - /* Glyph separator */ - if(i != (ustrlen(source) - 1)) - { - concat (dest, "11"); - } - } -} - - -/* ************************ EAN-13 ****************** */ - -char ean_check(char source[]) -{ /* Calculate the correct check digit for a EAN-13 barcode */ - int i; - unsigned int h, count, check_digit; - - count = 0; - - h = strlen(source); - for (i = h - 1; i >= 0; i--) { - count += ctoi(source[i]); - - if (i & 1) { - count += 2 * ctoi(source[i]); - } - } - check_digit = 10 - (count%10); - if (check_digit == 10) { check_digit = 0; } - return itoc(check_digit); -} - -void ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) -{ - unsigned int length, i, half_way; - char parity[6]; - char gtin[15]; - - strcpy(parity, ""); - strcpy(gtin, (char*)source); - - /* Add the appropriate check digit */ - length = strlen(gtin); - gtin[length] = ean_check(gtin); - gtin[length + 1] = '\0'; - - /* Get parity for first half of the symbol */ - lookup(SODIUM, EAN13Parity, gtin[0], parity); - - /* Now get on with the cipher */ - half_way = 7; - - /* start character */ - concat (dest, "111"); - length = strlen(gtin); - for(i = 1; i <= length; i++) - { - if (i == half_way) - { - /* middle character - separates manufacturer no. from product no. */ - /* also inverses right hand characters */ - concat (dest, "11111"); - } - - if(((i > 1) && (i < 7)) && (parity[i - 2] == 'B')) - { - lookup(NEON, EANsetB, gtin[i], dest); - } - else - { - lookup(NEON, EANsetA, gtin[i], dest); - } - } - - /* stop character */ - concat (dest, "111"); - - ustrcpy(symbol->text, (unsigned char*)gtin); -} - -void ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) -{ /* Make an EAN-8 barcode when we haven't been given the check digit */ - /* EAN-8 is basically the same as UPC-A but with fewer digits */ - int length; - char gtin[10]; - - strcpy(gtin, (char*)source); - length = strlen(gtin); - gtin[length] = upc_check(gtin); - gtin[length + 1] = '\0'; - upca_draw(gtin, dest); - ustrcpy(symbol->text, (unsigned char*)gtin); -} - -char isbn13_check(unsigned char source[]) /* For ISBN(13) only */ -{ - unsigned int i, weight, sum, check, h; - - sum = 0; - weight = 1; - h = ustrlen(source) - 1; - - for(i = 0; i < h; i++) - { - sum += ctoi(source[i]) * weight; - if(weight == 1) weight = 3; else weight = 1; - } - - check = sum % 10; - check = 10 - check; - return itoc(check); -} - -char isbn_check(unsigned char source[]) /* For ISBN(10) and SBN only */ -{ - unsigned int i, weight, sum, check, h; - char check_char; - - sum = 0; - weight = 1; - h = ustrlen(source) - 1; - - for(i = 0; i < h; i++) - { - sum += ctoi(source[i]) * weight; - weight++; - } - - check = sum % 11; - check_char = itoc(check); - if(check == 10) { check_char = 'X'; } - return check_char; -} - -int isbn(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, char dest[]) /* Make an EAN-13 barcode from an SBN or ISBN */ -{ - int i, error_number; - char check_digit; - - to_upper(source); - error_number = is_sane("0123456789X", source, src_len); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in input"); - return error_number; - } - - /* Input must be 9, 10 or 13 characters */ - if(((src_len < 9) || (src_len > 13)) || ((src_len > 10) && (src_len < 13))) - { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - - if(src_len == 13) /* Using 13 character ISBN */ - { - if(!(((source[0] == '9') && (source[1] == '7')) && - ((source[2] == '8') || (source[2] == '9')))) - { - strcpy(symbol->errtxt, "Invalid ISBN"); - return ERROR_INVALID_DATA1; - } - - check_digit = isbn13_check(source); - if (source[src_len - 1] != check_digit) - { - strcpy(symbol->errtxt, "Incorrect ISBN check"); - return ERROR_INVALID_CHECK; - } - source[12] = '\0'; - - ean13(symbol, source, dest); - } - - if(src_len == 10) /* Using 10 digit ISBN */ - { - check_digit = isbn_check(source); - if(check_digit != source[src_len - 1]) - { - strcpy(symbol->errtxt, "Incorrect ISBN check"); - return ERROR_INVALID_CHECK; - } - for(i = 13; i > 0; i--) - { - source[i] = source[i - 3]; - } - source[0] = '9'; - source[1] = '7'; - source[2] = '8'; - source[12] = '\0'; - - ean13(symbol, source, dest); - } - - if(src_len == 9) /* Using 9 digit SBN */ - { - /* Add leading zero */ - for(i = 10; i > 0; i--) - { - source[i] = source[i - 1]; - } - source[0] = '0'; - - /* Verify check digit */ - check_digit = isbn_check(source); - if(check_digit != source[ustrlen(source) - 1]) - { - strcpy(symbol->errtxt, "Incorrect SBN check"); - return ERROR_INVALID_CHECK; - } - - /* Convert to EAN-13 number */ - for(i = 13; i > 0; i--) - { - source[i] = source[i - 3]; - } - source[0] = '9'; - source[1] = '7'; - source[2] = '8'; - source[12] = '\0'; - - ean13(symbol, source, dest); - } - - return 0; -} - -void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) { - /* Add leading zeroes to EAN and UPC strings */ - unsigned char first_part[20], second_part[20], zfirst_part[20], zsecond_part[20]; - int with_addon = 0; - int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; - - h = ustrlen(source); - for(i = 0; i < h; i++) { - if(source[i] == '+') { - with_addon = 1; - } else { - if(with_addon == 0) { - first_len++; - } else { - second_len++; - } - } - } - - ustrcpy(first_part, (unsigned char *)""); - ustrcpy(second_part, (unsigned char *)""); - ustrcpy(zfirst_part, (unsigned char *)""); - ustrcpy(zsecond_part, (unsigned char *)""); - - /* Split input into two strings */ - for(i = 0; i < first_len; i++) { - first_part[i] = source[i]; - first_part[i + 1] = '\0'; - } - - for(i = 0; i < second_len; i++) { - second_part[i] = source[i + first_len + 1]; - second_part[i + 1] = '\0'; - } - - /* Calculate target lengths */ - if(second_len <= 5) { zsecond_len = 5; } - if(second_len <= 2) { zsecond_len = 2; } - if(second_len == 0) { zsecond_len = 0; } - switch(symbol->symbology) { - case BARCODE_EANX: - case BARCODE_EANX_CC: - if(first_len <= 12) { zfirst_len = 12; } - if(first_len <= 7) { zfirst_len = 7; } - if(second_len == 0) { - if(first_len <= 5) { zfirst_len = 5; } - if(first_len <= 2) { zfirst_len = 2; } - } - break; - case BARCODE_UPCA: - case BARCODE_UPCA_CC: - zfirst_len = 11; - break; - case BARCODE_UPCE: - case BARCODE_UPCE_CC: - if(first_len == 7) { zfirst_len = 7; } - if(first_len <= 6) { zfirst_len = 6; } - break; - case BARCODE_ISBNX: - if(first_len <= 9) { zfirst_len = 9; } - break; - } - - - /* Add leading zeroes */ - for(i = 0; i < (zfirst_len - first_len); i++) { - uconcat(zfirst_part, (unsigned char *)"0"); - } - uconcat(zfirst_part, first_part); - for(i = 0; i < (zsecond_len - second_len); i++) { - uconcat(zsecond_part, (unsigned char *)"0"); - } - uconcat(zsecond_part, second_part); - - /* Copy adjusted data back to local_source */ - uconcat(local_source, zfirst_part); - if(zsecond_len != 0) { - uconcat(local_source, (unsigned char *)"+"); - uconcat(local_source, zsecond_part); - } -} - -int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) -{ - /* splits string to parts before and after '+' parts */ - unsigned char first_part[20] = { 0 }, second_part[20] = { 0 }, dest[1000] = { 0 }; - unsigned char local_source[20] = { 0 }; - int latch, reader, writer, with_addon; - int error_number, i; - - - with_addon = FALSE; - latch = FALSE; - writer = 0; - - if(src_len > 19) { - strcpy(symbol->errtxt, "Input too long"); - return ERROR_TOO_LONG; - } - if(symbol->symbology != BARCODE_ISBNX) { - /* ISBN has it's own checking routine */ - error_number = is_sane("0123456789+", source, src_len); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in data"); - return error_number; - } - } else { - error_number = is_sane("0123456789Xx", source, src_len); - if(error_number == ERROR_INVALID_DATA1) { - strcpy(symbol->errtxt, "Invalid characters in input"); - return error_number; - } - } - - - /* Add leading zeroes */ - ustrcpy(local_source, (unsigned char *)""); - if(symbol->symbology == BARCODE_ISBNX) { - to_upper(local_source); - } - - ean_leading_zeroes(symbol, source, local_source); - - for(reader = 0; reader <= ustrlen(local_source); reader++) - { - if(source[reader] == '+') { with_addon = TRUE; } - } - - reader = 0; - if(with_addon) { - do { - if(local_source[reader] == '+') { - first_part[writer] = '\0'; - latch = TRUE; - reader++; - writer = 0; - } - - if(latch) { - second_part[writer] = local_source[reader]; - reader++; - writer++; - } else { - first_part[writer] = local_source[reader]; - reader++; - writer++; - } - } while (reader <= ustrlen(local_source)); - } else { - strcpy((char*)first_part, (char*)local_source); - } - - - switch(symbol->symbology) - { - case BARCODE_EANX: - switch(ustrlen(first_part)) - { - case 2: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; - case 5: add_on(first_part, (char*)dest, 0); ustrcpy(symbol->text, first_part); break; - case 7: ean8(symbol, first_part, (char*)dest); break; - case 12: ean13(symbol, first_part, (char*)dest); break; - default: strcpy(symbol->errtxt, "Invalid length input"); return ERROR_TOO_LONG; break; - } - break; - case BARCODE_EANX_CC: - switch(ustrlen(first_part)) - { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ - case 7: set_module(symbol, symbol->rows, 1); - set_module(symbol, symbol->rows, 67); - set_module(symbol, symbol->rows + 1, 0); - set_module(symbol, symbol->rows + 1, 68); - set_module(symbol, symbol->rows + 2, 1); - set_module(symbol, symbol->rows + 1, 67); - symbol->row_height[symbol->rows] = 2; - symbol->row_height[symbol->rows + 1] = 2; - symbol->row_height[symbol->rows + 2] = 2; - symbol->rows += 3; - ean8(symbol, first_part, (char*)dest); break; - case 12:set_module(symbol, symbol->rows, 1); - set_module(symbol, symbol->rows, 95); - set_module(symbol, symbol->rows + 1, 0); - set_module(symbol, symbol->rows + 1, 96); - set_module(symbol, symbol->rows + 2, 1); - set_module(symbol, symbol->rows + 2, 95); - symbol->row_height[symbol->rows] = 2; - symbol->row_height[symbol->rows + 1] = 2; - symbol->row_height[symbol->rows + 2] = 2; - symbol->rows += 3; - ean13(symbol, first_part, (char*)dest); break; - default: strcpy(symbol->errtxt, "Invalid length EAN input"); return ERROR_TOO_LONG; break; - } - break; - case BARCODE_UPCA: - if(ustrlen(first_part) == 11) { - upca(symbol, first_part, (char*)dest); - } else { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - break; - case BARCODE_UPCA_CC: - if(ustrlen(first_part) == 11) { - set_module(symbol, symbol->rows, 1); - set_module(symbol, symbol->rows, 95); - set_module(symbol, symbol->rows + 1, 0); - set_module(symbol, symbol->rows + 1, 96); - set_module(symbol, symbol->rows + 2, 1); - set_module(symbol, symbol->rows + 2, 95); - symbol->row_height[symbol->rows] = 2; - symbol->row_height[symbol->rows + 1] = 2; - symbol->row_height[symbol->rows + 2] = 2; - symbol->rows += 3; - upca(symbol, first_part, (char*)dest); - } else { - strcpy(symbol->errtxt, "UPCA input wrong length"); - return ERROR_TOO_LONG; - } - break; - case BARCODE_UPCE: - if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { - upce(symbol, first_part, (char*)dest); - } else { - strcpy(symbol->errtxt, "Input wrong length"); - return ERROR_TOO_LONG; - } - break; - case BARCODE_UPCE_CC: - if((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { - set_module(symbol, symbol->rows, 1); - set_module(symbol, symbol->rows, 51); - set_module(symbol, symbol->rows + 1, 0); - set_module(symbol, symbol->rows + 1, 52); - set_module(symbol, symbol->rows + 2, 1); - set_module(symbol, symbol->rows + 2, 51); - symbol->row_height[symbol->rows] = 2; - symbol->row_height[symbol->rows + 1] = 2; - symbol->row_height[symbol->rows + 2] = 2; - symbol->rows += 3; - upce(symbol, first_part, (char*)dest); - } else { - strcpy(symbol->errtxt, "UPCE input wrong length"); - return ERROR_TOO_LONG; - } - break; - case BARCODE_ISBNX: - error_number = isbn(symbol, first_part, ustrlen(first_part), (char*)dest); - if(error_number > 4) { - return error_number; - } - break; - } - switch(ustrlen(second_part)) - { - case 0: break; - case 2: - add_on(second_part, (char*)dest, 1); - uconcat(symbol->text, (unsigned char*)"+"); - uconcat(symbol->text, second_part); - break; - case 5: - add_on(second_part, (char*)dest, 1); - uconcat(symbol->text, (unsigned char*)"+"); - uconcat(symbol->text, second_part); - break; - default: - strcpy(symbol->errtxt, "Invalid length input"); - return ERROR_TOO_LONG; - break; - } - - expand(symbol, (char*)dest); - - switch(symbol->symbology) { - case BARCODE_EANX_CC: - case BARCODE_UPCA_CC: - case BARCODE_UPCE_CC: - /* shift the symbol to the right one space to allow for separator bars */ - for(i = (symbol->width + 1); i >= 1; i--) { - if(module_is_set(symbol, symbol->rows - 1, i - 1)) { - set_module(symbol, symbol->rows - 1, i); - } else { - unset_module(symbol, symbol->rows - 1, i); - } - } - unset_module(symbol, symbol->rows - 1, 0); - symbol->width += 2; - break; - } - - - if((symbol->errtxt[0] == 'w') && (error_number == 0)) { - error_number = 1; /* flag UPC-E warnings */ - } - return error_number; -} - - - - diff --git a/3rdparty/zint-2.4.4/backend/zint.h b/3rdparty/zint-2.4.4/backend/zint.h deleted file mode 100644 index 2d5e2c5..0000000 --- a/3rdparty/zint-2.4.4/backend/zint.h +++ /dev/null @@ -1,238 +0,0 @@ -/* zint.h - definitions for libzint - - libzint - the open source barcode library - Copyright (C) 2009 Robin Stuart - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef ZINT_H -#define ZINT_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct zint_render_line { - float x, y, length, width; - struct zint_render_line *next; /* Pointer to next line */ -}; - -struct zint_render_string { - float x, y, fsize; - float width; /* Suggested string width, may be 0 if none recommended */ - int length; - unsigned char *text; - struct zint_render_string *next; /* Pointer to next character */ -}; - -struct zint_render_ring { - float x, y, radius, line_width; - struct zint_render_ring *next; /* Pointer to next ring */ -}; - -struct zint_render_hexagon { - float x, y; - struct zint_render_hexagon *next; /* Pointer to next hexagon */ -}; - -struct zint_render { - float width, height; - struct zint_render_line *lines; /* Pointer to first line */ - struct zint_render_string *strings; /* Pointer to first string */ - struct zint_render_ring *rings; /* Pointer to first ring */ - struct zint_render_hexagon *hexagons; /* Pointer to first hexagon */ -}; - -struct zint_symbol { - int symbology; - int height; - int whitespace_width; - int border_width; - int output_options; - char fgcolour[10]; - char bgcolour[10]; - char outfile[256]; - float scale; - int option_1; - int option_2; - int option_3; - int show_hrt; - int input_mode; - unsigned char text[128]; - int rows; - int width; - char primary[128]; - unsigned char encoded_data[178][143]; - int row_height[178]; /* Largest symbol is 177x177 QR Code */ - char errtxt[100]; - char *bitmap; - int bitmap_width; - int bitmap_height; - struct zint_render *rendered; -}; - - -/* Tbarcode 7 codes */ -#define BARCODE_CODE11 1 -#define BARCODE_C25MATRIX 2 -#define BARCODE_C25INTER 3 -#define BARCODE_C25IATA 4 -#define BARCODE_C25LOGIC 6 -#define BARCODE_C25IND 7 -#define BARCODE_CODE39 8 -#define BARCODE_EXCODE39 9 -#define BARCODE_EANX 13 -#define BARCODE_EAN128 16 -#define BARCODE_CODABAR 18 -#define BARCODE_CODE128 20 -#define BARCODE_DPLEIT 21 -#define BARCODE_DPIDENT 22 -#define BARCODE_CODE16K 23 -#define BARCODE_CODE49 24 -#define BARCODE_CODE93 25 -#define BARCODE_FLAT 28 -#define BARCODE_RSS14 29 -#define BARCODE_RSS_LTD 30 -#define BARCODE_RSS_EXP 31 -#define BARCODE_TELEPEN 32 -#define BARCODE_UPCA 34 -#define BARCODE_UPCE 37 -#define BARCODE_POSTNET 40 -#define BARCODE_MSI_PLESSEY 47 -#define BARCODE_FIM 49 -#define BARCODE_LOGMARS 50 -#define BARCODE_PHARMA 51 -#define BARCODE_PZN 52 -#define BARCODE_PHARMA_TWO 53 -#define BARCODE_PDF417 55 -#define BARCODE_PDF417TRUNC 56 -#define BARCODE_MAXICODE 57 -#define BARCODE_QRCODE 58 -#define BARCODE_CODE128B 60 -#define BARCODE_AUSPOST 63 -#define BARCODE_AUSREPLY 66 -#define BARCODE_AUSROUTE 67 -#define BARCODE_AUSREDIRECT 68 -#define BARCODE_ISBNX 69 -#define BARCODE_RM4SCC 70 -#define BARCODE_DATAMATRIX 71 -#define BARCODE_EAN14 72 -#define BARCODE_CODABLOCKF 74 -#define BARCODE_NVE18 75 -#define BARCODE_JAPANPOST 76 -#define BARCODE_KOREAPOST 77 -#define BARCODE_RSS14STACK 79 -#define BARCODE_RSS14STACK_OMNI 80 -#define BARCODE_RSS_EXPSTACK 81 -#define BARCODE_PLANET 82 -#define BARCODE_MICROPDF417 84 -#define BARCODE_ONECODE 85 -#define BARCODE_PLESSEY 86 - -/* Tbarcode 8 codes */ -#define BARCODE_TELEPEN_NUM 87 -#define BARCODE_ITF14 89 -#define BARCODE_KIX 90 -#define BARCODE_AZTEC 92 -#define BARCODE_DAFT 93 -#define BARCODE_MICROQR 97 - -/* Tbarcode 9 codes */ -#define BARCODE_HIBC_128 98 -#define BARCODE_HIBC_39 99 -#define BARCODE_HIBC_DM 102 -#define BARCODE_HIBC_QR 104 -#define BARCODE_HIBC_PDF 106 -#define BARCODE_HIBC_MICPDF 108 -#define BARCODE_HIBC_BLOCKF 110 -#define BARCODE_HIBC_AZTEC 112 - -/* Zint specific */ -#define BARCODE_AZRUNE 128 -#define BARCODE_CODE32 129 -#define BARCODE_EANX_CC 130 -#define BARCODE_EAN128_CC 131 -#define BARCODE_RSS14_CC 132 -#define BARCODE_RSS_LTD_CC 133 -#define BARCODE_RSS_EXP_CC 134 -#define BARCODE_UPCA_CC 135 -#define BARCODE_UPCE_CC 136 -#define BARCODE_RSS14STACK_CC 137 -#define BARCODE_RSS14_OMNI_CC 138 -#define BARCODE_RSS_EXPSTACK_CC 139 -#define BARCODE_CHANNEL 140 -#define BARCODE_CODEONE 141 -#define BARCODE_GRIDMATRIX 142 - -#define BARCODE_NO_ASCII 1 -#define BARCODE_BIND 2 -#define BARCODE_BOX 4 -#define BARCODE_STDOUT 8 -#define READER_INIT 16 -#define SMALL_TEXT 32 - -#define DATA_MODE 0 -#define UNICODE_MODE 1 -#define GS1_MODE 2 -#define KANJI_MODE 3 -#define SJIS_MODE 4 - -#define DM_SQUARE 100 - -#define WARN_INVALID_OPTION 2 -#define ERROR_TOO_LONG 5 -#define ERROR_INVALID_DATA1 6 -#define ERROR_INVALID_CHECK 7 -#define ERROR_INVALID_OPTION 8 -#define ERROR_ENCODING_PROBLEM 9 -#define ERROR_FILE_ACCESS 10 -#define ERROR_MEMORY 11 - -#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER) -# if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL) -# define ZINT_EXTERN __declspec(dllexport) -# elif defined(ZINT_DLL) -# define ZINT_EXTERN __declspec(dllimport) -# else -# define ZINT_EXTERN extern -# endif -#else -# define ZINT_EXTERN extern -#endif - -ZINT_EXTERN struct zint_symbol *ZBarcode_Create(void); -ZINT_EXTERN void ZBarcode_Clear(struct zint_symbol *symbol); -ZINT_EXTERN void ZBarcode_Delete(struct zint_symbol *symbol); - -ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input, int length); -ZINT_EXTERN int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename); -ZINT_EXTERN int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle); -ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); -ZINT_EXTERN int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle); - -ZINT_EXTERN int ZBarcode_Render(struct zint_symbol *symbol, float width, float height); - -ZINT_EXTERN int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle); -ZINT_EXTERN int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); -ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle); - -ZINT_EXTERN int ZBarcode_ValidID(int symbol_id); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ZINT_H */ diff --git a/3rdparty/zint-2.4.4/backend_qt4/Zint.pro b/3rdparty/zint-2.4.4/backend_qt4/Zint.pro deleted file mode 100644 index f9747a2..0000000 --- a/3rdparty/zint-2.4.4/backend_qt4/Zint.pro +++ /dev/null @@ -1,119 +0,0 @@ -DEFINES += NO_PNG -TEMPLATE = lib - -contains(CONFIG, static_build){ - CONFIG += staticlib - DEFINES += HAVE_STATIC_BUILD -} - -!contains(CONFIG, staticlib){ - CONFIG += dll - DEFINES += QZINT_LIBRARY - -} - -include(../../../common.pri) - -macx{ - CONFIG -= dll - CONFIG += lib_bundle -} - -unix{ - CONFIG += plugin -} - -#VERSION = 2.4.4 - -INCLUDEPATH += $$PWD/../backend -DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$VERSION\\\" - -CONFIG(debug, debug|release) { - TARGET = QtZintd -} else { - TARGET = QtZint -} - - - - -!contains(DEFINES, NO_PNG) { - SOURCES += $$PWD/../backend/png.c - LIBS += -lpng -} - - -win32-msvc* { - DEFINES += _CRT_SECURE_NO_WARNINGS - #QMAKE_CFLAGS += /TP /wd4018 /wd4244 /wd4305 - #QMAKE_CXXFLAGS += /TP /wd4018 /wd4244 /wd4305 -} - - -INCLUDEPATH += zint zint/backend zint/backend_qt4 - -HEADERS += \ - $$PWD/qzint.h \ - $$PWD/qzint_global.h \ - $$PWD/../backend/aztec.h \ - $$PWD/../backend/code1.h \ - $$PWD/../backend/code49.h \ - $$PWD/../backend/common.h \ - $$PWD/../backend/composite.h \ - $$PWD/../backend/dmatrix.h \ - $$PWD/../backend/font.h \ - $$PWD/../backend/gb2312.h \ - $$PWD/../backend/gridmtx.h \ - $$PWD/../backend/gs1.h \ - $$PWD/../backend/large.h \ - $$PWD/../backend/maxicode.h \ - $$PWD/../backend/maxipng.h \ - $$PWD/../backend/ms_stdint.h \ - $$PWD/../backend/pdf417.h \ - $$PWD/../backend/qr.h \ - $$PWD/../backend/reedsol.h \ - $$PWD/../backend/rss.h \ - $$PWD/../backend/sjis.h \ - $$PWD/../backend/zint.h - -SOURCES += \ - $$PWD/qzint.cpp \ - $$PWD/../backend/2of5.c \ - $$PWD/../backend/auspost.c \ - $$PWD/../backend/aztec.c \ - $$PWD/../backend/code.c \ - $$PWD/../backend/code1.c \ - $$PWD/../backend/code16k.c \ - $$PWD/../backend/code49.c \ - $$PWD/../backend/code128.c \ - $$PWD/../backend/common.c \ - $$PWD/../backend/composite.c \ - $$PWD/../backend/dllversion.c \ - $$PWD/../backend/dmatrix.c \ - $$PWD/../backend/gridmtx.c \ - $$PWD/../backend/gs1.c \ - $$PWD/../backend/imail.c \ - $$PWD/../backend/large.c \ - $$PWD/../backend/library.c \ - $$PWD/../backend/maxicode.c \ - $$PWD/../backend/medical.c \ - $$PWD/../backend/pdf417.c \ - $$PWD/../backend/plessey.c \ - $$PWD/../backend/png.c \ - $$PWD/../backend/postal.c \ - $$PWD/../backend/ps.c \ - $$PWD/../backend/qr.c \ - $$PWD/../backend/reedsol.c \ - $$PWD/../backend/render.c \ - $$PWD/../backend/rss.c \ - $$PWD/../backend/svg.c \ - $$PWD/../backend/telepen.c \ - $$PWD/../backend/upcean.c - - -DESTDIR = $${DEST_LIBS} -#DLLDESTDIR = $${DESTDIR} -unix { - target.path = $${DESTDIR} - INSTALLS = target -} diff --git a/3rdparty/zint-2.4.4/backend_qt4/qzint.cpp b/3rdparty/zint-2.4.4/backend_qt4/qzint.cpp deleted file mode 100644 index eb4f65e..0000000 --- a/3rdparty/zint-2.4.4/backend_qt4/qzint.cpp +++ /dev/null @@ -1,692 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by BogDan Vatra * - * bogdan@licentia.eu * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#include "qzint.h" -#include - -Zint::QZint* createWidget() { - Zint::QZint *z = new Zint::QZint(); - return z; -} - -namespace Zint -{ - -static const qreal maxi_diagonal=11; -static const qreal maxi_width=1.73205807568877*maxi_diagonal/2; -static const char* fontstyle="Arial"; -static const int fontPixelSizeSmall=6; -static const int fontPixelSizeLarge=8; - -QZint::QZint() -{ - m_symbol=BARCODE_CODE128; - m_height=50; - m_border=NO_BORDER; - m_borderWidth=1; - m_securityLevel=-1; - m_pdf417CodeWords=928; - m_fgColor=Qt::black; - m_bgColor=Qt::white; - m_zintSymbol=0; - m_error=0; - m_input_mode = UNICODE_MODE; - m_scale = 1.0; - m_option_3 = 0; - m_hidetext = false; - m_whitespace = 0; -} - -QZint::~QZint() -{ - if (m_zintSymbol) - ZBarcode_Delete(m_zintSymbol); -} - -void QZint::encode() -{ - if (m_zintSymbol) - ZBarcode_Delete(m_zintSymbol); - - m_lastError.clear(); - m_zintSymbol = ZBarcode_Create(); - m_zintSymbol->output_options=m_border; - m_zintSymbol->symbology=m_symbol; - m_zintSymbol->height=m_height; - m_zintSymbol->whitespace_width=m_whitespace; - m_zintSymbol->border_width=m_borderWidth; - m_zintSymbol->option_1=m_securityLevel; - m_zintSymbol->input_mode = m_input_mode; - m_zintSymbol->option_2=m_width; - if(m_hidetext) { - m_zintSymbol->show_hrt = 0; - } else { - m_zintSymbol->show_hrt = 1; - } - if(m_symbol == BARCODE_PDF417) { - m_zintSymbol->option_3=m_pdf417CodeWords; - } else { - m_zintSymbol->option_3 = m_option_3; - } - QByteArray bstr=m_text.toUtf8(); - QByteArray pstr=m_primaryMessage.left(99).toLatin1(); - strcpy(m_zintSymbol->primary,pstr.data()); - int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*)bstr.data(), bstr.length()); - if (error > WARN_INVALID_OPTION) - m_lastError=m_zintSymbol->errtxt; - - if (m_zintSymbol->symbology == BARCODE_MAXICODE) - m_zintSymbol->height = 33; - - switch(m_zintSymbol->output_options) { - case 0: m_border = NO_BORDER; break; - case 2: m_border = BIND; break; - case 4: m_border = BOX; break; - } - m_borderWidth = (BorderType)m_zintSymbol->border_width; - m_whitespace = m_zintSymbol->whitespace_width; -} - -int QZint::symbol() -{ - return m_symbol; -} -void QZint::setSymbol(int symbol) -{ - m_symbol=symbol; -} - -void QZint::setInputMode(int input_mode) -{ - m_input_mode = input_mode; -} - -QString QZint::text() -{ - return m_text; -} -void QZint::setText(const QString & text) -{ - m_text=text; -} - -QString QZint::primaryMessage() -{ - return m_primaryMessage; -} -void QZint::setPrimaryMessage(const QString & primaryMessage) -{ - m_primaryMessage=primaryMessage; -} - -int QZint::height() -{ - encode(); - return (m_zintSymbol->height+(m_border!=NO_BORDER)?m_borderWidth*2:0)*(m_zintSymbol->symbology == BARCODE_MAXICODE?(maxi_width+1):1); -} - -void QZint::setHeight(int height) -{ - m_height=height; -} - -void QZint::setWidth(int width) -{ - m_width=width; -} - -void QZint::setOption3(int option) -{ - m_option_3 = option; -} - -int QZint::width() -{ - encode(); - return (m_zintSymbol->width+(m_border==BOX)?m_borderWidth*2:0)*(m_zintSymbol->symbology == BARCODE_MAXICODE?(maxi_width+1):1); -} - -float QZint::scale() -{ - return m_scale; -} - -void QZint::setScale(float scale) -{ - m_scale = scale; -} - -QColor QZint::fgColor() -{ - return m_fgColor; -} -void QZint::setFgColor(const QColor & fgColor) -{ - m_fgColor=fgColor; -} - -QColor QZint::bgColor() -{ - return m_bgColor; -} -void QZint::setBgColor(const QColor & bgColor) -{ - m_bgColor=bgColor; -} - -QZint::BorderType QZint::borderType() -{ - return m_border; -} -void QZint::setBorderType(BorderType border) -{ - m_border=border; -} - -int QZint::borderWidth() -{ - return m_borderWidth; -} -void QZint::setBorderWidth(int boderWidth) -{ - if (boderWidth<1 || boderWidth>16) - boderWidth=1; - m_borderWidth=boderWidth; -} - -void QZint::setWhitespace(int whitespace) -{ - m_whitespace = whitespace; -} - -int QZint::pdf417CodeWords() -{ - return m_pdf417CodeWords; -} -void QZint::setPdf417CodeWords(int pdf417CodeWords) -{ - m_pdf417CodeWords=pdf417CodeWords; -} - -int QZint::securityLevel() -{ - return m_securityLevel; -} -void QZint::setSecurityLevel(int securityLevel) -{ - m_securityLevel=securityLevel; -} - -QString QZint::error_message() -{ - return m_lastError; -} - -int QZint::mode() -{ - return m_securityLevel; -} -void QZint::setMode(int securityLevel) -{ - m_securityLevel=securityLevel; -} - -void QZint::setHideText(bool hide) -{ - m_hidetext = hide; -} - -bool QZint::save_to_file(QString filename) -{ - if (m_zintSymbol) - ZBarcode_Delete(m_zintSymbol); - - QString fg_colour_hash = m_fgColor.name(); - QString bg_colour_hash = m_bgColor.name(); - - m_lastError.clear(); - m_zintSymbol = ZBarcode_Create(); - m_zintSymbol->output_options=m_border; - m_zintSymbol->symbology=m_symbol; - m_zintSymbol->height=m_height; - m_zintSymbol->whitespace_width=m_whitespace; - m_zintSymbol->border_width=m_borderWidth; - m_zintSymbol->option_1=m_securityLevel; - m_zintSymbol->input_mode = m_input_mode; - m_zintSymbol->option_2=m_width; - if(m_hidetext) { - m_zintSymbol->show_hrt = 0; - } else { - m_zintSymbol->show_hrt = 1; - } - if(m_symbol == BARCODE_PDF417) { - m_zintSymbol->option_3=m_pdf417CodeWords; - } else { - m_zintSymbol->option_3 = m_option_3; - } - m_zintSymbol->scale=m_scale; - QByteArray bstr=m_text.toUtf8(); - QByteArray pstr=m_primaryMessage.left(99).toLatin1(); - QByteArray fstr=filename.left(255).toLatin1(); - strcpy(m_zintSymbol->primary,pstr.data()); - strcpy(m_zintSymbol->outfile,fstr.data()); - QByteArray fgcol=fg_colour_hash.right(6).toLatin1(); - QByteArray bgcol=bg_colour_hash.right(6).toLatin1(); - strcpy(m_zintSymbol->fgcolour,fgcol.data()); - strcpy(m_zintSymbol->bgcolour,bgcol.data()); - int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*)bstr.data(), bstr.length()); - if (error > WARN_INVALID_OPTION) - m_lastError=m_zintSymbol->errtxt; - error = ZBarcode_Print(m_zintSymbol, 0); - if (error > WARN_INVALID_OPTION) - m_lastError=m_zintSymbol->errtxt; - if(error == 0) { return true; } else { return false; } -} - -int QZint::module_set(int y_coord, int x_coord) -{ - int x_char, x_sub, result; - - x_char = x_coord / 7; - x_sub = x_coord % 7; - result = 0; - - switch(x_sub) { - case 0: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x01) != 0) { result = 1; } break; - case 1: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x02) != 0) { result = 1; } break; - case 2: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x04) != 0) { result = 1; } break; - case 3: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x08) != 0) { result = 1; } break; - case 4: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x10) != 0) { result = 1; } break; - case 5: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x20) != 0) { result = 1; } break; - case 6: if((m_zintSymbol->encoded_data[y_coord][x_char] & 0x40) != 0) { result = 1; } break; - } - - return result; -} - -void QZint::render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode) -{ - encode(); - bool textdone; - int comp_offset = 0, xoffset = m_whitespace, j, main_width = 0, addon_text_height = 0; - int yoffset = 0; - QString caption = QString::fromUtf8((const char *)m_zintSymbol->text, -1); - QFont fontSmall(fontstyle); - fontSmall.setPixelSize(fontPixelSizeSmall); - QFont fontLarge(fontstyle); - fontLarge.setPixelSize(fontPixelSizeLarge); - - if (m_lastError.length()) - { - painter.setFont(fontLarge); - painter.drawText(paintRect,Qt::AlignCenter,m_lastError); - return; - } - - painter.save(); - painter.setClipRect(paintRect,Qt::IntersectClip); - qreal xtr=paintRect.x(); - qreal ytr=paintRect.y(); - - int zrow_height=m_zintSymbol->height; - int zrows=0; - for (int i=0;irows;i++) - { - zrow_height-=m_zintSymbol->row_height[i]; - if (!m_zintSymbol->row_height[i]) - zrows++; - } - if (zrows) - { - zrow_height/=zrows; - for (int i=0;irows;i++) - if (!m_zintSymbol->row_height[i]) - m_zintSymbol->row_height[i]=zrow_height; - } - else - m_zintSymbol->height-=zrow_height; - - - qreal gwidth=m_zintSymbol->width; - qreal gheight=m_zintSymbol->height; - if (m_zintSymbol->symbology == BARCODE_MAXICODE) - { - gheight*=(maxi_width); - gwidth*=(maxi_width+1); - } - - qreal xsf=1; - qreal ysf=1; - qreal textoffset = 0; - - gwidth+=((m_border==BOX)?m_borderWidth*2:0); - gheight+=((m_border!=NO_BORDER)?m_borderWidth*2:0); - if(QString((const char*)m_zintSymbol->text).isEmpty() == false) { - textoffset = 9; - gheight += textoffset; - } else { - textoffset = 0; - } - gwidth+=m_zintSymbol->whitespace_width*2; - switch(mode) - { - case IgnoreAspectRatio: - xsf=(qreal)paintRect.width()/gwidth; - ysf=(qreal)paintRect.height()/gheight; - break; - - case KeepAspectRatio: - if (paintRect.width()/gwidthsymbology != BARCODE_MAXICODE) { - /* Draw boundary bars or boxes around the symbol */ - switch(m_border) - { - case BOX: - painter.fillRect(0,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor)); - painter.fillRect(m_zintSymbol->width + xoffset + xoffset + m_borderWidth,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor)); - painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth,m_borderWidth,QBrush(m_fgColor)); - painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth, m_borderWidth,QBrush(m_fgColor)); - painter.translate(m_borderWidth+m_zintSymbol->whitespace_width,m_borderWidth); - yoffset = m_borderWidth; - break; - case BIND: - painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset,m_borderWidth,QBrush(m_fgColor)); - painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset, m_borderWidth,QBrush(m_fgColor)); - painter.translate(m_zintSymbol->whitespace_width,m_borderWidth); - yoffset = m_borderWidth; - break; - - default: - painter.translate(m_zintSymbol->whitespace_width,0); - break;; - } - } - - while(!(module_set(m_zintSymbol->rows - 1, comp_offset))) { - comp_offset++; - } - xoffset = comp_offset; - - /* Set up some values for displaying EAN and UPC symbols correctly */ - main_width = m_zintSymbol->width; - if ((((m_zintSymbol->symbology == BARCODE_EANX) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) - || (m_zintSymbol->symbology == BARCODE_ISBNX)) { - switch(caption.size()) { - case 13: /* EAN 13 */ - case 16: - case 19: - if(m_zintSymbol->whitespace_width == 0) { - m_zintSymbol->whitespace_width = 10; - } - main_width = 96 + comp_offset; - break; - default: - main_width = 68 + comp_offset; - break; - } - } - - if (((m_zintSymbol->symbology == BARCODE_UPCA) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) { - if(m_zintSymbol->whitespace_width == 0) { - m_zintSymbol->whitespace_width = 10; - } - main_width = 96 + comp_offset; - } - - if (((m_zintSymbol->symbology == BARCODE_UPCE) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) { - if(m_zintSymbol->whitespace_width == 0) { - m_zintSymbol->whitespace_width = 10; - } - main_width = 51 + comp_offset; - } - - p.setWidth(1); - painter.setPen(p); - - if (m_zintSymbol->symbology == BARCODE_MAXICODE) - { - /* Draw Maxicode with hexagons */ - painter.save(); - painter.setRenderHint(QPainter::Antialiasing); - for (int r=0;rrows;r++) - { - for (int c=0;cwidth;c++) - { - if (module_set(r, c)) - { - qreal col=(qreal)c*(maxi_width+1)+(r%2)*((maxi_width+1)/2); - qreal row=(qreal)r*(maxi_width+1)*0.868; - QPainterPath pt; - pt.moveTo(col+maxi_width/2, row); - pt.lineTo(col+maxi_width, row+maxi_diagonal/4); - pt.lineTo(col+maxi_width, row+(maxi_diagonal-maxi_diagonal/4)); - pt.lineTo(col+maxi_width/2, row+maxi_diagonal); - pt.lineTo(col, row+(maxi_diagonal-maxi_diagonal/4)); - pt.lineTo(col, row+maxi_diagonal/4); - pt.lineTo(col+maxi_width/2, row); - painter.fillPath(pt,QBrush(m_fgColor)); - } - } - } - p.setWidth(maxi_width); - painter.setPen(p); - const qreal w=maxi_width+1; - painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w,w); - painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*1.5,w+w*1.5); - painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*3,w+w*3); - painter.restore(); - } - else - { - /* Draw all other symbols with rectangles */ - int y=0; - for (int row=0;rowrows;row++) - { - for (int i=0;iwidth;i++) { - if (module_set(row, i)) - { - int ed = module_set(row, i); - int linewidth=0; - for (int j=i;jwidth;j++,linewidth++) - if (ed != module_set(row, j)) - break; - QColor color; - color=m_fgColor; - - if(!((i > main_width) && (row == m_zintSymbol->rows - 1))) { - painter.fillRect(i,y,linewidth,m_zintSymbol->row_height[row],QBrush(color)); - } else { - painter.fillRect(i,y + 8,linewidth,m_zintSymbol->row_height[row] - 3,QBrush(color)); - addon_text_height = y; - } - } - } - /* Add row binding */ - if(((m_zintSymbol->symbology == BARCODE_CODE16K) || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) { - painter.fillRect(0,y - 1,m_zintSymbol->width,2,QBrush(m_fgColor)); - } - y+=m_zintSymbol->row_height[row]; - } - } - - textdone = false; - - if(m_hidetext == false) { - painter.setFont(fontSmall); - if(((m_zintSymbol->symbology == BARCODE_EANX) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) || - (m_zintSymbol->symbology == BARCODE_ISBNX)) { - /* Add bridge and format text for EAN */ - switch(caption.size()) { - case 8: - case 11: - case 14: - painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(32 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(34 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(64 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(66 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.setFont(fontLarge); - painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(0,4)); - painter.drawText(35 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(4,4)); - if(caption.size() == 11) { /* EAN-2 */ painter.drawText(76 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); }; - if(caption.size() == 14) { /* EAN-5 */ painter.drawText(76 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); }; - painter.setFont(fontSmall); - textdone = true; - break; - case 13: - case 16: - case 19: - painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(92 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(94 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.setFont(fontLarge); - painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 9,Qt::AlignCenter, caption.mid(0,1)); - painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6)); - painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(7,6)); - if(caption.size() == 16) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(14,2)); }; - if(caption.size() == 19) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(14,5)); }; - painter.setFont(fontSmall); - textdone = true; - break; - } - if(textdone == false) { - painter.setFont(fontLarge); - painter.drawText(0, m_zintSymbol->height, m_zintSymbol->width, 9,Qt::AlignCenter, caption); - painter.setFont(fontSmall); - textdone = true; - } - } - - if((m_zintSymbol->symbology == BARCODE_UPCA) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) { - /* Add bridge and format text for UPC-A */ - int block_width; - bool latch = true; - - j = 0 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j)); - if(latch == true) { - /* a bar */ - painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor)); - latch = false; - } else { - /* a space */ - latch = true; - } - j += block_width; - } while (j < 11 + comp_offset); - painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - latch = true; - j = 85 + comp_offset; - do { - block_width = 0; - do { - block_width++; - } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j)); - if(latch == true) { - /* a bar */ - painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor)); - latch = false; - } else { - /* a space */ - latch = true; - } - j += block_width; - } while (j < 96 + comp_offset); - painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(0,1)); - painter.drawText(96 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(11,1)); - painter.setFont(fontLarge); - painter.drawText(11 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(1,5)); - painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(6,5)); - if(caption.size() == 15) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(13,2)); }; - if(caption.size() == 18) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(13,5)); }; - painter.setFont(fontSmall); - textdone = true; - } - - if((m_zintSymbol->symbology == BARCODE_UPCE) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) { - /* Add bridge and format text for UPC-E */ - painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.fillRect(50 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor)); - painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(0,1)); - painter.drawText(51 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(7,1)); - painter.setFont(fontLarge); - painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6)); - if(caption.size() == 11) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); }; - if(caption.size() == 14) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); }; - painter.setFont(fontSmall); - textdone = true; - } - } /* if (m_hidetext == false) */ - - if((m_hidetext == false) && (textdone == false)) { - /* Add text to any other symbol */ - painter.drawText(0, m_zintSymbol->height + yoffset, m_zintSymbol->width, 7, Qt::AlignCenter, caption); - } - painter.restore(); -} - -const QString & QZint::lastError() -{ - return m_lastError; -} - -bool QZint::hasErrors() -{ - return m_lastError.length(); -} - -} - diff --git a/3rdparty/zint-2.4.4/COPYING b/3rdparty/zint-2.6.1/COPYING similarity index 100% rename from 3rdparty/zint-2.4.4/COPYING rename to 3rdparty/zint-2.6.1/COPYING diff --git a/3rdparty/zint-2.6.1/backend/2of5.c b/3rdparty/zint-2.6.1/backend/2of5.c new file mode 100644 index 0000000..60010b8 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/2of5.c @@ -0,0 +1,357 @@ +/* 2of5.c - Handles Code 2 of 5 barcodes */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" +#ifdef _MSC_VER +#include +#define inline _inline +#endif + +static const char *C25MatrixTable[10] = { + "113311", "311131", "131131", "331111", "113131", "313111", + "133111", "111331", "311311", "131311" +}; + +static const char *C25IndustTable[10] = { + "1111313111", "3111111131", "1131111131", "3131111111", "1111311131", + "3111311111", "1131311111", "1111113131", "3111113111", "1131113111" +}; + +static const char *C25InterTable[10] = { + "11331", "31113", "13113", "33111", "11313", "31311", "13311", "11133", + "31131", "13131" +}; + +static inline char check_digit(unsigned int count) { + return itoc((10 - (count % 10)) % 10); +} + +/* Code 2 of 5 Standard (Code 2 of 5 Matrix) */ +int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { + + int i, error_number; + char dest[512]; /* 6 + 80 * 6 + 6 + 1 ~ 512*/ + + if (length > 80) { + strcpy(symbol->errtxt, "301: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "302: Invalid characters in data"); + return error_number; + } + + /* start character */ + strcpy(dest, "411111"); + + for (i = 0; i < length; i++) { + lookup(NEON, C25MatrixTable, source[i], dest); + } + + /* Stop character */ + strcat(dest, "41111"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +/* Code 2 of 5 Industrial */ +int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { + + int i, error_number; + char dest[512]; /* 6 + 40 * 10 + 6 + 1 */ + + if (length > 45) { + strcpy(symbol->errtxt, "303: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "304: Invalid character in data"); + return error_number; + } + + /* start character */ + strcpy(dest, "313111"); + + for (i = 0; i < length; i++) { + lookup(NEON, C25IndustTable, source[i], dest); + } + + /* Stop character */ + strcat(dest, "31113"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +/* Code 2 of 5 IATA */ +int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { + int i, error_number; + char dest[512]; /* 4 + 45 * 10 + 3 + 1 */ + + if (length > 45) { + strcpy(symbol->errtxt, "305: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "306: Invalid characters in data"); + return error_number; + } + + /* start */ + strcpy(dest, "1111"); + + for (i = 0; i < length; i++) { + lookup(NEON, C25IndustTable, source[i], dest); + } + + /* stop */ + strcat(dest, "311"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +/* Code 2 of 5 Data Logic */ +int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) { + + int i, error_number; + char dest[512]; /* 4 + 80 * 6 + 3 + 1 */ + + if (length > 80) { + strcpy(symbol->errtxt, "307: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "308: Invalid characters in data"); + return error_number; + } + + /* start character */ + strcpy(dest, "1111"); + + for (i = 0; i < length; i++) { + lookup(NEON, C25MatrixTable, source[i], dest); + } + + /* Stop character */ + strcat(dest, "311"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +/* Code 2 of 5 Interleaved */ +int interleaved_two_of_five(struct zint_symbol *symbol, const unsigned char source[], size_t length) { + + int i, j, k, error_number; + char bars[7], spaces[7], mixed[14], dest[1000]; +#ifndef _MSC_VER + unsigned char temp[length + 2]; +#else + unsigned char* temp = (unsigned char *) _alloca((length + 2) * sizeof (unsigned char)); +#endif + + if (length > 89) { + strcpy(symbol->errtxt, "309: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "310: Invalid characters in data"); + return error_number; + } + + ustrcpy(temp, (unsigned char *) ""); + /* Input must be an even number of characters for Interlaced 2 of 5 to work: + if an odd number of characters has been entered then add a leading zero */ + if (length & 1) { + ustrcpy(temp, (unsigned char *) "0"); + length++; + } + strcat((char*) temp, (char*) source); + + /* start character */ + strcpy(dest, "1111"); + + for (i = 0; i < length; i += 2) { + /* look up the bars and the spaces and put them in two strings */ + strcpy(bars, ""); + lookup(NEON, C25InterTable, temp[i], bars); + strcpy(spaces, ""); + lookup(NEON, C25InterTable, temp[i + 1], spaces); + + /* then merge (interlace) the strings together */ + k = 0; + for (j = 0; j <= 4; j++) { + mixed[k] = bars[j]; + k++; + mixed[k] = spaces[j]; + k++; + } + mixed[k] = '\0'; + strcat(dest, mixed); + } + + /* Stop character */ + strcat(dest, "311"); + + expand(symbol, dest); + ustrcpy(symbol->text, temp); + return error_number; + +} + +/* Interleaved 2-of-5 (ITF) */ +int itf14(struct zint_symbol *symbol, unsigned char source[], int length) { + int i, error_number, zeroes; + unsigned int count; + char localstr[16]; + + count = 0; + + if (length > 13) { + strcpy(symbol->errtxt, "311: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "312: Invalid character in data"); + return error_number; + } + + /* Add leading zeros as required */ + zeroes = 13 - length; + for (i = 0; i < zeroes; i++) { + localstr[i] = '0'; + } + strcpy(localstr + zeroes, (char *) source); + + /* Calculate the check digit - the same method used for EAN-13 */ + for (i = 12; i >= 0; i--) { + count += ctoi(localstr[i]); + + if (!(i & 1)) { + count += 2 * ctoi(localstr[i]); + } + } + localstr[13] = check_digit(count); + localstr[14] = '\0'; + error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char*) localstr); + return error_number; +} + +/* Deutshe Post Leitcode */ +int dpleit(struct zint_symbol *symbol, unsigned char source[], int length) { + int i, error_number; + unsigned int count; + char localstr[16]; + int zeroes; + + count = 0; + if (length > 13) { + strcpy(symbol->errtxt, "313: Input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "314: Invalid characters in data"); + return error_number; + } + + zeroes = 13 - length; + for (i = 0; i < zeroes; i++) + localstr[i] = '0'; + strcpy(localstr + zeroes, (char *) source); + + for (i = 12; i >= 0; i--) { + count += 4 * ctoi(localstr[i]); + + if (i & 1) { + count += 5 * ctoi(localstr[i]); + } + } + localstr[13] = check_digit(count); + localstr[14] = '\0'; + error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char*) localstr); + return error_number; +} + +/* Deutsche Post Identcode */ +int dpident(struct zint_symbol *symbol, unsigned char source[], int length) { + int i, error_number, zeroes; + unsigned int count; + char localstr[16]; + + count = 0; + if (length > 11) { + strcpy(symbol->errtxt, "315: Input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "316: Invalid characters in data"); + return error_number; + } + + zeroes = 11 - length; + for (i = 0; i < zeroes; i++) + localstr[i] = '0'; + strcpy(localstr + zeroes, (char *) source); + + for (i = 10; i >= 0; i--) { + count += 4 * ctoi(localstr[i]); + + if (i & 1) { + count += 5 * ctoi(localstr[i]); + } + } + localstr[11] = check_digit(count); + localstr[12] = '\0'; + error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char*) localstr); + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/CMakeLists.txt b/3rdparty/zint-2.6.1/backend/CMakeLists.txt new file mode 100644 index 0000000..9de4127 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/CMakeLists.txt @@ -0,0 +1,31 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +project(zint) + +find_package(PNG) + +set(zint_COMMON_SRCS common.c library.c render.c large.c reedsol.c gs1.c eci.c) +set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c) +set(zint_POSTAL_SRCS postal.c auspost.c imail.c) +set(zint_TWODIM_SRCS code16k.c codablock.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c) +set(zint_OUTPUT_SRCS render.c ps.c svg.c emf.c bmp.c pcx.c gif.c png.c tif.c raster.c) +set(zint_SRCS ${zint_OUTPUT_SRCS} ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS}) + +if(PNG_FOUND) + include_directories( ${PNG_INCLUDES} ) +else(PNG_FOUND) + add_definitions (-DNO_PNG) +endif(PNG_FOUND) + +add_library(zint SHARED ${zint_SRCS}) + +set_target_properties(zint PROPERTIES SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}" + VERSION ${ZINT_VERSION}) + +if(PNG_FOUND) + target_link_libraries(zint ${PNG_LIBRARIES} ) +endif(PNG_FOUND) +target_link_libraries(zint -lm) + +install(TARGETS zint ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) diff --git a/3rdparty/zint-2.6.1/backend/DEVELOPER b/3rdparty/zint-2.6.1/backend/DEVELOPER new file mode 100644 index 0000000..478c78a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/DEVELOPER @@ -0,0 +1,133 @@ +Contents +-------- + +Here is a guide to which bit of source code does what. + +2of5.c: + Matrix 2 of 5 + Industrial 2 of 5 + IATA 2 of 5 + Data Logic + Interleaved 2 of 5 + ITF-14 + Deutche Post Leitcode + Deutche Post Identcode + +auspost.c: + Australia Post Standard Customer Barcode + Australia Post Customer Barcode 2 + Australia Post Customer Barcode 3 + Australia Post Reply Paid Barcode + Australia Post Routing Barcode + Australia Post Redirect Barcode + +aztec.c: + Aztec Code + Compact Aztec Code + Aztec Runes + +blockf.c: + Codablock-F + +code128.c: + Code 128 + Code 128 Subset B + NVE-18 + GS1-128 (UCC/EAN-128) + EAN-14 + +code16k.c: + Code 16k + +code.c: + Code 11 + Code 39 + Pharmazentral Nummer (PZN) + Extended Code 39 (Code 39+) + Code 93 + LOGMARS + Channel Code + +code1.c: + Code One + +code49.c: + Code 49 + +composite.c: + CC-A Composite Symbology + CC-B Composite Symbology + CC-C Composite Symbology + +dotcode.c: + Dot Code + +dm200.c: + Data Matrix ECC 200 + +gridmtx.c: + Grid Matrix + +hanxin.c: + Han Xin Code + +imail.c: + USPS OneCode (Intelligent Mail) + +maxicode.c: + UPS Maxicode + +medical.c: + Pharma Code + Two Track Pharma Code + Codabar + Code 32 + +pdf417.c: + PDF417 + Truncated PDF417 + MicroPDF417 + +plessey.c: + UK Plessey Code (bidirectional) + MSI Plessey + +postal.c: + PostNet + PLANET + Facing Identification Mark (FIM) + Royal Mail 4-State Country Code (RM4SCC) + KIX Code + DAFT Code + Flattermarken + Korean Postal Code + Japanese Postal Code + +qr.c: + QR Code + Micro QR Code + UPNQR + +rss.c: + GS1 DataBar (DataBar-14) (RSS-14) + GS1 DataBar Stacked (RSS-14 Stacked) + GS1 DataBar Stacked Omnidirectional (DataBar-14 Stacked Omnidirectional) + (RSS-14 Stacked Omnidirectional) + GS1 DataBar Limited (RSS Limited) + GS1 DataBar Expanded (RSS Expanded) + GS1 DataBar Expanded Stacked (RSS Expanded Stacked) + +telepen.c: + Telepen ASCII + Telepen Numeric + +upcean.c: + UPC-A + UPC-E + EAN-2 add-on + EAN-5 add-on + EAN-8 + EAN-13 + SBN (verification) + ISBN (verification) + ISBN-13 (verification) \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/LICENSE b/3rdparty/zint-2.6.1/backend/LICENSE new file mode 100644 index 0000000..723ef63 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/LICENSE @@ -0,0 +1,13 @@ +ZINT was originally developed by Robin Stuart and licensed under the terms of the GPL (Gnu +Public License). In 2013 Robin Stuart and all developers that contributed to the code agreed +to change the license to a less restrictive one (see ZINT mailing list of May 2013 for +related mails) under the following conditions: +- the names of original copyright holder Robin Stuart and contributors are not removed, + neither from sources nor from the manual +- the documentation is done in British English (as Robin said: "Oh, and please don't + replace the word "colour" with "color" in the documentation - that really annoys me!") + +Change to BSD-license is done for backend and therefore for ZINT shared library only, for +the frontends and Qt4-backend the GPL is still valid. Since BSD-license is GPL-compatible +this gives the possibility to include ZINT library in own products or link against it from +own software. diff --git a/3rdparty/zint-2.6.1/backend/auspost.c b/3rdparty/zint-2.6.1/backend/auspost.c new file mode 100644 index 0000000..35438a7 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/auspost.c @@ -0,0 +1,254 @@ +/* auspost.c - Handles Australia Post 4-State Barcode */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define GDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #" + +static const char *AusNTable[10] = { + "00", "01", "02", "10", "11", "12", "20", "21", "22", "30" +}; + +static const char *AusCTable[64] = { + "222", "300", "301", "302", "310", "311", "312", "320", "321", "322", + "000", "001", "002", "010", "011", "012", "020", "021", "022", "100", "101", "102", "110", + "111", "112", "120", "121", "122", "200", "201", "202", "210", "211", "212", "220", "221", + "023", "030", "031", "032", "033", "103", "113", "123", "130", "131", "132", "133", "203", + "213", "223", "230", "231", "232", "233", "303", "313", "323", "330", "331", "332", "333", + "003", "013" +}; + +static const char *AusBarTable[64] = { + "000", "001", "002", "003", "010", "011", "012", "013", "020", "021", + "022", "023", "030", "031", "032", "033", "100", "101", "102", "103", "110", "111", "112", + "113", "120", "121", "122", "123", "130", "131", "132", "133", "200", "201", "202", "203", + "210", "211", "212", "213", "220", "221", "222", "223", "230", "231", "232", "233", "300", + "301", "302", "303", "310", "311", "312", "313", "320", "321", "322", "323", "330", "331", + "332", "333" +}; + +#include +#include +#include +#include "common.h" +#include "reedsol.h" +#ifdef _MSC_VER +#define inline _inline +#endif + +static inline char convert_pattern(char data, int shift) { + return (data - '0') << shift; +} + +/* Adds Reed-Solomon error correction to auspost */ +void rs_error(char data_pattern[]) { + size_t reader, triple_writer = 0; + char triple[31], inv_triple[31]; + unsigned char result[5]; + + for (reader = 2; reader < strlen(data_pattern); reader += 3, triple_writer++) { + triple[triple_writer] = convert_pattern(data_pattern[reader], 4) + + convert_pattern(data_pattern[reader + 1], 2) + + convert_pattern(data_pattern[reader + 2], 0); + } + + for (reader = 0; reader < triple_writer; reader++) { + inv_triple[reader] = triple[(triple_writer - 1) - reader]; + } + + rs_init_gf(0x43); + rs_init_code(4, 1); + rs_encode(triple_writer, (unsigned char*) inv_triple, result); + + for (reader = 4; reader > 0; reader--) { + strcat(data_pattern, AusBarTable[(int) result[reader - 1]]); + } + rs_free(); +} + +/* Handles Australia Posts's 4 State Codes */ +int australia_post(struct zint_symbol *symbol, unsigned char source[], int length) { + /* Customer Standard Barcode, Barcode 2 or Barcode 3 system determined automatically + (i.e. the FCC doesn't need to be specified by the user) dependent + on the length of the input string */ + + /* The contents of data_pattern conform to the following standard: + 0 = Tracker, Ascender and Descender + 1 = Tracker and Ascender + 2 = Tracker and Descender + 3 = Tracker only */ + int error_number, zeroes; + int writer; + unsigned int loopey, reader; + size_t h; + + char data_pattern[200]; + char fcc[3] = {0, 0, 0}, dpid[10]; + char localstr[30]; + + error_number = 0; + strcpy(localstr, ""); + + /* Do all of the length checking first to avoid stack smashing */ + if (symbol->symbology == BARCODE_AUSPOST) { + /* Format control code (FCC) */ + switch (length) { + case 8: + strcpy(fcc, "11"); + break; + case 13: + strcpy(fcc, "59"); + break; + case 16: + strcpy(fcc, "59"); + error_number = is_sane(NEON, source, length); + break; + case 18: + strcpy(fcc, "62"); + break; + case 23: + strcpy(fcc, "62"); + error_number = is_sane(NEON, source, length); + break; + default: + strcpy(symbol->errtxt, "401: Auspost input is wrong length"); + return ZINT_ERROR_TOO_LONG; + } + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "402: Invalid characters in data"); + return error_number; + } + } else { + if (length > 8) { + strcpy(symbol->errtxt, "403: Auspost input is too long"); + return ZINT_ERROR_TOO_LONG; + } + switch (symbol->symbology) { + case BARCODE_AUSREPLY: strcpy(fcc, "45"); + break; + case BARCODE_AUSROUTE: strcpy(fcc, "87"); + break; + case BARCODE_AUSREDIRECT: strcpy(fcc, "92"); + break; + } + + /* Add leading zeros as required */ + zeroes = 8 - length; + memset(localstr, '0', zeroes); + localstr[8] = '\0'; + } + + strcat(localstr, (char*) source); + h = strlen(localstr); + error_number = is_sane(GDSET, (unsigned char *) localstr, h); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "404: Invalid characters in data"); + return error_number; + } + + /* Verifiy that the first 8 characters are numbers */ + memcpy(dpid, localstr, 8); + dpid[8] = '\0'; + error_number = is_sane(NEON, (unsigned char *) dpid, strlen(dpid)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "405: Invalid characters in DPID"); + return error_number; + } + + /* Start character */ + strcpy(data_pattern, "13"); + + /* Encode the FCC */ + for (reader = 0; reader < 2; reader++) { + lookup(NEON, AusNTable, fcc[reader], data_pattern); + } + + /* printf("AUSPOST FCC: %s ", fcc); */ + + /* Delivery Point Identifier (DPID) */ + for (reader = 0; reader < 8; reader++) { + lookup(NEON, AusNTable, dpid[reader], data_pattern); + } + + /* Customer Information */ + if (h > 8) { + if ((h == 13) || (h == 18)) { + for (reader = 8; reader < h; reader++) { + lookup(GDSET, AusCTable, localstr[reader], data_pattern); + } + } else if ((h == 16) || (h == 23)) { + for (reader = 8; reader < h; reader++) { + lookup(NEON, AusNTable, localstr[reader], data_pattern); + } + } + } + + /* Filler bar */ + h = strlen(data_pattern); + switch (h) { + case 22: + case 37: + case 52: + strcat(data_pattern, "3"); + break; + default: + break; + } + + /* Reed Solomon error correction */ + rs_error(data_pattern); + + /* Stop character */ + strcat(data_pattern, "13"); + + /* Turn the symbol into a bar pattern ready for plotting */ + writer = 0; + h = strlen(data_pattern); + for (loopey = 0; loopey < h; loopey++) { + if ((data_pattern[loopey] == '1') || (data_pattern[loopey] == '0')) { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if ((data_pattern[loopey] == '2') || (data_pattern[loopey] == '0')) { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 3; + symbol->row_height[1] = 2; + symbol->row_height[2] = 3; + + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + diff --git a/3rdparty/zint-2.6.1/backend/aztec.c b/3rdparty/zint-2.6.1/backend/aztec.c new file mode 100644 index 0000000..9b17375 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/aztec.c @@ -0,0 +1,1681 @@ +/* aztec.c - Handles Aztec 2D Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "aztec.h" +#include "reedsol.h" + +static int AztecMap[22801]; + +static int count_doubles(const unsigned char source[], const int posn, const size_t src_len) { + int c = 0; + int i = posn; + int cond = 1; + + do { + if (((source[i] == '.') || (source[i] == ',')) && (source[i + 1] == ' ')) { + c++; + } else { + cond = 0; + } + i += 2; + } while ((i < src_len) && cond); + + return c; +} + +static int count_cr(char source[], int posn, int length) { + int c = 0; + int i = posn; + int cond = 1; + + do { + if (source[i] == 13) { + c++; + } else { + cond = 0; + } + i++; + } while ((i < length) && cond); + + return c; +} + +static int count_dotcomma(char source[], int posn, int length) { + int c = 0; + int i = posn; + int cond = 1; + + do { + if ((source[i] == '.') || (source[i] == ',')) { + c++; + } else { + cond = 0; + } + i++; + } while ((i < length) && cond); + + return c; +} + +static int count_spaces(char source[], int posn, int length) { + int c = 0; + int i = posn; + int cond = 1; + + do { + if (source[i] == ' ') { + c++; + } else { + cond = 0; + } + i++; + } while ((i < length) && cond); + + return c; +} + +static char get_next_mode(char encode_mode[], const size_t src_len, const int posn) { + int i = posn; + + do { + i++; + } while ((i < src_len) && (encode_mode[i] == encode_mode[posn])); + if (i >= src_len) { + return 'E'; + } else { + return encode_mode[i]; + } +} + +static int aztec_text_process(const unsigned char source[], const size_t src_len, char binary_string[], const int gs1, const int eci, const int debug) { + + char *encode_mode; + int i, j; + char current_mode; + int count; + char next_mode; + char *reduced_source; + char *reduced_encode_mode; + int reduced_length; + int byte_mode = 0; + + encode_mode=(char*)alloca(src_len); + reduced_source=(char*)alloca(src_len); + reduced_encode_mode=(char*)alloca(src_len); + + if ((!encode_mode) || + (!reduced_source) || + (!reduced_encode_mode)) return -1; + + for (i = 0; i < src_len; i++) { + if (source[i] > 128) { + encode_mode[i] = 'B'; + } else { + encode_mode[i] = AztecModes[(int) source[i]]; + } + } + + // Deal first with letter combinations which can be combined to one codeword + // Combinations are (CR LF) (. SP) (, SP) (: SP) in Punct mode + current_mode = 'U'; + for (i = 0; i < src_len - 1; i++) { + // Combination (CR LF) should always be in Punct mode + if ((source[i] == 13) && (source[i + 1] == 10)) { + encode_mode[i] = 'P'; + encode_mode[i + 1] = 'P'; + } + + // Combination (: SP) should always be in Punct mode + if ((source[i] == ':') && (source[i + 1] == ' ')) { + encode_mode[i + 1] = 'P'; + } + + // Combinations (. SP) and (, SP) sometimes use fewer bits in Digit mode + if (((source[i] == '.') || (source[i] == ',')) && (source[i + 1] == ' ') && (encode_mode[i] == 'X')) { + count = count_doubles(source, i, src_len); + next_mode = get_next_mode(encode_mode, src_len, i); + + if (current_mode == 'U') { + if ((next_mode == 'D') && (count <= 5)) { + for (j = 0; j < (2 * count); j++) { + encode_mode[i + j] = 'D'; + } + } + } + + if (current_mode == 'L') { + if ((next_mode == 'U') && (count == 1)) { + encode_mode[i] = 'D'; + encode_mode[i + 1] = 'D'; + } + if ((next_mode == 'D') && (count <= 4)) { + for (j = 0; j < (2 * count); j++) { + encode_mode[i + j] = 'D'; + } + } + } + + if (current_mode == 'M') { + if ((next_mode == 'D') && (count == 1)) { + encode_mode[i] = 'D'; + encode_mode[i + 1] = 'D'; + } + } + + if (current_mode == 'D') { + if ((next_mode != 'D') && (count <= 4)) { + for (j = 0; j < (2 * count); j++) { + encode_mode[i + j] = 'D'; + } + } + if ((next_mode == 'D') && (count <= 7)) { + for (j = 0; j < (2 * count); j++) { + encode_mode[i + j] = 'D'; + } + } + } + + // Default is Punct mode + if (encode_mode[i] == 'X') { + encode_mode[i] = 'P'; + encode_mode[i + 1] = 'P'; + } + } + + if ((encode_mode[i] != 'X') && (encode_mode[i] != 'B')) { + current_mode = encode_mode[i]; + } + } + + if (debug) { + printf("First Pass:\n"); + for (i = 0; i < src_len; i++) { + printf("%c", encode_mode[i]); + } + printf("\n"); + } + + // Reduce two letter combinations to one codeword marked as [abcd] in Punct mode + i = 0; + j = 0; + do { + if ((source[i] == 13) && (source[i + 1] == 10)) { // CR LF + reduced_source[j] = 'a'; + reduced_encode_mode[j] = encode_mode[i]; + i += 2; + } else if (((source[i] == '.') && (source[i + 1] == ' ')) && (encode_mode[i] == 'P')) { + reduced_source[j] = 'b'; + reduced_encode_mode[j] = encode_mode[i]; + i += 2; + } else if (((source[i] == ',') && (source[i + 1] == ' ')) && (encode_mode[i] == 'P')) { + reduced_source[j] = 'c'; + reduced_encode_mode[j] = encode_mode[i]; + i += 2; + } else if ((source[i] == ':') && (source[i + 1] == ' ')) { + reduced_source[j] = 'd'; + reduced_encode_mode[j] = encode_mode[i]; + i += 2; + } else { + reduced_source[j] = source[i]; + reduced_encode_mode[j] = encode_mode[i]; + i++; + } + j++; + } while (i < src_len); + + reduced_length = j; + + current_mode = 'U'; + for(i = 0; i < reduced_length; i++) { + + // Resolve Carriage Return (CR) which can be Punct or Mixed mode + if (reduced_source[i] == 13) { + count = count_cr(reduced_source, i, reduced_length); + next_mode = get_next_mode(reduced_encode_mode, reduced_length, i); + + if ((current_mode == 'U') && ((next_mode == 'U') || (next_mode == 'B')) && (count == 1)) { + reduced_encode_mode[i] = 'P'; + } + + if ((current_mode == 'L') && ((next_mode == 'L') || (next_mode == 'B')) && (count == 1)) { + reduced_encode_mode[i] = 'P'; + } + + if ((current_mode == 'P') || (next_mode == 'P')) { + reduced_encode_mode[i] = 'P'; + } + + if (current_mode == 'D') { + if (((next_mode == 'E') || (next_mode == 'U') || (next_mode == 'D') || (next_mode == 'B')) && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'P'; + } + } + if ((next_mode == 'L') && (count == 1)) { + reduced_encode_mode[i] = 'P'; + } + } + + // Default is Mixed mode + if (reduced_encode_mode[i] == 'X') { + reduced_encode_mode[i] = 'M'; + } + } + + // Resolve full stop and comma which can be in Punct or Digit mode + if ((reduced_source[i] == '.') || (reduced_source[i] == ',')) { + count = count_dotcomma(reduced_source, i, reduced_length); + next_mode = get_next_mode(reduced_encode_mode, reduced_length, i); + + if (current_mode == 'U') { + if (((next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M') || (next_mode == 'B')) && (count == 1)) { + reduced_encode_mode[i] = 'P'; + } + } + + if (current_mode == 'L') { + if ((next_mode == 'L') && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'P'; + } + } + if (((next_mode == 'M') || (next_mode == 'B')) && (count == 1)) { + reduced_encode_mode[i] = 'P'; + } + } + + if (current_mode == 'M') { + if (((next_mode == 'E') || (next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M')) && (count <= 4)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'P'; + } + } + if ((next_mode == 'B') && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'P'; + } + } + } + + if ((current_mode == 'P') && (next_mode != 'D') && (count <= 9)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'P'; + } + } + + // Default is Digit mode + if (reduced_encode_mode[i] == 'X') { + reduced_encode_mode[i] = 'D'; + } + } + + // Resolve Space (SP) which can be any mode except Punct + if (reduced_source[i] == ' ') { + count = count_spaces(reduced_source, i, reduced_length); + next_mode = get_next_mode(reduced_encode_mode, reduced_length, i); + + if (current_mode == 'U') { + if ((next_mode == 'E') && (count <= 5)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'U'; + } + } + if (((next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M') || (next_mode == 'P') || (next_mode == 'B')) && (count <= 9)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'U'; + } + } + } + + if (current_mode == 'L') { + if ((next_mode == 'E') && (count <= 5)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'L'; + } + } + if ((next_mode == 'U') && (count == 1)) { + reduced_encode_mode[i] = 'L'; + } + if ((next_mode == 'L') && (count <= 14)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'L'; + } + } + if (((next_mode == 'M') || (next_mode == 'P') || (next_mode == 'B')) && (count <= 9)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'L'; + } + } + } + + if (current_mode == 'M') { + if (((next_mode == 'E') || (next_mode == 'U')) && (count <= 9)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'M'; + } + } + + if (((next_mode == 'L') || (next_mode == 'B')) && (count <= 14)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'M'; + } + } + + if (((next_mode == 'M') || (next_mode == 'P')) && (count <= 19)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'M'; + } + } + } + + if (current_mode == 'P') { + if ((next_mode == 'E') && (count <= 5)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'U'; + } + } + + if (((next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M') || (next_mode == 'P') || (next_mode == 'B')) && (count <= 9)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'U'; + } + } + } + + // Default is Digit mode + if (reduced_encode_mode[i] == 'X') { + reduced_encode_mode[i] = 'D'; + } + } + + if (reduced_encode_mode[i] != 'B') { + current_mode = reduced_encode_mode[i]; + } + } + + // Decide when to use P/S instead of P/L and U/S instead of U/L + current_mode = 'U'; + for(i = 0; i < reduced_length; i++) { + + if (reduced_encode_mode[i] != current_mode) { + + for (count = 0; ((i + count) <= reduced_length) && (reduced_encode_mode[i + count] == reduced_encode_mode[i]); count++); + next_mode = get_next_mode(reduced_encode_mode, reduced_length, i); + + if (reduced_encode_mode[i] == 'P') { + if ((current_mode == 'U') && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'p'; + } + } + + if ((current_mode == 'L') && (next_mode != 'U') && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'p'; + } + } + + if ((current_mode == 'L') && (next_mode == 'U') && (count == 1)) { + reduced_encode_mode[i] = 'p'; + } + + if ((current_mode == 'M') && (next_mode != 'M') && (count == 1)) { + reduced_encode_mode[i] = 'p'; + } + + if ((current_mode == 'M') && (next_mode == 'M') && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'p'; + } + } + + if ((current_mode == 'D') && (next_mode != 'D') && (count <= 3)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'p'; + } + } + + if ((current_mode == 'D') && (next_mode == 'D') && (count <= 6)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'p'; + } + } + } + + if (reduced_encode_mode[i] == 'U') { + if ((current_mode == 'L') && ((next_mode == 'L') || (next_mode == 'M')) && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'u'; + } + } + + if ((current_mode == 'L') && ((next_mode == 'E') || (next_mode == 'D') || (next_mode == 'B') || (next_mode == 'P')) && (count == 1)) { + reduced_encode_mode[i] = 'u'; + } + + if ((current_mode == 'D') && (next_mode == 'D') && (count == 1)) { + reduced_encode_mode[i] = 'u'; + } + + if ((current_mode == 'D') && (next_mode == 'P') && (count <= 2)) { + for (j = 0; j < count; j++) { + reduced_encode_mode[i + j] = 'u'; + } + } + } + } + + if ((reduced_encode_mode[i] != 'p') && (reduced_encode_mode[i] != 'u') && (reduced_encode_mode[i] != 'B')) { + current_mode = reduced_encode_mode[i]; + } + } + + if (debug) { + for (i = 0; i < reduced_length; i++) { + printf("%c", reduced_source[i]); + } + printf("\n"); + for (i = 0; i < reduced_length; i++) { + printf("%c", reduced_encode_mode[i]); + } + printf("\n"); + } + + strcpy(binary_string, ""); + + if (gs1) { + bin_append(0, 5, binary_string); // P/S + bin_append(0, 5, binary_string); // FLG(n) + bin_append(0, 3, binary_string); // FLG(0) + } + + if (eci != 3) { + bin_append(0, 5, binary_string); // P/S + bin_append(0, 5, binary_string); // FLG(n) + if (eci < 10) { + bin_append(1, 3, binary_string); // FLG(1) + bin_append(2 + eci, 4, binary_string); + } + if ((eci >= 10) && (eci <= 99)) { + bin_append(2, 3, binary_string); // FLG(2) + bin_append(2 + (eci / 10), 4, binary_string); + bin_append(2 + (eci % 10), 4, binary_string); + } + if ((eci >= 100) && (eci <= 999)) { + bin_append(3, 3, binary_string); // FLG(3) + bin_append(2 + (eci / 100), 4, binary_string); + bin_append(2 + ((eci % 100) / 10), 4, binary_string); + bin_append(2 + (eci % 10), 4, binary_string); + } + if ((eci >= 1000) && (eci <= 9999)) { + bin_append(4, 3, binary_string); // FLG(4) + bin_append(2 + (eci / 1000), 4, binary_string); + bin_append(2 + ((eci % 1000) / 100), 4, binary_string); + bin_append(2 + ((eci % 100) / 10), 4, binary_string); + bin_append(2 + (eci % 10), 4, binary_string); + } + if ((eci >= 10000) && (eci <= 99999)) { + bin_append(5, 3, binary_string); // FLG(5) + bin_append(2 + (eci / 10000), 4, binary_string); + bin_append(2 + ((eci % 10000) / 1000), 4, binary_string); + bin_append(2 + ((eci % 1000) / 100), 4, binary_string); + bin_append(2 + ((eci % 100) / 10), 4, binary_string); + bin_append(2 + (eci % 10), 4, binary_string); + } + if (eci >= 100000) { + bin_append(6, 3, binary_string); // FLG(6) + bin_append(2 + (eci / 100000), 4, binary_string); + bin_append(2 + ((eci % 100000) / 10000), 4, binary_string); + bin_append(2 + ((eci % 10000) / 1000), 4, binary_string); + bin_append(2 + ((eci % 1000) / 100), 4, binary_string); + bin_append(2 + ((eci % 100) / 10), 4, binary_string); + bin_append(2 + (eci % 10), 4, binary_string); + } + } + + current_mode = 'U'; + for(i = 0; i < reduced_length; i++) { + if (reduced_encode_mode[i] != current_mode) { + // Change mode + if (current_mode == 'U') { + switch (reduced_encode_mode[i]) { + case 'L': + bin_append(28, 5, binary_string); // L/L + break; + case 'M': + bin_append(29, 5, binary_string); // M/L + break; + case 'P': + bin_append(29, 5, binary_string); // M/L + bin_append(30, 5, binary_string); // P/L + break; + case 'p': + bin_append(0, 5, binary_string); // P/S + break; + case 'D': + bin_append(30, 5, binary_string); // D/L + break; + case 'B': + bin_append(31, 5, binary_string); // B/S + break; + } + } + + if (current_mode == 'L') { + switch (reduced_encode_mode[i]) { + case 'U': + bin_append(30, 5, binary_string); // D/L + bin_append(14, 4, binary_string); // U/L + break; + case 'u': + bin_append(28, 5, binary_string); // U/S + break; + case 'M': + bin_append(29, 5, binary_string); // M/L + break; + case 'P': + bin_append(30, 5, binary_string); // P/L + break; + case 'p': + bin_append(0, 5, binary_string); // P/S + break; + case 'D': + bin_append(30, 5, binary_string); // D/L + break; + case 'B': + bin_append(31, 5, binary_string); // B/S + break; + } + } + + if (current_mode == 'M') { + switch (reduced_encode_mode[i]) { + case 'U': + bin_append(29, 5, binary_string); // U/L + break; + case 'L': + bin_append(28, 5, binary_string); // L/L + break; + case 'P': + bin_append(30, 5, binary_string); // P/L + break; + case 'p': + bin_append(0, 5, binary_string); // P/S + break; + case 'D': + bin_append(29, 5, binary_string); // U/L + bin_append(30, 5, binary_string); // D/L + break; + case 'B': + bin_append(31, 5, binary_string); // B/S + break; + } + } + + if (current_mode == 'P') { + switch (reduced_encode_mode[i]) { + case 'U': + bin_append(31, 5, binary_string); // U/L + break; + case 'L': + bin_append(31, 5, binary_string); // U/L + bin_append(28, 5, binary_string); // L/L + break; + case 'M': + bin_append(31, 5, binary_string); // U/L + bin_append(29, 5, binary_string); // M/L + break; + case 'D': + bin_append(31, 5, binary_string); // U/L + bin_append(30, 5, binary_string); // D/L + break; + case 'B': + bin_append(31, 5, binary_string); // U/L + current_mode = 'U'; + bin_append(31, 5, binary_string); // B/S + break; + } + } + + if (current_mode == 'D') { + switch (reduced_encode_mode[i]) { + case 'U': + bin_append(14, 4, binary_string); // U/L + break; + case 'u': + bin_append(15, 4, binary_string); // U/S + break; + case 'L': + bin_append(14, 4, binary_string); // U/L + bin_append(28, 5, binary_string); // L/L + break; + case 'M': + bin_append(14, 4, binary_string); // U/L + bin_append(29, 5, binary_string); // M/L + break; + case 'P': + bin_append(14, 4, binary_string); // U/L + bin_append(29, 5, binary_string); // M/L + bin_append(30, 5, binary_string); // P/L + break; + case 'p': + bin_append(0, 4, binary_string); // P/S + break; + case 'B': + bin_append(14, 4, binary_string); // U/L + current_mode = 'U'; + bin_append(31, 5, binary_string); // B/S + break; + } + } + + // Byte mode length descriptor + if ((reduced_encode_mode[i] == 'B') && (!byte_mode)) { + for (count = 0; ((i + count) < reduced_length) && (reduced_encode_mode[i] == 'B'); count++); + + if (count > 2079) { + return ZINT_ERROR_TOO_LONG; + } + + if (count > 31) { + /* Put 00000 followed by 11-bit number of bytes less 31 */ + bin_append(0, 5, binary_string); + bin_append(count - 31, 11, binary_string); + } else { + /* Put 5-bit number of bytes */ + bin_append(count, 5, binary_string); + } + byte_mode = 1; + } + + if ((reduced_encode_mode[i] != 'B') && byte_mode) { + byte_mode = 0; + } + + if ((reduced_encode_mode[i] != 'B') && (reduced_encode_mode[i] != 'u') && (reduced_encode_mode[i] != 'p')) { + current_mode = reduced_encode_mode[i]; + } + } + + if ((reduced_encode_mode[i] == 'U') || (reduced_encode_mode[i] == 'u')) { + if (reduced_source[i] == ' ') { + bin_append(1, 5, binary_string); // SP + } else { + bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string); + } + } + + if (reduced_encode_mode[i] == 'L') { + if (reduced_source[i] == ' ') { + bin_append(1, 5, binary_string); // SP + } else { + bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string); + } + } + + if (reduced_encode_mode[i] == 'M') { + if (reduced_source[i] == ' ') { + bin_append(1, 5, binary_string); // SP + } else if (reduced_source[i] == 13) { + bin_append(14, 5, binary_string); // CR + } else { + bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string); + } + } + + if ((reduced_encode_mode[i] == 'P') || (reduced_encode_mode[i] == 'p')) { + if (gs1 && (reduced_source[i] == '[')) { + bin_append(0, 5, binary_string); // FLG(0) = FNC1 + } else if (reduced_source[i] == 13) { + bin_append(1, 5, binary_string); // CR + } else if (reduced_source[i] == 'a') { + bin_append(2, 5, binary_string); // CR LF + } else if (reduced_source[i] == 'b') { + bin_append(3, 5, binary_string); // . SP + } else if (reduced_source[i] == 'c') { + bin_append(4, 5, binary_string); // , SP + } else if (reduced_source[i] == 'd') { + bin_append(5, 5, binary_string); // : SP + } else if (reduced_source[i] == ',') { + bin_append(17, 5, binary_string); // Comma + } else if (reduced_source[i] == '.') { + bin_append(19, 5, binary_string); // Full stop + } else { + bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string); + } + } + + if (reduced_encode_mode[i] == 'D') { + if (reduced_source[i] == ' ') { + bin_append(1, 4, binary_string); // SP + } else if (reduced_source[i] == ',') { + bin_append(12, 4, binary_string); // Comma + } else if (reduced_source[i] == '.') { + bin_append(13, 4, binary_string); // Full stop + } else { + bin_append(AztecSymbolChar[(int) reduced_source[i]], 4, binary_string); + } + } + + if (reduced_encode_mode[i] == 'B') { + bin_append(reduced_source[i], 8, binary_string); + } + } + + if (debug) { + printf("Binary String:\n"); + printf("%s\n", binary_string); + } + + return 0; +} + +/* Prevent data from obscuring reference grid */ +static int avoidReferenceGrid(int output) { + + if (output > 10) { + output++; + } + if (output > 26) { + output++; + } + if (output > 42) { + output++; + } + if (output > 58) { + output++; + } + if (output > 74) { + output++; + } + if (output > 90) { + output++; + } + if (output > 106) { + output++; + } + if (output > 122) { + output++; + } + if (output > 138) { + output++; + } + + return output; +} + +/* Calculate the position of the bits in the grid */ +static void populate_map() { + int layer, start, length, n, i; + int x, y; + + for (x = 0; x < 151; x++) { + for (y = 0; y < 151; y++) { + AztecMap[(x * 151) + y] = 0; + } + } + + for (layer = 1; layer < 33; layer++) { + start = (112 * (layer - 1)) + (16 * (layer - 1) * (layer - 1)) + 2; + length = 28 + ((layer - 1) * 4) + (layer * 4); + /* Top */ + i = 0; + x = 64 - ((layer - 1) * 2); + y = 63 - ((layer - 1) * 2); + for (n = start; n < (start + length); n += 2) { + AztecMap[(avoidReferenceGrid(x + i) * 151) + avoidReferenceGrid(y)] = n; + AztecMap[(avoidReferenceGrid(x + i) * 151) + avoidReferenceGrid(y - 1)] = n + 1; + i++; + } + /* Right */ + i = 0; + x = 78 + ((layer - 1) * 2); + y = 64 - ((layer - 1) * 2); + for (n = start + length; n < (start + (length * 2)); n += 2) { + AztecMap[(avoidReferenceGrid(x) * 151) + avoidReferenceGrid(y + i)] = n; + AztecMap[(avoidReferenceGrid(x + 1) * 151) + avoidReferenceGrid(y + i)] = n + 1; + i++; + } + /* Bottom */ + i = 0; + x = 77 + ((layer - 1) * 2); + y = 78 + ((layer - 1) * 2); + for (n = start + (length * 2); n < (start + (length * 3)); n += 2) { + AztecMap[(avoidReferenceGrid(x - i) * 151) + avoidReferenceGrid(y)] = n; + AztecMap[(avoidReferenceGrid(x - i) * 151) + avoidReferenceGrid(y + 1)] = n + 1; + i++; + } + /* Left */ + i = 0; + x = 63 - ((layer - 1) * 2); + y = 77 + ((layer - 1) * 2); + for (n = start + (length * 3); n < (start + (length * 4)); n += 2) { + AztecMap[(avoidReferenceGrid(x) * 151) + avoidReferenceGrid(y - i)] = n; + AztecMap[(avoidReferenceGrid(x - 1) * 151) + avoidReferenceGrid(y - i)] = n + 1; + i++; + } + } + + /* Central finder pattern */ + for (y = 69; y <= 81; y++) { + for (x = 69; x <= 81; x++) { + AztecMap[(x * 151) + y] = 1; + } + } + for (y = 70; y <= 80; y++) { + for (x = 70; x <= 80; x++) { + AztecMap[(x * 151) + y] = 0; + } + } + for (y = 71; y <= 79; y++) { + for (x = 71; x <= 79; x++) { + AztecMap[(x * 151) + y] = 1; + } + } + for (y = 72; y <= 78; y++) { + for (x = 72; x <= 78; x++) { + AztecMap[(x * 151) + y] = 0; + } + } + for (y = 73; y <= 77; y++) { + for (x = 73; x <= 77; x++) { + AztecMap[(x * 151) + y] = 1; + } + } + for (y = 74; y <= 76; y++) { + for (x = 74; x <= 76; x++) { + AztecMap[(x * 151) + y] = 0; + } + } + + /* Guide bars */ + for (y = 11; y < 151; y += 16) { + for (x = 1; x < 151; x += 2) { + AztecMap[(x * 151) + y] = 1; + AztecMap[(y * 151) + x] = 1; + } + } + + /* Descriptor */ + for (i = 0; i < 10; i++) { + /* Top */ + AztecMap[(avoidReferenceGrid(66 + i) * 151) + avoidReferenceGrid(64)] = 20000 + i; + } + for (i = 0; i < 10; i++) { + /* Right */ + AztecMap[(avoidReferenceGrid(77) * 151) + avoidReferenceGrid(66 + i)] = 20010 + i; + } + for (i = 0; i < 10; i++) { + /* Bottom */ + AztecMap[(avoidReferenceGrid(75 - i) * 151) + avoidReferenceGrid(77)] = 20020 + i; + } + for (i = 0; i < 10; i++) { + /* Left */ + AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(75 - i)] = 20030 + i; + } + + /* Orientation */ + AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(64)] = 1; + AztecMap[(avoidReferenceGrid(65) * 151) + avoidReferenceGrid(64)] = 1; + AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(65)] = 1; + AztecMap[(avoidReferenceGrid(77) * 151) + avoidReferenceGrid(64)] = 1; + AztecMap[(avoidReferenceGrid(77) * 151) + avoidReferenceGrid(65)] = 1; + AztecMap[(avoidReferenceGrid(77) * 151) + avoidReferenceGrid(76)] = 1; +} + +int aztec(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + int x, y, i, j, p, data_blocks, ecc_blocks, layers, total_bits; + char binary_string[20000], bit_pattern[20045], descriptor[42]; + char adjusted_string[20000]; + unsigned char desc_data[4], desc_ecc[6]; + int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length; + int remainder, padbits, count, gs1, adjustment_size; + int debug = symbol->debug, reader = 0; + int comp_loop = 4; + +#ifdef _MSC_VER + unsigned int* data_part; + unsigned int* ecc_part; +#endif + + memset(binary_string, 0, 20000); + memset(adjusted_string, 0, 20000); + + if (symbol->input_mode == GS1_MODE) { + gs1 = 1; + } else { + gs1 = 0; + } + if (symbol->output_options & READER_INIT) { + reader = 1; + comp_loop = 1; + } + if (gs1 && reader) { + strcpy(symbol->errtxt, "501: Cannot encode in GS1 and Reader Initialisation mode at the same time"); + return ZINT_ERROR_INVALID_OPTION; + } + + populate_map(); + + err_code = aztec_text_process(source, length, binary_string, gs1, symbol->eci, symbol->debug); + + if (err_code != 0) { + strcpy(symbol->errtxt, "502: Input too long or too many extended ASCII characters"); + return err_code; + } + + if (!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) { + strcpy(symbol->errtxt, "503: Invalid error correction level - using default instead"); + err_code = ZINT_WARN_INVALID_OPTION; + symbol->option_1 = -1; + } + + ecc_level = symbol->option_1; + + if ((ecc_level == -1) || (ecc_level == 0)) { + ecc_level = 2; + } + + data_length = (int) strlen(binary_string); + + layers = 0; /* Keep compiler happy! */ + data_maxsize = 0; /* Keep compiler happy! */ + adjustment_size = 0; + if (symbol->option_2 == 0) { /* The size of the symbol can be determined by Zint */ + do { + /* Decide what size symbol to use - the smallest that fits the data */ + compact = 0; /* 1 = Aztec Compact, 0 = Normal Aztec */ + layers = 0; + + switch (ecc_level) { + /* For each level of error correction work out the smallest symbol which + the data will fit in */ + case 1: for (i = 32; i > 0; i--) { + if ((data_length + adjustment_size) < Aztec10DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec10DataSizes[i - 1]; + } + } + for (i = comp_loop; i > 0; i--) { + if ((data_length + adjustment_size) < AztecCompact10DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact10DataSizes[i - 1]; + } + } + break; + case 2: for (i = 32; i > 0; i--) { + if ((data_length + adjustment_size) < Aztec23DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec23DataSizes[i - 1]; + } + } + for (i = comp_loop; i > 0; i--) { + if ((data_length + adjustment_size) < AztecCompact23DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact23DataSizes[i - 1]; + } + } + break; + case 3: for (i = 32; i > 0; i--) { + if ((data_length + adjustment_size) < Aztec36DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec36DataSizes[i - 1]; + } + } + for (i = comp_loop; i > 0; i--) { + if ((data_length + adjustment_size) < AztecCompact36DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact36DataSizes[i - 1]; + } + } + break; + case 4: for (i = 32; i > 0; i--) { + if ((data_length + adjustment_size) < Aztec50DataSizes[i - 1]) { + layers = i; + compact = 0; + data_maxsize = Aztec50DataSizes[i - 1]; + } + } + for (i = comp_loop; i > 0; i--) { + if ((data_length + adjustment_size) < AztecCompact50DataSizes[i - 1]) { + layers = i; + compact = 1; + data_maxsize = AztecCompact50DataSizes[i - 1]; + } + } + break; + } + + if (layers == 0) { /* Couldn't find a symbol which fits the data */ + strcpy(symbol->errtxt, "504: Input too long (too many bits for selected ECC)"); + return ZINT_ERROR_TOO_LONG; + } + + /* Determine codeword bitlength - Table 3 */ + codeword_size = 6; /* if (layers <= 2) */ + if ((layers >= 3) && (layers <= 8)) { + codeword_size = 8; + } + if ((layers >= 9) && (layers <= 22)) { + codeword_size = 10; + } + if (layers >= 23) { + codeword_size = 12; + } + + j = 0; + i = 0; + do { + if ((j + 1) % codeword_size == 0) { + /* Last bit of codeword */ + int t, done = 0; + count = 0; + + /* Discover how many '1's in current codeword */ + for (t = 0; t < (codeword_size - 1); t++) { + if (binary_string[(i - (codeword_size - 1)) + t] == '1') count++; + } + + if (count == (codeword_size - 1)) { + adjusted_string[j] = '0'; + j++; + done = 1; + } + + if (count == 0) { + adjusted_string[j] = '1'; + j++; + done = 1; + } + + if (done == 0) { + adjusted_string[j] = binary_string[i]; + j++; + i++; + } + } + adjusted_string[j] = binary_string[i]; + j++; + i++; + } while (i <= (data_length + 1)); + adjusted_string[j] = '\0'; + adjusted_length = (int) strlen(adjusted_string); + adjustment_size = adjusted_length - data_length; + + /* Add padding */ + remainder = adjusted_length % codeword_size; + + padbits = codeword_size - remainder; + if (padbits == codeword_size) { + padbits = 0; + } + + for (i = 0; i < padbits; i++) { + strcat(adjusted_string, "1"); + } + adjusted_length = (int) strlen(adjusted_string); + + count = 0; + for (i = (adjusted_length - codeword_size); i < adjusted_length; i++) { + if (adjusted_string[i] == '1') { + count++; + } + } + if (count == codeword_size) { + adjusted_string[adjusted_length - 1] = '0'; + } + + if (debug) { + printf("Codewords:\n"); + for (i = 0; i < (adjusted_length / codeword_size); i++) { + for (j = 0; j < codeword_size; j++) { + printf("%c", adjusted_string[(i * codeword_size) + j]); + } + printf("\n"); + } + } + + } while (adjusted_length > data_maxsize); + /* This loop will only repeat on the rare occasions when the rule about not having all 1s or all 0s + means that the binary string has had to be lengthened beyond the maximum number of bits that can + be encoded in a symbol of the selected size */ + + } else { /* The size of the symbol has been specified by the user */ + if ((reader == 1) && ((symbol->option_2 >= 2) && (symbol->option_2 <= 4))) { + symbol->option_2 = 5; + } + if ((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) { + compact = 1; + layers = symbol->option_2; + } + if ((symbol->option_2 >= 5) && (symbol->option_2 <= 36)) { + compact = 0; + layers = symbol->option_2 - 4; + } + if ((symbol->option_2 < 0) || (symbol->option_2 > 36)) { + strcpy(symbol->errtxt, "510: Invalid Aztec Code size"); + return ZINT_ERROR_INVALID_OPTION; + } + + /* Determine codeword bitlength - Table 3 */ + if ((layers >= 0) && (layers <= 2)) { + codeword_size = 6; + } + if ((layers >= 3) && (layers <= 8)) { + codeword_size = 8; + } + if ((layers >= 9) && (layers <= 22)) { + codeword_size = 10; + } + if (layers >= 23) { + codeword_size = 12; + } + + j = 0; + i = 0; + do { + if ((j + 1) % codeword_size == 0) { + /* Last bit of codeword */ + int t, done = 0; + count = 0; + + /* Discover how many '1's in current codeword */ + for (t = 0; t < (codeword_size - 1); t++) { + if (binary_string[(i - (codeword_size - 1)) + t] == '1') count++; + } + + if (count == (codeword_size - 1)) { + adjusted_string[j] = '0'; + j++; + done = 1; + } + + if (count == 0) { + adjusted_string[j] = '1'; + j++; + done = 1; + } + + if (done == 0) { + adjusted_string[j] = binary_string[i]; + j++; + i++; + } + } + adjusted_string[j] = binary_string[i]; + j++; + i++; + } while (i <= (data_length + 1)); + adjusted_string[j] = '\0'; + adjusted_length = (int) strlen(adjusted_string); + + remainder = adjusted_length % codeword_size; + + padbits = codeword_size - remainder; + if (padbits == codeword_size) { + padbits = 0; + } + + for (i = 0; i < padbits; i++) { + strcat(adjusted_string, "1"); + } + adjusted_length = (int) strlen(adjusted_string); + + count = 0; + for (i = (adjusted_length - codeword_size); i < adjusted_length; i++) { + if (adjusted_string[i] == '1') { + count++; + } + } + if (count == codeword_size) { + adjusted_string[adjusted_length - 1] = '0'; + } + + /* Check if the data actually fits into the selected symbol size */ + if (compact) { + data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3); + } else { + data_maxsize = codeword_size * (AztecSizes[layers - 1] - 3); + } + + if (adjusted_length > data_maxsize) { + strcpy(symbol->errtxt, "505: Data too long for specified Aztec Code symbol size"); + return ZINT_ERROR_TOO_LONG; + } + + if (debug) { + printf("Codewords:\n"); + for (i = 0; i < (adjusted_length / codeword_size); i++) { + for (j = 0; j < codeword_size; j++) { + printf("%c", adjusted_string[(i * codeword_size) + j]); + } + printf("\n"); + } + } + + } + + if (reader && (layers > 22)) { + strcpy(symbol->errtxt, "506: Data too long for reader initialisation symbol"); + return ZINT_ERROR_TOO_LONG; + } + + data_blocks = adjusted_length / codeword_size; + + if (compact) { + ecc_blocks = AztecCompactSizes[layers - 1] - data_blocks; + } else { + ecc_blocks = AztecSizes[layers - 1] - data_blocks; + } + + if (debug) { + printf("Generating a "); + if (compact) { + printf("compact"); + } else { + printf("full-size"); + } + printf(" symbol with %d layers\n", layers); + printf("Requires "); + if (compact) { + printf("%d", AztecCompactSizes[layers - 1]); + } else { + printf("%d", AztecSizes[layers - 1]); + } + printf(" codewords of %d-bits\n", codeword_size); + printf(" (%d data words, %d ecc words)\n", data_blocks, ecc_blocks); + } + +#ifndef _MSC_VER + unsigned int data_part[data_blocks + 3], ecc_part[ecc_blocks + 3]; +#else + data_part = (unsigned int*) _alloca((data_blocks + 3) * sizeof (unsigned int)); + ecc_part = (unsigned int*) _alloca((ecc_blocks + 3) * sizeof (unsigned int)); +#endif + /* Copy across data into separate integers */ + memset(data_part, 0, (data_blocks + 2) * sizeof (int)); + memset(ecc_part, 0, (ecc_blocks + 2) * sizeof (int)); + + /* Split into codewords and calculate reed-solomon error correction codes */ + for (i = 0; i < data_blocks; i++) { + for (p = 0; p < codeword_size; p++) { + if (adjusted_string[i * codeword_size + p] == '1') { + data_part[i] += 0x01 << (codeword_size - (p + 1)); + } + } + } + + switch (codeword_size) { + case 6: + rs_init_gf(0x43); + break; + case 8: + rs_init_gf(0x12d); + break; + case 10: + rs_init_gf(0x409); + break; + case 12: + rs_init_gf(0x1069); + break; + } + + rs_init_code(ecc_blocks, 1); + rs_encode_long(data_blocks, data_part, ecc_part); + for (i = (ecc_blocks - 1); i >= 0; i--) { + bin_append(ecc_part[i], codeword_size, adjusted_string); + } + rs_free(); + + /* Invert the data so that actual data is on the outside and reed-solomon on the inside */ + memset(bit_pattern, '0', 20045); + + total_bits = (data_blocks + ecc_blocks) * codeword_size; + for (i = 0; i < total_bits; i++) { + bit_pattern[i] = adjusted_string[total_bits - i - 1]; + } + + /* Now add the symbol descriptor */ + memset(desc_data, 0, 4); + memset(desc_ecc, 0, 6); + memset(descriptor, 0, 42); + + if (compact) { + /* The first 2 bits represent the number of layers minus 1 */ + if ((layers - 1) & 0x02) { + descriptor[0] = '1'; + } else { + descriptor[0] = '0'; + } + if ((layers - 1) & 0x01) { + descriptor[1] = '1'; + } else { + descriptor[1] = '0'; + } + /* The next 6 bits represent the number of data blocks minus 1 */ + if (reader) { + descriptor[2] = '1'; + } else { + if ((data_blocks - 1) & 0x20) { + descriptor[2] = '1'; + } else { + descriptor[2] = '0'; + } + } + + for (i = 3; i < 8; i++) { + if ((data_blocks - 1) & (0x10 >> (i - 3))) { + descriptor[i] = '1'; + } else { + descriptor[i] = '0'; + } + } + + descriptor[8] = '\0'; + if (debug) printf("Mode Message = %s\n", descriptor); + } else { + /* The first 5 bits represent the number of layers minus 1 */ + for (i = 0; i < 5; i++) { + if ((layers - 1) & (0x10 >> i)) { + descriptor[i] = '1'; + } else { + descriptor[i] = '0'; + } + } + + /* The next 11 bits represent the number of data blocks minus 1 */ + if (reader) { + descriptor[5] = '1'; + } else { + if ((data_blocks - 1) & 0x400) { + descriptor[5] = '1'; + } else { + descriptor[5] = '0'; + } + } + for (i = 6; i < 16; i++) { + if ((data_blocks - 1) & (0x200 >> (i - 6))) { + descriptor[i] = '1'; + } else { + descriptor[i] = '0'; + } + } + descriptor[16] = '\0'; + if (debug) printf("Mode Message = %s\n", descriptor); + } + + /* Split into 4-bit codewords */ + for (i = 0; i < 4; i++) { + if (descriptor[i * 4] == '1') { + desc_data[i] += 8; + } + if (descriptor[(i * 4) + 1] == '1') { + desc_data[i] += 4; + } + if (descriptor[(i * 4) + 2] == '1') { + desc_data[i] += 2; + } + if (descriptor[(i * 4) + 3] == '1') { + desc_data[i] += 1; + } + } + + /* Add reed-solomon error correction with Galois field GF(16) and prime modulus + x^4 + x + 1 (section 7.2.3)*/ + + rs_init_gf(0x13); + if (compact) { + rs_init_code(5, 1); + rs_encode(2, desc_data, desc_ecc); + for (i = 0; i < 5; i++) { + if (desc_ecc[4 - i] & 0x08) { + descriptor[(i * 4) + 8] = '1'; + } else { + descriptor[(i * 4) + 8] = '0'; + } + if (desc_ecc[4 - i] & 0x04) { + descriptor[(i * 4) + 9] = '1'; + } else { + descriptor[(i * 4) + 9] = '0'; + } + if (desc_ecc[4 - i] & 0x02) { + descriptor[(i * 4) + 10] = '1'; + } else { + descriptor[(i * 4) + 10] = '0'; + } + if (desc_ecc[4 - i] & 0x01) { + descriptor[(i * 4) + 11] = '1'; + } else { + descriptor[(i * 4) + 11] = '0'; + } + } + } else { + rs_init_code(6, 1); + rs_encode(4, desc_data, desc_ecc); + for (i = 0; i < 6; i++) { + if (desc_ecc[5 - i] & 0x08) { + descriptor[(i * 4) + 16] = '1'; + } else { + descriptor[(i * 4) + 16] = '0'; + } + if (desc_ecc[5 - i] & 0x04) { + descriptor[(i * 4) + 17] = '1'; + } else { + descriptor[(i * 4) + 17] = '0'; + } + if (desc_ecc[5 - i] & 0x02) { + descriptor[(i * 4) + 18] = '1'; + } else { + descriptor[(i * 4) + 18] = '0'; + } + if (desc_ecc[5 - i] & 0x01) { + descriptor[(i * 4) + 19] = '1'; + } else { + descriptor[(i * 4) + 19] = '0'; + } + } + } + rs_free(); + + /* Merge descriptor with the rest of the symbol */ + for (i = 0; i < 40; i++) { + if (compact) { + bit_pattern[2000 + i - 2] = descriptor[i]; + } else { + bit_pattern[20000 + i - 2] = descriptor[i]; + } + } + + /* Plot all of the data into the symbol in pre-defined spiral pattern */ + if (compact) { + + for (y = AztecCompactOffset[layers - 1]; y < (27 - AztecCompactOffset[layers - 1]); y++) { + for (x = AztecCompactOffset[layers - 1]; x < (27 - AztecCompactOffset[layers - 1]); x++) { + if (CompactAztecMap[(y * 27) + x] == 1) { + set_module(symbol, y - AztecCompactOffset[layers - 1], x - AztecCompactOffset[layers - 1]); + } + if (CompactAztecMap[(y * 27) + x] >= 2) { + if (bit_pattern[CompactAztecMap[(y * 27) + x] - 2] == '1') { + set_module(symbol, y - AztecCompactOffset[layers - 1], x - AztecCompactOffset[layers - 1]); + } + } + } + symbol->row_height[y - AztecCompactOffset[layers - 1]] = 1; + } + symbol->rows = 27 - (2 * AztecCompactOffset[layers - 1]); + symbol->width = 27 - (2 * AztecCompactOffset[layers - 1]); + } else { + + for (y = AztecOffset[layers - 1]; y < (151 - AztecOffset[layers - 1]); y++) { + for (x = AztecOffset[layers - 1]; x < (151 - AztecOffset[layers - 1]); x++) { + if (AztecMap[(y * 151) + x] == 1) { + set_module(symbol, y - AztecOffset[layers - 1], x - AztecOffset[layers - 1]); + } + if (AztecMap[(y * 151) + x] >= 2) { + if (bit_pattern[AztecMap[(y * 151) + x] - 2] == '1') { + set_module(symbol, y - AztecOffset[layers - 1], x - AztecOffset[layers - 1]); + } + } + } + symbol->row_height[y - AztecOffset[layers - 1]] = 1; + } + symbol->rows = 151 - (2 * AztecOffset[layers - 1]); + symbol->width = 151 - (2 * AztecOffset[layers - 1]); + } + + return err_code; +} + +/* Encodes Aztec runes as specified in ISO/IEC 24778:2008 Annex A */ +int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length) { + int input_value, error_number, i, y, x; + char binary_string[28]; + unsigned char data_codewords[3], ecc_codewords[6]; + + error_number = 0; + input_value = 0; + if (length > 3) { + strcpy(symbol->errtxt, "507: Input too large"); + return ZINT_ERROR_INVALID_DATA; + } + error_number = is_sane(NEON, source, length); + if (error_number != 0) { + strcpy(symbol->errtxt, "508: Invalid characters in input"); + return ZINT_ERROR_INVALID_DATA; + } + switch (length) { + case 3: input_value = 100 * ctoi(source[0]); + input_value += 10 * ctoi(source[1]); + input_value += ctoi(source[2]); + break; + case 2: input_value = 10 * ctoi(source[0]); + input_value += ctoi(source[1]); + break; + case 1: input_value = ctoi(source[0]); + break; + } + + if (input_value > 255) { + strcpy(symbol->errtxt, "509: Input too large"); + return ZINT_ERROR_INVALID_DATA; + } + + strcpy(binary_string, ""); + bin_append(input_value, 8, binary_string); + + data_codewords[0] = 0; + data_codewords[1] = 0; + + for (i = 0; i < 2; i++) { + if (binary_string[i * 4] == '1') { + data_codewords[i] += 8; + } + if (binary_string[(i * 4) + 1] == '1') { + data_codewords[i] += 4; + } + if (binary_string[(i * 4) + 2] == '1') { + data_codewords[i] += 2; + } + if (binary_string[(i * 4) + 3] == '1') { + data_codewords[i] += 1; + } + } + + rs_init_gf(0x13); + rs_init_code(5, 1); + rs_encode(2, data_codewords, ecc_codewords); + rs_free(); + + strcpy(binary_string, ""); + + for (i = 0; i < 5; i++) { + if (ecc_codewords[4 - i] & 0x08) { + binary_string[(i * 4) + 8] = '1'; + } else { + binary_string[(i * 4) + 8] = '0'; + } + if (ecc_codewords[4 - i] & 0x04) { + binary_string[(i * 4) + 9] = '1'; + } else { + binary_string[(i * 4) + 9] = '0'; + } + if (ecc_codewords[4 - i] & 0x02) { + binary_string[(i * 4) + 10] = '1'; + } else { + binary_string[(i * 4) + 10] = '0'; + } + if (ecc_codewords[4 - i] & 0x01) { + binary_string[(i * 4) + 11] = '1'; + } else { + binary_string[(i * 4) + 11] = '0'; + } + } + + for (i = 0; i < 28; i += 2) { + if (binary_string[i] == '1') { + binary_string[i] = '0'; + } else { + binary_string[i] = '1'; + } + } + + for (y = 8; y < 19; y++) { + for (x = 8; x < 19; x++) { + if (CompactAztecMap[(y * 27) + x] == 1) { + set_module(symbol, y - 8, x - 8); + } + if (CompactAztecMap[(y * 27) + x] >= 2) { + if (binary_string[CompactAztecMap[(y * 27) + x] - 2000] == '1') { + set_module(symbol, y - 8, x - 8); + } + } + } + symbol->row_height[y - 8] = 1; + } + symbol->rows = 11; + symbol->width = 11; + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/aztec.h b/3rdparty/zint-2.6.1/backend/aztec.h new file mode 100644 index 0000000..8760568 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/aztec.h @@ -0,0 +1,145 @@ +/* aztec.c - Handles Aztec Mesa 2D Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define UPPER 1 +#define LOWER 2 +#define MIXED 4 +#define PUNC 8 +#define DIGIT 16 +#define BINARY 32 + +static const unsigned short int CompactAztecMap[] = { + /* 27 x 27 data grid */ + 609, 608, 411, 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457, 459, + 607, 606, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428, 430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454, 456, 458, + 605, 604, 409, 408, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 460, 461, + 603, 602, 407, 406, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 462, 463, + 601, 600, 405, 404, 241, 240, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 284, 285, 464, 465, + 599, 598, 403, 402, 239, 238, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 286, 287, 466, 467, + 597, 596, 401, 400, 237, 236, 105, 104, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 140, 141, 288, 289, 468, 469, + 595, 594, 399, 398, 235, 234, 103, 102, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 142, 143, 290, 291, 470, 471, + 593, 592, 397, 396, 233, 232, 101, 100, 1, 1, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 0, 1, 28, 29, 144, 145, 292, 293, 472, 473, + 591, 590, 395, 394, 231, 230, 99, 98, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 30, 31, 146, 147, 294, 295, 474, 475, + 589, 588, 393, 392, 229, 228, 97, 96, 2027, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2007, 32, 33, 148, 149, 296, 297, 476, 477, + 587, 586, 391, 390, 227, 226, 95, 94, 2026, 1, 0, 1, 1, 1, 1, 1, 0, 1, 2008, 34, 35, 150, 151, 298, 299, 478, 479, + 585, 584, 389, 388, 225, 224, 93, 92, 2025, 1, 0, 1, 0, 0, 0, 1, 0, 1, 2009, 36, 37, 152, 153, 300, 301, 480, 481, + 583, 582, 387, 386, 223, 222, 91, 90, 2024, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2010, 38, 39, 154, 155, 302, 303, 482, 483, + 581, 580, 385, 384, 221, 220, 89, 88, 2023, 1, 0, 1, 0, 0, 0, 1, 0, 1, 2011, 40, 41, 156, 157, 304, 305, 484, 485, + 579, 578, 383, 382, 219, 218, 87, 86, 2022, 1, 0, 1, 1, 1, 1, 1, 0, 1, 2012, 42, 43, 158, 159, 306, 307, 486, 487, + 577, 576, 381, 380, 217, 216, 85, 84, 2021, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2013, 44, 45, 160, 161, 308, 309, 488, 489, + 575, 574, 379, 378, 215, 214, 83, 82, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 47, 162, 163, 310, 311, 490, 491, + 573, 572, 377, 376, 213, 212, 81, 80, 0, 0, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 0, 0, 48, 49, 164, 165, 312, 313, 492, 493, + 571, 570, 375, 374, 211, 210, 78, 76, 74, 72, 70, 68, 66, 64, 62, 60, 58, 56, 54, 50, 51, 166, 167, 314, 315, 494, 495, + 569, 568, 373, 372, 209, 208, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59, 57, 55, 52, 53, 168, 169, 316, 317, 496, 497, + 567, 566, 371, 370, 206, 204, 202, 200, 198, 196, 194, 192, 190, 188, 186, 184, 182, 180, 178, 176, 174, 170, 171, 318, 319, 498, 499, + 565, 564, 369, 368, 207, 205, 203, 201, 199, 197, 195, 193, 191, 189, 187, 185, 183, 181, 179, 177, 175, 172, 173, 320, 321, 500, 501, + 563, 562, 366, 364, 362, 360, 358, 356, 354, 352, 350, 348, 346, 344, 342, 340, 338, 336, 334, 332, 330, 328, 326, 322, 323, 502, 503, + 561, 560, 367, 365, 363, 361, 359, 357, 355, 353, 351, 349, 347, 345, 343, 341, 339, 337, 335, 333, 331, 329, 327, 324, 325, 504, 505, + 558, 556, 554, 552, 550, 548, 546, 544, 542, 540, 538, 536, 534, 532, 530, 528, 526, 524, 522, 520, 518, 516, 514, 512, 510, 506, 507, + 559, 557, 555, 553, 551, 549, 547, 545, 543, 541, 539, 537, 535, 533, 531, 529, 527, 525, 523, 521, 519, 517, 515, 513, 511, 508, 509 +}; + +static const char AztecSymbolChar[128] = { + /* From Table 2 */ + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 15, 16, 17, 18, 19, 1, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 0, 18, 0, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 22, + 23, 24, 25, 26, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 21, 28, 22, 23, 24, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 29, 25, 30, 26, 27 +}; + +static const char AztecModes[129] = "BMMMMMMMMMMMMXBBBBBBBBBBBBBMMMMMXPPPPPPPPPPPXPXPDDDDDDDDDDPPPPPPMUUUUUUUUUUUUUUUUUUUUUUUUUUPMPMMMLLLLLLLLLLLLLLLLLLLLLLLLLLPMPMM"; + +static const unsigned short int AztecSizes[32] = { + /* Codewords per symbol */ + 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, + 864, 940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664 +}; + +static const int AztecCompactSizes[4] = { + 17, 40, 51, 76 +}; + +static const unsigned short int Aztec10DataSizes[32] = { + /* Data bits per symbol maximum with 10% error correction */ + 96, 246, 408, 616, 840, 1104, 1392, 1704, 2040, 2420, 2820, 3250, 3720, 4200, 4730, + 5270, 5840, 6450, 7080, 7750, 8430, 9150, 9900, 10680, 11484, 12324, 13188, 14076, + 15000, 15948, 16920, 17940 +}; + +static const unsigned short int Aztec23DataSizes[32] = { + /* Data bits per symbol maximum with 23% error correction */ + 84, 204, 352, 520, 720, 944, 1184, 1456, 1750, 2070, 2410, 2780, 3180, 3590, 4040, + 4500, 5000, 5520, 6060, 6630, 7210, 7830, 8472, 9132, 9816, 10536, 11280, 12036, + 12828, 13644, 14472, 15348 +}; + +static const unsigned short int Aztec36DataSizes[32] = { + /* Data bits per symbol maximum with 36% error correction */ + 66, 168, 288, 432, 592, 776, 984, 1208, 1450, 1720, 2000, 2300, 2640, 2980, 3350, + 3740, 4150, 4580, 5030, 5500, 5990, 6500, 7032, 7584, 8160, 8760, 9372, 9996, 10656, + 11340, 12024, 12744 +}; + +static const unsigned short int Aztec50DataSizes[32] = { + /* Data bits per symbol maximum with 50% error correction */ + 48, 126, 216, 328, 456, 600, 760, 936, 1120, 1330, 1550, 1790, 2050, 2320, 2610, + 2910, 3230, 3570, 3920, 4290, 4670, 5070, 5484, 5916, 6360, 6828, 7308, 7800, 8316, + 8844, 9384, 9948 +}; + +static const unsigned short int AztecCompact10DataSizes [4] = { + 78, 198, 336, 520 +}; + +static const unsigned short int AztecCompact23DataSizes [4] = { + 66, 168, 288, 440 +}; + +static const unsigned short int AztecCompact36DataSizes [4] = { + 48, 138, 232, 360 +}; + +static const unsigned short int AztecCompact50DataSizes [4] = { + 36, 102, 176, 280 +}; + +static const char AztecOffset[32] = { + 66, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, 42, 40, 38, 36, 34, 32, 30, 28, 25, 23, 21, + 19, 17, 15, 13, 10, 8, 6, 4, 2, 0 +}; + +static const char AztecCompactOffset[4] = { + 6, 4, 2, 0 +}; diff --git a/3rdparty/zint-2.6.1/backend/bmp.c b/3rdparty/zint-2.6.1/backend/bmp.c new file mode 100644 index 0000000..536bb4f --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/bmp.c @@ -0,0 +1,147 @@ +/* bmp.c - Handles output to Windows Bitmap file */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" +#include "bmp.h" /* Bitmap header structure */ +#include +#ifdef _MSC_VER +#include +#include +#endif + +#define SSET "0123456789ABCDEF" + +int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { + int i, row, column; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + int row_size; + unsigned int data_size; + unsigned char *bitmap_file_start, *bmp_posn; + char *bitmap; + FILE *bmp_file; + bitmap_file_header_t file_header; + bitmap_info_header_t info_header; + + if (symbol->bitmap != NULL) + free(symbol->bitmap); + + row_size = 4 * floor((24.0 * symbol->bitmap_width + 31) / 32); + bitmap = (char *) malloc(row_size * symbol->bitmap_height); + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + /* Pixel Plotting */ + i = 0; + for (row = 0; row < symbol->bitmap_height; row++) { + for (column = 0; column < symbol->bitmap_width; column++) { + i = (3 * column) + (row * row_size); + switch (*(pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1)) + column)) { + case '1': + bitmap[i] = fgblu; + bitmap[i + 1] = fggrn; + bitmap[i + 2] = fgred; + break; + default: + bitmap[i] = bgblu; + bitmap[i + 1] = bggrn; + bitmap[i + 2] = bgred; + break; + + } + } + } + + data_size = symbol->bitmap_height * row_size; + symbol->bitmap_byte_length = data_size; + + file_header.header_field = 0x4d42; // "BM" + file_header.file_size = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t) + data_size; + file_header.reserved = 0; + file_header.data_offset = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t); + + info_header.header_size = sizeof (bitmap_info_header_t); + info_header.width = symbol->bitmap_width; + info_header.height = symbol->bitmap_height; + info_header.colour_planes = 1; + info_header.bits_per_pixel = 24; + info_header.compression_method = 0; // BI_RGB + info_header.image_size = 0; + info_header.horiz_res = 0; + info_header.vert_res = 0; + info_header.colours = 0; + info_header.important_colours = 0; + + bitmap_file_start = (unsigned char*) malloc(file_header.file_size); + memset(bitmap_file_start, 0xff, file_header.file_size); + + bmp_posn = bitmap_file_start; + memcpy(bitmap_file_start, &file_header, sizeof (bitmap_file_header_t)); + bmp_posn += sizeof (bitmap_file_header_t); + memcpy(bmp_posn, &info_header, sizeof (bitmap_info_header_t)); + bmp_posn += sizeof (bitmap_info_header_t); + memcpy(bmp_posn, bitmap, data_size); + + /* Open output file in binary mode */ + if ((symbol->output_options & BARCODE_STDOUT) != 0) { +#ifdef _MSC_VER + if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { + strcpy(symbol->errtxt, "600: Can't open output file"); + free(bitmap_file_start); + free(bitmap); + return ZINT_ERROR_FILE_ACCESS; + } +#endif + bmp_file = stdout; + } else { + if (!(bmp_file = fopen(symbol->outfile, "wb"))) { + free(bitmap_file_start); + free(bitmap); + strcpy(symbol->errtxt, "601: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + } + + fwrite(bitmap_file_start, file_header.file_size, 1, bmp_file); + fclose(bmp_file); + + free(bitmap_file_start); + free(bitmap); + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/bmp.h b/3rdparty/zint-2.6.1/backend/bmp.h new file mode 100644 index 0000000..ed88f86 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/bmp.h @@ -0,0 +1,76 @@ +/* bmp.h - header structure for Windows bitmap files + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#ifndef BMP_H +#define BMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#include +#include "stdint_msvc.h" +#else +#include +#endif + +#pragma pack (1) + + typedef struct bitmap_file_header { + uint16_t header_field; + uint32_t file_size; + uint32_t reserved; + uint32_t data_offset; + } bitmap_file_header_t; + + typedef struct bitmap_info_header { + uint32_t header_size; + int32_t width; + int32_t height; + uint16_t colour_planes; + uint16_t bits_per_pixel; + uint32_t compression_method; + uint32_t image_size; + int32_t horiz_res; + int32_t vert_res; + uint32_t colours; + uint32_t important_colours; + } bitmap_info_header_t; + +#pragma pack () + +#ifdef __cplusplus +} +#endif + +#endif /* BMP_H */ + diff --git a/3rdparty/zint-2.6.1/backend/codablock.c b/3rdparty/zint-2.6.1/backend/codablock.c new file mode 100644 index 0000000..d6e1524 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/codablock.c @@ -0,0 +1,1008 @@ +/* codablock.c - Handles Codablock-F and Codablock-E */ + +/* + libzint - the open source barcode library + Copyright (C) 2016 Harald Oehlmann + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +#define uchar unsigned char + +/* FTab C128 flags - may be added */ +#define CodeA 1 +#define CodeB 2 +#define CodeC 4 +#define CEnd 8 +#define CShift 16 +#define CFill 32 +#define CodeFNC1 64 +#define ZTNum (CodeA+CodeB+CodeC) +#define ZTFNC1 (CodeA+CodeB+CodeC+CodeFNC1) + +/* ASCII-Extension for Codablock-F */ +#define aFNC1 (uchar)(128) +#define aFNC2 (uchar)(129) +#define aFNC3 (uchar)(130) +#define aFNC4 (uchar)(131) +#define aCodeA (uchar)(132) +#define aCodeB (uchar)(133) +#define aCodeC (uchar)(134) +#define aShift (uchar)(135) + +static const char *C128Table[107] = { + /* Code 128 character encodation - Table 1 */ + "212222", "222122", "222221", "121223", "121322", "131222", "122213", + "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", + "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", + "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", + "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", + "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", + "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", + "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", + "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", + "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", + "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", + "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", + "2331112" +}; + +/* Code F Analysing-Chart */ +typedef struct sCharacterSetTable +{ + int CharacterSet; /* Still possible character sets for actual*/ + int AFollowing; /* Still following Characters in Charset A */ + int BFollowing; /* Still following Characters in Charset B */ + int CFollowing; /* Still following Characters in Charset C */ +} CharacterSetTable; + +/* Find the possible Code-128 Character sets for a character + * The result is an or of CodeA,CodeB,CodeC,CodeFNC1 in dependency of the + * possible Code 128 character sets. + */ +int GetPossibleCharacterSet(unsigned char C) +{ + if (C<='\x19') /* Dec:31 */ + return CodeA; + if (C>='0' && C<='9') + return ZTNum; /* ZTNum=CodeA+CodeB+CodeC */ + if (C==aFNC1) + return ZTFNC1; /* ZTFNC1=CodeA+CodeB+CodeC+CodeFNC1 */ + if (C>='\x60' && C<='\x7f') /* 60 to 127 */ + return CodeB; + return CodeA+CodeB; +} + +/* Create a Table with the following information for each Data character: + * int CharacterSet is an or of CodeA,CodeB,CodeC,CodeFNC1, in + * dependency which character set is applicable. + * (Result of GetPossibleCharacterSet) + * int AFollowing,BFollowing The number of source characters you still may encode + * in this character set. + * int CFollowing The number of characters encodable in CodeC if we + * start here. + */ +static void CreateCharacterSetTable(CharacterSetTable T[], unsigned char *data,const size_t dataLength) +{ + int charCur; + int runChar; + + /* Treat the Data backwards */ + charCur=dataLength-1; + T[charCur].CharacterSet=GetPossibleCharacterSet(data[charCur]); + T[charCur].AFollowing=((T[charCur].CharacterSet & CodeA)==0)?0:1; + T[charCur].BFollowing=((T[charCur].CharacterSet & CodeB)==0)?0:1; + T[charCur].CFollowing=0; + + for (charCur--;charCur>=0;charCur--) + { + T[charCur].CharacterSet=GetPossibleCharacterSet(data[charCur]); + T[charCur].AFollowing= + ((T[charCur].CharacterSet & CodeA)==0)?0:T[charCur+1].AFollowing+1; + T[charCur].BFollowing= + ((T[charCur].CharacterSet & CodeB)==0)?0:T[charCur+1].BFollowing+1; + T[charCur].CFollowing=0; + + } + /* Find the CodeC-chains */ + for (charCur=0;charCur=dataLength) + break; + /* Only a Number may follow */ + if (T[runChar].CharacterSet==ZTNum) + T[charCur].CFollowing+=2; + else + break; + } + ++runChar; + } while (runChar0 && runChar44) are requested the columns is extended. + * A oneLigner may be choosen if shorter. + * Parameters : + * T Pointer on the Characters which fit in the row + * If a different count is calculated it is corrected + * in the callers workspace. + * pFillings Output of filling characters + * pSet Output of the character sets used, allocated by me. + * Data The Data string to encode, exceptionnally not an out + * Return value Resulting row count + */ + +static int Columns2Rows(CharacterSetTable *T, unsigned char *data, const size_t dataLength, + int * pRows, int * pUseColumns, int * pSet, int * pFillings) +{ + int useColumns; /* Usable Characters per line */ + int fillings; /* Number of filling characters */ + int rowsCur; + int charCur; + int runChar; + int emptyColumns; /* Number of codes still empty in line. */ + int emptyColumns2; /* Alternative emptyColumns to compare */ + int fOneLiner; /* Flag if One Liner */ + int CPaires; /* Number of digit pairs which may fit in the line */ + int characterSetCur; /* Current Character Set */ + + useColumns=*pUseColumns; + if (useColumns<3) + useColumns=3; + + /* >>> Loop until rowsCur<44 */ + do { + memset(pSet,0,dataLength*sizeof(int)); + charCur=0; + rowsCur=0; + fOneLiner=1; /* First try one-Liner */ + + /* >>> Line and OneLiner-try Loop */ + do{ + /* >> Start Character */ + emptyColumns=useColumns; /* Remained place in Line */ + if (fOneLiner) + emptyColumns+=2; + + /* >>Choose in Set A or B */ + /* (C is changed as an option later on) */ + + pSet[charCur]=characterSetCur= + (T[charCur].AFollowing > T[charCur].BFollowing) + ? CodeA : CodeB; + + /* >> Test on Numeric Mode C */ + CPaires=RemainingDigits(T,charCur, emptyColumns); + if (CPaires>=4) + { + /* 4 Digits in Numeric compression ->OK */ + /* > May an odd start find more ? */ + /* Skip leading 's */ + /* Typical structure : 12... */ + /* Test if numeric after one isn't better.*/ + runChar=charCur; + emptyColumns2=emptyColumns; + while (T[runChar].CharacterSet==ZTFNC1) + { + ++runChar; + --emptyColumns2; + } + if (CPaires>=RemainingDigits(T,runChar+1,emptyColumns2-1)) + { + /* Start odd is not better */ + /* We start in C */ + pSet[charCur]=characterSetCur=CodeC; + /* Inkrement charCur */ + if (T[charCur].CharacterSet!=ZTFNC1) + ++charCur; /* 2 Num.Digits */ + } + } + ++charCur; + --emptyColumns; + + /* >> Following characters */ + while(emptyColumns>0 && charCur> Check switching to CodeC */ + /* Switch if : + * - Character not FNC1 + * - 4 real Digits will fit in line + * - an odd Start will not be better + */ + if (T[charCur].CharacterSet==ZTNum + && (CPaires=RemainingDigits(T,charCur, emptyColumns-1))>=4 + && CPaires > RemainingDigits(T,charCur+1,emptyColumns-2)) + { + /* > Change to C */ + pSet[charCur]=characterSetCur=CodeC; + charCur+=2; /* 2 Digit */ + emptyColumns-=2; /* 12 */ + } else if (characterSetCur==CodeA) + { + if(T[charCur].AFollowing==0) + { + /* Must change to B */ + if (emptyColumns==1) + { + /* Can't switch: */ + pSet[charCur-1]|=CEnd+CFill; + emptyColumns=0; + }else{ + /* or ? */ + if (T[charCur].BFollowing==1) + { + pSet[charCur]|=CShift; + } else { + pSet[charCur]|=CodeB; + characterSetCur = CodeB; + } + emptyColumns-=2; + ++charCur; + } + }else{ + --emptyColumns; + ++charCur; + } + } else { /* Last possibility : CodeB */ + if(T[charCur].BFollowing==0) + { + /* Must change to A */ + if (emptyColumns==1) + { + /* Can't switch: */ + pSet[charCur-1]|=CEnd+CFill; + emptyColumns=0; + } else { + /* or ? */ + if (T[charCur].AFollowing==1) + { + pSet[charCur]|=CShift; + } else { + pSet[charCur]|=CodeA; + characterSetCur = CodeA; + } + emptyColumns-=2; + ++charCur; + } + }else{ + --emptyColumns; + ++charCur; + } + } + break; + case CodeC: + if(T[charCur].CFollowing>0) + { + charCur+=(T[charCur].CharacterSet==ZTFNC1)?1:2; + emptyColumns--; + }else{ + /* Must change to A or B */ + if (emptyColumns==1) + { + /* Can't switch: */ + pSet[charCur-1]|=CEnd+CFill; + emptyColumns=0; + }else{ + /* or ?*/ + characterSetCur=pSet[charCur]= + (T[charCur].AFollowing > T[charCur].BFollowing) + ?CodeA:CodeB; + emptyColumns-=2; + ++charCur; + } + } + break; + } /* switch */ + } /* while */ + + /* > End of Codeline */ + pSet[charCur-1]|=CEnd; + ++rowsCur; + if ( fOneLiner) + { + if (charCur44) { + ++useColumns; + if (useColumns > 62) { + return ZINT_ERROR_TOO_LONG; + } + } + } while(rowsCur>44); + #ifdef _DEBUG + printf(" -> out: rowsCur <%i>, useColumns <%i>, fillings <%i>\n",rowsCur,useColumns,fillings); + #endif + *pUseColumns=useColumns; + *pRows=rowsCur; + *pFillings=fillings; + return 0; +} +/* Find columns if row count is given. + */ +static int Rows2Columns(CharacterSetTable *T, unsigned char *data, const size_t dataLength, + int * pRows, int * pUseColumns, int * pSet, int * pFillings) +{ + int errorCur; + int rowsCur; + int rowsRequested; /* Number of requested rows */ + int backupRows = 0; + int fillings; + int backupFillings = 0; + int useColumns; + int testColumns; /* To enter into Width2Rows */ + int backupColumns = 0; + int fBackupOk = 0; /* The memorysed set is o.k. */ + int testListSize = 0; + int pTestList[62]; +#ifndef _MSC_VER + int *pBackupSet[dataLength]; +#else + int *pBackupSet = (int *)_alloca(dataLength*sizeof(int)); +#endif + + rowsRequested=*pRows; + + #ifdef _DEBUG + fprintf(stderr,"Optimizer : Searching <%i> rows\n",rowsRequested); + #endif + + if (rowsRequested==1) + /* OneLiners are self-calibrating */ + testColumns=32767; + else { + /* First guess */ + testColumns=dataLength/rowsRequested; + if (testColumns > 62) + testColumns = 62; + else if (testColumns < 1) + testColumns = 1; + } + + for (;;) { + pTestList[testListSize] = testColumns; + testListSize++; + useColumns=testColumns; /* Make a copy because it may be modified */ + errorCur = Columns2Rows(T, data, dataLength, &rowsCur, &useColumns, pSet, &fillings); + if (errorCur != 0) + return errorCur; + if (rowsCur<=rowsRequested) { + /* Less or exactly line number found */ + /* check if column count below already tested or Count = 1*/ + int fInTestList = (rowsCur == 1 || testColumns == 1); + int posCur; + for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) { + if ( pTestList[posCur] == testColumns-1 ) + fInTestList = 1; + } + if (fInTestList) { + /* >> Smaller Width already tested + * if rowsCur=rowsRequested->Exit + * if rowsCur0 + * -> New search for rowsRequested:=rowsCur + */ + if ( rowsCur == rowsRequested || fillings == 0 || testColumns == 1 ) { + /* Exit with actual */ + *pFillings=fillings; + *pRows=rowsCur; + *pUseColumns = useColumns; + return 0; + } + /* Search again for smaller Line number */ + rowsRequested=rowsCur; + pTestList[0] = testColumns; + testListSize = 1; + } + /* > Test more rows (shorter CDB) */ + fBackupOk=(rowsCur==rowsRequested); + memcpy(pBackupSet,pSet,dataLength*sizeof(int)); + backupFillings=fillings; + backupColumns=useColumns; + backupRows=rowsCur; + --testColumns; + } else { + /* > To many rows */ + int fInTestList = fBackupOk; + int posCur; + for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) { + if ( pTestList[posCur] == testColumns+1 ) + fInTestList = 1; + } + if (fInTestList) { + /* The next less-rows (larger) code was + * already tested. So give the larger + * back. + */ + memcpy(pSet,pBackupSet,dataLength*sizeof(int)); + *pFillings=backupFillings; + *pRows=backupRows; + *pUseColumns=backupColumns; + return 0; + } + /* > Test less rows (longer code) */ + backupRows=rowsCur; + memcpy(pBackupSet,pSet,dataLength*sizeof(int)); + backupFillings=fillings; + backupColumns=useColumns; + fBackupOk=0; + ++testColumns; + } + } +} + +/* Print a character in character set A + */ +void A2C128_A(uchar **ppOutPos,uchar c) +{ + uchar * pOutPos = *ppOutPos; + switch(c){ + case aCodeB: *pOutPos=100; break; + case aFNC4: *pOutPos=101; break; + case aFNC1: *pOutPos=102; break; + case aFNC2: *pOutPos=97; break; + case aFNC3: *pOutPos=96; break; + case aCodeC: *pOutPos=99; break; + case aShift: *pOutPos=98; break; + default: + /* +++ HaO 13.11.98 c>' ' && c < '\x1F' corrected */ + if(c>=' ' && c<='_') + *pOutPos=(uchar)(c-' '); + else + *pOutPos=(uchar)(c+64); + break; + } + (*ppOutPos)++; +} +/* Output c in Set B + */ +void A2C128_B(uchar **ppOutPos,uchar c) +{ + uchar * pOutPos = *ppOutPos; + switch(c){ + case aFNC1: *pOutPos=102; break; + case aFNC2: *pOutPos=97; break; + case aFNC3: *pOutPos=96; break; + case aFNC4: *pOutPos=100; break; + case aCodeA: *pOutPos=101; break; + case aCodeC: *pOutPos=99; break; + case aShift: *pOutPos=98; break; + default: *pOutPos=(uchar)(c-' '); break; + } + ++(*ppOutPos); +} +/* Output c1, c2 in Set C + */ +void A2C128_C(uchar **ppOutPos,uchar c1,uchar c2) +{ + uchar * pOutPos = *ppOutPos; + switch(c1){ + case aFNC1: *pOutPos=102; break; + case aCodeB: *pOutPos=100; break; + case aCodeA: *pOutPos=101; break; + default: *pOutPos=(char)(10 * (c1- '0') + (c2 - '0'));break; + } + (*ppOutPos)++; +} +/* Output a character in Characterset + */ +void ASCIIZ128(uchar **ppOutPos, int CharacterSet,uchar c1, uchar c2) +{ + if (CharacterSet==CodeA) + A2C128_A(ppOutPos,c1); + else if(CharacterSet==CodeB) + A2C128_B(ppOutPos,c1); + else + A2C128_C(ppOutPos,c1,c2); +} +/* XLate Table A of Codablock-F Specification and call output + */ +void SumASCII(uchar **ppOutPos, int Sum, int CharacterSet) +{ + switch (CharacterSet){ + case CodeA: + A2C128_A(ppOutPos, (uchar)Sum); + break; + case CodeB: + if (Sum<=31) + A2C128_B(ppOutPos, (uchar)(Sum+96)); + else if(Sum<=47) + A2C128_B(ppOutPos, (uchar)Sum); + else + A2C128_B(ppOutPos, (uchar)(Sum+10)); + break; + case CodeC: + A2C128_C(ppOutPos + ,(char)(Sum/10+'0') ,(uchar)(Sum%10+'0')); + break; + } +} + +/* Main function called by zint framework + */ +int codablock(struct zint_symbol *symbol,const unsigned char source[], const size_t length) { + size_t charCur,dataLength; + int Error; + int rows, columns, useColumns; + int fillings; + int Sum1,Sum2; + uchar * pOutPos; + int rowCur; + int characterSetCur; + int emptyColumns; + char dest[1000]; + int r, c; +#ifdef _MSC_VER + CharacterSetTable *T; + unsigned char *data; + int *pSet; + uchar * pOutput; +#endif + + /* Parameter check */ + /* option1: rows 0: automatic, 1..44 */ + rows = symbol->option_1; + if (rows > 44) { + strcpy(symbol->errtxt, "410: Row parameter not in 0..44"); + return ZINT_ERROR_INVALID_OPTION; + } + /* option_2: (usable data) columns: 0: automatic, 6..66 */ + columns = symbol->option_2; + if ( ! (columns <= 0 || (columns >= 6 && columns <=66)) ) { + strcpy(symbol->errtxt, "411: Columns parameter not in 0,6..66"); + return ZINT_ERROR_INVALID_OPTION; + } + /* GS1 not implemented */ + if (symbol->input_mode == GS1_MODE) { + strcpy(symbol->errtxt, "412: GS1 mode not supported"); + return ZINT_ERROR_INVALID_OPTION; + } +#ifndef _MSC_VER + unsigned char data[length*2+1]; +#else + data = (unsigned char *) _alloca(length * 2+1); +#endif + + dataLength = 0; + if (symbol->output_options & READER_INIT) { + data[dataLength] = aFNC3; + dataLength++; + } + /* Replace all Codes>127 with Code-128 */ + for (charCur=0;charCur127) + { + data[dataLength] = aFNC4; + dataLength++; + data[dataLength] = (unsigned char)(source[charCur]&127); + } else + data[dataLength] = source[charCur]; + dataLength++; + } + + /* Build character set table */ +#ifndef _MSC_VER + CharacterSetTable T[dataLength]; + int pSet[dataLength]; +#else + T=(CharacterSetTable *)_alloca(dataLength*sizeof(CharacterSetTable)); + pSet = (int *)_alloca(dataLength*sizeof(int)); +#endif + CreateCharacterSetTable(T,data,dataLength); + + /* Find final row and column count */ + /* nor row nor column count given */ + if ( rows <= 0 && columns <= 5 ) { + /* Use Code128 until reasonable size */ + if (dataLength < 9) { + rows = 1; + } else { + /* use 1/1 aspect/ratio Codablock */ + columns = ((int)floor(sqrt(1.0*dataLength))+5); + if (columns > 64) + columns = 64; + #ifdef _DEBUG + printf("Auto column count for %d characters:%d\n",dataLength,columns); + #endif + } + } + /* There are 5 Codewords for Organisation Start(2),row(1),CheckSum,Stop */ + useColumns = columns - 5; + if ( rows > 0 ) { + /* row count given */ + Error=Rows2Columns(T,data,dataLength,&rows,&useColumns,pSet,&fillings); + } else { + /* column count given */ + Error=Columns2Rows(T,data,dataLength,&rows,&useColumns,pSet,&fillings); + } + if (Error != 0) { + strcpy(symbol->errtxt, "413: Data string to long"); + return Error; + } + /* Checksum */ + Sum1=Sum2=0; + if (rows>1) + { + size_t charCur; + for (charCur=0 ; charCur>> Build C128 code numbers */ + /* The C128 column count contains Start (2CW), Row ID, Checksum, Stop */ +#ifndef _MSC_VER + uchar pOutput[columns * rows]; +#else + pOutput = (unsigned char *)_alloca(columns * rows * sizeof(char)); +#endif + pOutPos = pOutput; + charCur=0; + /* >> Loop over rows */ + for (rowCur=0 ; rowCur=dataLength) + { + /* >> Empty line with StartCCodeBCodeC */ + characterSetCur=CodeC; + /* CDB Start C*/ + *pOutPos='\x67'; + pOutPos++; + *pOutPos='\x63'; + pOutPos++; + SumASCII(&pOutPos,rowCur+42,CodeC); + emptyColumns=useColumns-2; + while (emptyColumns>0) + { + if(characterSetCur==CodeC) + { + A2C128_C(&pOutPos,aCodeB,'\0'); + characterSetCur=CodeB; + }else{ + A2C128_B(&pOutPos,aCodeC); + characterSetCur=CodeC; + } + --emptyColumns; + } + }else{ + /* >> Normal Line */ + /* > Startcode */ + switch (pSet[charCur] & (CodeA+CodeB+CodeC)){ + case CodeA: + *pOutPos = '\x67'; + pOutPos++; + if (rows>1) { + *pOutPos = '\x62'; + pOutPos++; + } + characterSetCur=CodeA; + break; + case CodeB: + if (rows==1) { + *pOutPos = '\x68'; + pOutPos++; + } else { + *pOutPos = '\x67'; + pOutPos++; + *pOutPos = '\x64'; + pOutPos++; + } + characterSetCur=CodeB; + break; + case CodeC: + default: + if (rows==1) { + *pOutPos = '\x69'; + pOutPos++; + } else { + *pOutPos = '\x67'; + pOutPos++; + *pOutPos = '\x63'; + pOutPos++; + } + characterSetCur=CodeC; + break; + } + if (rows>1) + { + /* > Set F1 */ + /* In first line : # of rows */ + /* In Case of CodeA we shifted to CodeB */ + SumASCII(&pOutPos + ,(rowCur==0)?rows-2:rowCur+42 + ,(characterSetCur==CodeA)?CodeB:characterSetCur + ); + } + /* >>> Data */ + emptyColumns=useColumns; + /* +++ One liner don't have start/stop code */ + if (rows == 1) + emptyColumns +=2; + /* >> Character loop */ + while (emptyColumns>0) + { + /* ? Change character set */ + /* not at first possition (It was then the start set) */ + /* +++ special case for one-ligner */ + if (emptyColumns> Shift it and put out the shifted character */ + ASCIIZ128(&pOutPos,characterSetCur,aShift,'\0'); + emptyColumns-=2; + characterSetCur=(characterSetCur==CodeB)?CodeA:CodeB; + ASCIIZ128(&pOutPos,characterSetCur,data[charCur],'\0'); + characterSetCur=(characterSetCur==CodeB)?CodeA:CodeB; + }else{ + /* Normal Character */ + if (characterSetCur==CodeC) + { + if (data[charCur]==aFNC1) + A2C128_C(&pOutPos,aFNC1,'\0'); + else + { + A2C128_C(&pOutPos,data[charCur],data[charCur+1]); + ++charCur; + /* We need this here to get the good index */ + /* for the termination flags in Set. */ + } + }else + ASCIIZ128(&pOutPos,characterSetCur,data[charCur],'\0'); + --emptyColumns; + } + /* >> End Criteria */ + if ((pSet[charCur] & CFill)!=0) + { + /* Fill Line but leave space for checks in last line */ + if(rowCur==rows-1 && emptyColumns>=2) + emptyColumns-=2; + while(emptyColumns>0) + { + switch(characterSetCur){ + case CodeC: + A2C128_C(&pOutPos,aCodeB,'\0'); + characterSetCur=CodeB; + break; + case CodeB: + A2C128_B(&pOutPos,aCodeC); + characterSetCur=CodeC; + break; + case CodeA: + A2C128_A(&pOutPos,aCodeC); + characterSetCur=CodeC; + break; + } + --emptyColumns; + } + } + if ((pSet[charCur] & CEnd)!=0) + emptyColumns=0; + ++charCur; + } /* Loop over characters */ + } /* if filling-Line / normal */ + + /* Add checksum in last line */ + if(rows>1 && rowCur==rows-1) + { + SumASCII(&pOutPos,Sum1,characterSetCur); + SumASCII(&pOutPos,Sum2,characterSetCur); + } + /* Add Code 128 checksum */ + { + int Sum=0; + int Pos=0; + for ( ; Pos < useColumns+3 ; Pos++) + { + Sum = (Sum + + ((Pos==0?1:Pos) * pOutput[columns*rowCur+Pos]) % 103 + ) % 103; + } + *pOutPos=(uchar)Sum; + pOutPos++; + } + /* Add end character */ + *pOutPos=106; + pOutPos++; + } /* End Lineloop */ + + #ifdef _DEBUG + /* Dump the output to the screen + */ + printf("\nCode 128 Code Numbers:\n"); + { /* start a new level of local variables */ + int DPos, DPos2; + for (DPos=0 ; DPos< rows ; DPos++) + { + for (DPos2=0 ; DPos2 < columns ; DPos2++) + { + printf("%3d ",(int)(pOutput[DPos*columns+DPos2])); + } + printf("\n"); + } + } + printf("rows=%i columns=%i fillings=%i\n", rows, columns, fillings); + #endif + + /* Paint the C128 patterns */ + for (r = 0; r < rows; r++) { + strcpy(dest, ""); + for(c = 0; c < columns; c++) { + strcat(dest, C128Table[pOutput[r * columns + c]]); + } + expand(symbol, dest); + symbol->row_height[r] = 10; + } + + if (!(symbol->output_options & BARCODE_BIND)) { + symbol->output_options += BARCODE_BIND; + } + + if (symbol->border_width < 2) { + symbol->border_width = 2; + } + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/code.c b/3rdparty/zint-2.6.1/backend/code.c new file mode 100644 index 0000000..cac63ae --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code.c @@ -0,0 +1,591 @@ +/* code.c - Handles Code 11, 39, 39+ and 93 */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* In version 0.5 this file was 1,553 lines long! */ + +#include +#include +#include +#include "common.h" + +#define SODIUM "0123456789-" +#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd" + +static const char *C11Table[11] = { + "111121", "211121", "121121", "221111", "112121", "212111", "122111", + "111221", "211211", "211111", "112111" +}; + +/* Code 39 tables checked against ISO/IEC 16388:2007 */ + +/* Incorporates Table A1 */ + +static const char *C39Table[43] = { + /* Code 39 character assignments (Table 1) */ + "1112212111", "2112111121", "1122111121", "2122111111", "1112211121", + "2112211111", "1122211111", "1112112121", "2112112111", "1122112111", "2111121121", + "1121121121", "2121121111", "1111221121", "2111221111", "1121221111", "1111122121", + "2111122111", "1121122111", "1111222111", "2111111221", "1121111221", "2121111211", + "1111211221", "2111211211", "1121211211", "1111112221", "2111112211", "1121112211", + "1111212211", "2211111121", "1221111121", "2221111111", "1211211121", "2211211111", + "1221211111", "1211112121", "2211112111", "1221112111", "1212121111", "1212111211", + "1211121211", "1112121211" +}; + +static const char *EC39Ctrl[128] = { + /* Encoding the full ASCII character set in Code 39 (Table A2) */ + "%U", "$A", "$B", "$C", "$D", "$E", "$F", "$G", "$H", "$I", "$J", "$K", + "$L", "$M", "$N", "$O", "$P", "$Q", "$R", "$S", "$T", "$U", "$V", "$W", "$X", "$Y", "$Z", + "%A", "%B", "%C", "%D", "%E", " ", "/A", "/B", "/C", "/D", "/E", "/F", "/G", "/H", "/I", "/J", + "/K", "/L", "-", ".", "/O", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/Z", "%F", + "%G", "%H", "%I", "%J", "%V", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "%K", "%L", "%M", "%N", "%O", + "%W", "+A", "+B", "+C", "+D", "+E", "+F", "+G", "+H", "+I", "+J", "+K", "+L", "+M", "+N", "+O", + "+P", "+Q", "+R", "+S", "+T", "+U", "+V", "+W", "+X", "+Y", "+Z", "%P", "%Q", "%R", "%S", "%T" +}; + +static const char *C93Ctrl[128] = { + "bU", "aA", "aB", "aC", "aD", "aE", "aF", "aG", "aH", "aI", "aJ", "aK", + "aL", "aM", "aN", "aO", "aP", "aQ", "aR", "aS", "aT", "aU", "aV", "aW", "aX", "aY", "aZ", + "bA", "bB", "bC", "bD", "bE", " ", "cA", "cB", "cC", "$", "%", "cF", "cG", "cH", "cI", "cJ", + "+", "cL", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "cZ", "bF", + "bG", "bH", "bI", "bJ", "bV", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bK", "bL", "bM", "bN", "bO", + "bW", "dA", "dB", "dC", "dD", "dE", "dF", "dG", "dH", "dI", "dJ", "dK", "dL", "dM", "dN", "dO", + "dP", "dQ", "dR", "dS", "dT", "dU", "dV", "dW", "dX", "dY", "dZ", "bP", "bQ", "bR", "bS", "bT" +}; + +static const char *C93Table[47] = { + "131112", "111213", "111312", "111411", "121113", "121212", "121311", + "111114", "131211", "141111", "211113", "211212", "211311", "221112", "221211", "231111", + "112113", "112212", "112311", "122112", "132111", "111123", "111222", "111321", "121122", + "131121", "212112", "212211", "211122", "211221", "221121", "222111", "112122", "112221", + "122121", "123111", "121131", "311112", "311211", "321111", "112131", "113121", "211131", + "121221", "312111", "311121", "122211" +}; + +/* Global Variables for Channel Code */ +int S[11], B[11]; +long value; +long target_value; +char pattern[30]; + +/* Function Prototypes */ +void NextS(int Chan, int i, int MaxS, int MaxB); +void NextB(int Chan, int i, int MaxB, int MaxS); + +/* *********************** CODE 11 ******************** */ +int code_11(struct zint_symbol *symbol, unsigned char source[], int length) { /* Code 11 */ + + unsigned int i; + int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count; + int weight[128], error_number; + char dest[1024]; /* 6 + 121 * 6 + 2 * 6 + 5 + 1 ~ 1024*/ + char checkstr[3]; + + if (length > 121) { + strcpy(symbol->errtxt, "320: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(SODIUM, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "321: Invalid characters in data"); + return error_number; + } + c_weight = 1; + c_count = 0; + k_weight = 1; + k_count = 0; + + /* start character */ + strcpy(dest, "112211"); + + /* Draw main body of barcode */ + for (i = 0; i < (unsigned int) length; i++) { + lookup(SODIUM, C11Table, source[i], dest); + if (source[i] == '-') + weight[i] = 10; + else + weight[i] = ctoi(source[i]); + } + + /* Calculate C checksum */ + for (h = length - 1; h >= 0; h--) { + c_count += (c_weight * weight[h]); + c_weight++; + + if (c_weight > 10) { + c_weight = 1; + } + } + c_digit = c_count % 11; + + weight[length] = c_digit; + + /* Calculate K checksum */ + for (h = length; h >= 0; h--) { + k_count += (k_weight * weight[h]); + k_weight++; + + if (k_weight > 9) { + k_weight = 1; + } + } + k_digit = k_count % 11; + + checkstr[0] = itoc(c_digit); + checkstr[1] = itoc(k_digit); + if (checkstr[0] == 'A') { + checkstr[0] = '-'; + } + if (checkstr[1] == 'A') { + checkstr[1] = '-'; + } + checkstr[2] = '\0'; + lookup(SODIUM, C11Table, checkstr[0], dest); + lookup(SODIUM, C11Table, checkstr[1], dest); + + /* Stop character */ + strcat(dest, "11221"); + + expand(symbol, dest); + + ustrcpy(symbol->text, source); + strcat((char*) symbol->text, checkstr); + return error_number; +} + +/* Code 39 */ +int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + unsigned int i; + unsigned int counter; + char check_digit; + int error_number; + char dest[775]; + char localstr[2] = {0}; + + counter = 0; + + if ((symbol->option_2 < 0) || (symbol->option_2 > 1)) { + symbol->option_2 = 0; + } + + if ((symbol->symbology == BARCODE_LOGMARS) && (length > 59)) { + strcpy(symbol->errtxt, "322: Input too long"); + return ZINT_ERROR_TOO_LONG; + } else if (length > 74) { + strcpy(symbol->errtxt, "323: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(SILVER, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "324: Invalid characters in data"); + return error_number; + } + + /* Start character */ + strcpy(dest, "1211212111"); + + for (i = 0; i < (unsigned int) length; i++) { + lookup(SILVER, C39Table, source[i], dest); + counter += posn(SILVER, source[i]); + } + + if ((symbol->symbology == BARCODE_LOGMARS) || (symbol->option_2 == 1)) { + + counter = counter % 43; + if (counter < 10) { + check_digit = itoc(counter); + } else { + if (counter < 36) { + check_digit = (counter - 10) + 'A'; + } else { + switch (counter) { + case 36: check_digit = '-'; + break; + case 37: check_digit = '.'; + break; + case 38: check_digit = ' '; + break; + case 39: check_digit = '$'; + break; + case 40: check_digit = '/'; + break; + case 41: check_digit = '+'; + break; + case 42: check_digit = 37; + break; + default: check_digit = ' '; + break; /* Keep compiler happy */ + } + } + } + lookup(SILVER, C39Table, check_digit, dest); + + /* Display a space check digit as _, otherwise it looks like an error */ + if (check_digit == ' ') { + check_digit = '_'; + } + + localstr[0] = check_digit; + localstr[1] = '\0'; + } + + /* Stop character */ + strcat(dest, "121121211"); + + if ((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_HIBC_39)) { + /* LOGMARS uses wider 'wide' bars than normal Code 39 */ + counter = (unsigned int) strlen(dest); + for (i = 0; i < counter; i++) { + if (dest[i] == '2') { + dest[i] = '3'; + } + } + } + + expand(symbol, dest); + + if (symbol->symbology == BARCODE_CODE39) { + strcpy((char*) symbol->text, "*"); + strcat((char*) symbol->text, (char*) source); + strcat((char*) symbol->text, localstr); + strcat((char*) symbol->text, "*"); + } else { + strcpy((char*) symbol->text, (char*) source); + strcat((char*) symbol->text, localstr); + } + return error_number; +} + +/* Pharmazentral Nummer (PZN) */ +int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) { + + int i, error_number, zeroes; + unsigned int count, check_digit; + char localstr[11]; + + count = 0; + if (length > 7) { + strcpy(symbol->errtxt, "325: Input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "326: Invalid characters in data"); + return error_number; + } + + localstr[0] = '-'; + zeroes = 7 - length + 1; + for (i = 1; i < zeroes; i++) + localstr[i] = '0'; + strcpy(localstr + zeroes, (char *) source); + + for (i = 1; i < 8; i++) { + count += i * ctoi(localstr[i]); + } + + check_digit = count % 11; + if (check_digit == 11) { + check_digit = 0; + } + localstr[8] = itoc(check_digit); + localstr[9] = '\0'; + if (localstr[8] == 'A') { + strcpy(symbol->errtxt, "327: Invalid PZN Data"); + return ZINT_ERROR_INVALID_DATA; + } + error_number = c39(symbol, (unsigned char *) localstr, strlen(localstr)); + ustrcpy(symbol->text, (unsigned char *) "PZN"); + strcat((char*) symbol->text, localstr); + return error_number; +} + +/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */ +int ec39(struct zint_symbol *symbol, unsigned char source[], int length) { + + unsigned char buffer[150] = {0}; + unsigned int i; + int error_number; + + if (length > 74) { + strcpy(symbol->errtxt, "328: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Creates a buffer string and places control characters into it */ + for (i = 0; i < (unsigned int) length; i++) { + if (source[i] > 127) { + /* Cannot encode extended ASCII */ + strcpy(symbol->errtxt, "329: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + strcat((char*) buffer, EC39Ctrl[source[i]]); + } + + /* Then sends the buffer to the C39 function */ + error_number = c39(symbol, buffer, ustrlen(buffer)); + + for (i = 0; i < (unsigned int) length; i++) + symbol->text[i] = source[i] ? source[i] : ' '; + symbol->text[length] = '\0'; + + return error_number; +} + +/* Code 93 is an advancement on Code 39 and the definition is a lot tighter */ +int c93(struct zint_symbol *symbol, unsigned char source[], int length) { + + /* SILVER includes the extra characters a, b, c and d to represent Code 93 specific + shift characters 1, 2, 3 and 4 respectively. These characters are never used by + c39() and ec39() */ + + int i; + int h, weight, c, k, values[128], error_number; + char buffer[220]; + char dest[670]; + char set_copy[] = SILVER; + + error_number = 0; + strcpy(buffer, ""); + + if (length > 107) { + strcpy(symbol->errtxt, "330: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Message Content */ + for (i = 0; i < length; i++) { + if (source[i] > 127) { + /* Cannot encode extended ASCII */ + strcpy(symbol->errtxt, "331: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + strcat(buffer, C93Ctrl[source[i]]); + symbol->text[i] = source[i] ? source[i] : ' '; + } + + /* Now we can check the true length of the barcode */ + h = (int) strlen(buffer); + if (h > 107) { + strcpy(symbol->errtxt, "332: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + for (i = 0; i < h; i++) { + values[i] = posn(SILVER, buffer[i]); + } + + /* Putting the data into dest[] is not done until after check digits are calculated */ + + /* Check digit C */ + c = 0; + weight = 1; + for (i = h - 1; i >= 0; i--) { + c += values[i] * weight; + weight++; + if (weight == 21) + weight = 1; + } + c = c % 47; + values[h] = c; + buffer[h] = set_copy[c]; + + /* Check digit K */ + k = 0; + weight = 1; + for (i = h; i >= 0; i--) { + k += values[i] * weight; + weight++; + if (weight == 16) + weight = 1; + } + k = k % 47; + buffer[++h] = set_copy[k]; + buffer[++h] = '\0'; + + /* Start character */ + strcpy(dest, "111141"); + + for (i = 0; i < h; i++) { + lookup(SILVER, C93Table, buffer[i], dest); + } + + /* Stop character */ + strcat(dest, "1111411"); + expand(symbol, dest); + + symbol->text[length] = set_copy[c]; + symbol->text[length + 1] = set_copy[k]; + symbol->text[length + 2] = '\0'; + + return error_number; +} + +/* NextS() and NextB() are from ANSI/AIM BC12-1998 and are Copyright (c) AIM 1997 */ + +/* Their are used here on the understanding that they form part of the specification + for Channel Code and therefore their use is permitted under the following terms + set out in that document: + + "It is the intent and understanding of AIM [t]hat the symbology presented in this + specification is entirely in the public domain and free of all use restrictions, + licenses and fees. AIM USA, its memer companies, or individual officers + assume no liability for the use of this document." */ + +void CheckCharacter() { + int i; + char part[3]; + + if (value == target_value) { + /* Target reached - save the generated pattern */ + strcpy(pattern, "11110"); + for (i = 0; i < 11; i++) { + part[0] = itoc(S[i]); + part[1] = itoc(B[i]); + part[2] = '\0'; + strcat(pattern, part); + } + } +} + +void NextB(int Chan, int i, int MaxB, int MaxS) { + int b; + + b = (S[i] + B[i - 1] + S[i - 1] + B[i - 2] > 4) ? 1 : 2; + if (i < Chan + 2) { + for (; b <= MaxB; b++) { + B[i] = b; + NextS(Chan, i + 1, MaxS, MaxB + 1 - b); + } + } else if (b <= MaxB) { + B[i] = MaxB; + CheckCharacter(); + value++; + } +} + +void NextS(int Chan, int i, int MaxS, int MaxB) { + int s; + + for (s = (i < Chan + 2) ? 1 : MaxS; s <= MaxS; s++) { + S[i] = s; + NextB(Chan, i, MaxB, MaxS + 1 - s); + } +} + +/* Channel Code - According to ANSI/AIM BC12-1998 */ +int channel_code(struct zint_symbol *symbol, unsigned char source[], int length) { + int channels, i; + int error_number = 0, range = 0, zeroes; + char hrt[9]; + + target_value = 0; + + if (length > 7) { + strcpy(symbol->errtxt, "333: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "334: Invalid characters in data"); + return error_number; + } + + if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) { + channels = 0; + } else { + channels = symbol->option_2; + } + if (channels == 0) { + channels = length + 1; + } + if (channels == 2) { + channels = 3; + } + + for (i = 0; i < length; i++) { + target_value *= 10; + target_value += ctoi((char) source[i]); + } + + switch (channels) { + case 3: if (target_value > 26) { + range = 1; + } + break; + case 4: if (target_value > 292) { + range = 1; + } + break; + case 5: if (target_value > 3493) { + range = 1; + } + break; + case 6: if (target_value > 44072) { + range = 1; + } + break; + case 7: if (target_value > 576688) { + range = 1; + } + break; + case 8: if (target_value > 7742862) { + range = 1; + } + break; + } + if (range) { + strcpy(symbol->errtxt, "335: Value out of range"); + return ZINT_ERROR_INVALID_DATA; + } + + for (i = 0; i < 11; i++) { + B[i] = 0; + S[i] = 0; + } + + B[0] = S[1] = B[1] = S[2] = B[2] = 1; + value = 0; + NextS(channels, 3, channels, channels); + + zeroes = channels - 1 - length; + memset(hrt, '0', zeroes); + strcpy(hrt + zeroes, (char *) source); + ustrcpy(symbol->text, (unsigned char *) hrt); + + expand(symbol, pattern); + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/code1.c b/3rdparty/zint-2.6.1/backend/code1.c new file mode 100644 index 0000000..5e5861a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code1.c @@ -0,0 +1,1765 @@ +/* code1.c - USS Code One */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include "common.h" +#include "code1.h" +#include "reedsol.h" +#include "large.h" +#include +#include +#include + +void horiz(struct zint_symbol *symbol, int row_no, int full) { + int i; + + if (full) { + for (i = 0; i < symbol->width; i++) { + set_module(symbol, row_no, i); + } + } else { + for (i = 1; i < symbol->width - 1; i++) { + set_module(symbol, row_no, i); + } + } +} + +void central_finder(struct zint_symbol *symbol, int start_row, int row_count, int full_rows) { + int i; + + for (i = 0; i < row_count; i++) { + if (i < full_rows) { + horiz(symbol, start_row + (i * 2), 1); + } else { + horiz(symbol, start_row + (i * 2), 0); + if (i != row_count - 1) { + set_module(symbol, start_row + (i * 2) + 1, 1); + set_module(symbol, start_row + (i * 2) + 1, symbol->width - 2); + } + } + } +} + +void vert(struct zint_symbol *symbol, int column, int height, int top) { + int i; + + if (top) { + for (i = 0; i < height; i++) { + set_module(symbol, i, column); + } + } else { + for (i = 0; i < height; i++) { + set_module(symbol, symbol->rows - i - 1, column); + } + } +} + +void spigot(struct zint_symbol *symbol, int row_no) { + int i; + + for (i = symbol->width - 1; i > 0; i--) { + if (module_is_set(symbol, row_no, i - 1)) { + set_module(symbol, row_no, i); + } + } +} + +int isedi(unsigned char input) { + int result = 0; + + if (input == 13) { + result = 1; + } + if (input == '*') { + result = 1; + } + if (input == '>') { + result = 1; + } + if (input == ' ') { + result = 1; + } + if ((input >= '0') && (input <= '9')) { + result = 1; + } + if ((input >= 'A') && (input <= 'Z')) { + result = 1; + } + + return result; +} + +int dq4bi(unsigned char source[], int sourcelen, int position) { + int i; + + for (i = position; isedi(source[position + i]) && ((position + i) < sourcelen); i++); + + if ((position + i) == sourcelen) { + /* Reached end of input */ + return 0; + } + + if (source[position + i - 1] == 13) { + return 1; + } + if (source[position + i - 1] == '*') { + return 1; + } + if (source[position + i - 1] == '>') { + return 1; + } + + return 0; +} + +static int c1_look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1) { + float ascii_count, c40_count, text_count, edi_count, byte_count; + char reduced_char; + int done, best_scheme, best_count, sp; + + /* Step J */ + if (current_mode == C1_ASCII) { + ascii_count = 0.0; + c40_count = 1.0; + text_count = 1.0; + edi_count = 1.0; + byte_count = 2.0; + } else { + ascii_count = 1.0; + c40_count = 2.0; + text_count = 2.0; + edi_count = 2.0; + byte_count = 3.0; + } + + switch (current_mode) { + case C1_C40: c40_count = 0.0; + break; + case C1_TEXT: text_count = 0.0; + break; + case C1_BYTE: byte_count = 0.0; + break; + case C1_EDI: edi_count = 0.0; + break; + } + + for (sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) { + + if (source[sp] <= 127) { + reduced_char = source[sp]; + } else { + reduced_char = source[sp] - 127; + } + + /* Step L */ + if ((source[sp] >= '0') && (source[sp] <= '9')) { + ascii_count += 0.5; + } else { + ascii_count = ceil(ascii_count); + if (source[sp] > 127) { + ascii_count += 2.0; + } else { + ascii_count += 1.0; + } + } + + /* Step M */ + done = 0; + if (reduced_char == ' ') { + c40_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= '0') && (reduced_char <= '9')) { + c40_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= 'A') && (reduced_char <= 'Z')) { + c40_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] > 127) { + c40_count += (4.0 / 3.0); + } + if (done == 0) { + c40_count += (4.0 / 3.0); + } + + /* Step N */ + done = 0; + if (reduced_char == ' ') { + text_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= '0') && (reduced_char <= '9')) { + text_count += (2.0 / 3.0); + done = 1; + } + if ((reduced_char >= 'a') && (reduced_char <= 'z')) { + text_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] > 127) { + text_count += (4.0 / 3.0); + } + if (done == 0) { + text_count += (4.0 / 3.0); + } + + /* Step O */ + done = 0; + if (source[sp] == 13) { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] == '*') { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] == '>') { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] == ' ') { + edi_count += (2.0 / 3.0); + done = 1; + } + if ((source[sp] >= '0') && (source[sp] <= '9')) { + edi_count += (2.0 / 3.0); + done = 1; + } + if ((source[sp] >= 'A') && (source[sp] <= 'Z')) { + edi_count += (2.0 / 3.0); + done = 1; + } + if (source[sp] > 127) { + edi_count += (13.0 / 3.0); + } else { + if (done == 0) { + edi_count += (10.0 / 3.0); + } + } + + /* Step P */ + if (gs1 && (source[sp] == '[')) { + byte_count += 3.0; + } else { + byte_count += 1.0; + } + + } + + ascii_count = ceil(ascii_count); + c40_count = ceil(c40_count); + text_count = ceil(text_count); + edi_count = ceil(edi_count); + byte_count = ceil(byte_count); + best_scheme = C1_ASCII; + + if (sp == sourcelen) { + /* Step K */ + best_count = (int) edi_count; + + if (text_count <= best_count) { + best_count = (int) text_count; + best_scheme = C1_TEXT; + } + + if (c40_count <= best_count) { + best_count = (int) c40_count; + best_scheme = C1_C40; + } + + if (ascii_count <= best_count) { + best_count = (int) ascii_count; + best_scheme = C1_ASCII; + } + + if (byte_count <= best_count) { + best_count = (int) byte_count; + best_scheme = C1_BYTE; + } + } else { + /* Step Q */ + + if (((edi_count + 1.0 <= ascii_count) && (edi_count + 1.0 <= c40_count)) && + ((edi_count + 1.0 <= byte_count) && (edi_count + 1.0 <= text_count))) { + best_scheme = C1_EDI; + } + + if ((c40_count + 1.0 <= ascii_count) && (c40_count + 1.0 <= text_count)) { + + if (c40_count < edi_count) { + best_scheme = C1_C40; + } else { + done = 0; + if (c40_count == edi_count) { + if (dq4bi(source, sourcelen, position)) { + best_scheme = C1_EDI; + } else { + best_scheme = C1_C40; + } + } + } + } + + if (((text_count + 1.0 <= ascii_count) && (text_count + 1.0 <= c40_count)) && + ((text_count + 1.0 <= byte_count) && (text_count + 1.0 <= edi_count))) { + best_scheme = C1_TEXT; + } + + if (((ascii_count + 1.0 <= byte_count) && (ascii_count + 1.0 <= c40_count)) && + ((ascii_count + 1.0 <= text_count) && (ascii_count + 1.0 <= edi_count))) { + best_scheme = C1_ASCII; + } + + if (((byte_count + 1.0 <= ascii_count) && (byte_count + 1.0 <= c40_count)) && + ((byte_count + 1.0 <= text_count) && (byte_count + 1.0 <= edi_count))) { + best_scheme = C1_BYTE; + } + } + + return best_scheme; +} + +int c1_encode(struct zint_symbol *symbol, unsigned char source[], unsigned int target[], int length) { + int current_mode, next_mode; + int sp, tp, gs1, i, j, p, latch; + int c40_buffer[6], c40_p; + int text_buffer[6], text_p; + int edi_buffer[6], edi_p; + char decimal_binary[40]; + int byte_start = 0; + + sp = 0; + tp = 0; + latch = 0; + memset(c40_buffer, 0, 6); + c40_p = 0; + memset(text_buffer, 0, 6); + text_p = 0; + memset(edi_buffer, 0, 6); + edi_p = 0; + strcpy(decimal_binary, ""); + + if (symbol->input_mode == GS1_MODE) { + gs1 = 1; + } else { + gs1 = 0; + } + if (gs1) { + /* FNC1 */ + target[tp] = 232; + tp++; + } + + /* Step A */ + current_mode = C1_ASCII; + next_mode = C1_ASCII; + + do { + if (current_mode != next_mode) { + /* Change mode */ + switch (next_mode) { + case C1_C40: target[tp] = 230; + tp++; + break; + case C1_TEXT: target[tp] = 239; + tp++; + break; + case C1_EDI: target[tp] = 238; + tp++; + break; + case C1_BYTE: target[tp] = 231; + tp++; + break; + } + } + + if ((current_mode != C1_BYTE) && (next_mode == C1_BYTE)) { + byte_start = tp; + } + current_mode = next_mode; + + if (current_mode == C1_ASCII) { + /* Step B - ASCII encodation */ + next_mode = C1_ASCII; + + if ((length - sp) >= 21) { + /* Step B1 */ + j = 0; + + for (i = 0; i < 21; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 21) { + next_mode = C1_DECIMAL; + bin_append(15, 4, decimal_binary); + } + } + + if ((next_mode == C1_ASCII) && ((length - sp) >= 13)) { + /* Step B2 */ + j = 0; + + for (i = 0; i < 13; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 13) { + latch = 0; + for (i = sp + 13; i < length; i++) { + if (!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { + latch = 1; + } + } + + if (!(latch)) { + next_mode = C1_DECIMAL; + bin_append(15, 4, decimal_binary); + } + } + } + + if (next_mode == C1_ASCII) { /* Step B3 */ + if (istwodigits(source, sp) && ((sp + 1) != length)) { + target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130; + tp++; + sp += 2; + } else { + if ((gs1) && (source[sp] == '[')) { + if ((length - sp) >= 15) { + /* Step B4 */ + j = 0; + + for (i = 0; i < 15; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 15) { + target[tp] = 236; /* FNC1 and change to Decimal */ + tp++; + sp++; + next_mode = C1_DECIMAL; + } + } + + if ((length - sp) >= 7) { /* Step B5 */ + j = 0; + + for (i = 0; i < 7; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 7) { + latch = 0; + for (i = sp + 7; i < length; i++) { + if (!((source[sp + i] >= '0') && (source[sp + i] <= '9'))) { + latch = 1; + } + } + + if (!(latch)) { + target[tp] = 236; /* FNC1 and change to Decimal */ + tp++; + sp++; + next_mode = C1_DECIMAL; + } + } + } + } + + if (next_mode == C1_ASCII) { + + /* Step B6 */ + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + + if (next_mode == C1_ASCII) { + if (source[sp] > 127) { + /* Step B7 */ + target[tp] = 235; /* FNC4 */ + tp++; + target[tp] = (source[sp] - 128) + 1; + tp++; + sp++; + } else { + /* Step B8 */ + if ((gs1) && (source[sp] == '[')) { + target[tp] = 232; /* FNC1 */ + tp++; + sp++; + } else { + target[tp] = source[sp] + 1; + tp++; + sp++; + } + } + } + } + } + } + } + + if (current_mode == C1_C40) { + /* Step C - C40 encodation */ + int shift_set, value, done = 0, latch = 0; + + next_mode = C1_C40; + if (c40_p == 0) { + if ((length - sp) >= 12) { + j = 0; + + for (i = 0; i < 12; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 12) { + next_mode = C1_ASCII; + done = 1; + } + } + + if ((length - sp) >= 8) { + j = 0; + + for (i = 0; i < 8; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if ((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for (j = sp + 8; j < length; j++) { + if ((source[j] <= '0') || (source[j] >= '9')) { + latch = 0; + } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; + done = 1; + } + } + + if (!(done)) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if (next_mode != C1_C40) { + target[tp] = 255; /* Unlatch */ + tp++; + } else { + if (source[sp] > 127) { + c40_buffer[c40_p] = 1; + c40_p++; + c40_buffer[c40_p] = 30; /* Upper Shift */ + c40_p++; + shift_set = c40_shift[source[sp] - 128]; + value = c40_value[source[sp] - 128]; + } else { + shift_set = c40_shift[source[sp]]; + value = c40_value[source[sp]]; + } + + if (gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if (shift_set != 0) { + c40_buffer[c40_p] = shift_set - 1; + c40_p++; + } + c40_buffer[c40_p] = value; + c40_p++; + + if (c40_p >= 3) { + int iv; + + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + + c40_buffer[0] = c40_buffer[3]; + c40_buffer[1] = c40_buffer[4]; + c40_buffer[2] = c40_buffer[5]; + c40_buffer[3] = 0; + c40_buffer[4] = 0; + c40_buffer[5] = 0; + c40_p -= 3; + } + sp++; + } + } + + if (current_mode == C1_TEXT) { + /* Step D - Text encodation */ + int shift_set, value, done = 0, latch = 0; + + next_mode = C1_TEXT; + if (text_p == 0) { + if ((length - sp) >= 12) { + j = 0; + + for (i = 0; i < 12; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 12) { + next_mode = C1_ASCII; + done = 1; + } + } + + if ((length - sp) >= 8) { + j = 0; + + for (i = 0; i < 8; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if ((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for (j = sp + 8; j < length; j++) { + if ((source[j] <= '0') || (source[j] >= '9')) { + latch = 0; + } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; + done = 1; + } + } + + if (!(done)) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if (next_mode != C1_TEXT) { + target[tp] = 255; + tp++; /* Unlatch */ + } else { + if (source[sp] > 127) { + text_buffer[text_p] = 1; + text_p++; + text_buffer[text_p] = 30; + text_p++; /* Upper Shift */ + shift_set = text_shift[source[sp] - 128]; + value = text_value[source[sp] - 128]; + } else { + shift_set = text_shift[source[sp]]; + value = text_value[source[sp]]; + } + + if (gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if (shift_set != 0) { + text_buffer[text_p] = shift_set - 1; + text_p++; + } + text_buffer[text_p] = value; + text_p++; + + if (text_p >= 3) { + int iv; + + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + + text_buffer[0] = text_buffer[3]; + text_buffer[1] = text_buffer[4]; + text_buffer[2] = text_buffer[5]; + text_buffer[3] = 0; + text_buffer[4] = 0; + text_buffer[5] = 0; + text_p -= 3; + } + sp++; + } + } + + if (current_mode == C1_EDI) { + /* Step E - EDI Encodation */ + int value = 0, latch = 0; + + next_mode = C1_EDI; + if (edi_p == 0) { + if ((length - sp) >= 12) { + j = 0; + + for (i = 0; i < 12; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if (j == 12) { + next_mode = C1_ASCII; + } + } + + if ((length - sp) >= 8) { + j = 0; + + for (i = 0; i < 8; i++) { + if ((source[sp + i] >= '0') && (source[sp + i] <= '9')) { + j++; + } + } + + if ((length - sp) == 8) { + latch = 1; + } else { + latch = 1; + for (j = sp + 8; j < length; j++) { + if ((source[j] <= '0') || (source[j] >= '9')) { + latch = 0; + } + } + } + + if ((j == 8) && latch) { + next_mode = C1_ASCII; + } + } + + if (!((isedi(source[sp]) && isedi(source[sp + 1])) && isedi(source[sp + 2]))) { + next_mode = C1_ASCII; + } + } + + if (next_mode != C1_EDI) { + target[tp] = 255; /* Unlatch */ + tp++; + } else { + if (source[sp] == 13) { + value = 0; + } + if (source[sp] == '*') { + value = 1; + } + if (source[sp] == '>') { + value = 2; + } + if (source[sp] == ' ') { + value = 3; + } + if ((source[sp] >= '0') && (source[sp] <= '9')) { + value = source[sp] - '0' + 4; + } + if ((source[sp] >= 'A') && (source[sp] <= 'Z')) { + value = source[sp] - 'A' + 14; + } + + edi_buffer[edi_p] = value; + edi_p++; + + if (edi_p >= 3) { + int iv; + + iv = (1600 * edi_buffer[0]) + (40 * edi_buffer[1]) + (edi_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + + edi_buffer[0] = edi_buffer[3]; + edi_buffer[1] = edi_buffer[4]; + edi_buffer[2] = edi_buffer[5]; + edi_buffer[3] = 0; + edi_buffer[4] = 0; + edi_buffer[5] = 0; + edi_p -= 3; + } + sp++; + } + } + + if (current_mode == C1_DECIMAL) { + /* Step F - Decimal encodation */ + int decimal_count, data_left; + + next_mode = C1_DECIMAL; + + data_left = length - sp; + decimal_count = 0; + + if (data_left >= 1) { + if ((source[sp] >= '0') && (source[sp] <= '9')) { + decimal_count = 1; + } + } + if (data_left >= 2) { + if ((decimal_count == 1) && ((source[sp + 1] >= '0') && (source[sp + 1] <= '9'))) { + decimal_count = 2; + } + } + if (data_left >= 3) { + if ((decimal_count == 2) && ((source[sp + 2] >= '0') && (source[sp + 2] <= '9'))) { + decimal_count = 3; + } + } + + if (decimal_count != 3) { + size_t bits_left_in_byte, target_count; + int sub_target; + /* Finish Decimal mode and go back to ASCII */ + + bin_append(63, 6, decimal_binary); /* Unlatch */ + + target_count = 3; + if (strlen(decimal_binary) <= 16) { + target_count = 2; + } + if (strlen(decimal_binary) <= 8) { + target_count = 1; + } + bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); + if (bits_left_in_byte == 8) { + bits_left_in_byte = 0; + } + + if (bits_left_in_byte == 2) { + bin_append(1, 2, decimal_binary); + } + + if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { + if (decimal_count >= 1) { + bin_append(ctoi(source[sp]) + 1, 4, decimal_binary); + sp++; + } else { + bin_append(15, 4, decimal_binary); + } + } + + if (bits_left_in_byte == 6) { + bin_append(1, 2, decimal_binary); + } + + /* Binary buffer is full - transfer to target */ + if (target_count >= 1) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count >= 2) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 8] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count == 3) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 16] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + + next_mode = C1_ASCII; + } else { + /* There are three digits - convert the value to binary */ + bin_append((100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1, 10, decimal_binary); + sp += 3; + } + + if (strlen(decimal_binary) >= 24) { + int target1 = 0, target2 = 0, target3 = 0; + char temp_binary[40]; + + /* Binary buffer is full - transfer to target */ + + for (p = 0; p < 8; p++) { + if (decimal_binary[p] == '1') { + target1 += (0x80 >> p); + } + if (decimal_binary[p + 8] == '1') { + target2 += (0x80 >> p); + } + if (decimal_binary[p + 16] == '1') { + target3 += (0x80 >> p); + } + } + target[tp] = target1; + tp++; + target[tp] = target2; + tp++; + target[tp] = target3; + tp++; + + strcpy(temp_binary, ""); + if (strlen(decimal_binary) > 24) { + for (i = 0; i <= (int) (strlen(decimal_binary) - 24); i++) { + temp_binary[i] = decimal_binary[i + 24]; + } + strcpy(decimal_binary, temp_binary); + } + } + } + + if (current_mode == C1_BYTE) { + next_mode = C1_BYTE; + + if (gs1 && (source[sp] == '[')) { + next_mode = C1_ASCII; + } else { + if (source[sp] <= 127) { + next_mode = c1_look_ahead_test(source, length, sp, current_mode, gs1); + } + } + + if (next_mode != C1_BYTE) { + /* Insert byte field length */ + if ((tp - byte_start) <= 249) { + for (i = tp; i >= byte_start; i--) { + target[i + 1] = target[i]; + } + target[byte_start] = (tp - byte_start); + tp++; + } else { + for (i = tp; i >= byte_start; i--) { + target[i + 2] = target[i]; + } + target[byte_start] = 249 + ((tp - byte_start) / 250); + target[byte_start + 1] = ((tp - byte_start) % 250); + tp += 2; + } + } else { + target[tp] = source[sp]; + tp++; + sp++; + } + } + + if (tp > 1480) { + /* Data is too large for symbol */ + strcpy(symbol->errtxt, "511: Input data too long"); + return 0; + } + } while (sp < length); + + /* Empty buffers */ + if (c40_p == 2) { + int iv; + + c40_buffer[2] = 1; + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + if (c40_p == 1) { + int iv; + + c40_buffer[1] = 1; + c40_buffer[2] = 31; /* Pad */ + iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + if (text_p == 2) { + int iv; + + text_buffer[2] = 1; + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + if (text_p == 1) { + int iv; + + text_buffer[1] = 1; + text_buffer[2] = 31; /* Pad */ + iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1; + target[tp] = iv / 256; + tp++; + target[tp] = iv % 256; + tp++; + target[tp] = 255; + tp++; /* Unlatch */ + } + + if (current_mode == C1_DECIMAL) { + size_t bits_left_in_byte, target_count; + int sub_target; + /* Finish Decimal mode and go back to ASCII */ + + bin_append(63, 6, decimal_binary); /* Unlatch */ + + target_count = 3; + if (strlen(decimal_binary) <= 16) { + target_count = 2; + } + if (strlen(decimal_binary) <= 8) { + target_count = 1; + } + bits_left_in_byte = (8 * target_count) - strlen(decimal_binary); + if (bits_left_in_byte == 8) { + bits_left_in_byte = 0; + } + + if (bits_left_in_byte == 2) { + bin_append(1, 2, decimal_binary); + } + + if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) { + bin_append(15, 4, decimal_binary); + } + + if (bits_left_in_byte == 6) { + bin_append(1, 2, decimal_binary); + } + + /* Binary buffer is full - transfer to target */ + if (target_count >= 1) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count >= 2) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 8] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + if (target_count == 3) { + sub_target = 0; + + for (i = 0; i < 8; i++) { + if (decimal_binary[i + 16] == '1') { + sub_target += 128 >> i; + } + } + target[tp] = sub_target; + tp++; + } + } + + if (current_mode == C1_BYTE) { + /* Insert byte field length */ + if ((tp - byte_start) <= 249) { + for (i = tp; i >= byte_start; i--) { + target[i + 1] = target[i]; + } + target[byte_start] = (tp - byte_start); + tp++; + } else { + for (i = tp; i >= byte_start; i--) { + target[i + 2] = target[i]; + } + target[byte_start] = 249 + ((tp - byte_start) / 250); + target[byte_start + 1] = ((tp - byte_start) % 250); + tp += 2; + } + } + + /* Re-check length of data */ + if (tp > 1480) { + /* Data is too large for symbol */ + strcpy(symbol->errtxt, "512: Input data too long"); + return 0; + } + /* + printf("targets:\n"); + for(i = 0; i < tp; i++) { + printf("[%d]", target[i]); + } + printf("\n"); + */ + return tp; +} + +void block_copy(struct zint_symbol *symbol, char grid[][120], int start_row, int start_col, int height, int width, int row_offset, int col_offset) { + int i, j; + + for (i = start_row; i < (start_row + height); i++) { + for (j = start_col; j < (start_col + width); j++) { + if (grid[i][j] == '1') { + set_module(symbol, i + row_offset, j + col_offset); + } + } + } +} + +int code_one(struct zint_symbol *symbol, unsigned char source[], int length) { + int size = 1, i, j, data_blocks; + + char datagrid[136][120]; + int row, col; + int sub_version = 0; + + if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) { + strcpy(symbol->errtxt, "513: Invalid symbol size"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (symbol->option_2 == 9) { + /* Version S */ + int codewords; + short int elreg[112]; + unsigned int data[15], ecc[15]; + int stream[30]; + int block_width; + + if (length > 18) { + strcpy(symbol->errtxt, "514: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "515: Invalid input data (Version S encodes numeric input only)"); + return ZINT_ERROR_INVALID_DATA; + } + + sub_version = 3; + codewords = 12; + block_width = 6; /* Version S-30 */ + if (length <= 12) { + /* Version S-20 */ + sub_version = 2; + codewords = 8; + block_width = 4; + } + if (length <= 6) { + /* Version S-10 */ + sub_version = 1; + codewords = 4; + block_width = 2; + } + + binary_load(elreg, (char *) source, length); + + for (i = 0; i < 15; i++) { + data[i] = 0; + ecc[i] = 0; + } + + for (i = 0; i < codewords; i++) { + data[codewords - i - 1] += 1 * elreg[(i * 5)]; + data[codewords - i - 1] += 2 * elreg[(i * 5) + 1]; + data[codewords - i - 1] += 4 * elreg[(i * 5) + 2]; + data[codewords - i - 1] += 8 * elreg[(i * 5) + 3]; + data[codewords - i - 1] += 16 * elreg[(i * 5) + 4]; + } + + rs_init_gf(0x25); + rs_init_code(codewords, 1); + rs_encode_long(codewords, data, ecc); + rs_free(); + + for (i = 0; i < codewords; i++) { + stream[i] = data[i]; + stream[i + codewords] = ecc[codewords - i - 1]; + } + + for (i = 0; i < 136; i++) { + for (j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for (row = 0; row < 2; row++) { + for (col = 0; col < block_width; col++) { + if (stream[i] & 0x10) { + datagrid[row * 2][col * 5] = '1'; + } + if (stream[i] & 0x08) { + datagrid[row * 2][(col * 5) + 1] = '1'; + } + if (stream[i] & 0x04) { + datagrid[row * 2][(col * 5) + 2] = '1'; + } + if (stream[i] & 0x02) { + datagrid[(row * 2) + 1][col * 5] = '1'; + } + if (stream[i] & 0x01) { + datagrid[(row * 2) + 1][(col * 5) + 1] = '1'; + } + if (stream[i + 1] & 0x10) { + datagrid[row * 2][(col * 5) + 3] = '1'; + } + if (stream[i + 1] & 0x08) { + datagrid[row * 2][(col * 5) + 4] = '1'; + } + if (stream[i + 1] & 0x04) { + datagrid[(row * 2) + 1][(col * 5) + 2] = '1'; + } + if (stream[i + 1] & 0x02) { + datagrid[(row * 2) + 1][(col * 5) + 3] = '1'; + } + if (stream[i + 1] & 0x01) { + datagrid[(row * 2) + 1][(col * 5) + 4] = '1'; + } + i += 2; + } + } + + size = 9; + symbol->rows = 8; + symbol->width = 10 * sub_version + 1; + } + + if (symbol->option_2 == 10) { + /* Version T */ + unsigned int data[40], ecc[25]; + unsigned int stream[65]; + int data_length; + int data_cw, ecc_cw, block_width; + + for (i = 0; i < 40; i++) { + data[i] = 0; + } + data_length = c1_encode(symbol, source, data, length); + + if (data_length == 0) { + return ZINT_ERROR_TOO_LONG; + } + + if (data_length > 38) { + strcpy(symbol->errtxt, "516: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + size = 10; + sub_version = 3; + data_cw = 38; + ecc_cw = 22; + block_width = 12; + if (data_length <= 24) { + sub_version = 2; + data_cw = 24; + ecc_cw = 16; + block_width = 8; + } + if (data_length <= 10) { + sub_version = 1; + data_cw = 10; + ecc_cw = 10; + block_width = 4; + } + + for (i = data_length; i < data_cw; i++) { + data[i] = 129; /* Pad */ + } + + /* Calculate error correction data */ + rs_init_gf(0x12d); + rs_init_code(ecc_cw, 1); + rs_encode_long(data_cw, data, ecc); + rs_free(); + + /* "Stream" combines data and error correction data */ + for (i = 0; i < data_cw; i++) { + stream[i] = data[i]; + } + for (i = 0; i < ecc_cw; i++) { + stream[data_cw + i] = ecc[ecc_cw - i - 1]; + } + + for (i = 0; i < 136; i++) { + for (j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for (row = 0; row < 5; row++) { + for (col = 0; col < block_width; col++) { + if (stream[i] & 0x80) { + datagrid[row * 2][col * 4] = '1'; + } + if (stream[i] & 0x40) { + datagrid[row * 2][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x20) { + datagrid[row * 2][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x10) { + datagrid[row * 2][(col * 4) + 3] = '1'; + } + if (stream[i] & 0x08) { + datagrid[(row * 2) + 1][col * 4] = '1'; + } + if (stream[i] & 0x04) { + datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x02) { + datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x01) { + datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; + } + i++; + } + } + + symbol->rows = 16; + symbol->width = (sub_version * 16) + 1; + } + + if ((symbol->option_2 != 9) && (symbol->option_2 != 10)) { + /* Version A to H */ + unsigned int data[1500], ecc[600]; + unsigned int sub_data[190], sub_ecc[75]; + unsigned int stream[2100]; + int data_length; + + for (i = 0; i < 1500; i++) { + data[i] = 0; + } + data_length = c1_encode(symbol, source, data, length); + + if (data_length == 0) { + strcpy(symbol->errtxt, "517: Input data is too long"); + return ZINT_ERROR_TOO_LONG; + } + + for (i = 7; i >= 0; i--) { + if (c1_data_length[i] >= data_length) { + size = i + 1; + } + } + + if (symbol->option_2 > size) { + size = symbol->option_2; + } + + if ((symbol-> option_2 != 0) && (symbol->option_2 < size)) { + strcpy(symbol->errtxt, "518: Input too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + + for (i = data_length; i < c1_data_length[size - 1]; i++) { + data[i] = 129; /* Pad */ + } + + /* Calculate error correction data */ + data_length = c1_data_length[size - 1]; + for (i = 0; i < 190; i++) { + sub_data[i] = 0; + } + for (i = 0; i < 75; i++) { + sub_ecc[i] = 0; + } + + data_blocks = c1_blocks[size - 1]; + + rs_init_gf(0x12d); + rs_init_code(c1_ecc_blocks[size - 1], 0); + for (i = 0; i < data_blocks; i++) { + for (j = 0; j < c1_data_blocks[size - 1]; j++) { + + sub_data[j] = data[j * data_blocks + i]; + } + rs_encode_long(c1_data_blocks[size - 1], sub_data, sub_ecc); + for (j = 0; j < c1_ecc_blocks[size - 1]; j++) { + ecc[c1_ecc_length[size - 1] - (j * data_blocks + i) - 1] = sub_ecc[j]; + } + } + rs_free(); + + /* "Stream" combines data and error correction data */ + for (i = 0; i < data_length; i++) { + stream[i] = data[i]; + } + for (i = 0; i < c1_ecc_length[size - 1]; i++) { + stream[data_length + i] = ecc[i]; + } + + for (i = 0; i < 136; i++) { + for (j = 0; j < 120; j++) { + datagrid[i][j] = '0'; + } + } + + i = 0; + for (row = 0; row < c1_grid_height[size - 1]; row++) { + for (col = 0; col < c1_grid_width[size - 1]; col++) { + if (stream[i] & 0x80) { + datagrid[row * 2][col * 4] = '1'; + } + if (stream[i] & 0x40) { + datagrid[row * 2][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x20) { + datagrid[row * 2][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x10) { + datagrid[row * 2][(col * 4) + 3] = '1'; + } + if (stream[i] & 0x08) { + datagrid[(row * 2) + 1][col * 4] = '1'; + } + if (stream[i] & 0x04) { + datagrid[(row * 2) + 1][(col * 4) + 1] = '1'; + } + if (stream[i] & 0x02) { + datagrid[(row * 2) + 1][(col * 4) + 2] = '1'; + } + if (stream[i] & 0x01) { + datagrid[(row * 2) + 1][(col * 4) + 3] = '1'; + } + i++; + } + } + + symbol->rows = c1_height[size - 1]; + symbol->width = c1_width[size - 1]; + } + + switch (size) { + case 1: /* Version A */ + central_finder(symbol, 6, 3, 1); + vert(symbol, 4, 6, 1); + vert(symbol, 12, 5, 0); + set_module(symbol, 5, 12); + spigot(symbol, 0); + spigot(symbol, 15); + block_copy(symbol, datagrid, 0, 0, 5, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 5, 12, 0, 2); + block_copy(symbol, datagrid, 5, 0, 5, 12, 6, 0); + block_copy(symbol, datagrid, 5, 12, 5, 4, 6, 2); + break; + case 2: /* Version B */ + central_finder(symbol, 8, 4, 1); + vert(symbol, 4, 8, 1); + vert(symbol, 16, 7, 0); + set_module(symbol, 7, 16); + spigot(symbol, 0); + spigot(symbol, 21); + block_copy(symbol, datagrid, 0, 0, 7, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 7, 16, 0, 2); + block_copy(symbol, datagrid, 7, 0, 7, 16, 8, 0); + block_copy(symbol, datagrid, 7, 16, 7, 4, 8, 2); + break; + case 3: /* Version C */ + central_finder(symbol, 11, 4, 2); + vert(symbol, 4, 11, 1); + vert(symbol, 26, 13, 1); + vert(symbol, 4, 10, 0); + vert(symbol, 26, 10, 0); + spigot(symbol, 0); + spigot(symbol, 27); + block_copy(symbol, datagrid, 0, 0, 10, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 10, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 10, 4, 0, 4); + block_copy(symbol, datagrid, 10, 0, 10, 4, 8, 0); + block_copy(symbol, datagrid, 10, 4, 10, 20, 8, 2); + block_copy(symbol, datagrid, 10, 24, 10, 4, 8, 4); + break; + case 4: /* Version D */ + central_finder(symbol, 16, 5, 1); + vert(symbol, 4, 16, 1); + vert(symbol, 20, 16, 1); + vert(symbol, 36, 16, 1); + vert(symbol, 4, 15, 0); + vert(symbol, 20, 15, 0); + vert(symbol, 36, 15, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 27); + spigot(symbol, 39); + block_copy(symbol, datagrid, 0, 0, 15, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 15, 14, 0, 2); + block_copy(symbol, datagrid, 0, 18, 15, 14, 0, 4); + block_copy(symbol, datagrid, 0, 32, 15, 4, 0, 6); + block_copy(symbol, datagrid, 15, 0, 15, 4, 10, 0); + block_copy(symbol, datagrid, 15, 4, 15, 14, 10, 2); + block_copy(symbol, datagrid, 15, 18, 15, 14, 10, 4); + block_copy(symbol, datagrid, 15, 32, 15, 4, 10, 6); + break; + case 5: /* Version E */ + central_finder(symbol, 22, 5, 2); + vert(symbol, 4, 22, 1); + vert(symbol, 26, 24, 1); + vert(symbol, 48, 22, 1); + vert(symbol, 4, 21, 0); + vert(symbol, 26, 21, 0); + vert(symbol, 48, 21, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 39); + spigot(symbol, 51); + block_copy(symbol, datagrid, 0, 0, 21, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 21, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 21, 20, 0, 4); + block_copy(symbol, datagrid, 0, 44, 21, 4, 0, 6); + block_copy(symbol, datagrid, 21, 0, 21, 4, 10, 0); + block_copy(symbol, datagrid, 21, 4, 21, 20, 10, 2); + block_copy(symbol, datagrid, 21, 24, 21, 20, 10, 4); + block_copy(symbol, datagrid, 21, 44, 21, 4, 10, 6); + break; + case 6: /* Version F */ + central_finder(symbol, 31, 5, 3); + vert(symbol, 4, 31, 1); + vert(symbol, 26, 35, 1); + vert(symbol, 48, 31, 1); + vert(symbol, 70, 35, 1); + vert(symbol, 4, 30, 0); + vert(symbol, 26, 30, 0); + vert(symbol, 48, 30, 0); + vert(symbol, 70, 30, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 45); + spigot(symbol, 57); + spigot(symbol, 69); + block_copy(symbol, datagrid, 0, 0, 30, 4, 0, 0); + block_copy(symbol, datagrid, 0, 4, 30, 20, 0, 2); + block_copy(symbol, datagrid, 0, 24, 30, 20, 0, 4); + block_copy(symbol, datagrid, 0, 44, 30, 20, 0, 6); + block_copy(symbol, datagrid, 0, 64, 30, 4, 0, 8); + block_copy(symbol, datagrid, 30, 0, 30, 4, 10, 0); + block_copy(symbol, datagrid, 30, 4, 30, 20, 10, 2); + block_copy(symbol, datagrid, 30, 24, 30, 20, 10, 4); + block_copy(symbol, datagrid, 30, 44, 30, 20, 10, 6); + block_copy(symbol, datagrid, 30, 64, 30, 4, 10, 8); + break; + case 7: /* Version G */ + central_finder(symbol, 47, 6, 2); + vert(symbol, 6, 47, 1); + vert(symbol, 27, 49, 1); + vert(symbol, 48, 47, 1); + vert(symbol, 69, 49, 1); + vert(symbol, 90, 47, 1); + vert(symbol, 6, 46, 0); + vert(symbol, 27, 46, 0); + vert(symbol, 48, 46, 0); + vert(symbol, 69, 46, 0); + vert(symbol, 90, 46, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 36); + spigot(symbol, 67); + spigot(symbol, 79); + spigot(symbol, 91); + spigot(symbol, 103); + block_copy(symbol, datagrid, 0, 0, 46, 6, 0, 0); + block_copy(symbol, datagrid, 0, 6, 46, 19, 0, 2); + block_copy(symbol, datagrid, 0, 25, 46, 19, 0, 4); + block_copy(symbol, datagrid, 0, 44, 46, 19, 0, 6); + block_copy(symbol, datagrid, 0, 63, 46, 19, 0, 8); + block_copy(symbol, datagrid, 0, 82, 46, 6, 0, 10); + block_copy(symbol, datagrid, 46, 0, 46, 6, 12, 0); + block_copy(symbol, datagrid, 46, 6, 46, 19, 12, 2); + block_copy(symbol, datagrid, 46, 25, 46, 19, 12, 4); + block_copy(symbol, datagrid, 46, 44, 46, 19, 12, 6); + block_copy(symbol, datagrid, 46, 63, 46, 19, 12, 8); + block_copy(symbol, datagrid, 46, 82, 46, 6, 12, 10); + break; + case 8: /* Version H */ + central_finder(symbol, 69, 6, 3); + vert(symbol, 6, 69, 1); + vert(symbol, 26, 73, 1); + vert(symbol, 46, 69, 1); + vert(symbol, 66, 73, 1); + vert(symbol, 86, 69, 1); + vert(symbol, 106, 73, 1); + vert(symbol, 126, 69, 1); + vert(symbol, 6, 68, 0); + vert(symbol, 26, 68, 0); + vert(symbol, 46, 68, 0); + vert(symbol, 66, 68, 0); + vert(symbol, 86, 68, 0); + vert(symbol, 106, 68, 0); + vert(symbol, 126, 68, 0); + spigot(symbol, 0); + spigot(symbol, 12); + spigot(symbol, 24); + spigot(symbol, 36); + spigot(symbol, 48); + spigot(symbol, 60); + spigot(symbol, 87); + spigot(symbol, 99); + spigot(symbol, 111); + spigot(symbol, 123); + spigot(symbol, 135); + spigot(symbol, 147); + block_copy(symbol, datagrid, 0, 0, 68, 6, 0, 0); + block_copy(symbol, datagrid, 0, 6, 68, 18, 0, 2); + block_copy(symbol, datagrid, 0, 24, 68, 18, 0, 4); + block_copy(symbol, datagrid, 0, 42, 68, 18, 0, 6); + block_copy(symbol, datagrid, 0, 60, 68, 18, 0, 8); + block_copy(symbol, datagrid, 0, 78, 68, 18, 0, 10); + block_copy(symbol, datagrid, 0, 96, 68, 18, 0, 12); + block_copy(symbol, datagrid, 0, 114, 68, 6, 0, 14); + block_copy(symbol, datagrid, 68, 0, 68, 6, 12, 0); + block_copy(symbol, datagrid, 68, 6, 68, 18, 12, 2); + block_copy(symbol, datagrid, 68, 24, 68, 18, 12, 4); + block_copy(symbol, datagrid, 68, 42, 68, 18, 12, 6); + block_copy(symbol, datagrid, 68, 60, 68, 18, 12, 8); + block_copy(symbol, datagrid, 68, 78, 68, 18, 12, 10); + block_copy(symbol, datagrid, 68, 96, 68, 18, 12, 12); + block_copy(symbol, datagrid, 68, 114, 68, 6, 12, 14); + break; + case 9: /* Version S */ + horiz(symbol, 5, 1); + horiz(symbol, 7, 1); + set_module(symbol, 6, 0); + set_module(symbol, 6, symbol->width - 1); + unset_module(symbol, 7, 1); + unset_module(symbol, 7, symbol->width - 2); + switch (sub_version) { + case 1: /* Version S-10 */ + set_module(symbol, 0, 5); + block_copy(symbol, datagrid, 0, 0, 4, 5, 0, 0); + block_copy(symbol, datagrid, 0, 5, 4, 5, 0, 1); + break; + case 2: /* Version S-20 */ + set_module(symbol, 0, 10); + set_module(symbol, 4, 10); + block_copy(symbol, datagrid, 0, 0, 4, 10, 0, 0); + block_copy(symbol, datagrid, 0, 10, 4, 10, 0, 1); + break; + case 3: /* Version S-30 */ + set_module(symbol, 0, 15); + set_module(symbol, 4, 15); + set_module(symbol, 6, 15); + block_copy(symbol, datagrid, 0, 0, 4, 15, 0, 0); + block_copy(symbol, datagrid, 0, 15, 4, 15, 0, 1); + break; + } + break; + case 10: /* Version T */ + horiz(symbol, 11, 1); + horiz(symbol, 13, 1); + horiz(symbol, 15, 1); + set_module(symbol, 12, 0); + set_module(symbol, 12, symbol->width - 1); + set_module(symbol, 14, 0); + set_module(symbol, 14, symbol->width - 1); + unset_module(symbol, 13, 1); + unset_module(symbol, 13, symbol->width - 2); + unset_module(symbol, 15, 1); + unset_module(symbol, 15, symbol->width - 2); + switch (sub_version) { + case 1: /* Version T-16 */ + set_module(symbol, 0, 8); + set_module(symbol, 10, 8); + block_copy(symbol, datagrid, 0, 0, 10, 8, 0, 0); + block_copy(symbol, datagrid, 0, 8, 10, 8, 0, 1); + break; + case 2: /* Version T-32 */ + set_module(symbol, 0, 16); + set_module(symbol, 10, 16); + set_module(symbol, 12, 16); + block_copy(symbol, datagrid, 0, 0, 10, 16, 0, 0); + block_copy(symbol, datagrid, 0, 16, 10, 16, 0, 1); + break; + case 3: /* Verion T-48 */ + set_module(symbol, 0, 24); + set_module(symbol, 10, 24); + set_module(symbol, 12, 24); + set_module(symbol, 14, 24); + block_copy(symbol, datagrid, 0, 0, 10, 24, 0, 0); + block_copy(symbol, datagrid, 0, 24, 10, 24, 0, 1); + break; + } + break; + } + + for (i = 0; i < symbol->rows; i++) { + symbol->row_height[i] = 1; + } + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/code1.h b/3rdparty/zint-2.6.1/backend/code1.h new file mode 100644 index 0000000..e517544 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code1.h @@ -0,0 +1,102 @@ +/* code1.h - Lookup info for USS Code One */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +static const char c40_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +static const char c40_value[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 15, 16, 17, 18, 19, 20, 21, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 22, 23, 24, 25, 26, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +static const char text_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 +}; + +static const char text_value[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 15, 16, 17, 18, 19, 20, 21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 22, 23, 24, 25, 26, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31 +}; + +static const unsigned short int c1_height[] = { + 16, 22, 28, 40, 52, 70, 104, 148 +}; + +static const unsigned short int c1_width[] = { + 18, 22, 32, 42, 54, 76, 98, 134 +}; + +static const unsigned short int c1_data_length[] = { + 10, 19, 44, 91, 182, 370, 732, 1480 +}; + +static const unsigned short int c1_ecc_length[] = { + 10, 16, 26, 44, 70, 140, 280, 560 +}; + +static const unsigned short int c1_blocks[] = { + 1, 1, 1, 1, 1, 2, 4, 8 +}; + +static const unsigned short int c1_data_blocks[] = { + 10, 19, 44, 91, 182, 185, 183, 185 +}; + +static const unsigned short int c1_ecc_blocks[] = { + 10, 16, 26, 44, 70, 70, 70, 70 +}; + +static const unsigned short int c1_grid_width[] = { + 4, 5, 7, 9, 12, 17, 22, 30 +}; + +static const unsigned short int c1_grid_height[] = { + 5, 7, 10, 15, 21, 30, 46, 68 +}; + +#define C1_ASCII 1 +#define C1_C40 2 +#define C1_DECIMAL 3 +#define C1_TEXT 4 +#define C1_EDI 5 +#define C1_BYTE 6 \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/code128.c b/3rdparty/zint-2.6.1/backend/code128.c new file mode 100644 index 0000000..54ccf60 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code128.c @@ -0,0 +1,1088 @@ +/* code128.c - Handles Code 128 and derivatives */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + Bugfixes thanks to Christian Sakowski and BogDan Vatra + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +#define TRUE 1 +#define FALSE 0 +#define SHIFTA 90 +#define LATCHA 91 +#define SHIFTB 92 +#define LATCHB 93 +#define SHIFTC 94 +#define LATCHC 95 +#define AORB 96 +#define ABORC 97 + +#define DPDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*" + +static int list[2][170]; + +/* Code 128 tables checked against ISO/IEC 15417:2007 */ + +static const char *C128Table[107] = { + /* Code 128 character encodation - Table 1 */ + "212222", "222122", "222221", "121223", "121322", "131222", "122213", + "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", + "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", + "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", + "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", + "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", + "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", + "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", + "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", + "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", + "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", + "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", + "2331112" +}; + +/* Determine appropriate mode for a given character */ +int parunmodd(const unsigned char llyth) { + int modd; + modd = 0; + + if (llyth <= 31) { + modd = SHIFTA; + } else if ((llyth >= 48) && (llyth <= 57)) { + modd = ABORC; + } else if (llyth <= 95) { + modd = AORB; + } else if (llyth <= 127) { + modd = SHIFTB; + } else if (llyth <= 159) { + modd = SHIFTA; + } else if (llyth <= 223) { + modd = AORB; + } else { + modd = SHIFTB; + } + + return modd; +} + +/** + * bring together same type blocks + */ +void grwp(int *indexliste) { + int i, j; + + /* bring together same type blocks */ + if (*(indexliste) > 1) { + i = 1; + while (i < *(indexliste)) { + if (list[1][i - 1] == list[1][i]) { + /* bring together */ + list[0][i - 1] = list[0][i - 1] + list[0][i]; + j = i + 1; + + /* decreace the list */ + while (j < *(indexliste)) { + list[0][j - 1] = list[0][j]; + list[1][j - 1] = list[1][j]; + j++; + } + *(indexliste) = *(indexliste) - 1; + i--; + } + i++; + } + } +} + +/** + * Implements rules from ISO 15417 Annex E + */ +void dxsmooth(int *indexliste) { + int i, current, last, next, length; + + for (i = 0; i < *(indexliste); i++) { + current = list[1][i]; + length = list[0][i]; + if (i != 0) { + last = list[1][i - 1]; + } else { + last = FALSE; + } + if (i != *(indexliste) - 1) { + next = list[1][i + 1]; + } else { + next = FALSE; + } + + if (i == 0) { /* first block */ + if ((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) { + /* Rule 1a */ + list[1][i] = LATCHC; + } + if (current == ABORC) { + if (length >= 4) { + /* Rule 1b */ + list[1][i] = LATCHC; + } else { + list[1][i] = AORB; + current = AORB; + } + } + if (current == SHIFTA) { + /* Rule 1c */ + list[1][i] = LATCHA; + } + if ((current == AORB) && (next == SHIFTA)) { + /* Rule 1c */ + list[1][i] = LATCHA; + current = LATCHA; + } + if (current == AORB) { + /* Rule 1d */ + list[1][i] = LATCHB; + } + } else { + if ((current == ABORC) && (length >= 4)) { + /* Rule 3 */ + list[1][i] = LATCHC; + current = LATCHC; + } + if (current == ABORC) { + list[1][i] = AORB; + current = AORB; + } + if ((current == AORB) && (last == LATCHA)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == AORB) && (last == LATCHB)) { + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == AORB) && (next == SHIFTA)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == AORB) && (next == SHIFTB)) { + list[1][i] = LATCHB; + current = LATCHB; + } + if (current == AORB) { + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == SHIFTA) && (length > 1)) { + /* Rule 4 */ + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == SHIFTB) && (length > 1)) { + /* Rule 5 */ + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == SHIFTA) && (last == LATCHA)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == SHIFTB) && (last == LATCHB)) { + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == SHIFTA) && (last == LATCHC)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == SHIFTB) && (last == LATCHC)) { + list[1][i] = LATCHB; + current = LATCHB; + } + } /* Rule 2 is implimented elsewhere, Rule 6 is implied */ + } + grwp(indexliste); + +} + +/** + * Translate Code 128 Set A characters into barcodes. + * This set handles all control characters NULL to US. + */ +void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) { + + if (source > 127) { + if (source < 160) { + strcat(dest, C128Table[(source - 128) + 64]); + values[(*bar_chars)] = (source - 128) + 64; + } else { + strcat(dest, C128Table[(source - 128) - 32]); + values[(*bar_chars)] = (source - 128) - 32; + } + } else { + if (source < 32) { + strcat(dest, C128Table[source + 64]); + values[(*bar_chars)] = source + 64; + } else { + strcat(dest, C128Table[source - 32]); + values[(*bar_chars)] = source - 32; + } + } + (*bar_chars)++; +} + +/** + * Translate Code 128 Set B characters into barcodes. + * This set handles all characters which are not part of long numbers and not + * control characters. + */ +void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars) { + if (source > 127) { + strcat(dest, C128Table[source - 32 - 128]); + values[(*bar_chars)] = source - 32 - 128; + } else { + strcat(dest, C128Table[source - 32]); + values[(*bar_chars)] = source - 32; + } + (*bar_chars)++; +} + +/* Translate Code 128 Set C characters into barcodes + * This set handles numbers in a compressed form + */ +void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int values[], int *bar_chars) { + int weight; + + weight = (10 * ctoi(source_a)) + ctoi(source_b); + strcat(dest, C128Table[weight]); + values[(*bar_chars)] = weight; + (*bar_chars)++; +} + +/* Handle Code 128 and NVE-18 */ +int code_128(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + int i, j, k, values[170] = {0}, bar_characters, read, total_sum; + int error_number, indexchaine, indexliste, f_state; + size_t sourcelen; + char set[170] = {' '}, fset[170] = {' '}, mode, last_set, current_set = ' '; + float glyph_count; + char dest[1000]; + + error_number = 0; + strcpy(dest, ""); + + sourcelen = length; + + j = 0; + bar_characters = 0; + f_state = 0; + + if (sourcelen > 160) { + /* This only blocks rediculously long input - the actual length of the + resulting barcode depends on the type of data, so this is trapped later */ + strcpy(symbol->errtxt, "340: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Detect extended ASCII characters */ + for (i = 0; i < sourcelen; i++) { + if (source[i] >= 128) + fset[i] = 'f'; + } + fset[i] = '\0'; + + /* Decide when to latch to extended mode - Annex E note 3 */ + j = 0; + for (i = 0; i < sourcelen; i++) { + if (fset[i] == 'f') { + j++; + } else { + j = 0; + } + + if (j >= 5) { + for (k = i; k > (i - 5); k--) { + fset[k] = 'F'; + } + } + + if ((j >= 3) && (i == (sourcelen - 1))) { + for (k = i; k > (i - 3); k--) { + fset[k] = 'F'; + } + } + } + + /* Decide if it is worth reverting to 646 encodation for a few characters as described in 4.3.4.2 (d) */ + for (i = 1; i < sourcelen; i++) { + if ((fset[i - 1] == 'F') && (fset[i] == ' ')) { + /* Detected a change from 8859-1 to 646 - count how long for */ + for (j = 0; (fset[i + j] == ' ') && ((i + j) < sourcelen); j++); + if ((j < 5) || ((j < 3) && ((i + j) == (sourcelen - 1)))) { + /* Uses the same figures recommended by Annex E note 3 */ + /* Change to shifting back rather than latching back */ + for (k = 0; k < j; k++) { + fset[i + k] = 'n'; + } + } + } + } + + /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ + indexliste = 0; + indexchaine = 0; + + mode = parunmodd(source[indexchaine]); + if ((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { + mode = AORB; + } + + for (i = 0; i < 170; i++) { + list[0][i] = 0; + } + + do { + list[1][indexliste] = mode; + while ((list[1][indexliste] == mode) && (indexchaine < sourcelen)) { + list[0][indexliste]++; + indexchaine++; + mode = parunmodd(source[indexchaine]); + if ((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) { + mode = AORB; + } + } + indexliste++; + } while (indexchaine < sourcelen); + + dxsmooth(&indexliste); + + /* Resolve odd length LATCHC blocks */ + if ((list[1][0] == LATCHC) && (list[0][0] & 1)) { + /* Rule 2 */ + list[0][1]++; + list[0][0]--; + if (indexliste == 1) { + list[0][1] = 1; + list[1][1] = LATCHB; + indexliste = 2; + } + } + if (indexliste > 1) { + for (i = 1; i < indexliste; i++) { + if ((list[1][i] == LATCHC) && (list[0][i] & 1)) { + /* Rule 3b */ + list[0][i - 1]++; + list[0][i]--; + } + } + } + + /* Put set data into set[] */ + + read = 0; + for (i = 0; i < indexliste; i++) { + for (j = 0; j < list[0][i]; j++) { + switch (list[1][i]) { + case SHIFTA: set[read] = 'a'; + break; + case LATCHA: set[read] = 'A'; + break; + case SHIFTB: set[read] = 'b'; + break; + case LATCHB: set[read] = 'B'; + break; + case LATCHC: set[read] = 'C'; + break; + } + read++; + } + } + + /* Adjust for strings which start with shift characters - make them latch instead */ + if (set[0] == 'a') { + i = 0; + do { + set[i] = 'A'; + i++; + } while (set[i] == 'a'); + } + + if (set[0] == 'b') { + i = 0; + do { + set[i] = 'B'; + i++; + } while (set[i] == 'b'); + } + + /* Now we can calculate how long the barcode is going to be - and stop it from + being too long */ + last_set = ' '; + glyph_count = 0.0; + for (i = 0; i < sourcelen; i++) { + if ((set[i] == 'a') || (set[i] == 'b')) { + glyph_count = glyph_count + 1.0; + } + if ((fset[i] == 'f') || (fset[i] == 'n')) { + glyph_count = glyph_count + 1.0; + } + if (((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { + if (set[i] != last_set) { + last_set = set[i]; + glyph_count = glyph_count + 1.0; + } + } + if (i == 0) { + if (fset[i] == 'F') { + glyph_count = glyph_count + 2.0; + } + } else { + if ((fset[i] == 'F') && (fset[i - 1] != 'F')) { + glyph_count = glyph_count + 2.0; + } + if ((fset[i] != 'F') && (fset[i - 1] == 'F')) { + glyph_count = glyph_count + 2.0; + } + } + + if (set[i] == 'C') { + glyph_count = glyph_count + 0.5; + } else { + glyph_count = glyph_count + 1.0; + } + } + if (glyph_count > 60.0) { + strcpy(symbol->errtxt, "341: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* So now we know what start character to use - we can get on with it! */ + if (symbol->output_options & READER_INIT) { + /* Reader Initialisation mode */ + switch (set[0]) { + case 'A': /* Start A */ + strcat(dest, C128Table[103]); + values[0] = 103; + current_set = 'A'; + strcat(dest, C128Table[96]); /* FNC3 */ + values[1] = 96; + bar_characters++; + break; + case 'B': /* Start B */ + strcat(dest, C128Table[104]); + values[0] = 104; + current_set = 'B'; + strcat(dest, C128Table[96]); /* FNC3 */ + values[1] = 96; + bar_characters++; + break; + case 'C': /* Start C */ + strcat(dest, C128Table[104]); /* Start B */ + values[0] = 105; + strcat(dest, C128Table[96]); /* FNC3 */ + values[1] = 96; + strcat(dest, C128Table[99]); /* Code C */ + values[2] = 99; + bar_characters += 2; + current_set = 'C'; + break; + } + } else { + /* Normal mode */ + switch (set[0]) { + case 'A': /* Start A */ + strcat(dest, C128Table[103]); + values[0] = 103; + current_set = 'A'; + break; + case 'B': /* Start B */ + strcat(dest, C128Table[104]); + values[0] = 104; + current_set = 'B'; + break; + case 'C': /* Start C */ + strcat(dest, C128Table[105]); + values[0] = 105; + current_set = 'C'; + break; + } + } + bar_characters++; + last_set = set[0]; + + if (fset[0] == 'F') { + switch (current_set) { + case 'A': + strcat(dest, C128Table[101]); + strcat(dest, C128Table[101]); + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + strcat(dest, C128Table[100]); + strcat(dest, C128Table[100]); + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + + /* Encode the data */ + read = 0; + do { + + if ((read != 0) && (set[read] != current_set)) { + /* Latch different code set */ + switch (set[read]) { + case 'A': strcat(dest, C128Table[101]); + values[bar_characters] = 101; + bar_characters++; + current_set = 'A'; + break; + case 'B': strcat(dest, C128Table[100]); + values[bar_characters] = 100; + bar_characters++; + current_set = 'B'; + break; + case 'C': strcat(dest, C128Table[99]); + values[bar_characters] = 99; + bar_characters++; + current_set = 'C'; + break; + } + } + + if (read != 0) { + if ((fset[read] == 'F') && (f_state == 0)) { + /* Latch beginning of extended mode */ + switch (current_set) { + case 'A': + strcat(dest, C128Table[101]); + strcat(dest, C128Table[101]); + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + strcat(dest, C128Table[100]); + strcat(dest, C128Table[100]); + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + if ((fset[read] == ' ') && (f_state == 1)) { + /* Latch end of extended mode */ + switch (current_set) { + case 'A': + strcat(dest, C128Table[101]); + strcat(dest, C128Table[101]); + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + strcat(dest, C128Table[100]); + strcat(dest, C128Table[100]); + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 0; + } + } + + if ((fset[read] == 'f') || (fset[read] == 'n')) { + /* Shift to or from extended mode */ + switch (current_set) { + case 'A': + strcat(dest, C128Table[101]); /* FNC 4 */ + values[bar_characters] = 101; + break; + case 'B': + strcat(dest, C128Table[100]); /* FNC 4 */ + values[bar_characters] = 100; + break; + } + bar_characters++; + } + + if ((set[read] == 'a') || (set[read] == 'b')) { + /* Insert shift character */ + strcat(dest, C128Table[98]); + values[bar_characters] = 98; + bar_characters++; + } + + switch (set[read]) { /* Encode data characters */ + case 'a': + case 'A': c128_set_a(source[read], dest, values, &bar_characters); + read++; + break; + case 'b': + case 'B': c128_set_b(source[read], dest, values, &bar_characters); + read++; + break; + case 'C': c128_set_c(source[read], source[read + 1], dest, values, &bar_characters); + read += 2; + break; + } + + } while (read < sourcelen); + + /* check digit calculation */ + total_sum = 0; + + for (i = 0; i < bar_characters; i++) { + if (i > 0) { + values[i] *= i; + } + total_sum += values[i]; + } + strcat(dest, C128Table[total_sum % 103]); + + /* Stop character */ + strcat(dest, C128Table[106]); + expand(symbol, dest); + return error_number; +} + +/* Handle EAN-128 (Now known as GS1-128) */ +int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + int i, j, values[170], bar_characters, read, total_sum; + int error_number, indexchaine, indexliste; + char set[170], mode, last_set; + float glyph_count; + char dest[1000]; + int separator_row, linkage_flag, c_count; +#ifndef _MSC_VER + char reduced[length + 1]; +#else + char* reduced = (char*) _alloca(length + 1); +#endif + error_number = 0; + strcpy(dest, ""); + linkage_flag = 0; + + j = 0; + bar_characters = 0; + separator_row = 0; + + memset(values, 0, sizeof (values)); + memset(set, ' ', sizeof (set)); + + if (length > 160) { + /* This only blocks rediculously long input - the actual length of the + resulting barcode depends on the type of data, so this is trapped later */ + strcpy(symbol->errtxt, "342: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + for (i = 0; i < length; i++) { + if (source[i] == '\0') { + /* Null characters not allowed! */ + strcpy(symbol->errtxt, "343: NULL character in input data"); + return ZINT_ERROR_INVALID_DATA; + } + } + + /* if part of a composite symbol make room for the separator pattern */ + if (symbol->symbology == BARCODE_EAN128_CC) { + separator_row = symbol->rows; + symbol->row_height[symbol->rows] = 1; + symbol->rows += 1; + } + + if (symbol->input_mode != GS1_MODE) { + /* GS1 data has not been checked yet */ + error_number = gs1_verify(symbol, source, length, reduced); + if (error_number != 0) { + return error_number; + } + } + + /* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */ + indexliste = 0; + indexchaine = 0; + + mode = parunmodd(reduced[indexchaine]); + if (reduced[indexchaine] == '[') { + mode = ABORC; + } + + for (i = 0; i < 170; i++) { + list[0][i] = 0; + } + + do { + list[1][indexliste] = mode; + while ((list[1][indexliste] == mode) && (indexchaine < (int) strlen(reduced))) { + list[0][indexliste]++; + indexchaine++; + mode = parunmodd(reduced[indexchaine]); + if (reduced[indexchaine] == '[') { + mode = ABORC; + } + } + indexliste++; + } while (indexchaine < (int) strlen(reduced)); + + dxsmooth(&indexliste); + + /* Put set data into set[] */ + read = 0; + for (i = 0; i < indexliste; i++) { + for (j = 0; j < list[0][i]; j++) { + switch (list[1][i]) { + case SHIFTA: set[read] = 'a'; + break; + case LATCHA: set[read] = 'A'; + break; + case SHIFTB: set[read] = 'b'; + break; + case LATCHB: set[read] = 'B'; + break; + case LATCHC: set[read] = 'C'; + break; + } + read++; + } + } + + /* Watch out for odd-length Mode C blocks */ + c_count = 0; + for (i = 0; i < read; i++) { + if (set[i] == 'C') { + if (reduced[i] == '[') { + if (c_count & 1) { + if ((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } else { + c_count++; + } + } else { + if (c_count & 1) { + if ((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } + } + if (c_count & 1) { + if ((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + for (i = 1; i < read - 1; i++) { + if ((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { + set[i] = 'B'; + } + } + + /* Now we can calculate how long the barcode is going to be - and stop it from + being too long */ + last_set = ' '; + glyph_count = 0.0; + for (i = 0; i < (int) strlen(reduced); i++) { + if ((set[i] == 'a') || (set[i] == 'b')) { + glyph_count = glyph_count + 1.0; + } + if (((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { + if (set[i] != last_set) { + last_set = set[i]; + glyph_count = glyph_count + 1.0; + } + } + + if ((set[i] == 'C') && (reduced[i] != '[')) { + glyph_count = glyph_count + 0.5; + } else { + glyph_count = glyph_count + 1.0; + } + } + if (glyph_count > 60.0) { + strcpy(symbol->errtxt, "344: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* So now we know what start character to use - we can get on with it! */ + switch (set[0]) { + case 'A': /* Start A */ + strcat(dest, C128Table[103]); + values[0] = 103; + break; + case 'B': /* Start B */ + strcat(dest, C128Table[104]); + values[0] = 104; + break; + case 'C': /* Start C */ + strcat(dest, C128Table[105]); + values[0] = 105; + break; + } + bar_characters++; + + strcat(dest, C128Table[102]); + values[1] = 102; + bar_characters++; + + /* Encode the data */ + read = 0; + do { + + if ((read != 0) && (set[read] != set[read - 1])) { /* Latch different code set */ + switch (set[read]) { + case 'A': strcat(dest, C128Table[101]); + values[bar_characters] = 101; + bar_characters++; + break; + case 'B': strcat(dest, C128Table[100]); + values[bar_characters] = 100; + bar_characters++; + break; + case 'C': strcat(dest, C128Table[99]); + values[bar_characters] = 99; + bar_characters++; + break; + } + } + + if ((set[read] == 'a') || (set[read] == 'b')) { + /* Insert shift character */ + strcat(dest, C128Table[98]); + values[bar_characters] = 98; + bar_characters++; + } + + if (reduced[read] != '[') { + switch (set[read]) { /* Encode data characters */ + case 'A': + case 'a': + c128_set_a(reduced[read], dest, values, &bar_characters); + read++; + break; + case 'B': + case 'b': + c128_set_b(reduced[read], dest, values, &bar_characters); + read++; + break; + case 'C': + c128_set_c(reduced[read], reduced[read + 1], dest, values, &bar_characters); + read += 2; + break; + } + } else { + strcat(dest, C128Table[102]); + values[bar_characters] = 102; + bar_characters++; + read++; + } + } while (read < (int) strlen(reduced)); + + /* "...note that the linkage flag is an extra code set character between + the last data character and the Symbol Check Character" (GS1 Specification) */ + + /* Linkage flags in GS1-128 are determined by ISO/IEC 24723 section 7.4 */ + + switch (symbol->option_1) { + case 1: + case 2: + /* CC-A or CC-B 2D component */ + switch (set[strlen(reduced) - 1]) { + case 'A': linkage_flag = 100; + break; + case 'B': linkage_flag = 99; + break; + case 'C': linkage_flag = 101; + break; + } + break; + case 3: + /* CC-C 2D component */ + switch (set[strlen(reduced) - 1]) { + case 'A': linkage_flag = 99; + break; + case 'B': linkage_flag = 101; + break; + case 'C': linkage_flag = 100; + break; + } + break; + } + + if (linkage_flag != 0) { + strcat(dest, C128Table[linkage_flag]); + values[bar_characters] = linkage_flag; + bar_characters++; + } + + /* check digit calculation */ + total_sum = 0; + for (i = 0; i < bar_characters; i++) { + if (i > 0) { + values[i] *= i; + + } + total_sum += values[i]; + } + strcat(dest, C128Table[total_sum % 103]); + values[bar_characters] = total_sum % 103; + bar_characters++; + + /* Stop character */ + strcat(dest, C128Table[106]); + values[bar_characters] = 106; + bar_characters++; + expand(symbol, dest); + + /* Add the separator pattern for composite symbols */ + if (symbol->symbology == BARCODE_EAN128_CC) { + for (i = 0; i < symbol->width; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + } + + for (i = 0; i < length; i++) { + if ((source[i] != '[') && (source[i] != ']')) { + symbol->text[i] = source[i]; + } + if (source[i] == '[') { + symbol->text[i] = '('; + } + if (source[i] == ']') { + symbol->text[i] = ')'; + } + } + + return error_number; +} + +/* Add check digit if encoding an NVE18 symbol */ +int nve_18(struct zint_symbol *symbol, unsigned char source[], int length) { + int error_number, zeroes, i, nve_check, total_sum, sourcelen; + unsigned char ean128_equiv[25]; + + memset(ean128_equiv, 0, 25); + sourcelen = length; + + if (sourcelen > 17) { + strcpy(symbol->errtxt, "345: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "346: Invalid characters in data"); + return error_number; + } + zeroes = 17 - sourcelen; + strcpy((char *) ean128_equiv, "[00]"); + memset(ean128_equiv + 4, '0', zeroes); + strcpy((char*) ean128_equiv + 4 + zeroes, (char*) source); + + total_sum = 0; + for (i = sourcelen - 1; i >= 0; i--) { + total_sum += ctoi(source[i]); + + if (!(i & 1)) { + total_sum += 2 * ctoi(source[i]); + } + } + nve_check = 10 - total_sum % 10; + if (nve_check == 10) { + nve_check = 0; + } + ean128_equiv[21] = itoc(nve_check); + ean128_equiv[22] = '\0'; + + error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); + + return error_number; +} + +/* EAN-14 - A version of EAN-128 */ +int ean_14(struct zint_symbol *symbol, unsigned char source[], int length) { + int i, count, check_digit; + int error_number, zeroes; + unsigned char ean128_equiv[20]; + + if (length > 13) { + strcpy(symbol->errtxt, "347: Input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "348: Invalid character in data"); + return error_number; + } + + zeroes = 13 - length; + strcpy((char*) ean128_equiv, "[01]"); + memset(ean128_equiv + 4, '0', zeroes); + ustrcpy(ean128_equiv + 4 + zeroes, source); + + count = 0; + for (i = length - 1; i >= 0; i--) { + count += ctoi(source[i]); + + if (!(i & 1)) { + count += 2 * ctoi(source[i]); + } + } + check_digit = 10 - (count % 10); + if (check_digit == 10) { + check_digit = 0; + } + ean128_equiv[17] = itoc(check_digit); + ean128_equiv[18] = '\0'; + + error_number = ean_128(symbol, ean128_equiv, ustrlen(ean128_equiv)); + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/code16k.c b/3rdparty/zint-2.6.1/backend/code16k.c new file mode 100644 index 0000000..f4578f3 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code16k.c @@ -0,0 +1,733 @@ +/* code16k.c - Handles Code 16k stacked symbology */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* Updated to comply with BS EN 12323:2005 */ + +/* Code 16k can hold up to 77 characters or 154 numbers */ + +#include +#include +#include +#include "common.h" + +#define TRUE 1 +#define FALSE 0 +#define SHIFTA 90 +#define LATCHA 91 +#define SHIFTB 92 +#define LATCHB 93 +#define SHIFTC 94 +#define LATCHC 95 +#define AORB 96 +#define ABORC 97 +#define CANDB 98 +#define CANDBB 99 + +extern int parunmodd(const unsigned char llyth); + +static int list[2][170]; + +static const char *C16KTable[107] = { + /* EN 12323 Table 1 - "Code 16K" character encodations */ + "212222", "222122", "222221", "121223", "121322", "131222", "122213", + "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", + "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", + "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", + "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", + "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", + "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", + "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", + "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", + "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", + "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", + "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", + "211133" +}; + + +static const char *C16KStartStop[8] = { + /* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */ + "3211", "2221", "2122", "1411", "1132", "1231", "1114", "3112" +}; + +/* EN 12323 Table 5 - Start and stop values defining row numbers */ +static const int C16KStartValues[16] = { + 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 +}; + +static const int C16KStopValues[16] = { + 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3 +}; + +static void grwp16(unsigned int *indexliste) { + int i, j; + + /* bring together same type blocks */ + if (*(indexliste) > 1) { + i = 1; + while(i < (int)*(indexliste)) { + if (list[1][i - 1] == list[1][i]) { + /* bring together */ + list[0][i - 1] = list[0][i - 1] + list[0][i]; + j = i + 1; + + /* decreace the list */ + while(j < (int)*(indexliste)) { + list[0][j - 1] = list[0][j]; + list[1][j - 1] = list[1][j]; + j++; + } + *(indexliste) = *(indexliste) - 1; + i--; + } + i++; + } + } +} + +/* Implements rules from ISO 15417 Annex E */ +static void dxsmooth16(unsigned int *indexliste) { + int i, current, last, next, length; + + for(i = 0; i < (int)*(indexliste); i++) { + current = list[1][i]; + length = list[0][i]; + if (i != 0) { + last = list[1][i - 1]; + } else { + last = FALSE; + } + if (i != *(indexliste) - 1) { + next = list[1][i + 1]; + } else { + next = FALSE; + } + + if (i == 0) { + /* first block */ + if ((*(indexliste) == 1) && ((length == 2) && (current == ABORC))) { + /* Rule 1a */ + list[1][i] = LATCHC; + } + if (current == ABORC) { + if (length >= 4) { + /* Rule 1b */ + list[1][i] = LATCHC; + } else { + list[1][i] = AORB; + current = AORB; + } + } + if (current == SHIFTA) { + /* Rule 1c */ + list[1][i] = LATCHA; + } + if ((current == AORB) && (next == SHIFTA)) { + /* Rule 1c */ + list[1][i] = LATCHA; + current = LATCHA; + } + if (current == AORB) { + /* Rule 1d */ + list[1][i] = LATCHB; + } + } else { + if ((current == ABORC) && (length >= 4)) { + /* Rule 3 */ + list[1][i] = LATCHC; + current = LATCHC; + } + if (current == ABORC) { + list[1][i] = AORB; + current = AORB; + } + if ((current == AORB) && (last == LATCHA)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == AORB) && (last == LATCHB)) { + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == AORB) && (next == SHIFTA)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == AORB) && (next == SHIFTB)) { + list[1][i] = LATCHB; + current = LATCHB; + } + if (current == AORB) { + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == SHIFTA) && (length > 1)) { + /* Rule 4 */ + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == SHIFTB) && (length > 1)) { + /* Rule 5 */ + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == SHIFTA) && (last == LATCHA)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == SHIFTB) && (last == LATCHB)) { + list[1][i] = LATCHB; + current = LATCHB; + } + if ((current == SHIFTA) && (last == LATCHC)) { + list[1][i] = LATCHA; + current = LATCHA; + } + if ((current == SHIFTB) && (last == LATCHC)) { + list[1][i] = LATCHB; + current = LATCHB; + } + } /* Rule 2 is implimented elsewhere, Rule 6 is implied */ + } + grwp16(indexliste); + +} + +static void c16k_set_a(const unsigned char source, unsigned int values[], unsigned int *bar_chars) { + if (source > 127) { + if (source < 160) { + values[(*bar_chars)] = source + 64 - 128; + } else { + values[(*bar_chars)] = source - 32 - 128; + } + } else { + if (source < 32) { + values[(*bar_chars)] = source + 64; + } else { + values[(*bar_chars)] = source - 32; + } + } + (*bar_chars)++; +} + +static void c16k_set_b(const unsigned char source, unsigned int values[], unsigned int *bar_chars) { + if (source > 127) { + values[(*bar_chars)] = source - 32 - 128; + } else { + values[(*bar_chars)] = source - 32; + } + (*bar_chars)++; +} + +static void c16k_set_c(const unsigned char source_a, unsigned char source_b, unsigned int values[], unsigned int *bar_chars) { + int weight; + + weight = (10 * ctoi(source_a)) + ctoi(source_b); + values[(*bar_chars)] = weight; + (*bar_chars)++; +} + +int code16k(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + char width_pattern[100]; + int current_row, rows_needed, flip_flop, looper, first_check, second_check; + int indexchaine, f_state; + char set[160] = {' '}, fset[160] = {' '}, mode, last_set, current_set; + unsigned int pads_needed, indexliste, i, j, k, m, read, mx_reader, writer; + unsigned int values[160] = {0}; + unsigned int bar_characters; + float glyph_count; + int errornum, first_sum, second_sum; + size_t input_length; + int gs1, c_count; + + errornum = 0; + strcpy(width_pattern, ""); + input_length = length; + + if (symbol->input_mode == GS1_MODE) { + gs1 = 1; + } else { + gs1 = 0; + } + + if (input_length > 157) { + strcpy(symbol->errtxt, "420: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + bar_characters = 0; + + /* Detect extended ASCII characters */ + for (i = 0; i < (unsigned int) input_length; i++) { + if (source[i] >= 128) { + fset[i] = 'f'; + } + } + fset[i] = '\0'; + + /* Decide when to latch to extended mode */ + for (i = 0; i < (unsigned int) input_length; i++) { + j = 0; + if (fset[i] == 'f') { + do { + j++; + } while (fset[i + j] == 'f'); + if ((j >= 5) || ((j >= 3) && ((i + j) == (input_length - 1)))) { + for (k = 0; k <= j; k++) { + fset[i + k] = 'F'; + } + } + } + } + + /* Decide if it is worth reverting to 646 encodation for a few characters */ + if (input_length > 1) { + for (i = 1; i < (unsigned int) input_length; i++) { + if ((fset[i - 1] == 'F') && (fset[i] == ' ')) { + /* Detected a change from 8859-1 to 646 - count how long for */ + for (j = 0; (fset[i + j] == ' ') && ((i + j) < (unsigned int) input_length); j++); + if ((j < 5) || ((j < 3) && ((i + j) == (input_length - 1)))) { + /* Change to shifting back rather than latching back */ + for (k = 0; k < j; k++) { + fset[i + k] = 'n'; + } + } + } + } + } + /* Detect mode A, B and C characters */ + indexliste = 0; + indexchaine = 0; + + mode = parunmodd(source[indexchaine]); + if ((gs1) && (source[indexchaine] == '[')) { + mode = ABORC; + } /* FNC1 */ + + for (i = 0; i < 160; i++) { + list[0][i] = 0; + } + + do { + list[1][indexliste] = mode; + while ((list[1][indexliste] == mode) && (indexchaine < input_length)) { + list[0][indexliste]++; + indexchaine++; + mode = parunmodd(source[indexchaine]); + if ((gs1) && (source[indexchaine] == '[')) { + mode = ABORC; + } /* FNC1 */ + } + indexliste++; + } while (indexchaine < input_length); + + dxsmooth16(&indexliste); + + /* Put set data into set[] */ + read = 0; + for (i = 0; i < indexliste; i++) { + for (j = 0; j < list[0][i]; j++) { + switch (list[1][i]) { + case SHIFTA: set[read] = 'a'; + break; + case LATCHA: set[read] = 'A'; + break; + case SHIFTB: set[read] = 'b'; + break; + case LATCHB: set[read] = 'B'; + break; + case LATCHC: set[read] = 'C'; + break; + } + read++; + } + } + + /* Adjust for strings which start with shift characters - make them latch instead */ + if (set[0] == 'a') { + i = 0; + do { + set[i] = 'A'; + i++; + } while (set[i] == 'a'); + } + + if (set[0] == 'b') { + i = 0; + do { + set[i] = 'B'; + i++; + } while (set[i] == 'b'); + } + + /* Watch out for odd-length Mode C blocks */ + c_count = 0; + for (i = 0; i < read; i++) { + if (set[i] == 'C') { + if (source[i] == '[') { + if (c_count & 1) { + if ((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } else { + c_count++; + } + } else { + if (c_count & 1) { + if ((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + c_count = 0; + } + } + if (c_count & 1) { + if ((i - c_count) != 0) { + set[i - c_count] = 'B'; + } else { + set[i - 1] = 'B'; + } + } + for (i = 1; i < read - 1; i++) { + if ((set[i] == 'C') && ((set[i - 1] == 'B') && (set[i + 1] == 'B'))) { + set[i] = 'B'; + } + } + + /* Make sure the data will fit in the symbol */ + last_set = ' '; + glyph_count = 0.0; + for (i = 0; i < input_length; i++) { + if ((set[i] == 'a') || (set[i] == 'b')) { + glyph_count = glyph_count + 1.0; + } + if ((fset[i] == 'f') || (fset[i] == 'n')) { + glyph_count = glyph_count + 1.0; + } + if (((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) { + if (set[i] != last_set) { + last_set = set[i]; + glyph_count = glyph_count + 1.0; + } + } + if (i == 0) { + if ((set[i] == 'B') && (set[1] == 'C')) { + glyph_count = glyph_count - 1.0; + } + if ((set[i] == 'B') && (set[1] == 'B')) { + if (set[2] == 'C') { + glyph_count = glyph_count - 1.0; + } + } + if (fset[i] == 'F') { + glyph_count = glyph_count + 2.0; + } + } else { + if ((fset[i] == 'F') && (fset[i - 1] != 'F')) { + glyph_count = glyph_count + 2.0; + } + if ((fset[i] != 'F') && (fset[i - 1] == 'F')) { + glyph_count = glyph_count + 2.0; + } + } + + if ((set[i] == 'C') && (!((gs1) && (source[i] == '[')))) { + glyph_count = glyph_count + 0.5; + } else { + glyph_count = glyph_count + 1.0; + } + } + + if ((gs1) && (set[0] != 'A')) { + /* FNC1 can be integrated with mode character */ + glyph_count--; + } + + if (glyph_count > 77.0) { + strcpy(symbol->errtxt, "421: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Calculate how tall the symbol will be */ + glyph_count = glyph_count + 2.0; + i = (int)glyph_count; + rows_needed = (i / 5); + if (i % 5 > 0) { + rows_needed++; + } + + if (rows_needed == 1) { + rows_needed = 2; + } + + /* start with the mode character - Table 2 */ + m = 0; + switch (set[0]) { + case 'A': m = 0; + break; + case 'B': m = 1; + break; + case 'C': m = 2; + break; + } + + if (symbol->output_options & READER_INIT) { + if (m == 2) { + m = 5; + } + if (gs1) { + strcpy(symbol->errtxt, "422: Cannot use both GS1 mode and Reader Initialisation"); + return ZINT_ERROR_INVALID_OPTION; + } else { + if ((set[0] == 'B') && (set[1] == 'C')) { + m = 6; + } + } + values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ + values[bar_characters + 1] = 96; /* FNC3 */ + bar_characters += 2; + } else { + if (gs1) { + /* Integrate FNC1 */ + switch (set[0]) { + case 'B': m = 3; + break; + case 'C': m = 4; + break; + } + } else { + if ((set[0] == 'B') && (set[1] == 'C')) { + m = 5; + } + if (((set[0] == 'B') && (set[1] == 'B')) && (set[2] == 'C')) { + m = 6; + } + } + values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */ + bar_characters++; + } + + current_set = set[0]; + f_state = 0; + /* f_state remembers if we are in Extended ASCII mode (value 1) or + in ISO/IEC 646 mode (value 0) */ + if (fset[0] == 'F') { + switch (current_set) { + case 'A': + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + + read = 0; + + /* Encode the data */ + do { + + if ((read != 0) && (set[read] != set[read - 1])) { + /* Latch different code set */ + switch (set[read]) { + case 'A': + values[bar_characters] = 101; + bar_characters++; + current_set = 'A'; + break; + case 'B': + values[bar_characters] = 100; + bar_characters++; + current_set = 'B'; + break; + case 'C': + if (!((read == 1) && (set[0] == 'B'))) { + /* Not Mode C/Shift B */ + if (!((read == 2) && ((set[0] == 'B') && (set[1] == 'B')))) { + /* Not Mode C/Double Shift B */ + values[bar_characters] = 99; + bar_characters++; + } + } + current_set = 'C'; + break; + } + } + + if (read != 0) { + if ((fset[read] == 'F') && (f_state == 0)) { + /* Latch beginning of extended mode */ + switch (current_set) { + case 'A': + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 1; + } + if ((fset[read] == ' ') && (f_state == 1)) { + /* Latch end of extended mode */ + switch (current_set) { + case 'A': + values[bar_characters] = 101; + values[bar_characters + 1] = 101; + break; + case 'B': + values[bar_characters] = 100; + values[bar_characters + 1] = 100; + break; + } + bar_characters += 2; + f_state = 0; + } + } + + if ((fset[i] == 'f') || (fset[i] == 'n')) { + /* Shift extended mode */ + switch (current_set) { + case 'A': + values[bar_characters] = 101; /* FNC 4 */ + break; + case 'B': + values[bar_characters] = 100; /* FNC 4 */ + break; + } + bar_characters++; + } + + if ((set[i] == 'a') || (set[i] == 'b')) { + /* Insert shift character */ + values[bar_characters] = 98; + bar_characters++; + } + + if (!((gs1) && (source[read] == '['))) { + switch (set[read]) { /* Encode data characters */ + case 'A': + case 'a': + c16k_set_a(source[read], values, &bar_characters); + read++; + break; + case 'B': + case 'b': + c16k_set_b(source[read], values, &bar_characters); + read++; + break; + case 'C': c16k_set_c(source[read], source[read + 1], values, &bar_characters); + read += 2; + break; + } + } else { + values[bar_characters] = 102; + bar_characters++; + read++; + } + } while (read < ustrlen(source)); + + pads_needed = 5 - ((bar_characters + 2) % 5); + if (pads_needed == 5) { + pads_needed = 0; + } + if ((bar_characters + pads_needed) < 8) { + pads_needed += 8 - (bar_characters + pads_needed); + } + for (i = 0; i < pads_needed; i++) { + values[bar_characters] = 106; + bar_characters++; + } + + /* Calculate check digits */ + first_sum = 0; + second_sum = 0; + for (i = 0; i < bar_characters; i++) { + first_sum += (i + 2) * values[i]; + second_sum += (i + 1) * values[i]; + } + first_check = first_sum % 107; + second_sum += first_check * (bar_characters + 1); + second_check = second_sum % 107; + values[bar_characters] = first_check; + values[bar_characters + 1] = second_check; + bar_characters += 2; + + for (current_row = 0; current_row < rows_needed; current_row++) { + + strcpy(width_pattern, ""); + strcat(width_pattern, C16KStartStop[C16KStartValues[current_row]]); + strcat(width_pattern, "1"); + for (i = 0; i < 5; i++) { + strcat(width_pattern, C16KTable[values[(current_row * 5) + i]]); + } + strcat(width_pattern, C16KStartStop[C16KStopValues[current_row]]); + + /* Write the information into the symbol */ + writer = 0; + flip_flop = 1; + for (mx_reader = 0; mx_reader < strlen(width_pattern); mx_reader++) { + for (looper = 0; looper < ctoi(width_pattern[mx_reader]); looper++) { + if (flip_flop == 1) { + set_module(symbol, current_row, writer); + writer++; + } else { + writer++; + } + } + if (flip_flop == 0) { + flip_flop = 1; + } else { + flip_flop = 0; + } + } + symbol->row_height[current_row] = 10; + } + + symbol->rows = rows_needed; + symbol->width = 70; + return errornum; +} + + diff --git a/3rdparty/zint-2.6.1/backend/code49.c b/3rdparty/zint-2.6.1/backend/code49.c new file mode 100644 index 0000000..8ab92a6 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code49.c @@ -0,0 +1,345 @@ +/* code49.c - Handles Code 49 */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" +#include "code49.h" + +#define INSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%!&*" + +/* "!" represents Shift 1 and "&" represents Shift 2, "*" represents FNC1 */ + +int code_49(struct zint_symbol *symbol, unsigned char source[], const int length) { + int i, j, rows, M, x_count, y_count, z_count, posn_val, local_value; + char intermediate[170] = ""; + int codewords[170], codeword_count; + int c_grid[8][8]; /* Refers to table 3 */ + int w_grid[8][4]; /* Refets to table 2 */ + int pad_count = 0; + char pattern[80]; + int gs1; + size_t h; + + if (length > 81) { + strcpy(symbol->errtxt, "430: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + if (symbol->input_mode == GS1_MODE) { + gs1 = 1; + strcpy(intermediate, "*"); /* FNC1 */ + } else { + gs1 = 0; + } + + for (i = 0; i < length; i++) { + if (source[i] > 127) { + strcpy(symbol->errtxt, "431: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + if (gs1 && (source[i] == '[')) + strcat(intermediate, "*"); /* FNC1 */ + else + strcat(intermediate, c49_table7[source[i]]); + } + + codeword_count = 0; + i = 0; + h = strlen(intermediate); + do { + if ((intermediate[i] >= '0') && (intermediate[i] <= '9')) { + /* Numeric data */ + for (j = 0; (intermediate[i + j] >= '0') && (intermediate[i + j] <= '9'); j++); + if (j >= 5) { + /* Use Numeric Encodation Method */ + int block_count, c; + int block_remain; + int block_value; + + codewords[codeword_count] = 48; /* Numeric Shift */ + codeword_count++; + + block_count = j / 5; + block_remain = j % 5; + + for (c = 0; c < block_count; c++) { + if ((c == block_count - 1) && (block_remain == 2)) { + /* Rule (d) */ + block_value = 100000; + block_value += ctoi(intermediate[i]) * 1000; + block_value += ctoi(intermediate[i + 1]) * 100; + block_value += ctoi(intermediate[i + 2]) * 10; + block_value += ctoi(intermediate[i + 3]); + + codewords[codeword_count] = block_value / (48 * 48); + block_value = block_value - (48 * 48) * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 4; + block_value = ctoi(intermediate[i]) * 100; + block_value += ctoi(intermediate[i + 1]) * 10; + block_value += ctoi(intermediate[i + 2]); + + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 3; + } else { + block_value = ctoi(intermediate[i]) * 10000; + block_value += ctoi(intermediate[i + 1]) * 1000; + block_value += ctoi(intermediate[i + 2]) * 100; + block_value += ctoi(intermediate[i + 3]) * 10; + block_value += ctoi(intermediate[i + 4]); + + codewords[codeword_count] = block_value / (48 * 48); + block_value = block_value - (48 * 48) * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 5; + } + } + + switch (block_remain) { + case 1: + /* Rule (a) */ + codewords[codeword_count] = posn(INSET, intermediate[i]); + codeword_count++; + i++; + break; + case 3: + /* Rule (b) */ + block_value = ctoi(intermediate[i]) * 100; + block_value += ctoi(intermediate[i + 1]) * 10; + block_value += ctoi(intermediate[i + 2]); + + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 3; + break; + case 4: + /* Rule (c) */ + block_value = 100000; + block_value += ctoi(intermediate[i]) * 1000; + block_value += ctoi(intermediate[i + 1]) * 100; + block_value += ctoi(intermediate[i + 2]) * 10; + block_value += ctoi(intermediate[i + 3]); + + codewords[codeword_count] = block_value / (48 * 48); + block_value = block_value - (48 * 48) * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value / 48; + block_value = block_value - 48 * codewords[codeword_count]; + codeword_count++; + codewords[codeword_count] = block_value; + codeword_count++; + i += 4; + break; + } + if (i < h) { + /* There is more to add */ + codewords[codeword_count] = 48; /* Numeric Shift */ + codeword_count++; + } + } else { + codewords[codeword_count] = posn(INSET, intermediate[i]); + codeword_count++; + i++; + } + } else { + codewords[codeword_count] = posn(INSET, intermediate[i]); + codeword_count++; + i++; + } + } while (i < h); + + switch (codewords[0]) { + /* Set starting mode value */ + case 48: M = 2; + break; + case 43: M = 4; + break; + case 44: M = 5; + break; + default: M = 0; + break; + } + + if (M != 0) { + codeword_count--; + for (i = 0; i < codeword_count; i++) { + codewords[i] = codewords[i + 1]; + } + } + + if (codeword_count > 49) { + strcpy(symbol->errtxt, "432: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Place codewords in code character array (c grid) */ + rows = 0; + do { + for (i = 0; i < 7; i++) { + if (((rows * 7) + i) < codeword_count) { + c_grid[rows][i] = codewords[(rows * 7) + i]; + } else { + c_grid[rows][i] = 48; /* Pad */ + pad_count++; + } + } + rows++; + } while ((rows * 7) < codeword_count); + + if ((((rows <= 6) && (pad_count < 5))) || (rows > 6) || (rows == 1)) { + /* Add a row */ + for (i = 0; i < 7; i++) { + c_grid[rows][i] = 48; /* Pad */ + } + rows++; + } + + /* Add row count and mode character */ + c_grid[rows - 1][6] = (7 * (rows - 2)) + M; + + /* Add row check character */ + for (i = 0; i < rows - 1; i++) { + int row_sum = 0; + + for (j = 0; j < 7; j++) { + row_sum += c_grid[i][j]; + } + c_grid[i][7] = row_sum % 49; + } + + /* Calculate Symbol Check Characters */ + posn_val = 0; + x_count = c_grid[rows - 1][6] * 20; + y_count = c_grid[rows - 1][6] * 16; + z_count = c_grid[rows - 1][6] * 38; + for (i = 0; i < rows - 1; i++) { + for (j = 0; j < 4; j++) { + local_value = (c_grid[i][2 * j] * 49) + c_grid[i][(2 * j) + 1]; + x_count += c49_x_weight[posn_val] * local_value; + y_count += c49_y_weight[posn_val] * local_value; + z_count += c49_z_weight[posn_val] * local_value; + posn_val++; + } + } + + if (rows > 6) { + /* Add Z Symbol Check */ + c_grid[rows - 1][0] = (z_count % 2401) / 49; + c_grid[rows - 1][1] = (z_count % 2401) % 49; + } + + local_value = (c_grid[rows - 1][0] * 49) + c_grid[rows - 1][1]; + x_count += c49_x_weight[posn_val] * local_value; + y_count += c49_y_weight[posn_val] * local_value; + posn_val++; + + /* Add Y Symbol Check */ + c_grid[rows - 1][2] = (y_count % 2401) / 49; + c_grid[rows - 1][3] = (y_count % 2401) % 49; + + local_value = (c_grid[rows - 1][2] * 49) + c_grid[rows - 1][3]; + x_count += c49_x_weight[posn_val] * local_value; + + /* Add X Symbol Check */ + c_grid[rows - 1][4] = (x_count % 2401) / 49; + c_grid[rows - 1][5] = (x_count % 2401) % 49; + + /* Add last row check character */ + j = 0; + for (i = 0; i < 7; i++) { + j += c_grid[rows - 1][i]; + } + c_grid[rows - 1][7] = j % 49; + + /* Transfer data to symbol character array (w grid) */ + for (i = 0; i < rows; i++) { + for (j = 0; j < 4; j++) { + w_grid[i][j] = (c_grid[i][2 * j] * 49) + c_grid[i][(2 * j) + 1]; + } + } + + for (i = 0; i < rows; i++) { + strcpy(pattern, "10"); /* Start character */ + for (j = 0; j < 4; j++) { + if (i != (rows - 1)) { + if (c49_table4[i][j] == 'E') { + /* Even Parity */ + bin_append(c49_even_bitpattern[w_grid[i][j]], 16, pattern); + } else { + /* Odd Parity */ + bin_append(c49_odd_bitpattern[w_grid[i][j]], 16, pattern); + } + } else { + /* Last row uses all even parity */ + bin_append(c49_even_bitpattern[w_grid[i][j]], 16, pattern); + } + } + strcat(pattern, "1111"); /* Stop character */ + + /* Expand into symbol */ + symbol->row_height[i] = 10; + + for (j = 0; j < strlen(pattern); j++) { + if (pattern[j] == '1') { + set_module(symbol, i, j); + } + } + } + + symbol->rows = rows; + symbol->width = strlen(pattern); + symbol->whitespace_width = 10; + if (!(symbol->output_options & BARCODE_BIND)) { + symbol->output_options += BARCODE_BIND; + } + symbol->border_width = 2; + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/code49.h b/3rdparty/zint-2.6.1/backend/code49.h new file mode 100644 index 0000000..01dec46 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/code49.h @@ -0,0 +1,558 @@ +/* code49.h - Code 49 Tables */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* This data set taken from ANSI/AIM-BC6-2000, 4th April 2000 */ + +static const char *c49_table7[128] = { + /* Table 7: Code 49 ASCII Chart */ + "! ", "!A", "!B", "!C", "!D", "!E", "!F", "!G", "!H", "!I", "!J", "!K", "!L", + "!M", "!N", "!O", "!P", "!Q", "!R", "!S", "!T", "!U", "!V", "!W", "!X", "!Y", + "!Z", "!1", "!2", "!3", "!4", "!5", " ", "!6", "!7", "!8", "$", "%", "!9", "!0", + "!-", "!.", "!$", "+", "!/", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", + "7", "8", "9", "!+", "&1", "&2", "&3", "&4", "&5", "&6", "A", "B", "C", "D", "E", + "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z", "&7", "&8", "&9", "&0", "&-", "&.", "&A", "&B", "&C", + "&D", "&E", "&F", "&G", "&H", "&I", "&J", "&K", "&L", "&M", "&N", "&O", "&P", + "&Q", "&R", "&S", "&T", "&U", "&V", "&W", "&X", "&Y", "&Z", "&$", "&/", "&+", + "&%", "& " +}; + +/* Table 5: Check Character Weighting Values */ +static const char c49_x_weight[] = { + 1, 9, 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, + 39, 11, 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10 +}; + +static const char c49_y_weight[] = { + 9, 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, 39, + 11, 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10, 24 +}; + +static const char c49_z_weight[] = { + 31, 26, 2, 12, 17, 23, 37, 18, 22, 6, 27, 44, 15, 43, 39, 11, + 13, 5, 41, 33, 36, 8, 4, 32, 3, 19, 40, 25, 29, 10, 24, 30 +}; + +static const char *c49_table4[8] = { + /* Table 4: Row Parity Pattern for Code 49 Symbols */ + "OEEO", "EOEO", "OOEE", "EEOO", "OEOE", "EOOE", "OOOO", "EEEE" +}; + +static const unsigned short int c49_even_bitpattern[] = { + /* Appendix E - Code 49 Encodation Patterns (Even Symbol Character Parity) */ + 0xBE5C, 0xC16E, 0x86DC, 0xC126, 0x864C, 0x9EDC, 0xC726, 0x9E4C, 0xDF26, 0x82CC, + 0x8244, 0x8ECC, 0xC322, 0x8E44, 0xBECC, 0xCF22, 0xBE44, 0xC162, 0x86C4, 0xC762, + 0x9EC4, 0xDF62, 0x812E, 0x872E, 0x9F2E, 0x836E, 0x8326, 0x8F6E, 0x8F26, 0xBF6E, + 0x8166, 0x8122, 0x8766, 0x8722, 0x9F66, 0x9F22, 0x8362, 0x8F62, 0xBF62, 0xA2E0, + 0xE8B8, 0xFA2E, 0xD370, 0xF4DC, 0xD130, 0xF44C, 0xAEE0, 0xEBB8, 0xFAEE, 0xA660, + 0xE998, 0xFA66, 0xA220, 0xE888, 0xFA22, 0xD730, 0xF5CC, 0xD310, 0xF4C4, 0xAE20, + 0xEB88, 0xFAE2, 0x9170, 0xE45C, 0xD8B8, 0xF62E, 0xC9B8, 0xF26E, 0xB370, 0xC898, + 0xF226, 0xB130, 0xEC4C, 0x9770, 0xE5DC, 0x9330, 0xE4CC, 0x9110, 0xE444, 0xD888, + 0xF622, 0xCB98, 0xF2E6, 0xB730, 0xC988, 0xF262, 0xB310, 0xECC4, 0x9710, 0xE5C4, + 0xDB88, 0xF6E2, 0x88B8, 0xE22E, 0xCC5C, 0xB8B8, 0xEE2E, 0xC4DC, 0x99B8, 0xC44C, + 0x9898, 0xE626, 0xDC4C, 0x8BB8, 0xE2EE, 0x8998, 0xE266, 0xBBB8, 0x8888, 0xE222, + 0xB998, 0xCC44, 0xB888, 0xEE22, 0xC5CC, 0x9B98, 0xC4C4, 0x9988, 0xE662, 0xDCC4, + 0x8B88, 0xE2E2, 0xCDC4, 0xBB88, 0xEEE2, 0x845C, 0xC62E, 0x9C5C, 0xDE2E, 0xC26E, + 0x8CDC, 0xC226, 0x8C4C, 0xBCDC, 0xCE26, 0xBC4C, 0x85DC, 0x84CC, 0x9DDC, 0x8444, + 0x9CCC, 0xC622, 0x9C44, 0xDE22, 0xC2E6, 0x8DCC, 0xC262, 0x8CC4, 0xBDCC, 0xCE62, + 0xBCC4, 0x85C4, 0xC6E2, 0x9DC4, 0xDEE2, 0x822E, 0x8E2E, 0x866E, 0x8626, 0x9E6E, + 0x9E26, 0x82EE, 0x8266, 0x8EEE, 0x8222, 0x8E66, 0xBEEE, 0x8E22, 0xBE66, 0x86E6, + 0x8662, 0x9EE6, 0x9E62, 0x82E2, 0x8EE2, 0xBEE2, 0xA170, 0xE85C, 0xD1B8, 0xF46E, + 0xD098, 0xF426, 0xA770, 0xE9DC, 0xA330, 0xE8CC, 0xA110, 0xE844, 0xD7B8, 0xF5EE, + 0xD398, 0xF4E6, 0xD188, 0xF462, 0xAF30, 0xEBCC, 0xA710, 0xE9C4, 0xD788, 0xF5E2, + 0x90B8, 0xE42E, 0xD85C, 0xC8DC, 0xB1B8, 0xC84C, 0xB098, 0xEC26, 0x93B8, 0xE4EE, + 0x9198, 0xE466, 0x9088, 0xE422, 0xD844, 0xCBDC, 0xB7B8, 0xC9CC, 0xB398, 0xC8C4, + 0xB188, 0xEC62, 0x9798, 0xE5E6, 0x9388, 0xE4E2, 0xD9C4, 0xCBC4, 0xB788, 0xEDE2, + 0x885C, 0xCC2E, 0xB85C, 0xC46E, 0x98DC, 0xC426, 0x984C, 0xDC26, 0x89DC, 0x88CC, + 0xB9DC, 0x8844, 0xB8CC, 0xCC22, 0xB844, 0xC5EE, 0x9BDC, 0xC4E6, 0x99CC, 0xC462, + 0x98C4, 0xDC62, 0x8BCC, 0x89C4, 0xBBCC, 0xCCE2, 0xB9C4, 0xC5E2, 0x9BC4, 0xDDE2, + 0x842E, 0x9C2E, 0x8C6E, 0x8C26, 0xBC6E, 0x84EE, 0x8466, 0x9CEE, 0x8422, 0x9C66, + 0x9C22, 0x8DEE, 0x8CE6, 0xBDEE, 0x8C62, 0xBCE6, 0xBC62, 0x85E6, 0x84E2, 0x9DE6, + 0x9CE2, 0x8DE2, 0xBDE2, 0xA0B8, 0xE82E, 0xD0DC, 0xD04C, 0xA3B8, 0xE8EE, 0xA198, + 0xE866, 0xA088, 0xE822, 0xD3DC, 0xD1CC, 0xD0C4, 0xAFB8, 0xEBEE, 0xA798, 0xE9E6, + 0xA388, 0xE8E2, 0xD7CC, 0xD3C4, 0x905C, 0xD82E, 0xC86E, 0xB0DC, 0xC826, 0xB04C, + 0x91DC, 0x90CC, 0x9044, 0xD822, 0xC9EE, 0xB3DC, 0xC8E6, 0xB1CC, 0xC862, 0xB0C4, + 0x97DC, 0x93CC, 0x91C4, 0xD8E2, 0xCBE6, 0xB7CC, 0xC9E2, 0xB3C4, 0x882E, 0x986E, + 0x9826, 0x88EE, 0x8866, 0xB8EE, 0x8822, 0xB866, 0x99EE, 0x98E6, 0x9862, 0x8BEE, + 0x89E6, 0xBBEE, 0x88E2, 0xB9E6, 0xB8E2, 0x9BE6, 0x99E2, 0xA05C, 0xD06E, 0xD026, + 0xA1DC, 0xA0CC, 0xA044, 0xD1EE, 0xD0E6, 0xD062, 0xA7DC, 0xA3CC, 0xA1C4, 0xD7EE, + 0xD3E6, 0xD1E2, 0x902E, 0xB06E, 0x90EE, 0x9066, 0x9022, 0xB1EE, 0xB0E6, 0xB062, + 0x93EE, 0x91E6, 0x90E2, 0xB7EE, 0xB3E6, 0xB1E2, 0xA9C0, 0xEA70, 0xFA9C, 0xD460, + 0xF518, 0xFD46, 0xA840, 0xEA10, 0xFA84, 0xED78, 0xFB5E, 0x94E0, 0xE538, 0xF94E, + 0xDA70, 0xF69C, 0xCA30, 0xF28C, 0xB460, 0xED18, 0xFB46, 0x9420, 0xE508, 0xF942, + 0xDA10, 0xF684, 0x9AF0, 0xE6BC, 0xDD78, 0xF75E, 0x8A70, 0xE29C, 0xCD38, 0xF34E, + 0xBA70, 0xEE9C, 0xC518, 0xF146, 0x9A30, 0xE68C, 0xDD18, 0xF746, 0x8A10, 0xE284, + 0xCD08, 0xF342, 0xBA10, 0xEE84, 0x8D78, 0xE35E, 0xCEBC, 0xBD78, 0xEF5E, 0x8538, + 0xE14E, 0xC69C, 0x9D38, 0xE74E, 0xDE9C, 0xC28C, 0x8D18, 0xE346, 0xCE8C, 0xBD18, + 0xEF46, 0x8508, 0xE142, 0xC684, 0x9D08, 0xE742, 0xDE84, 0x86BC, 0xC75E, 0x9EBC, + 0xDF5E, 0x829C, 0xC34E, 0x8E9C, 0xCF4E, 0xBE9C, 0xC146, 0x868C, 0xC746, 0x9E8C, + 0xDF46, 0x8284, 0xC342, 0x8E84, 0xCF42, 0xBE84, 0x835E, 0x8F5E, 0xBF5E, 0x814E, + 0x874E, 0x9F4E, 0x8346, 0x8F46, 0xBF46, 0x8142, 0x8742, 0x9F42, 0xD2F0, 0xF4BC, + 0xADE0, 0xEB78, 0xFADE, 0xA4E0, 0xE938, 0xFA4E, 0xD670, 0xF59C, 0xD230, 0xF48C, + 0xAC60, 0xEB18, 0xFAC6, 0xA420, 0xE908, 0xFA42, 0xD610, 0xF584, 0xC978, 0xF25E, + 0xB2F0, 0xECBC, 0x96F0, 0xE5BC, 0x9270, 0xE49C, 0xD938, 0xF64E, 0xCB38, 0xF2CE, + 0xB670, 0xC918, 0xF246, 0xB230, 0xEC8C, 0x9630, 0xE58C, 0x9210, 0xE484, 0xD908, + 0xF642, 0xCB08, 0xF2C2, 0xB610, 0xED84, 0xC4BC, 0x9978, 0xE65E, 0xDCBC, 0x8B78, + 0xE2DE, 0x8938, 0xE24E, 0xBB78, 0xCC9C, 0xB938, 0xEE4E, 0xC59C, 0x9B38, 0xC48C, + 0x9918, 0xE646, 0xDC8C, 0x8B18, 0xE2C6, 0x8908, 0xE242, 0xBB18, 0xCC84, 0xB908, + 0xEE42, 0xC584, 0x9B08, 0xE6C2, 0xDD84, 0xC25E, 0x8CBC, 0xCE5E, 0xBCBC, 0x85BC, + 0x849C, 0x9DBC, 0xC64E, 0x9C9C, 0xDE4E, 0xC2CE, 0x8D9C, 0xC246, 0x8C8C, 0xBD9C, + 0xCE46, 0xBC8C, 0x858C, 0x8484, 0x9D8C, 0xC642, 0x9C84, 0xDE42, 0xC2C2, 0x8D84, + 0xCEC2, 0xBD84, 0x865E, 0x9E5E, 0x82DE, 0x824E, 0x8EDE, 0x8E4E, 0xBEDE, 0xBE4E, + 0x86CE, 0x8646, 0x9ECE, 0x9E46, 0x82C6, 0x8242, 0x8EC6, 0x8E42, 0xBEC6, 0xBE42, + 0x86C2, 0x9EC2, 0xD178, 0xF45E, 0xA6F0, 0xE9BC, 0xA270, 0xE89C, 0xD778, 0xF5DE, + 0xD338, 0xF4CE, 0xD118, 0xF446, 0xAE70, 0xEB9C, 0xA630, 0xE98C, 0xA210, 0xE884, + 0xD718, 0xF5C6, 0xD308, 0xF4C2, 0xAE10, 0xEB84, 0xC8BC, 0xB178, 0xEC5E, 0x9378, + 0xE4DE, 0x9138, 0xE44E, 0xD89C, 0xCBBC, 0xB778, 0xC99C, 0xB338, 0xC88C, 0xB118, + 0xEC46, 0x9738, 0xE5CE, 0x9318, 0xE4C6, 0x9108, 0xE442, 0xD884, 0xCB8C, 0xB718, + 0xC984, 0xB308, 0xECC2, 0x9708, 0xE5C2, 0xDB84, 0xC45E, 0x98BC, 0xDC5E, 0x89BC, + 0x889C, 0xB9BC, 0xCC4E, 0xB89C, 0xC5DE, 0x9BBC, 0xC4CE, 0x999C, 0xC446, 0x988C, + 0xDC46, 0x8B9C, 0x898C, 0xBB9C, 0x8884, 0xB98C, 0xCC42, 0xB884, 0xC5C6, 0x9B8C, + 0xC4C2, 0x9984, 0xDCC2, 0x8B84, 0xCDC2, 0xBB84, 0x8C5E, 0xBC5E, 0x84DE, 0x844E, + 0x9CDE, 0x9C4E, 0x8DDE, 0x8CCE, 0xBDDE, 0x8C46, 0xBCCE, 0xBC46, 0x85CE, 0x84C6, + 0x9DCE, 0x8442, 0x9CC6, 0x9C42, 0x8DC6, 0x8CC2, 0xBDC6, 0xBCC2, 0x85C2, 0x9DC2, + 0xD0BC, 0xA378, 0xE8DE, 0xA138, 0xE84E, 0xD3BC, 0xD19C, 0xD08C, 0xAF78, 0xEBDE, + 0xA738, 0xE9CE, 0xA318, 0xE8C6, 0xA108, 0xE842, 0xD79C, 0xD38C, 0xD184, 0xAF18, + 0xEBC6, 0xA708, 0xE9C2, 0xC85E, 0xB0BC, 0x91BC, 0x909C, 0xD84E, 0xC9DE, 0xB3BC, + 0xC8CE, 0xB19C, 0xC846, 0xB08C, 0x97BC, 0x939C, 0x918C, 0x9084, 0xD842, 0xCBCE, + 0xB79C, 0xC9C6, 0xB38C, 0xC8C2, 0xB184, 0x978C, 0x9384, 0xD9C2, 0x985E, 0x88DE, + 0x884E, 0xB8DE, 0xB84E, 0x99DE, 0x98CE, 0x9846, 0x8BDE, 0x89CE, 0xBBDE, 0x88C6, + 0xB9CE, 0x8842, 0xB8C6, 0xB842, 0x9BCE, 0x99C6, 0x98C2, 0x8BC6, 0x89C2, 0xBBC6, + 0xB9C2, 0xD05E, 0xA1BC, 0xA09C, 0xD1DE, 0xD0CE, 0xD046, 0xA7BC, 0xA39C, 0xA18C, + 0xA084, 0xD7DE, 0xD3CE, 0xD1C6, 0xD0C2, 0xAF9C, 0xA78C, 0xA384, 0xB05E, 0x90DE, + 0x904E, 0xB1DE, 0xB0CE, 0xB046, 0x93DE, 0x91CE, 0x90C6, 0x9042, 0xB7DE, 0xB3CE, + 0xB1C6, 0xB0C2, 0x97CE, 0x93C6, 0x91C2, 0xA0DE, 0xA04E, 0xA3DE, 0xA1CE, 0xA0C6, + 0xA042, 0xAFDE, 0xA7CE, 0xA3C6, 0xA1C2, 0xD4F0, 0xF53C, 0xA8E0, 0xEA38, 0xFA8E, + 0xD430, 0xF50C, 0xA820, 0xEA08, 0xFA82, 0xDAF8, 0xF6BE, 0xCA78, 0xF29E, 0xB4F0, + 0xED3C, 0x9470, 0xE51C, 0xDA38, 0xF68E, 0xCA18, 0xF286, 0xB430, 0xED0C, 0x9410, + 0xE504, 0xDA08, 0xF682, 0xCD7C, 0xBAF8, 0xEEBE, 0xC53C, 0x9A78, 0xE69E, 0xDD3C, + 0x8A38, 0xE28E, 0xCD1C, 0xBA38, 0xEE8E, 0xC50C, 0x9A18, 0xE686, 0xDD0C, 0x8A08, + 0xE282, 0xCD04, 0xBA08, 0xEE82, 0xC6BE, 0x9D7C, 0xDEBE, 0xC29E, 0x8D3C, 0xCE9E, + 0xBD3C, 0x851C, 0xC68E, 0x9D1C, 0xDE8E, 0xC286, 0x8D0C, 0xCE86, 0xBD0C, 0x8504, + 0xC682, 0x9D04, 0xDE82, 0x8EBE, 0xBEBE, 0x869E, 0x9E9E, 0x828E, 0x8E8E, 0xBE8E, + 0x8686, 0x9E86, 0x8282, 0x8E82, 0xBE82, 0xE97C, 0xD6F8, 0xF5BE, 0xD278, 0xF49E, + 0xACF0, 0xEB3C, 0xA470, 0xE91C, 0xD638, 0xF58E, 0xD218, 0xF486, 0xAC30, 0xEB0C, + 0xA410, 0xE904, 0xD608, 0xF582, 0x92F8, 0xE4BE, 0xD97C, 0xCB7C, 0xB6F8, 0xC93C, + 0xB278, 0xEC9E, 0x9678, 0xE59E, 0x9238, 0xE48E, 0xD91C, 0xCB1C, 0xB638, 0xC90C, + 0xB218, 0xEC86, 0x9618, 0xE586, 0x9208, 0xE482, 0xD904, 0xCB04, 0xB608, 0xED82, + 0x897C, 0xCCBE, 0xB97C, 0xC5BE, 0x9B7C, 0xC49E, 0x993C, 0xDC9E, 0x8B3C, 0x891C, + 0xBB3C, 0xCC8E, 0xB91C, 0xC58E, 0x9B1C, 0xC486, 0x990C, 0xDC86, 0x8B0C, 0x8904, + 0xBB0C, 0xCC82, 0xB904, 0xC582, 0x9B04, 0xDD82, 0x84BE, 0x9CBE, 0x8DBE, 0x8C9E, + 0xBDBE, 0xBC9E, 0x859E, 0x848E, 0x9D9E, 0x9C8E, 0x8D8E, 0x8C86, 0xBD8E, 0xBC86, + 0x8586, 0x8482, 0x9D86, 0x9C82, 0x8D82, 0xBD82, 0xA2F8, 0xE8BE, 0xD37C, 0xD13C, + 0xAEF8, 0xEBBE, 0xA678, 0xE99E, 0xA238, 0xE88E, 0xD73C, 0xD31C, 0xD10C, 0xAE38, + 0xEB8E, 0xA618, 0xE986, 0xA208, 0xE882, 0xD70C, 0xD304, 0x917C, 0xD8BE, 0xC9BE, + 0xB37C, 0xC89E, 0xB13C, 0x977C, 0x933C, 0x911C, 0xD88E, 0xCB9E, 0xB73C, 0xC98E, + 0xB31C, 0xC886, 0xB10C, 0x971C, 0x930C, 0x9104, 0xD882, 0xCB86, 0xB70C, 0xC982, + 0xB304, 0x88BE, 0xB8BE, 0x99BE, 0x989E, 0x8BBE, 0x899E, 0xBBBE, 0x888E, 0xB99E, + 0xB88E, 0x9B9E, 0x998E, 0x9886, 0x8B8E, 0x8986, 0xBB8E, 0x8882, 0xB986, 0xB882, + 0x9B86, 0x9982, 0xA17C, 0xD1BE, 0xD09E, 0xA77C, 0xA33C, 0xA11C, 0xD7BE, 0xD39E, + 0xD18E, 0xD086, 0xAF3C, 0xA71C, 0xA30C, 0xA104, 0xD78E, 0xD386, 0xD182, 0x90BE, + 0xB1BE, 0xB09E, 0x93BE, 0x919E, 0x908E, 0xB7BE, 0xB39E, 0xB18E, 0xB086, 0x979E, + 0x938E, 0x9186, 0x9082, 0xB78E, 0xB386, 0xB182, 0xA0BE, 0xA3BE, 0xA19E, 0xA08E, + 0xAFBE, 0xA79E, 0xA38E, 0xA186, 0xA082, 0xA9F0, 0xEA7C, 0xD478, 0xF51E, 0xA870, + 0xEA1C, 0xD418, 0xF506, 0xA810, 0xEA04, 0xED7E, 0x94F8, 0xE53E, 0xDA7C, 0xCA3C, + 0xB478, 0xED1E, 0x9438, 0xE50E, 0xDA1C, 0xCA0C, 0xB418, 0xED06, 0x9408, 0xE502, + 0xDA04, 0x9AFC, 0xDD7E, 0x8A7C, 0xCD3E, 0xBA7C, 0xC51E, 0x9A3C, 0xDD1E, 0x8A1C, + 0xCD0E, 0xBA1C, 0xC506, 0x9A0C, 0xDD06, 0x8A04, 0xCD02, 0xBA04, 0x8D7E, 0xBD7E, + 0x853E, 0x9D3E, 0x8D1E, 0xBD1E, 0x850E, 0x9D0E, 0x8D06, 0xBD06, 0x8502, 0x9D02, + 0xD2FC, 0xADF8, 0xEB7E, 0xA4F8, 0xE93E, 0xD67C, 0xD23C, 0xAC78, 0xEB1E, 0xA438, + 0xE90E, 0xD61C, 0xD20C, 0xAC18, 0xEB06, 0xA408, 0xE902, 0xC97E, 0xB2FC, 0x96FC, + 0x927C, 0xD93E, 0xCB3E, 0xB67C, 0xC91E, 0xB23C, 0x963C, 0x921C, 0xD90E, 0xCB0E, + 0xB61C, 0xC906, 0xB20C, 0x960C, 0x9204, 0xD902, 0x997E, 0x8B7E, 0x893E, 0xBB7E, + 0xB93E, 0xE4A0, 0xF928, 0xD940, 0xF650, 0xFD94, 0xCB40, 0xF2D0, 0xEDA0, 0xFB68, + 0x8940, 0xE250, 0xCCA0, 0xF328, 0xB940, 0xEE50, 0xFB94, 0xC5A0, 0xF168, 0x9B40, + 0xE6D0, 0xF9B4, 0xDDA0, 0xF768, 0xFDDA, 0x84A0, 0xE128, 0xC650, 0xF194, 0x9CA0, + 0xE728, 0xF9CA, 0xDE50, 0xF794, 0xC2D0, 0x8DA0, 0xE368, 0xCED0, 0xF3B4, 0xBDA0, + 0xEF68, 0xFBDA, 0x8250, 0xC328, 0x8E50, 0xE394, 0xCF28, 0xF3CA, 0xBE50, 0xEF94, + 0xC168, 0x86D0, 0xE1B4, 0xC768, 0xF1DA, 0x9ED0, 0xE7B4, 0xDF68, 0xF7DA, 0x8128, + 0xC194, 0x8728, 0xE1CA, 0xC794, 0x9F28, 0xE7CA, 0x8368, 0xC3B4, 0x8F68, 0xE3DA, + 0xCFB4, 0xBF68, 0xEFDA, 0xE8A0, 0xFA28, 0xD340, 0xF4D0, 0xFD34, 0xEBA0, 0xFAE8, + 0x9140, 0xE450, 0xF914, 0xD8A0, 0xF628, 0xFD8A, 0xC9A0, 0xF268, 0xB340, 0xECD0, + 0xFB34, 0x9740, 0xE5D0, 0xF974, 0xDBA0, 0xF6E8, 0xFDBA, 0x88A0, 0xE228, 0xCC50, + 0xF314, 0xB8A0, 0xEE28, 0xFB8A, 0xC4D0, 0xF134, 0x99A0, 0xE668, 0xF99A, 0xDCD0, + 0xF734, 0x8BA0, 0xE2E8, 0xCDD0, 0xF374, 0xBBA0, 0xEEE8, 0xFBBA, 0x8450, 0xE114, + 0xC628, 0xF18A, 0x9C50, 0xE714, 0xDE28, 0xF78A, 0xC268, 0x8CD0, 0xE334, 0xCE68, + 0xF39A, 0xBCD0, 0xEF34, 0x85D0, 0xE174, 0xC6E8, 0xF1BA, 0x9DD0, 0xE774, 0xDEE8, + 0xF7BA, 0x8228, 0xC314, 0x8E28, 0xE38A, 0xCF14, 0xC134, 0x8668, 0xE19A, 0xC734, + 0x9E68, 0xE79A, 0xDF34, 0x82E8, 0xC374, 0x8EE8, 0xE3BA, 0xCF74, 0xBEE8, 0xEFBA, + 0x8114, 0xC18A, 0x8714, 0xC78A, 0x8334, 0xC39A, 0x8F34, 0xCF9A, 0x8174, 0xC1BA, + 0x8774, 0xC7BA, 0x9F74, 0xDFBA, 0xA140, 0xE850, 0xFA14, 0xD1A0, 0xF468, 0xFD1A, + 0xA740, 0xE9D0, 0xFA74, 0xD7A0, 0xF5E8, 0xFD7A, 0x90A0, 0xE428, 0xF90A, 0xD850, + 0xF614, 0xC8D0, 0xF234, 0xB1A0, 0xEC68, 0xFB1A, 0x93A0, 0xE4E8, 0xF93A, 0xD9D0, + 0xF674, 0xCBD0, 0xF2F4, 0xB7A0, 0xEDE8, 0xFB7A, 0x8850, 0xE214, 0xCC28, 0xF30A, + 0xB850, 0xEE14, 0xC468, 0xF11A, 0x98D0, 0xE634, 0xDC68, 0xF71A, 0x89D0, 0xE274, + 0xCCE8, 0xF33A, 0xB9D0, 0xEE74, 0xC5E8, 0xF17A, 0x9BD0, 0xE6F4, 0xDDE8, 0xF77A, + 0x8428, 0xE10A, 0xC614, 0x9C28, 0xE70A, 0xC234, 0x8C68, 0xE31A, 0xCE34, 0xBC68, + 0xEF1A, 0x84E8, 0xE13A, 0xC674, 0x9CE8, 0xE73A, 0xDE74, 0xC2F4, 0x8DE8, 0xE37A, + 0xCEF4, 0xBDE8, 0xEF7A, 0x8214, 0xC30A, 0x8E14, 0xC11A, 0x8634, 0xC71A, 0x9E34, + 0x8274, 0xC33A, 0x8E74, 0xCF3A, 0xBE74, 0xC17A, 0x86F4, 0xC77A, 0x9EF4, 0xDF7A, + 0x810A, 0x870A, 0x831A, 0x8F1A, 0x813A, 0x873A, 0x9F3A, 0x837A, 0x8F7A, 0xBF7A, + 0xA0A0, 0xE828, 0xFA0A, 0xD0D0, 0xF434, 0xA3A0, 0xE8E8, 0xFA3A, 0xD3D0, 0xF4F4, + 0xAFA0, 0xEBE8, 0xFAFA, 0x9050, 0xE414, 0xD828, 0xF60A, 0xC868, 0xF21A, 0xB0D0, + 0xEC34, 0x91D0, 0xE474, 0xD8E8, 0xF63A, 0xC9E8, 0xF27A, 0xB3D0, 0xECF4, 0x97D0, + 0xE5F4, 0xDBE8, 0xF6FA, 0x8828, 0xE20A, 0xCC14, 0xC434, 0x9868, 0xE61A, 0xDC34, + 0x88E8, 0xE23A, 0xCC74, 0xB8E8, 0xEE3A, 0xC4F4, 0x99E8, 0xE67A, 0xDCF4, 0x8BE8, + 0xE2FA, 0xCDF4, 0xBBE8, 0xEEFA, 0x8414, 0xC60A, 0xC21A, 0x8C34, 0xCE1A, 0x8474, + 0xC63A, 0x9C74, 0xDE3A, 0xC27A, 0x8CF4, 0xCE7A, 0xBCF4, 0x85F4, 0xC6FA, 0x9DF4, + 0xDEFA, 0x820A, 0x861A, 0x823A, 0x8E3A, 0x867A, 0x9E7A, 0x82FA, 0x8EFA, 0xBEFA, + 0xA050, 0xE814, 0xD068, 0xF41A, 0xA1D0, 0xE874, 0xD1E8, 0xF47A, 0xA7D0, 0xE9F4, + 0xD7E8, 0xF5FA, 0x9028, 0xE40A, 0xC834, 0xB068, 0xEC1A, 0x90E8, 0xE43A, 0xD874, + 0xC8F4, 0xB1E8, 0xEC7A, 0x93E8, 0xE4FA, 0xD9F4, 0xCBF4, 0xB7E8, 0xEDFA, 0x8814, + 0xC41A, 0x9834, 0x8874, 0xCC3A, 0xB874, 0xC47A, 0x98F4, 0xDC7A, 0x89F4, 0xCCFA, + 0xB9F4, 0xC5FA, 0x9BF4, 0xDDFA, 0x840A, 0x8C1A, 0x843A, 0x9C3A, 0x8C7A, 0xBC7A, + 0x84FA, 0x9CFA, 0x8DFA, 0xBDFA, 0xEA40, 0xFA90, 0xED60, 0xFB58, 0xE520, 0xF948, + 0xDA40, 0xF690, 0xFDA4, 0x9AC0, 0xE6B0, 0xF9AC, 0xDD60, 0xF758, 0xFDD6, 0x8A40, + 0xE290, 0xCD20, 0xF348, 0xBA40, 0xEE90, 0xFBA4, 0x8D60, 0xE358, 0xCEB0, 0xF3AC, + 0xBD60, 0xEF58, 0xFBD6, 0x8520, 0xE148, 0xC690, 0xF1A4, 0x9D20, 0xE748, 0xF9D2, + 0xDE90, 0xF7A4, 0x86B0, 0xE1AC, 0xC758, 0xF1D6, 0x9EB0, 0xE7AC, 0xDF58, 0xF7D6, + 0x8290, 0xC348, 0x8E90, 0xE3A4, 0xCF48, 0xF3D2, 0xBE90, 0xEFA4, 0x8358, 0xC3AC, + 0x8F58, 0xE3D6, 0xCFAC, 0xBF58, 0xEFD6, 0x8148, 0xC1A4, 0x8748, 0xE1D2, 0xC7A4, + 0x9F48, 0xE7D2, 0xDFA4, 0xD2C0, 0xF4B0, 0xFD2C, 0xEB60, 0xFAD8, 0xE920, 0xFA48, + 0xD640, 0xF590, 0xFD64, 0xC960, 0xF258, 0xB2C0, 0xECB0, 0xFB2C, 0x96C0, 0xE5B0, + 0xF96C, 0x9240, 0xE490, 0xF924, 0xD920, 0xF648, 0xFD92, 0xCB20, 0xF2C8, 0xB640, + 0xED90, 0xFB64, 0xC4B0, 0xF12C, 0x9960, 0xE658, 0xF996, 0xDCB0, 0xF72C, 0x8B60, + 0xE2D8, 0x8920, 0xE248, 0xBB60, 0xCC90, 0xF324, 0xB920, 0xEE48, 0xFB92, 0xC590, + 0xF164, 0x9B20, 0xE6C8, 0xF9B2, 0xDD90, 0xF764, 0xC258, 0x8CB0, 0xE32C, 0xCE58, + 0xF396, 0xBCB0, 0xEF2C, 0x85B0, 0xE16C, 0x8490, 0xE124, 0x9DB0, 0xC648, 0xF192, + 0x9C90, 0xE724, 0xDE48, 0xF792, 0xC2C8, 0x8D90, 0xE364, 0xCEC8, 0xF3B2, 0xBD90, + 0xEF64, 0xC12C, 0x8658, 0xE196, 0xC72C, 0x9E58, 0xE796, 0xDF2C, 0x82D8, 0x8248, + 0x8ED8, 0xC324, 0x8E48, 0xE392, 0xBED8, 0xCF24, 0xBE48, 0xEF92, 0xC164, 0x86C8, + 0xE1B2, 0xC764, 0x9EC8, 0xE7B2, 0xDF64, 0x832C, 0xC396, 0x8F2C, 0xCF96, 0x816C, + 0x8124, 0x876C, 0xC192, 0x8724, 0x9F6C, 0xC792, 0x9F24, 0x8364, 0xC3B2, 0x8F64, + 0xCFB2, 0xBF64, 0xD160, 0xF458, 0xFD16, 0xA6C0, 0xE9B0, 0xFA6C, 0xA240, 0xE890, + 0xFA24, 0xD760, 0xF5D8, 0xFD76, 0xD320, 0xF4C8, 0xFD32, 0xAE40, 0xEB90, 0xFAE4, + 0xC8B0, 0xF22C, 0xB160, 0xEC58, 0xFB16, 0x9360, 0xE4D8, 0xF936, 0x9120, 0xE448, + 0xF912, 0xD890, 0xF624, 0xCBB0, 0xF2EC, 0xB760, 0xC990, 0xF264, 0xB320, 0xECC8, + 0xFB32, 0x9720, 0xE5C8, 0xF972, 0xDB90, 0xF6E4, 0xC458, 0xF116, 0x98B0, 0xE62C, + 0xDC58, 0xF716, 0x89B0, 0xE26C, 0x8890, 0xE224, 0xB9B0, 0xCC48, 0xF312, 0xB890, + 0xEE24, 0xC5D8, 0xF176, 0x9BB0, 0xC4C8, 0xF132, 0x9990, 0xE664, 0xDCC8, 0xF732, + 0x8B90, 0xE2E4, 0xCDC8, 0xF372, 0xBB90, 0xEEE4, 0xC22C, 0x8C58, 0xE316, 0xCE2C, + 0xBC58, 0xEF16, 0x84D8, 0xE136, 0x8448, 0xE112, 0x9CD8, 0xC624, 0x9C48, 0xE712, + 0xDE24, 0xC2EC, 0x8DD8, 0xC264, 0x8CC8, 0xE332, 0xBDD8, 0xCE64, 0xBCC8, 0xEF32, + 0x85C8, 0xE172, 0xC6E4, 0x9DC8, 0xE772, 0xDEE4, 0xC116, 0x862C, 0xC716, 0x9E2C, + 0x826C, 0x8224, 0x8E6C, 0xC312, 0x8E24, 0xBE6C, 0xCF12, 0xC176, 0x86EC, 0xC132, + 0x8664, 0x9EEC, 0xC732, 0x9E64, 0xDF32, 0x82E4, 0xC372, 0x8EE4, 0xCF72, 0xBEE4, + 0x8316, 0x8F16, 0x8136, 0x8112, 0x8736, 0x8712, 0x9F36, 0x8376, 0x8332, 0x8F76, + 0x8F32, 0xBF76, 0x8172, 0x8772, 0x9F72, 0xD0B0, 0xF42C, 0xA360, 0xE8D8, 0xFA36, + 0xA120, 0xE848, 0xFA12, 0xD3B0, 0xF4EC, 0xD190, 0xF464, 0xAF60, 0xEBD8, 0xFAF6, + 0xA720, 0xE9C8, 0xFA72, 0xD790, 0xF5E4, 0xC858, 0xF216, 0xB0B0, 0xEC2C, 0x91B0, + 0xE46C, 0x9090, 0xE424, 0xD848, 0xF612, 0xC9D8, 0xF276, 0xB3B0, 0xC8C8, 0xF232, + 0xB190, 0xEC64, 0x97B0, 0xE5EC, 0x9390, 0xE4E4, 0xD9C8, 0xF672, 0xCBC8, 0xF2F2, + 0xB790, 0xEDE4, 0xC42C, 0x9858, 0xE616, 0xDC2C, 0x88D8, 0xE236, 0x8848, 0xE212, + 0xB8D8, 0xCC24, 0xB848, 0xEE12, 0xC4EC, 0x99D8, 0xC464, 0x98C8, 0xE632, 0xDC64, + 0x8BD8, 0xE2F6, 0x89C8, 0xE272, 0xBBD8, 0xCCE4, 0xB9C8, 0xEE72, 0xC5E4, 0x9BC8, + 0xE6F2, 0xDDE4, 0xC216, 0x8C2C, 0xCE16, 0x846C, 0x8424, 0x9C6C, 0xC612, 0x9C24, + 0xC276, 0x8CEC, 0xC232, 0x8C64, 0xBCEC, 0xCE32, 0xBC64, 0x85EC, 0x84E4, 0x9DEC, + 0xC672, 0x9CE4, 0xDE72, 0xC2F2, 0x8DE4, 0xCEF2, 0xBDE4, 0x8616, 0x8236, 0x8212, + 0x8E36, 0x8E12, 0x8676, 0x8632, 0x9E76, 0x9E32, 0x82F6, 0x8272, 0x8EF6, 0x8E72, + 0xBEF6, 0xBE72, 0x86F2, 0x9EF2, 0xD058, 0xF416, 0xA1B0, 0xE86C, 0xA090, 0xE824, + 0xD1D8, 0xF476, 0xD0C8, 0xF432, 0xA7B0, 0xE9EC, 0xA390, 0xE8E4, 0xD7D8, 0xF5F6, + 0xD3C8, 0xF4F2, 0xAF90, 0xEBE4, 0xC82C, 0xB058, 0xEC16, 0x90D8, 0xE436, 0x9048, + 0xE412, 0xD824, 0xC8EC, 0xB1D8, 0xC864, 0xB0C8, 0xEC32, 0x93D8, 0xE4F6, 0x91C8, + 0xE472, 0xD8E4, 0xCBEC, 0xB7D8, 0xC9E4, 0xB3C8, 0xECF2, 0x97C8, 0xE5F2, 0xDBE4, + 0xC416, 0x982C, 0x886C, 0x8824, 0xB86C, 0xCC12, 0xC476, 0x98EC, 0xC432, 0x9864, + 0xDC32, 0x89EC, 0x88E4, 0xB9EC, 0xCC72, 0xB8E4, 0xC5F6, 0x9BEC, 0xC4F2, 0x99E4, + 0xDCF2, 0x8BE4, 0xCDF2, 0xBBE4, 0x8C16, 0x8436, 0x8412, 0x9C36, 0x8C76, 0x8C32, + 0xBC76, 0x84F6, 0x8472, 0x9CF6, 0x9C72, 0x8DF6, 0x8CF2, 0xBDF6, 0xBCF2, 0x85F2, + 0x9DF2, 0xD02C, 0xA0D8, 0xE836, 0xA048, 0xE812, 0xD0EC, 0xD064, 0xA3D8, 0xE8F6, + 0xA1C8, 0xE872, 0xD3EC, 0xD1E4, 0xAFD8, 0xEBF6, 0xA7C8, 0xE9F2, 0xC816, 0x906C, + 0x9024, 0xC876, 0xB0EC, 0xC832, 0xB064, 0x91EC, 0x90E4, 0xD872, 0xC9F6, 0xB3EC, + 0xC8F2, 0xB1E4, 0x97EC, 0x93E4, 0xD9F2, 0x8836, 0x8812, 0x9876, 0x9832, 0x88F6, + 0x8872, 0xB8F6, 0xB872, 0x99F6, 0x98F2, 0x8BF6, 0x89F2, 0xBBF6, 0xB9F2, 0xD4C0, + 0xF530, 0xFD4C, 0xEA20, 0xFA88, 0xDAE0, 0xF6B8, 0xFDAE, 0xCA60, 0xF298, 0xB4C0, + 0xED30, 0xFB4C, 0x9440, 0xE510, 0xF944, 0xDA20, 0xF688, 0xFDA2, 0xCD70, 0xF35C, + 0xBAE0, 0xEEB8, 0xFBAE, 0xC530, 0xF14C, 0x9A60, 0xE698, 0xF9A6, 0xDD30, 0xF74C, + 0x8A20, 0xE288, 0xCD10, 0xF344, 0xBA20, 0xEE88, 0xFBA2, 0xC6B8, 0xF1AE, 0x9D70, + 0xE75C, 0xDEB8, 0xF7AE, 0xC298, 0x8D30, 0xE34C, 0xCE98, 0xF3A6, 0xBD30, 0xEF4C, + 0x8510, 0xE144, 0xC688, 0xF1A2, 0x9D10, 0xE744, 0xDE88, 0xF7A2, 0xC35C, 0x8EB8, + 0xE3AE, 0xCF5C, 0xBEB8, 0xEFAE, 0xC14C, 0x8698, 0xE1A6, 0xC74C, 0x9E98, 0xE7A6, + 0xDF4C, 0x8288, 0xC344, 0x8E88, 0xE3A2, 0xCF44, 0xBE88, 0xEFA2, 0xC1AE, 0x875C, + 0xC7AE, 0x9F5C, 0xDFAE, 0x834C, 0xC3A6, 0x8F4C, 0xCFA6, 0xBF4C, 0x8144, 0xC1A2, + 0x8744, 0xC7A2, 0x9F44, 0xDFA2, 0xE970, 0xFA5C, 0xD6E0, 0xF5B8, 0xFD6E, 0xD260, + 0xF498, 0xFD26, 0xACC0, 0xEB30, 0xFACC, 0xA440, 0xE910, 0xFA44, 0xD620, 0xF588, + 0xFD62, 0x92E0, 0xE4B8, 0xF92E, 0xD970, 0xF65C, 0xCB70, 0xF2DC, 0xB6E0, 0xC930, + 0xF24C, 0xB260, 0xEC98, 0xFB26, 0x9660, 0xE598, 0xF966, 0x9220, 0xE488, 0xF922, + 0xD910, 0xF644, 0xCB10, 0xF2C4, 0xB620, 0xED88, 0xFB62, 0x8970, 0xE25C, 0xCCB8, + 0xF32E, 0xB970, 0xEE5C, 0xC5B8, 0xF16E, 0x9B70, 0xC498, 0xF126, 0x9930, 0xE64C, + 0xDC98, 0xF726, 0x8B30, 0xE2CC, 0x8910, 0xE244, 0xBB30, 0xCC88, 0xF322, 0xB910, + 0xEE44, 0xC588, 0xF162, 0x9B10, 0xE6C4, 0xDD88, 0xF762, 0x84B8, 0xE12E, 0xC65C, + 0x9CB8, 0xE72E, 0xDE5C, 0xC2DC, 0x8DB8, 0xC24C, 0x8C98, 0xE326, 0xBDB8, 0xCE4C, + 0xBC98, 0xEF26, 0x8598, 0xE166, 0x8488, 0xE122, 0x9D98, 0xC644, 0x9C88, 0xE722, + 0xDE44, 0xC2C4, 0x8D88, 0xE362, 0xCEC4, 0xBD88, 0xEF62, 0x825C, 0xC32E, 0x8E5C, + 0xCF2E +}; + +static const unsigned short int c49_odd_bitpattern[] = { + /* Appendix E - Code 49 Encodation Patterns (Odd Symbol Character Parity) */ + 0xC940, 0xF250, 0xECA0, 0xFB28, 0xE5A0, 0xF968, 0xDB40, 0xF6D0, 0xFDB4, 0xC4A0, + 0xF128, 0x9940, 0xE650, 0xF994, 0xDCA0, 0xF728, 0xFDCA, 0x8B40, 0xE2D0, 0xCDA0, + 0xF368, 0xBB40, 0xEED0, 0xFBB4, 0xC250, 0x8CA0, 0xE328, 0xCE50, 0xF394, 0xBCA0, + 0xEF28, 0xFBCA, 0x85A0, 0xE168, 0xC6D0, 0xF1B4, 0x9DA0, 0xE768, 0xF9DA, 0xDED0, + 0xF7B4, 0xC128, 0x8650, 0xE194, 0xC728, 0xF1CA, 0x9E50, 0xE794, 0xDF28, 0xF7CA, + 0x82D0, 0xC368, 0x8ED0, 0xE3B4, 0xCF68, 0xF3DA, 0xBED0, 0xEFB4, 0x8328, 0xC394, + 0x8F28, 0xE3CA, 0xCF94, 0x8168, 0xC1B4, 0x8768, 0xE1DA, 0xC7B4, 0x9F68, 0xE7DA, + 0xDFB4, 0xD140, 0xF450, 0xFD14, 0xE9A0, 0xFA68, 0xD740, 0xF5D0, 0xFD74, 0xC8A0, + 0xF228, 0xB140, 0xEC50, 0xFB14, 0x9340, 0xE4D0, 0xF934, 0xD9A0, 0xF668, 0xFD9A, + 0xCBA0, 0xF2E8, 0xB740, 0xEDD0, 0xFB74, 0xC450, 0xF114, 0x98A0, 0xE628, 0xF98A, + 0xDC50, 0xF714, 0x89A0, 0xE268, 0xCCD0, 0xF334, 0xB9A0, 0xEE68, 0xFB9A, 0xC5D0, + 0xF174, 0x9BA0, 0xE6E8, 0xF9BA, 0xDDD0, 0xF774, 0xC228, 0x8C50, 0xE314, 0xCE28, + 0xF38A, 0xBC50, 0xEF14, 0x84D0, 0xE134, 0xC668, 0xF19A, 0x9CD0, 0xE734, 0xDE68, + 0xF79A, 0xC2E8, 0x8DD0, 0xE374, 0xCEE8, 0xF3BA, 0xBDD0, 0xEF74, 0xC114, 0x8628, + 0xE18A, 0xC714, 0x9E28, 0xE78A, 0x8268, 0xC334, 0x8E68, 0xE39A, 0xCF34, 0xBE68, + 0xEF9A, 0xC174, 0x86E8, 0xE1BA, 0xC774, 0x9EE8, 0xE7BA, 0xDF74, 0x8314, 0xC38A, + 0x8F14, 0x8134, 0xC19A, 0x8734, 0xC79A, 0x9F34, 0x8374, 0xC3BA, 0x8F74, 0xCFBA, + 0xBF74, 0xD0A0, 0xF428, 0xFD0A, 0xA340, 0xE8D0, 0xFA34, 0xD3A0, 0xF4E8, 0xFD3A, + 0xAF40, 0xEBD0, 0xFAF4, 0xC850, 0xF214, 0xB0A0, 0xEC28, 0xFB0A, 0x91A0, 0xE468, + 0xF91A, 0xD8D0, 0xF634, 0xC9D0, 0xF274, 0xB3A0, 0xECE8, 0xFB3A, 0x97A0, 0xE5E8, + 0xF97A, 0xDBD0, 0xF6F4, 0xC428, 0xF10A, 0x9850, 0xE614, 0xDC28, 0xF70A, 0x88D0, + 0xE234, 0xCC68, 0xF31A, 0xB8D0, 0xEE34, 0xC4E8, 0xF13A, 0x99D0, 0xE674, 0xDCE8, + 0xF73A, 0x8BD0, 0xE2F4, 0xCDE8, 0xF37A, 0xBBD0, 0xEEF4, 0xC214, 0x8C28, 0xE30A, + 0xCE14, 0x8468, 0xE11A, 0xC634, 0x9C68, 0xE71A, 0xDE34, 0xC274, 0x8CE8, 0xE33A, + 0xCE74, 0xBCE8, 0xEF3A, 0x85E8, 0xE17A, 0xC6F4, 0x9DE8, 0xE77A, 0xDEF4, 0xC10A, + 0x8614, 0xC70A, 0x8234, 0xC31A, 0x8E34, 0xCF1A, 0xC13A, 0x8674, 0xC73A, 0x9E74, + 0xDF3A, 0x82F4, 0xC37A, 0x8EF4, 0xCF7A, 0xBEF4, 0x830A, 0x811A, 0x871A, 0x833A, + 0x8F3A, 0x817A, 0x877A, 0x9F7A, 0xD050, 0xF414, 0xA1A0, 0xE868, 0xFA1A, 0xD1D0, + 0xF474, 0xA7A0, 0xE9E8, 0xFA7A, 0xD7D0, 0xF5F4, 0xC828, 0xF20A, 0xB050, 0xEC14, + 0x90D0, 0xE434, 0xD868, 0xF61A, 0xC8E8, 0xF23A, 0xB1D0, 0xEC74, 0x93D0, 0xE4F4, + 0xD9E8, 0xF67A, 0xCBE8, 0xF2FA, 0xB7D0, 0xEDF4, 0xC414, 0x9828, 0xE60A, 0x8868, + 0xE21A, 0xCC34, 0xB868, 0xEE1A, 0xC474, 0x98E8, 0xE63A, 0xDC74, 0x89E8, 0xE27A, + 0xCCF4, 0xB9E8, 0xEE7A, 0xC5F4, 0x9BE8, 0xE6FA, 0xDDF4, 0xC20A, 0x8C14, 0x8434, + 0xC61A, 0x9C34, 0xC23A, 0x8C74, 0xCE3A, 0xBC74, 0x84F4, 0xC67A, 0x9CF4, 0xDE7A, + 0xC2FA, 0x8DF4, 0xCEFA, 0xBDF4, 0x860A, 0x821A, 0x8E1A, 0x863A, 0x9E3A, 0x827A, + 0x8E7A, 0xBE7A, 0x86FA, 0x9EFA, 0xD028, 0xF40A, 0xA0D0, 0xE834, 0xD0E8, 0xF43A, + 0xA3D0, 0xE8F4, 0xD3E8, 0xF4FA, 0xAFD0, 0xEBF4, 0xC814, 0x9068, 0xE41A, 0xD834, + 0xC874, 0xB0E8, 0xEC3A, 0x91E8, 0xE47A, 0xD8F4, 0xC9F4, 0xB3E8, 0xECFA, 0x97E8, + 0xE5FA, 0xDBF4, 0xC40A, 0x8834, 0xCC1A, 0xC43A, 0x9874, 0xDC3A, 0x88F4, 0xCC7A, + 0xB8F4, 0xC4FA, 0x99F4, 0xDCFA, 0x8BF4, 0xCDFA, 0xBBF4, 0x841A, 0x8C3A, 0x847A, + 0x9C7A, 0x8CFA, 0xBCFA, 0x85FA, 0x9DFA, 0xF520, 0xFD48, 0xDAC0, 0xF6B0, 0xFDAC, + 0xCA40, 0xF290, 0xED20, 0xFB48, 0xCD60, 0xF358, 0xBAC0, 0xEEB0, 0xFBAC, 0xC520, + 0xF148, 0x9A40, 0xE690, 0xF9A4, 0xDD20, 0xF748, 0xFDD2, 0xC6B0, 0xF1AC, 0x9D60, + 0xE758, 0xF9D6, 0xDEB0, 0xF7AC, 0xC290, 0x8D20, 0xE348, 0xCE90, 0xF3A4, 0xBD20, + 0xEF48, 0xFBD2, 0xC358, 0x8EB0, 0xE3AC, 0xCF58, 0xF3D6, 0xBEB0, 0xEFAC, 0xC148, + 0x8690, 0xE1A4, 0xC748, 0xF1D2, 0x9E90, 0xE7A4, 0xDF48, 0xF7D2, 0xC1AC, 0x8758, + 0xE1D6, 0xC7AC, 0x9F58, 0xE7D6, 0xDFAC, 0x8348, 0xC3A4, 0x8F48, 0xE3D2, 0xCFA4, + 0xBF48, 0xEFD2, 0xE960, 0xFA58, 0xD6C0, 0xF5B0, 0xFD6C, 0xD240, 0xF490, 0xFD24, + 0xEB20, 0xFAC8, 0x92C0, 0xE4B0, 0xF92C, 0xD960, 0xF658, 0xFD96, 0xCB60, 0xF2D8, + 0xB6C0, 0xC920, 0xF248, 0xB240, 0xEC90, 0xFB24, 0x9640, 0xE590, 0xF964, 0xDB20, + 0xF6C8, 0xFDB2, 0x8960, 0xE258, 0xCCB0, 0xF32C, 0xB960, 0xEE58, 0xFB96, 0xC5B0, + 0xF16C, 0x9B60, 0xC490, 0xF124, 0x9920, 0xE648, 0xF992, 0xDC90, 0xF724, 0x8B20, + 0xE2C8, 0xCD90, 0xF364, 0xBB20, 0xEEC8, 0xFBB2, 0x84B0, 0xE12C, 0xC658, 0xF196, + 0x9CB0, 0xE72C, 0xDE58, 0xF796, 0xC2D8, 0x8DB0, 0xC248, 0x8C90, 0xE324, 0xBDB0, + 0xCE48, 0xF392, 0xBC90, 0xEF24, 0x8590, 0xE164, 0xC6C8, 0xF1B2, 0x9D90, 0xE764, + 0xDEC8, 0xF7B2, 0x8258, 0xC32C, 0x8E58, 0xE396, 0xCF2C, 0xBE58, 0xEF96, 0xC16C, + 0x86D8, 0xC124, 0x8648, 0xE192, 0x9ED8, 0xC724, 0x9E48, 0xE792, 0xDF24, 0x82C8, + 0xC364, 0x8EC8, 0xE3B2, 0xCF64, 0xBEC8, 0xEFB2, 0x812C, 0xC196, 0x872C, 0xC796, + 0x9F2C, 0x836C, 0x8324, 0x8F6C, 0xC392, 0x8F24, 0xBF6C, 0xCF92, 0x8164, 0xC1B2, + 0x8764, 0xC7B2, 0x9F64, 0xDFB2, 0xA2C0, 0xE8B0, 0xFA2C, 0xD360, 0xF4D8, 0xFD36, + 0xD120, 0xF448, 0xFD12, 0xAEC0, 0xEBB0, 0xFAEC, 0xA640, 0xE990, 0xFA64, 0xD720, + 0xF5C8, 0xFD72, 0x9160, 0xE458, 0xF916, 0xD8B0, 0xF62C, 0xC9B0, 0xF26C, 0xB360, + 0xC890, 0xF224, 0xB120, 0xEC48, 0xFB12, 0x9760, 0xE5D8, 0xF976, 0x9320, 0xE4C8, + 0xF932, 0xD990, 0xF664, 0xCB90, 0xF2E4, 0xB720, 0xEDC8, 0xFB72, 0x88B0, 0xE22C, + 0xCC58, 0xF316, 0xB8B0, 0xEE2C, 0xC4D8, 0xF136, 0x99B0, 0xC448, 0xF112, 0x9890, + 0xE624, 0xDC48, 0xF712, 0x8BB0, 0xE2EC, 0x8990, 0xE264, 0xBBB0, 0xCCC8, 0xF332, + 0xB990, 0xEE64, 0xC5C8, 0xF172, 0x9B90, 0xE6E4, 0xDDC8, 0xF772, 0x8458, 0xE116, + 0xC62C, 0x9C58, 0xE716, 0xDE2C, 0xC26C, 0x8CD8, 0xC224, 0x8C48, 0xE312, 0xBCD8, + 0xCE24, 0xBC48, 0xEF12, 0x85D8, 0xE176, 0x84C8, 0xE132, 0x9DD8, 0xC664, 0x9CC8, + 0xE732, 0xDE64, 0xC2E4, 0x8DC8, 0xE372, 0xCEE4, 0xBDC8, 0xEF72, 0x822C, 0xC316, + 0x8E2C, 0xCF16, 0xC136, 0x866C, 0xC112, 0x8624, 0x9E6C, 0xC712, 0x9E24, 0x82EC, + 0x8264, 0x8EEC, 0xC332, 0x8E64, 0xBEEC, 0xCF32, 0xBE64, 0xC172, 0x86E4, 0xC772, + 0x9EE4, 0xDF72, 0x8116, 0x8716, 0x8336, 0x8312, 0x8F36, 0x8F12, 0x8176, 0x8132, + 0x8776, 0x8732, 0x9F76, 0x9F32, 0x8372, 0x8F72, 0xBF72, 0xA160, 0xE858, 0xFA16, + 0xD1B0, 0xF46C, 0xD090, 0xF424, 0xA760, 0xE9D8, 0xFA76, 0xA320, 0xE8C8, 0xFA32, + 0xD7B0, 0xF5EC, 0xD390, 0xF4E4, 0xAF20, 0xEBC8, 0xFAF2, 0x90B0, 0xE42C, 0xD858, + 0xF616, 0xC8D8, 0xF236, 0xB1B0, 0xC848, 0xF212, 0xB090, 0xEC24, 0x93B0, 0xE4EC, + 0x9190, 0xE464, 0xD8C8, 0xF632, 0xCBD8, 0xF2F6, 0xB7B0, 0xC9C8, 0xF272, 0xB390, + 0xECE4, 0x9790, 0xE5E4, 0xDBC8, 0xF6F2, 0x8858, 0xE216, 0xCC2C, 0xB858, 0xEE16, + 0xC46C, 0x98D8, 0xC424, 0x9848, 0xE612, 0xDC24, 0x89D8, 0xE276, 0x88C8, 0xE232, + 0xB9D8, 0xCC64, 0xB8C8, 0xEE32, 0xC5EC, 0x9BD8, 0xC4E4, 0x99C8, 0xE672, 0xDCE4, + 0x8BC8, 0xE2F2, 0xCDE4, 0xBBC8, 0xEEF2, 0x842C, 0xC616, 0x9C2C, 0xC236, 0x8C6C, + 0xC212, 0x8C24, 0xBC6C, 0xCE12, 0x84EC, 0x8464, 0x9CEC, 0xC632, 0x9C64, 0xDE32, + 0xC2F6, 0x8DEC, 0xC272, 0x8CE4, 0xBDEC, 0xCE72, 0xBCE4, 0x85E4, 0xC6F2, 0x9DE4, + 0xDEF2, 0x8216, 0x8E16, 0x8636, 0x8612, 0x9E36, 0x8276, 0x8232, 0x8E76, 0x8E32, + 0xBE76, 0x86F6, 0x8672, 0x9EF6, 0x9E72, 0x82F2, 0x8EF2, 0xBEF2, 0xA0B0, 0xE82C, + 0xD0D8, 0xF436, 0xD048, 0xF412, 0xA3B0, 0xE8EC, 0xA190, 0xE864, 0xD3D8, 0xF4F6, + 0xD1C8, 0xF472, 0xAFB0, 0xEBEC, 0xA790, 0xE9E4, 0xD7C8, 0xF5F2, 0x9058, 0xE416, + 0xD82C, 0xC86C, 0xB0D8, 0xC824, 0xB048, 0xEC12, 0x91D8, 0xE476, 0x90C8, 0xE432, + 0xD864, 0xC9EC, 0xB3D8, 0xC8E4, 0xB1C8, 0xEC72, 0x97D8, 0xE5F6, 0x93C8, 0xE4F2, + 0xD9E4, 0xCBE4, 0xB7C8, 0xEDF2, 0x882C, 0xCC16, 0xC436, 0x986C, 0xC412, 0x9824, + 0x88EC, 0x8864, 0xB8EC, 0xCC32, 0xB864, 0xC4F6, 0x99EC, 0xC472, 0x98E4, 0xDC72, + 0x8BEC, 0x89E4, 0xBBEC, 0xCCF2, 0xB9E4, 0xC5F2, 0x9BE4, 0xDDF2, 0x8416, 0x8C36, + 0x8C12, 0x8476, 0x8432, 0x9C76, 0x9C32, 0x8CF6, 0x8C72, 0xBCF6, 0xBC72, 0x85F6, + 0x84F2, 0x9DF6, 0x9CF2, 0x8DF2, 0xBDF2, 0xA058, 0xE816, 0xD06C, 0xD024, 0xA1D8, + 0xE876, 0xA0C8, 0xE832, 0xD1EC, 0xD0E4, 0xA7D8, 0xE9F6, 0xA3C8, 0xE8F2, 0xD7EC, + 0xD3E4, 0x902C, 0xC836, 0xB06C, 0xC812, 0x90EC, 0x9064, 0xD832, 0xC8F6, 0xB1EC, + 0xC872, 0xB0E4, 0x93EC, 0x91E4, 0xD8F2, 0xCBF6, 0xB7EC, 0xC9F2, 0xB3E4, 0x8816, + 0x9836, 0x8876, 0x8832, 0xB876, 0x98F6, 0x9872, 0x89F6, 0x88F2, 0xB9F6, 0xB8F2, + 0x9BF6, 0x99F2, 0xEA60, 0xFA98, 0xD440, 0xF510, 0xFD44, 0xED70, 0xFB5C, 0x94C0, + 0xE530, 0xF94C, 0xDA60, 0xF698, 0xFDA6, 0xCA20, 0xF288, 0xB440, 0xED10, 0xFB44, + 0x9AE0, 0xE6B8, 0xF9AE, 0xDD70, 0xF75C, 0x8A60, 0xE298, 0xCD30, 0xF34C, 0xBA60, + 0xEE98, 0xFBA6, 0xC510, 0xF144, 0x9A20, 0xE688, 0xF9A2, 0xDD10, 0xF744, 0x8D70, + 0xE35C, 0xCEB8, 0xF3AE, 0xBD70, 0xEF5C, 0x8530, 0xE14C, 0xC698, 0xF1A6, 0x9D30, + 0xE74C, 0xDE98, 0xF7A6, 0xC288, 0x8D10, 0xE344, 0xCE88, 0xF3A2, 0xBD10, 0xEF44, + 0x86B8, 0xE1AE, 0xC75C, 0x9EB8, 0xE7AE, 0xDF5C, 0x8298, 0xC34C, 0x8E98, 0xE3A6, + 0xCF4C, 0xBE98, 0xEFA6, 0xC144, 0x8688, 0xE1A2, 0xC744, 0x9E88, 0xE7A2, 0xDF44, + 0x835C, 0xC3AE, 0x8F5C, 0xCFAE, 0xBF5C, 0x814C, 0xC1A6, 0x874C, 0xC7A6, 0x9F4C, + 0xDFA6, 0x8344, 0xC3A2, 0x8F44, 0xCFA2, 0xBF44, 0xD2E0, 0xF4B8, 0xFD2E, 0xADC0, + 0xEB70, 0xFADC, 0xA4C0, 0xE930, 0xFA4C, 0xD660, 0xF598, 0xFD66, 0xD220, 0xF488, + 0xFD22, 0xAC40, 0xEB10, 0xFAC4, 0xC970, 0xF25C, 0xB2E0, 0xECB8, 0xFB2E, 0x96E0, + 0xE5B8, 0xF96E, 0x9260, 0xE498, 0xF926, 0xD930, 0xF64C, 0xCB30, 0xF2CC, 0xB660, + 0xC910, 0xF244, 0xB220, 0xEC88, 0xFB22, 0x9620, 0xE588, 0xF962, 0xDB10, 0xF6C4, + 0xC4B8, 0xF12E, 0x9970, 0xE65C, 0xDCB8, 0xF72E, 0x8B70, 0xE2DC, 0x8930, 0xE24C, + 0xBB70, 0xCC98, 0xF326, 0xB930, 0xEE4C, 0xC598, 0xF166, 0x9B30, 0xC488, 0xF122, + 0x9910, 0xE644, 0xDC88, 0xF722, 0x8B10, 0xE2C4, 0xCD88, 0xF362, 0xBB10, 0xEEC4, + 0xC25C, 0x8CB8, 0xE32E, 0xCE5C, 0xBCB8, 0xEF2E, 0x85B8, 0xE16E, 0x8498, 0xE126, + 0x9DB8, 0xC64C, 0x9C98, 0xE726, 0xDE4C, 0xC2CC, 0x8D98, 0xC244, 0x8C88, 0xE322, + 0xBD98, 0xCE44, 0xBC88, 0xEF22, 0x8588, 0xE162, 0xC6C4, 0x9D88, 0xE762, 0xDEC4, + 0xC12E, 0x865C, 0xC72E, 0x9E5C, 0xDF2E, 0x82DC, 0x824C, 0x8EDC, 0xC326, 0x8E4C, + 0xBEDC, 0xCF26, 0xBE4C, 0xC166, 0x86CC, 0xC122, 0x8644, 0x9ECC, 0xC722, 0x9E44, + 0xDF22, 0x82C4, 0xC362, 0x8EC4, 0xCF62, 0xBEC4, 0x832E, 0x8F2E, 0x816E, 0x8126, + 0x876E, 0x8726, 0x9F6E, 0x9F26, 0x8366, 0x8322, 0x8F66, 0x8F22, 0xBF66, 0x8162, + 0x8762, 0x9F62, 0xD170, 0xF45C, 0xA6E0, 0xE9B8, 0xFA6E, 0xA260, 0xE898, 0xFA26, + 0xD770, 0xF5DC, 0xD330, 0xF4CC, 0xD110, 0xF444, 0xAE60, 0xEB98, 0xFAE6, 0xA620, + 0xE988, 0xFA62, 0xD710, 0xF5C4, 0xC8B8, 0xF22E, 0xB170, 0xEC5C, 0x9370, 0xE4DC, + 0x9130, 0xE44C, 0xD898, 0xF626, 0xCBB8, 0xF2EE, 0xB770, 0xC998, 0xF266, 0xB330, + 0xC888, 0xF222, 0xB110, 0xEC44, 0x9730, 0xE5CC, 0x9310, 0xE4C4, 0xD988, 0xF662, + 0xCB88, 0xF2E2, 0xB710, 0xEDC4, 0xC45C, 0x98B8, 0xE62E, 0xDC5C, 0x89B8, 0xE26E, + 0x8898, 0xE226, 0xB9B8, 0xCC4C, 0xB898, 0xEE26, 0xC5DC, 0x9BB8, 0xC4CC, 0x9998, + 0xC444, 0x9888, 0xE622, 0xDC44, 0x8B98, 0xE2E6, 0x8988, 0xE262, 0xBB98, 0xCCC4, + 0xB988, 0xEE62, 0xC5C4, 0x9B88, 0xE6E2, 0xDDC4, 0xC22E, 0x8C5C, 0xCE2E, 0xBC5C, + 0x84DC, 0x844C, 0x9CDC, 0xC626, 0x9C4C, 0xDE26, 0xC2EE, 0x8DDC, 0xC266, 0x8CCC, + 0xC222, 0xBDDC, 0x8C44, 0xBCCC, 0xCE22, 0xBC44, 0x85CC, 0x84C4, 0x9DCC, 0xC662, + 0x9CC4, 0xDE62, 0xC2E2, 0x8DC4, 0xCEE2, 0xBDC4, 0x862E, 0x9E2E, 0x826E, 0x8226, + 0x8E6E, 0x8E26, 0xBE6E, 0x86EE, 0x8666, 0x9EEE, 0x8622, 0x9E66, 0x9E22, 0x82E6, + 0x8262, 0x8EE6, 0x8E62, 0xBEE6, 0xBE62, 0x86E2, 0x9EE2, 0xD0B8, 0xF42E, 0xA370, + 0xE8DC, 0xA130, 0xE84C, 0xD3B8, 0xF4EE, 0xD198, 0xF466, 0xD088, 0xF422, 0xAF70, + 0xEBDC, 0xA730, 0xE9CC, 0xA310, 0xE8C4, 0xD798, 0xF5E6, 0xD388, 0xF4E2, 0xAF10, + 0xEBC4, 0xC85C, 0xB0B8, 0xEC2E, 0x91B8, 0xE46E, 0x9098, 0xE426, 0xD84C, 0xC9DC, + 0xB3B8, 0xC8CC, 0xB198, 0xC844, 0xB088, 0xEC22, 0x97B8, 0xE5EE, 0x9398, 0xE4E6, + 0x9188, 0xE462, 0xD8C4, 0xCBCC, 0xB798, 0xC9C4, 0xB388, 0xECE2, 0x9788, 0xE5E2, + 0xDBC4, 0xC42E, 0x985C, 0xDC2E, 0x88DC, 0x884C, 0xB8DC, 0xCC26, 0xB84C, 0xC4EE, + 0x99DC, 0xC466, 0x98CC, 0xC422, 0x9844, 0xDC22, 0x8BDC, 0x89CC, 0xBBDC, 0x88C4, + 0xB9CC, 0xCC62, 0xB8C4, 0xC5E6, 0x9BCC, 0xC4E2, 0x99C4, 0xDCE2, 0x8BC4, 0xCDE2, + 0xBBC4, 0x8C2E, 0x846E, 0x8426, 0x9C6E, 0x9C26, 0x8CEE, 0x8C66, 0xBCEE, 0x8C22, + 0xBC66, 0x85EE, 0x84E6, 0x9DEE, 0x8462, 0x9CE6, 0x9C62, 0x8DE6, 0x8CE2, 0xBDE6, + 0xBCE2, 0x85E2, 0x9DE2, 0xD05C, 0xA1B8, 0xE86E, 0xA098, 0xE826, 0xD1DC, 0xD0CC, + 0xD044, 0xA7B8, 0xE9EE, 0xA398, 0xE8E6, 0xA188, 0xE862, 0xD7DC, 0xD3CC, 0xD1C4, + 0xAF98, 0xEBE6, 0xA788, 0xE9E2, 0xC82E, 0xB05C, 0x90DC, 0x904C, 0xD826, 0xC8EE, + 0xB1DC, 0xC866, 0xB0CC, 0xC822, 0xB044, 0x93DC, 0x91CC, 0x90C4, 0xD862, 0xCBEE, + 0xB7DC, 0xC9E6, 0xB3CC, 0xC8E2, 0xB1C4, 0x97CC, 0x93C4, 0xD9E2, 0x982E, 0x886E, + 0x8826, 0xB86E, 0x98EE, 0x9866, 0x9822, 0x89EE, 0x88E6, 0xB9EE, 0x8862, 0xB8E6, + 0xB862, 0x9BEE, 0x99E6, 0x98E2, 0x8BE6, 0x89E2, 0xBBE6, 0xB9E2, 0xD02E, 0xA0DC, + 0xA04C, 0xD0EE, 0xD066, 0xD022, 0xA3DC, 0xA1CC, 0xA0C4, 0xD3EE, 0xD1E6, 0xD0E2, + 0xAFDC, 0xA7CC, 0xA3C4, 0x906E, 0x9026, 0xB0EE, 0xB066, 0x91EE, 0x90E6, 0x9062, + 0xB3EE, 0xB1E6, 0xB0E2, 0x97EE, 0x93E6, 0x91E2, 0xD4E0, 0xF538, 0xFD4E, 0xA8C0, + 0xEA30, 0xFA8C, 0xD420, 0xF508, 0xFD42, 0xDAF0, 0xF6BC, 0xCA70, 0xF29C, 0xB4E0, + 0xED38, 0xFB4E, 0x9460, 0xE518, 0xF946, 0xDA30, 0xF68C, 0xCA10, 0xF284, 0xB420, + 0xED08, 0xFB42, 0xCD78, 0xF35E, 0xBAF0, 0xEEBC, 0xC538, 0xF14E, 0x9A70, 0xE69C, + 0xDD38, 0xF74E, 0x8A30, 0xE28C, 0xCD18, 0xF346, 0xBA30, 0xEE8C, 0xC508, 0xF142, + 0x9A10, 0xE684, 0xDD08, 0xF742, 0xC6BC, 0x9D78, 0xE75E, 0xDEBC, 0xC29C, 0x8D38, + 0xE34E, 0xCE9C, 0xBD38, 0xEF4E, 0x8518, 0xE146, 0xC68C, 0x9D18, 0xE746, 0xDE8C, + 0xC284, 0x8D08, 0xE342, 0xCE84, 0xBD08, 0xEF42, 0xC35E, 0x8EBC, 0xCF5E, 0xBEBC, + 0xC14E, 0x869C, 0xC74E, 0x9E9C, 0xDF4E, 0x828C, 0xC346, 0x8E8C, 0xCF46, 0xBE8C, + 0xC142, 0x8684, 0xC742, 0x9E84, 0xDF42, 0x875E, 0x9F5E, 0x834E, 0x8F4E, 0xBF4E, + 0x8146, 0x8746, 0x9F46, 0x8342, 0x8F42, 0xBF42, 0xE978, 0xFA5E, 0xD6F0, 0xF5BC, + 0xD270, 0xF49C, 0xACE0, 0xEB38, 0xFACE, 0xA460, 0xE918, 0xFA46, 0xD630, 0xF58C, + 0xD210, 0xF484, 0xAC20, 0xEB08, 0xFAC2, 0x92F0, 0xE4BC, 0xD978, 0xF65E, 0xCB78, + 0xF2DE, 0xB6F0, 0xC938, 0xF24E, 0xB270, 0xEC9C, 0x9670, 0xE59C, 0x9230, 0xE48C, + 0xD918, 0xF646, 0xCB18, 0xF2C6, 0xB630, 0xC908, 0xF242, 0xB210, 0xEC84, 0x9610, + 0xE584, 0xDB08, 0xF6C2, 0x8978, 0xE25E, 0xCCBC, 0xB978, 0xEE5E, 0xC5BC, 0x9B78, + 0xC49C, 0x9938, 0xE64E, 0xDC9C, 0x8B38, 0xE2CE, 0x8918, 0xE246, 0xBB38, 0xCC8C, + 0xB918, 0xEE46, 0xC58C, 0x9B18, 0xC484, 0x9908, 0xE642, 0xDC84, 0x8B08, 0xE2C2, + 0xCD84, 0xBB08, 0xEEC2, 0x84BC, 0xC65E, 0x9CBC, 0xDE5E, 0xC2DE, 0x8DBC, 0xC24E, + 0x8C9C, 0xBDBC, 0xCE4E, 0xBC9C, 0x859C, 0x848C, 0x9D9C, 0xC646, 0x9C8C, 0xDE46, + 0xC2C6, 0x8D8C, 0xC242, 0x8C84, 0xBD8C, 0xCE42, 0xBC84, 0x8584, 0xC6C2, 0x9D84, + 0xDEC2, 0x825E, 0x8E5E, 0xBE5E, 0x86DE, 0x864E, 0x9EDE, 0x9E4E, 0x82CE, 0x8246, + 0x8ECE, 0x8E46, 0xBECE, 0xBE46, 0x86C6, 0x8642, 0x9EC6, 0x9E42, 0x82C2, 0x8EC2, + 0xBEC2, 0xA2F0, 0xE8BC, 0xD378, 0xF4DE, 0xD138, 0xF44E, 0xAEF0, 0xEBBC, 0xA670, + 0xE99C, 0xA230, 0xE88C, 0xD738, 0xF5CE, 0xD318, 0xF4C6, 0xD108, 0xF442, 0xAE30, + 0xEB8C, 0xA610, 0xE984, 0xD708, 0xF5C2, 0x9178, 0xE45E, 0xD8BC, 0xC9BC, 0xB378, + 0xC89C, 0xB138, 0xEC4E, 0x9778, 0xE5DE, 0x9338, 0xE4CE, 0x9118, 0xE446, 0xD88C, + 0xCB9C, 0xB738, 0xC98C, 0xB318, 0xC884, 0xB108, 0xEC42, 0x9718, 0xE5C6, 0x9308, + 0xE4C2, 0xD984, 0xCB84, 0xB708, 0xEDC2, 0x88BC, 0xCC5E, 0xB8BC, 0xC4DE, 0x99BC, + 0xC44E, 0x989C, 0xDC4E, 0x8BBC, 0x899C, 0xBBBC, 0x888C, 0xB99C, 0xCC46, 0xB88C, + 0xC5CE, 0x9B9C, 0xC4C6, 0x998C, 0xC442, 0x9884, 0xDC42, 0x8B8C, 0x8984, 0xBB8C, + 0xCCC2, 0xB984, 0xC5C2, 0x9B84, 0xDDC2, 0x845E, 0x9C5E, 0x8CDE, 0x8C4E, 0xBCDE, + 0xBC4E, 0x85DE, 0x84CE, 0x9DDE, 0x8446, 0x9CCE, 0x9C46, 0x8DCE, 0x8CC6, 0xBDCE, + 0x8C42, 0xBCC6, 0xBC42, 0x85C6, 0x84C2, 0x9DC6, 0x9CC2, 0x8DC2, 0xBDC2, 0xA178, + 0xE85E, 0xD1BC, 0xD09C, 0xA778, 0xE9DE, 0xA338, 0xE8CE, 0xA118, 0xE846, 0xD7BC, + 0xD39C, 0xD18C, 0xD084, 0xAF38, 0xEBCE, 0xA718, 0xE9C6, 0xA308, 0xE8C2, 0xD78C, + 0xD384, 0x90BC, 0xD85E, 0xC8DE, 0xB1BC, 0xC84E, 0xB09C, 0x93BC, 0x919C, 0x908C, + 0xD846, 0xCBDE, 0xB7BC, 0xC9CE, 0xB39C, 0xC8C6, 0xB18C, 0xC842, 0xB084, 0x979C, + 0x938C, 0x9184, 0xD8C2, 0xCBC6, 0xB78C, 0xC9C2, 0xB384, 0x885E, 0xB85E, 0x98DE, + 0x984E, 0x89DE, 0x88CE, 0xB9DE, 0x8846, 0xB8CE, 0xB846, 0x9BDE, 0x99CE, 0x98C6, + 0x9842, 0x8BCE, 0x89C6, 0xBBCE, 0x88C2, 0xB9C6, 0xB8C2, 0x9BC6, 0x99C2, 0xA0BC, + 0xD0DE, 0xD04E, 0xA3BC, 0xA19C, 0xA08C, 0xD3DE, 0xD1CE, 0xD0C6, 0xD042, 0xAFBC, + 0xA79C, 0xA38C, 0xA184, 0xD7CE, 0xD3C6, 0xD1C2, 0x905E, 0xB0DE, 0xB04E, 0x91DE, + 0x90CE, 0x9046, 0xB3DE, 0xB1CE, 0xB0C6, 0xB042, 0x97DE, 0x93CE, 0x91C6, 0x90C2, + 0xB7CE, 0xB3C6, 0xB1C2, 0xA05E, 0xA1DE, 0xA0CE, 0xA046, 0xA7DE, 0xA3CE, 0xA1C6, + 0xA0C2, 0xA9E0, 0xEA78, 0xFA9E, 0xD470, 0xF51C, 0xA860, 0xEA18, 0xFA86, 0xD410, + 0xF504, 0xED7C, 0x94F0, 0xE53C, 0xDA78, 0xF69E, 0xCA38, 0xF28E, 0xB470, 0xED1C, + 0x9430, 0xE50C, 0xDA18, 0xF686, 0xCA08, 0xF282, 0xB410, 0xED04, 0x9AF8, 0xE6BE, + 0xDD7C, 0x8A78, 0xE29E, 0xCD3C, 0xBA78, 0xEE9E, 0xC51C, 0x9A38, 0xE68E, 0xDD1C, + 0x8A18, 0xE286, 0xCD0C, 0xBA18, 0xEE86, 0xC504, 0x9A08, 0xE682, 0xDD04, 0x8D7C, + 0xCEBE, 0xBD7C, 0x853C, 0xC69E, 0x9D3C, 0xDE9E, 0xC28E, 0x8D1C, 0xCE8E, 0xBD1C, + 0x850C, 0xC686, 0x9D0C, 0xDE86, 0xC282, 0x8D04, 0xCE82, 0xBD04, 0x86BE, 0x9EBE, + 0x829E, 0x8E9E, 0xBE9E, 0x868E, 0x9E8E, 0x8286, 0x8E86, 0xBE86, 0x8682, 0x9E82, + 0xD2F8, 0xF4BE, 0xADF0, 0xEB7C, 0xA4F0, 0xE93C, 0xD678, 0xF59E, 0xD238, 0xF48E, + 0xAC70, 0xEB1C, 0xA430, 0xE90C, 0xD618, 0xF586, 0xD208, 0xF482, 0xAC10, 0xEB04, + 0xC97C, 0xB2F8, 0xECBE, 0x96F8, 0xE5BE, 0x9278, 0xE49E, 0xD93C, 0xCB3C, 0xB678, + 0xC91C, 0xB238, 0xEC8E, 0x9638, 0xE58E, 0x9218, 0xE486, 0xD90C, 0xCB0C, 0xB618, + 0xC904, 0xB208, 0xEC82, 0x9608, 0xE582, 0xDB04, 0xC4BE, 0x997C, 0xDCBE, 0x8B7C, + 0x893C, 0xBB7C, 0xCC9E, 0xB93C, 0xC59E, 0x9B3C, 0xC48E, 0x991C, 0xDC8E, 0x8B1C, + 0x890C, 0xBB1C, 0xCC86, 0xB90C, 0xC586, 0x9B0C, 0xC482, 0x9904, 0xDC82, 0x8B04, + 0xCD82, 0xBB04, 0x8CBE, 0xBCBE, 0x85BE, 0x849E, 0x9DBE, 0x9C9E, 0x8D9E, 0x8C8E, + 0xBD9E, 0xBC8E, 0x858E, 0x8486, 0x9D8E, 0x9C86, 0x8D86, 0x8C82, 0xBD86, 0xBC82, + 0x8582, 0x9D82, 0xD17C, 0xA6F8, 0xE9BE, 0xA278, 0xE89E, 0xD77C, 0xD33C, 0xD11C, + 0xAE78, 0xEB9E, 0xA638, 0xE98E, 0xA218, 0xE886, 0xD71C, 0xD30C, 0xD104, 0xAE18, + 0xEB86, 0xA608, 0xE982, 0xC8BE, 0xB17C, 0x937C, 0x913C, 0xD89E, 0xCBBE, 0xB77C, + 0xC99E, 0xB33C, 0xC88E, 0xB11C, 0x973C, 0x931C, 0x910C, 0xD886, 0xCB8E, 0xB71C, + 0xC986, 0xB30C, 0xC882, 0xB104, 0x970C, 0x9304, 0xD982, 0x98BE, 0x89BE, 0x889E, + 0xB9BE, 0xB89E, 0x9BBE, 0x999E, 0x988E, 0x8B9E, 0x898E, 0xBB9E, 0x8886, 0xB98E, + 0xB886, 0x9B8E, 0x9986, 0x9882, 0x8B86, 0x8982, 0xBB86, 0xB982, 0xD0BE, 0xA37C, + 0xA13C, 0xD3BE, 0xD19E, 0xD08E, 0xAF7C, 0xA73C, 0xA31C, 0xA10C, 0xD79E, 0xD38E, + 0xD186, 0xD082, 0xAF1C, 0xA70C, 0xA304, 0xB0BE, 0x91BE, 0x909E, 0xB3BE, 0xB19E, + 0xB08E, 0x97BE, 0x939E, 0x918E, 0x9086, 0xB79E, 0xB38E, 0xB186, 0xB082, 0x978E, + 0x9386, 0x9182, 0xA1BE, 0xA09E, 0xA7BE, 0xA39E, 0xA18E, 0xA086, 0xAF9E, 0xA78E, + 0xA386, 0xA182, 0xD4F8, 0xF53E, 0xA8F0, 0xEA3C, 0xD438, 0xF50E, 0xA830, 0xEA0C, + 0xD408, 0xF502, 0xDAFC, 0xCA7C, 0xB4F8, 0xED3E, 0x9478, 0xE51E, 0xDA3C, 0xCA1C, + 0xB438, 0xED0E, 0x9418, 0xE506, 0xDA0C, 0xCA04, 0xB408, 0xED02, 0xCD7E, 0xBAFC, + 0xC53E, 0x9A7C, 0xDD3E, 0x8A3C, 0xCD1E, 0xBA3C, 0xC50E, 0x9A1C, 0xDD0E, 0x8A0C, + 0xCD06, 0xBA0C, 0xC502, 0x9A04, 0xDD02, 0x9D7E, 0x8D3E, 0xBD3E, 0x851E, 0x9D1E, + 0x8D0E, 0xBD0E, 0x8506, 0x9D06, 0x8D02, 0xBD02, 0xE97E, 0xD6FC, 0xD27C, 0xACF8, + 0xEB3E, 0xA478, 0xE91E, 0xD63C, 0xD21C, 0xAC38, 0xEB0E, 0xA418, 0xE906, 0xD60C, + 0xD204, 0x92FC, 0xD97E, 0xCB7E, 0xB6FC, 0xC93E, 0xB27C, 0x967C, 0x923C, 0xD91E, + 0xCB1E, 0xB63C, 0xC90E, 0xB21C, 0x961C, 0x920C, 0xD906, 0xCB06, 0xB60C, 0xC902, + 0xB204, 0x897E, 0xB97E, 0x9B7E, 0x993E, 0x8B3E, 0x891E, 0xBB3E, 0xB91E, 0x9B1E, + 0x990E, 0x8B0E, 0x8906, 0xBB0E, 0xB906, 0x9B06, 0x9902, 0xA2FC, 0xD37E, 0xD13E, + 0xAEFC +}; diff --git a/3rdparty/zint-2.6.1/backend/common.c b/3rdparty/zint-2.6.1/backend/common.c new file mode 100644 index 0000000..708c417 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/common.c @@ -0,0 +1,317 @@ +/* common.c - Contains functions needed for a number of barcodes */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ +#include +#include +#include +#include "common.h" + +/* Local replacement for strlen() with unsigned char strings */ +size_t ustrlen(const unsigned char data[]) { + return strlen((const char*) data); +} + +/* Converts a character 0-9 to its equivalent integer value */ +int ctoi(const char source) { + if ((source >= '0') && (source <= '9')) + return (source - '0'); + return (source - 'A' + 10); +} + + +/* Convert an integer value to a string representing its binary equivalent */ +void bin_append(const int arg, const int length, char *binary) { + int i; + int start; + size_t posn = strlen(binary); + + start = 0x01 << (length - 1); + + for (i = 0; i < length; i++) { + binary[posn + i] = '0'; + if (arg & (start >> i)) { + binary[posn + i] = '1'; + } + } + binary[posn + length] = '\0'; + + return; +} + +/* Converts an integer value to its hexadecimal character */ +char itoc(const int source) { + if ((source >= 0) && (source <= 9)) { + return ('0' + source); + } else { + return ('A' + (source - 10)); + } +} +/* Converts lower case characters to upper case in a string source[] */ +void to_upper(unsigned char source[]) { + size_t i, src_len = ustrlen(source); + + for (i = 0; i < src_len; i++) { + if ((source[i] >= 'a') && (source[i] <= 'z')) { + source [i] = (source[i] - 'a') + 'A'; + } + } +} + +/* Verifies that a string only uses valid characters */ +int is_sane(const char test_string[], const unsigned char source[], const size_t length) { + unsigned int j, latch; + size_t i, lt = strlen(test_string); + + for (i = 0; i < length; i++) { + latch = FALSE; + for (j = 0; j < lt; j++) { + if (source[i] == test_string[j]) { + latch = TRUE; + break; + } + } + if (!(latch)) { + return ZINT_ERROR_INVALID_DATA; + } + } + + return 0; +} + +/* Replaces huge switch statements for looking up in tables */ +void lookup(const char set_string[], const char *table[], const char data, char dest[]) { + size_t i, n = strlen(set_string); + + for (i = 0; i < n; i++) { + if (data == set_string[i]) { + strcat(dest, table[i]); + } + } +} + +/* Returns the position of data in set_string */ +int posn(const char set_string[], const char data) { + int i, n = (int)strlen(set_string); + + for (i = 0; i < n; i++) { + if (data == set_string[i]) { + return i; + } + } + return -1; +} + +/* Return true (1) if a module is dark/black, otherwise false (0) */ +int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) { + return (symbol->encoded_data[y_coord][x_coord / 7] >> (x_coord % 7)) & 1; +} + +/* Set a module to dark/black */ +void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) { + symbol->encoded_data[y_coord][x_coord / 7] |= 1 << (x_coord % 7); +} + +/* Set (or unset) a module to white */ +void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) { + symbol->encoded_data[y_coord][x_coord / 7] &= ~(1 << (x_coord % 7)); +} + +/* Expands from a width pattern to a bit pattern */ +void expand(struct zint_symbol *symbol, const char data[]) { + + size_t reader, n = strlen(data); + int writer, i; + char latch; + + writer = 0; + latch = '1'; + + for (reader = 0; reader < n; reader++) { + for (i = 0; i < ctoi(data[reader]); i++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } + writer++; + } + + latch = (latch == '1' ? '0' : '1'); + } + + if (symbol->symbology != BARCODE_PHARMA) { + if (writer > symbol->width) { + symbol->width = writer; + } + } else { + /* Pharmacode One ends with a space - adjust for this */ + if (writer > symbol->width + 2) { + symbol->width = writer - 2; + } + } + symbol->rows = symbol->rows + 1; +} + +/* Indicates which symbologies can have row binding */ +int is_stackable(const int symbology) { + if (symbology < BARCODE_PDF417) { + return 1; + } + + switch (symbology) { + case BARCODE_CODE128B: + case BARCODE_ISBNX: + case BARCODE_EAN14: + case BARCODE_NVE18: + case BARCODE_KOREAPOST: + case BARCODE_PLESSEY: + case BARCODE_TELEPEN_NUM: + case BARCODE_ITF14: + case BARCODE_CODE32: + case BARCODE_CODABLOCKF: + return 1; + } + + return 0; +} + +/* Indicates which symbols can have addon (EAN-2 and EAN-5) */ +int is_extendable(const int symbology) { + if (symbology == BARCODE_EANX) { + return 1; + } + if (symbology == BARCODE_UPCA) { + return 1; + } + if (symbology == BARCODE_UPCE) { + return 1; + } + if (symbology == BARCODE_ISBNX) { + return 1; + } + if (symbology == BARCODE_UPCA_CC) { + return 1; + } + if (symbology == BARCODE_UPCE_CC) { + return 1; + } + if (symbology == BARCODE_EANX_CC) { + return 1; + } + + return 0; +} + +int istwodigits(const unsigned char source[], const size_t position) { + if ((source[position] >= '0') && (source[position] <= '9')) { + if ((source[position + 1] >= '0') && (source[position + 1] <= '9')) { + return 1; + } + } + + return 0; +} + +int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], size_t *length) { + size_t bpos; + int jpos, error_number; + int next; + + bpos = 0; + jpos = 0; + error_number = 0; + next = 0; + + do { + if (source[bpos] <= 0x7f) { + /* 1 byte mode (7-bit ASCII) */ + vals[jpos] = source[bpos]; + next = bpos + 1; + jpos++; + } else { + if ((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) { + strcpy(symbol->errtxt, "240: Corrupt Unicode data"); + return ZINT_ERROR_INVALID_DATA; + } + if ((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) { + strcpy(symbol->errtxt, "241: Overlong encoding not supported"); + return ZINT_ERROR_INVALID_DATA; + } + + if ((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) { + /* 2 byte mode */ + vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f); + next = bpos + 2; + jpos++; + } else + if ((source[bpos] >= 0xe0) && (source[bpos] <= 0xef)) { + /* 3 byte mode */ + vals[jpos] = ((source[bpos] & 0x0f) << 12) + ((source[bpos + 1] & 0x3f) << 6) + (source[bpos + 2] & 0x3f); + next = bpos + 3; + jpos++; + } else + if (source[bpos] >= 0xf0) { + strcpy(symbol->errtxt, "242: Unicode sequences of more than 3 bytes not supported"); + return ZINT_ERROR_INVALID_DATA; + } + } + + bpos = next; + + } while (bpos < *length); + *length = jpos; + + return error_number; +} + + +void set_minimum_height(struct zint_symbol *symbol, const int min_height) { + /* Enforce minimum permissable height of rows */ + int fixed_height = 0; + int zero_count = 0; + int i; + + for (i = 0; i < symbol->rows; i++) { + fixed_height += symbol->row_height[i]; + + if (symbol->row_height[i] == 0) { + zero_count++; + } + } + + if (zero_count > 0) { + if (((symbol->height - fixed_height) / zero_count) < min_height) { + for (i = 0; i < symbol->rows; i++) { + if (symbol->row_height[i] == 0) { + symbol->row_height[i] = min_height; + } + } + } + } +} diff --git a/3rdparty/zint-2.6.1/backend/common.h b/3rdparty/zint-2.6.1/backend/common.h new file mode 100644 index 0000000..4bc3fc1 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/common.h @@ -0,0 +1,79 @@ +/* common.h - Header for all common functions in common.c */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* Used in some logic */ +#ifndef __COMMON_H +#define __COMMON_H + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +/* The most commonly used set */ +#define NEON "0123456789" + +#include "zint.h" +#include + +#define ustrcpy(target,source) strcpy((char*)target,(const char*)source) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + extern size_t ustrlen(const unsigned char source[]); + extern int ctoi(const char source); + extern char itoc(const int source); + extern void to_upper(unsigned char source[]); + extern int is_sane(const char test_string[], const unsigned char source[], const size_t length); + extern void lookup(const char set_string[], const char *table[], const char data, char dest[]); + extern void bin_append(const int arg, const int length, char *binary); + extern int posn(const char set_string[], const char data); + extern int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord); + extern void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord); + extern int istwodigits(const unsigned char source[], const size_t position); + extern int parunmodd(const unsigned char llyth); + extern void expand(struct zint_symbol *symbol, const char data[]); + extern void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord); + extern int is_stackable(const int symbology); + extern int is_extendable(const int symbology); + extern int utf8toutf16(struct zint_symbol *symbol, const unsigned char source[], int vals[], size_t *length); + extern void set_minimum_height(struct zint_symbol *symbol, const int min_height); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __COMMON_H */ diff --git a/3rdparty/zint-2.6.1/backend/composite.c b/3rdparty/zint-2.6.1/backend/composite.c new file mode 100644 index 0000000..842901c --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/composite.c @@ -0,0 +1,1872 @@ +/* composite.c - Handles GS1 Composite Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* The functions "getBit", "init928" and "encode928" are copyright BSI and are + released with permission under the following terms: + + "Copyright subsists in all BSI publications. BSI also holds the copyright, in the + UK, of the international standardisation bodies. Except as + permitted under the Copyright, Designs and Patents Act 1988 no extract may be + reproduced, stored in a retrieval system or transmitted in any form or by any + means - electronic, photocopying, recording or otherwise - without prior written + permission from BSI. + + "This does not preclude the free use, in the course of implementing the standard, + of necessary details such as symbols, and size, type or grade designations. If these + details are to be used for any other purpose than implementation then the prior + written permission of BSI must be obtained." + + The date of publication for these functions is 31 May 2006 + */ + +#include +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "large.h" +#include "composite.h" +#include "pdf417.h" +#include "gs1.h" + +#define UINT unsigned short + +extern int general_rules(char field[], char type[]); +extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); +extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); +extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); +extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); +extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); + +static UINT pwr928[69][7]; + +static int _min(int first, int second) { + + if (first <= second) + return first; + else + return second; +} + +/* gets bit in bitString at bitPos */ +static int getBit(UINT *bitStr, int bitPos) { + return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15))); +} + +/* initialize pwr928 encoding table */ +static void init928(void) { + int i, j, v; + int cw[7]; + cw[6] = 1L; + for (i = 5; i >= 0; i--) + cw[i] = 0; + + for (i = 0; i < 7; i++) + pwr928[0][i] = cw[i]; + for (j = 1; j < 69; j++) { + for (v = 0, i = 6; i >= 1; i--) { + v = (2 * cw[i]) + (v / 928); + pwr928[j][i] = cw[i] = v % 928; + } + pwr928[j][0] = cw[0] = (2 * cw[0]) + (v / 928); + } + return; +} + +/* converts bit string to base 928 values, codeWords[0] is highest order */ +static int encode928(UINT bitString[], UINT codeWords[], int bitLng) { + int i, j, b, bitCnt, cwNdx, cwCnt, cwLng; + for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) { + bitCnt = _min(bitLng - b, 69); + cwLng += cwCnt = bitCnt / 10 + 1; + for (i = 0; i < cwCnt; i++) + codeWords[cwNdx + i] = 0; /* init 0 */ + for (i = 0; i < bitCnt; i++) { + if (getBit(bitString, b + bitCnt - i - 1)) { + for (j = 0; j < cwCnt; j++) + codeWords[cwNdx + j] += pwr928[i][j + 7 - cwCnt]; + } + } + for (i = cwCnt - 1; i > 0; i--) { + /* add "carries" */ + codeWords[cwNdx + i - 1] += codeWords[cwNdx + i] / 928L; + codeWords[cwNdx + i] %= 928L; + } + } + return (cwLng); +} + +/* CC-A 2D component */ +static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) { + int i, strpos, segment, bitlen, cwCnt, variant, rows; + int k, offset, j, total, rsCodeWords[8]; + int LeftRAPStart, RightRAPStart, CentreRAPStart, StartCluster; + int LeftRAP, RightRAP, CentreRAP, Cluster, dummy[5]; + int loop; + UINT codeWords[28]; + UINT bitStr[13]; + char pattern[580]; + char local_source[210]; /* A copy of source but with padding zeroes to make 208 bits */ + + variant = 0; + + for (i = 0; i < 13; i++) { + bitStr[i] = 0; + } + for (i = 0; i < 28; i++) { + codeWords[i] = 0; + } + + bitlen = (int)strlen(source); + + for (i = 0; i < 208; i++) { + local_source[i] = '0'; + } + for (i = 0; i < bitlen; i++) { + local_source[i] = source[i]; + } + local_source[208] = '\0'; + + for (segment = 0; segment < 13; segment++) { + strpos = segment * 16; + for (i = 0; i < 16; i++) { + if (local_source[strpos + i] == '1') { + bitStr[segment] += (0x8000 >> i); + } + } + } + + init928(); + /* encode codeWords from bitStr */ + cwCnt = encode928(bitStr, codeWords, bitlen); + + switch (cc_width) { + case 2: + switch (cwCnt) { + case 6: variant = 0; + break; + case 8: variant = 1; + break; + case 9: variant = 2; + break; + case 11: variant = 3; + break; + case 12: variant = 4; + break; + case 14: variant = 5; + break; + case 17: variant = 6; + break; + } + break; + case 3: + switch (cwCnt) { + case 8: variant = 7; + break; + case 10: variant = 8; + break; + case 12: variant = 9; + break; + case 14: variant = 10; + break; + case 17: variant = 11; + break; + } + break; + case 4: + switch (cwCnt) { + case 8: variant = 12; + break; + case 11: variant = 13; + break; + case 14: variant = 14; + break; + case 17: variant = 15; + break; + case 20: variant = 16; + break; + } + break; + } + + rows = ccaVariants[variant]; + k = ccaVariants[17 + variant]; + offset = ccaVariants[34 + variant]; + + /* Reed-Solomon error correction */ + + for (i = 0; i < 8; i++) { + rsCodeWords[i] = 0; + } + total = 0; + for (i = 0; i < cwCnt; i++) { + total = (codeWords[i] + rsCodeWords[k - 1]) % 929; + for (j = k - 1; j >= 0; j--) { + if (j == 0) { + rsCodeWords[j] = (929 - (total * ccaCoeffs[offset + j]) % 929) % 929; + } else { + rsCodeWords[j] = (rsCodeWords[j - 1] + 929 - (total * ccaCoeffs[offset + j]) % 929) % 929; + } + } + } + + for (j = 0; j < k; j++) { + if (rsCodeWords[j] != 0) { + rsCodeWords[j] = 929 - rsCodeWords[j]; + } + } + + for (i = k - 1; i >= 0; i--) { + codeWords[cwCnt] = rsCodeWords[i]; + cwCnt++; + } + + /* Place data into table */ + LeftRAPStart = aRAPTable[variant]; + CentreRAPStart = aRAPTable[variant + 17]; + RightRAPStart = aRAPTable[variant + 34]; + StartCluster = aRAPTable[variant + 51] / 3; + + LeftRAP = LeftRAPStart; + CentreRAP = CentreRAPStart; + RightRAP = RightRAPStart; + Cluster = StartCluster; /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + + for (i = 0; i < rows; i++) { + strcpy(pattern, ""); + offset = 929 * Cluster; + for (j = 0; j < 5; j++) { + dummy[j] = 0; + } + for (j = 0; j < cc_width; j++) { + dummy[j + 1] = codeWords[i * cc_width + j]; + } + /* Copy the data into codebarre */ + bin_append(rap_side[LeftRAP - 1], 10, pattern); + bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern); + strcat(pattern, "0"); + if (cc_width == 3) { + bin_append(rap_centre[CentreRAP - 1], 10, pattern); + } + if (cc_width >= 2) { + bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern); + strcat(pattern, "0"); + } + if (cc_width == 4) { + bin_append(rap_centre[CentreRAP - 1], 10, pattern); + } + if (cc_width >= 3) { + bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern); + strcat(pattern, "0"); + } + if (cc_width == 4) { + bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern); + strcat(pattern, "0"); + } + bin_append(rap_side[RightRAP - 1], 10, pattern); + strcat(pattern, "1"); /* stop */ + + /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + for (loop = 0; loop < (int) strlen(pattern); loop++) { + if (pattern[loop] == '1') { + set_module(symbol, i, loop); + } + } + symbol->row_height[i] = 2; + symbol->rows++; + symbol->width = strlen(pattern); + + /* Set up RAPs and Cluster for next row */ + LeftRAP++; + CentreRAP++; + RightRAP++; + Cluster++; + + if (LeftRAP == 53) { + LeftRAP = 1; + } + if (CentreRAP == 53) { + CentreRAP = 1; + } + if (RightRAP == 53) { + RightRAP = 1; + } + if (Cluster == 3) { + Cluster = 0; + } + } + + return 0; +} + +/* CC-B 2D component */ +static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) { + int length, i, binloc; +#ifndef _MSC_VER + unsigned char data_string[(strlen(source) / 8) + 3]; +#else + unsigned char* data_string = (unsigned char*) _alloca((strlen(source) / 8) + 3); +#endif + int chainemc[180], mclength; + int k, j, p, longueur, mccorrection[50], offset; + int total, dummy[5]; + char pattern[580]; + int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; + int LeftRAP, CentreRAP, RightRAP, Cluster, loop; + + length = strlen(source) / 8; + + for (i = 0; i < length; i++) { + binloc = i * 8; + + data_string[i] = 0; + for (p = 0; p < 8; p++) { + if (source[binloc + p] == '1') { + data_string[i] += (0x80 >> p); + } + } + } + + + mclength = 0; + + /* "the CC-B component shall have codeword 920 in the first symbol character position" (section 9a) */ + chainemc[mclength] = 920; + mclength++; + + byteprocess(chainemc, &mclength, data_string, 0, length, 0); + + /* Now figure out which variant of the symbol to use and load values accordingly */ + + variant = 0; + + if (cc_width == 2) { + variant = 13; + if (mclength <= 33) { + variant = 12; + } + if (mclength <= 29) { + variant = 11; + } + if (mclength <= 24) { + variant = 10; + } + if (mclength <= 19) { + variant = 9; + } + if (mclength <= 13) { + variant = 8; + } + if (mclength <= 8) { + variant = 7; + } + } + + if (cc_width == 3) { + variant = 23; + if (mclength <= 70) { + variant = 22; + } + if (mclength <= 58) { + variant = 21; + } + if (mclength <= 46) { + variant = 20; + } + if (mclength <= 34) { + variant = 19; + } + if (mclength <= 24) { + variant = 18; + } + if (mclength <= 18) { + variant = 17; + } + if (mclength <= 14) { + variant = 16; + } + if (mclength <= 10) { + variant = 15; + } + if (mclength <= 6) { + variant = 14; + } + } + + if (cc_width == 4) { + variant = 34; + if (mclength <= 108) { + variant = 33; + } + if (mclength <= 90) { + variant = 32; + } + if (mclength <= 72) { + variant = 31; + } + if (mclength <= 54) { + variant = 30; + } + if (mclength <= 39) { + variant = 29; + } + if (mclength <= 30) { + variant = 28; + } + if (mclength <= 24) { + variant = 27; + } + if (mclength <= 18) { + variant = 26; + } + if (mclength <= 12) { + variant = 25; + } + if (mclength <= 8) { + variant = 24; + } + } + + /* Now we have the variant we can load the data - from here on the same as MicroPDF417 code */ + variant--; + assert(variant >= 0); + symbol->option_2 = MicroVariants[variant]; /* columns */ + symbol->rows = MicroVariants[variant + 34]; /* rows */ + k = MicroVariants[variant + 68]; /* number of EC CWs */ + longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */ + i = longueur - mclength; /* amount of padding required */ + offset = MicroVariants[variant + 102]; /* coefficient offset */ + + /* We add the padding */ + while (i > 0) { + chainemc[mclength] = 900; + mclength++; + i--; + } + + /* Reed-Solomon error correction */ + longueur = mclength; + for (loop = 0; loop < 50; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for (i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for (j = k - 1; j >= 0; j--) { + if (j == 0) { + mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } else { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } + } + } + + for (j = 0; j < k; j++) { + if (mccorrection[j] != 0) { + mccorrection[j] = 929 - mccorrection[j]; + } + } + /* we add these codes to the string */ + for (i = k - 1; i >= 0; i--) { + chainemc[mclength] = mccorrection[i]; + mclength++; + } + + /* Now get the RAP (Row Address Pattern) start values */ + LeftRAPStart = RAPTable[variant]; + CentreRAPStart = RAPTable[variant + 34]; + RightRAPStart = RAPTable[variant + 68]; + StartCluster = RAPTable[variant + 102] / 3; + + /* That's all values loaded, get on with the encoding */ + + LeftRAP = LeftRAPStart; + CentreRAP = CentreRAPStart; + RightRAP = RightRAPStart; + Cluster = StartCluster; + /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + + for (i = 0; i < symbol->rows; i++) { + strcpy(pattern, ""); + offset = 929 * Cluster; + for (j = 0; j < 5; j++) { + dummy[j] = 0; + } + for (j = 0; j < symbol->option_2; j++) { + dummy[j + 1] = chainemc[i * symbol->option_2 + j]; + } + /* Copy the data into codebarre */ + bin_append(rap_side[LeftRAP - 1], 10, pattern); + bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern); + strcat(pattern, "0"); + if (cc_width == 3) { + bin_append(rap_centre[CentreRAP - 1], 10, pattern); + } + if (cc_width >= 2) { + bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern); + strcat(pattern, "0"); + } + if (cc_width == 4) { + bin_append(rap_centre[CentreRAP - 1], 10, pattern); + } + if (cc_width >= 3) { + bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern); + strcat(pattern, "0"); + } + if (cc_width == 4) { + bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern); + strcat(pattern, "0"); + } + bin_append(rap_side[RightRAP - 1], 10, pattern); + strcat(pattern, "1"); /* stop */ + + /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + for (loop = 0; loop < (int) strlen(pattern); loop++) { + if (pattern[loop] == '1') { + set_module(symbol, i, loop); + } + } + symbol->row_height[i] = 2; + symbol->width = strlen(pattern); + + /* Set up RAPs and Cluster for next row */ + LeftRAP++; + CentreRAP++; + RightRAP++; + Cluster++; + + if (LeftRAP == 53) { + LeftRAP = 1; + } + if (CentreRAP == 53) { + CentreRAP = 1; + } + if (RightRAP == 53) { + RightRAP = 1; + } + if (Cluster == 3) { + Cluster = 0; + } + } + + return 0; +} + +/* CC-C 2D component - byte compressed PDF417 */ +static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level) { + int length, i, p, binloc; +#ifndef _MSC_VER + unsigned char data_string[(strlen(source) / 8) + 4]; +#else + unsigned char* data_string = (unsigned char*) _alloca((strlen(source) / 8) + 4); +#endif + int chainemc[1000], mclength, k; + int offset, longueur, loop, total, j, mccorrection[520]; + int c1, c2, c3, dummy[35]; + char pattern[580]; + + length = strlen(source) / 8; + + for (i = 0; i < length; i++) { + binloc = i * 8; + + data_string[i] = 0; + for (p = 0; p < 8; p++) { + if (source[binloc + p] == '1') { + data_string[i] += (0x80 >> p); + } + } + } + + mclength = 0; + + chainemc[mclength] = 0; /* space for length descriptor */ + mclength++; + chainemc[mclength] = 920; /* CC-C identifier */ + mclength++; + + byteprocess(chainemc, &mclength, data_string, 0, length, 0); + + chainemc[0] = mclength; + + k = 1; + for (i = 1; i <= (ecc_level + 1); i++) { + k *= 2; + } + + /* 796 - we now take care of the Reed Solomon codes */ + switch (ecc_level) { + case 1: offset = 2; + break; + case 2: offset = 6; + break; + case 3: offset = 14; + break; + case 4: offset = 30; + break; + case 5: offset = 62; + break; + case 6: offset = 126; + break; + case 7: offset = 254; + break; + case 8: offset = 510; + break; + default: offset = 0; + break; + } + + longueur = mclength; + for (loop = 0; loop < 520; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for (i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for (j = k - 1; j >= 0; j--) { + if (j == 0) { + mccorrection[j] = (929 - (total * coefrs[offset + j]) % 929) % 929; + } else { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; + } + } + } + + for (j = 0; j < k; j++) { + if (mccorrection[j] != 0) { + mccorrection[j] = 929 - mccorrection[j]; + } + } + /* we add these codes to the string */ + for (i = k - 1; i >= 0; i--) { + chainemc[mclength] = mccorrection[i]; + mclength++; + } + + /* 818 - The CW string is finished */ + c1 = (mclength / cc_width - 1) / 3; + c2 = ecc_level * 3 + (mclength / cc_width - 1) % 3; + c3 = cc_width - 1; + + /* we now encode each row */ + for (i = 0; i <= (mclength / cc_width) - 1; i++) { + for (j = 0; j < cc_width; j++) { + dummy[j + 1] = chainemc[i * cc_width + j]; + } + k = (i / 3) * 30; + switch (i % 3) { + case 0: + dummy[0] = k + c1; + dummy[cc_width + 1] = k + c3; + offset = 0; /* cluster(0) */ + break; + case 1: + dummy[0] = k + c2; + dummy[cc_width + 1] = k + c1; + offset = 929; /* cluster(3) */ + break; + case 2: + dummy[0] = k + c3; + dummy[cc_width + 1] = k + c2; + offset = 1858; /* cluster(6) */ + break; + } + strcpy(pattern, ""); + bin_append(0x1FEA8, 17, pattern); /* Row start */ + + for (j = 0; j <= cc_width + 1; j++) { + bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern); + strcat(pattern, "0"); + } + bin_append(0x3FA29, 18, pattern); /* Row Stop */ + + for (loop = 0; loop < (int) strlen(pattern); loop++) { + if (pattern[loop] == '1') { + set_module(symbol, i, loop); + } + } + symbol->row_height[i] = 3; + } + symbol->rows = (mclength / cc_width); + symbol->width = (int)strlen(pattern); + + return 0; +} + +static int calc_padding_cca(int binary_length, int cc_width) { + int target_bitsize = 0; + + switch (cc_width) { + case 2: + if (binary_length <= 167) { + target_bitsize = 167; + } + if (binary_length <= 138) { + target_bitsize = 138; + } + if (binary_length <= 118) { + target_bitsize = 118; + } + if (binary_length <= 108) { + target_bitsize = 108; + } + if (binary_length <= 88) { + target_bitsize = 88; + } + if (binary_length <= 78) { + target_bitsize = 78; + } + if (binary_length <= 59) { + target_bitsize = 59; + } + break; + case 3: + if (binary_length <= 167) { + target_bitsize = 167; + } + if (binary_length <= 138) { + target_bitsize = 138; + } + if (binary_length <= 118) { + target_bitsize = 118; + } + if (binary_length <= 98) { + target_bitsize = 98; + } + if (binary_length <= 78) { + target_bitsize = 78; + } + break; + case 4: + if (binary_length <= 197) { + target_bitsize = 197; + } + if (binary_length <= 167) { + target_bitsize = 167; + } + if (binary_length <= 138) { + target_bitsize = 138; + } + if (binary_length <= 108) { + target_bitsize = 108; + } + if (binary_length <= 78) { + target_bitsize = 78; + } + break; + } + + return target_bitsize; +} + +int calc_padding_ccb(int binary_length, int cc_width) { + int target_bitsize = 0; + + switch (cc_width) { + case 2: + if (binary_length <= 336) { + target_bitsize = 336; + } + if (binary_length <= 296) { + target_bitsize = 296; + } + if (binary_length <= 256) { + target_bitsize = 256; + } + if (binary_length <= 208) { + target_bitsize = 208; + } + if (binary_length <= 160) { + target_bitsize = 160; + } + if (binary_length <= 104) { + target_bitsize = 104; + } + if (binary_length <= 56) { + target_bitsize = 56; + } + break; + case 3: + if (binary_length <= 768) { + target_bitsize = 768; + } + if (binary_length <= 648) { + target_bitsize = 648; + } + if (binary_length <= 536) { + target_bitsize = 536; + } + if (binary_length <= 416) { + target_bitsize = 416; + } + if (binary_length <= 304) { + target_bitsize = 304; + } + if (binary_length <= 208) { + target_bitsize = 208; + } + if (binary_length <= 152) { + target_bitsize = 152; + } + if (binary_length <= 112) { + target_bitsize = 112; + } + if (binary_length <= 72) { + target_bitsize = 72; + } + if (binary_length <= 32) { + target_bitsize = 32; + } + break; + case 4: + if (binary_length <= 1184) { + target_bitsize = 1184; + } + if (binary_length <= 1016) { + target_bitsize = 1016; + } + if (binary_length <= 840) { + target_bitsize = 840; + } + if (binary_length <= 672) { + target_bitsize = 672; + } + if (binary_length <= 496) { + target_bitsize = 496; + } + if (binary_length <= 352) { + target_bitsize = 352; + } + if (binary_length <= 264) { + target_bitsize = 264; + } + if (binary_length <= 208) { + target_bitsize = 208; + } + if (binary_length <= 152) { + target_bitsize = 152; + } + if (binary_length <= 96) { + target_bitsize = 96; + } + if (binary_length <= 56) { + target_bitsize = 56; + } + break; + } + + return target_bitsize; +} + +int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int *ecc) { + int target_bitsize = 0; + int byte_length, codewords_used, ecc_level, ecc_codewords, rows; + int codewords_total, target_codewords, target_bytesize; + int i; + + byte_length = binary_length / 8; + if (binary_length % 8 != 0) { + byte_length++; + } + + codewords_used = (byte_length / 6) * 5; + codewords_used += byte_length % 6; + + ecc_level = 7; + if (codewords_used <= 1280) { + ecc_level = 6; + } + if (codewords_used <= 640) { + ecc_level = 5; + } + if (codewords_used <= 320) { + ecc_level = 4; + } + if (codewords_used <= 160) { + ecc_level = 3; + } + if (codewords_used <= 40) { + ecc_level = 2; + } + *(ecc) = ecc_level; + ecc_codewords = 1; + for (i = 1; i <= (ecc_level + 1); i++) { + ecc_codewords *= 2; + } + + codewords_used += ecc_codewords; + codewords_used += 3; + + *(cc_width) = (lin_width - 62) / 17; + /* stop the symbol from becoming too high */ + do { + *(cc_width) = *(cc_width) + 1; + rows = codewords_used / *(cc_width); + } while (rows > 90); + + if (codewords_used % *(cc_width) != 0) { + rows++; + } + + codewords_total = *(cc_width) * rows; + + if (codewords_total > 928) { // PDF_MAX + return 0; + } + + target_codewords = codewords_total - ecc_codewords; + target_codewords -= 3; + + target_bytesize = 6 * (target_codewords / 5); + target_bytesize += target_codewords % 5; + + target_bitsize = 8 * target_bytesize; + + return target_bitsize; +} + +static int cc_binary_string(struct zint_symbol *symbol, const char source[], char binary_string[], int cc_mode, int *cc_width, int *ecc, int lin_width) { /* Handles all data encodation from section 5 of ISO/IEC 24723 */ + int encoding_method, read_posn, d1, d2, alpha_pad; + int i, j, ai_crop, fnc1_latch; + long int group_val; + int ai90_mode, latch, remainder, binary_length; + char date_str[4]; +#ifndef _MSC_VER + char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1]; +#else + char* general_field = (char*) _alloca(strlen(source) + 1); + char* general_field_type = (char*) _alloca(strlen(source) + 1); +#endif + int target_bitsize; + + encoding_method = 1; + read_posn = 0; + ai_crop = 0; + fnc1_latch = 0; + alpha_pad = 0; + ai90_mode = 0; + *ecc = 0; + target_bitsize = 0; + + if ((source[0] == '1') && ((source[1] == '0') || (source[1] == '1') || (source[1] == '7')) && (strlen(source) > 8)) { + /* Source starts (10), (11) or (17) */ + encoding_method = 2; + } + + if ((source[0] == '9') && (source[1] == '0')) { + /* Source starts (90) */ + encoding_method = 3; + } + + if (encoding_method == 1) { + strcat(binary_string, "0"); + } + + if (encoding_method == 2) { + /* Encoding Method field "10" - date and lot number */ + + strcat(binary_string, "10"); + + if (source[1] == '0') { + /* No date data */ + strcat(binary_string, "11"); + read_posn = 2; + } else { + /* Production Date (11) or Expiration Date (17) */ + date_str[0] = source[2]; + date_str[1] = source[3]; + date_str[2] = '\0'; + group_val = atoi(date_str) * 384; + + date_str[0] = source[4]; + date_str[1] = source[5]; + group_val += (atoi(date_str) - 1) * 32; + + date_str[0] = source[6]; + date_str[1] = source[7]; + group_val += atoi(date_str); + + bin_append(group_val, 16, binary_string); + + if (source[1] == '1') { + /* Production Date AI 11 */ + strcat(binary_string, "0"); + } else { + /* Expiration Date AI 17 */ + strcat(binary_string, "1"); + } + read_posn = 8; + } + + if ((source[read_posn] == '1') && (source[read_posn + 1] == '0')) { + /* Followed by AI 10 - strip this from general field */ + read_posn += 2; + } else { + /* An FNC1 character needs to be inserted in the general field */ + fnc1_latch = 1; + } + } + + if (encoding_method == 3) { + /* Encodation Method field of "11" - AI 90 */ +#ifndef _MSC_VER + char ninety[strlen(source) + 1]; +#else + char* ninety = (char*) _alloca(strlen(source) + 1); +#endif + char numeric_part[4]; + int alpha, alphanum, numeric, test1, test2, test3, next_ai_posn; + int numeric_value, table3_letter; + + /* "This encodation method may be used if an element string with an AI + 90 occurs at the start of the data message, and if the data field + following the two-digit AI 90 starts with an alphanumeric string which + complies with a specific format." (para 5.2.2) */ + + i = 0; + do { + ninety[i] = source[i + 2]; + i++; + } while ((strlen(source) > i + 2) && ('[' != source[i + 2])); + ninety[i] = '\0'; + + /* Find out if the AI 90 data is alphabetic or numeric or both */ + + alpha = 0; + alphanum = 0; + numeric = 0; + + for (i = 0; i < (int) strlen(ninety); i++) { + + if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) { + /* Character is alphabetic */ + alpha += 1; + } + + if ((ninety[i] >= '0') && (ninety[i] <= '9')) { + /* Character is numeric */ + numeric += 1; + } + + switch (ninety[i]) { + case '*': + case ',': + case '-': + case '.': + case '/': alphanum += 1; + break; + } + + if (!(((ninety[i] >= '0') && (ninety[i] <= '9')) || ((ninety[i] >= 'A') && (ninety[i] <= 'Z')))) { + if ((ninety[i] != '*') && (ninety[i] != ',') && (ninety[i] != '-') && (ninety[i] != '.') && (ninety[i] != '/')) { + /* An Invalid AI 90 character */ + strcpy(symbol->errtxt, "440: Invalid AI 90 data"); + return ZINT_ERROR_INVALID_DATA; + } + } + } + + /* must start with 0, 1, 2 or 3 digits followed by an uppercase character */ + test1 = -1; + for (i = 3; i >= 0; i--) { + if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) { + test1 = i; + } + } + + test2 = 0; + for (i = 0; i < test1; i++) { + if (!((ninety[i] >= '0') && (ninety[i] <= '9'))) { + test2 = 1; + } + } + + /* leading zeros are not permitted */ + test3 = 0; + if ((test1 >= 1) && (ninety[0] == '0')) { + test3 = 1; + } + + if ((test1 != -1) && (test2 != 1) && (test3 == 0)) { + /* Encodation method "11" can be used */ + strcat(binary_string, "11"); + + numeric -= test1; + alpha--; + + /* Decide on numeric, alpha or alphanumeric mode */ + /* Alpha mode is a special mode for AI 90 */ + + if (alphanum > 0) { + /* Alphanumeric mode */ + strcat(binary_string, "0"); + ai90_mode = 1; + } else { + if (alpha > numeric) { + /* Alphabetic mode */ + strcat(binary_string, "11"); + ai90_mode = 2; + } else { + /* Numeric mode */ + strcat(binary_string, "10"); + ai90_mode = 3; + } + } + + next_ai_posn = 2 + (int)strlen(ninety); + + if (source[next_ai_posn] == '[') { + /* There are more AIs afterwords */ + if ((source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) { + /* AI 21 follows */ + ai_crop = 1; + } + + if ((source[next_ai_posn + 1] == '8') && (source[next_ai_posn + 2] == '0') && (source[next_ai_posn + 3] == '0') && (source[next_ai_posn + 4] == '4')) { + /* AI 8004 follows */ + ai_crop = 2; + } + } + + switch (ai_crop) { + case 0: strcat(binary_string, "0"); + break; + case 1: strcat(binary_string, "10"); + break; + case 2: strcat(binary_string, "11"); + break; + } + + if (test1 == 0) { + strcpy(numeric_part, "0"); + } else { + for (i = 0; i < test1; i++) { + numeric_part[i] = ninety[i]; + } + numeric_part[i] = '\0'; + } + + numeric_value = atoi(numeric_part); + + table3_letter = -1; + if (numeric_value < 31) { + table3_letter = posn("BDHIJKLNPQRSTVWZ", ninety[test1]); + } + + if (table3_letter != -1) { + /* Encoding can be done according to 5.2.2 c) 2) */ + /* five bit binary string representing value before letter */ + bin_append(numeric_value, 5, binary_string); + + /* followed by four bit representation of letter from Table 3 */ + bin_append(table3_letter, 4, binary_string); + } else { + /* Encoding is done according to 5.2.2 c) 3) */ + bin_append(31, 5, binary_string); + /* ten bit representation of number */ + bin_append(numeric_value, 10, binary_string); + + /* five bit representation of ASCII character */ + bin_append(ninety[test1] - 65, 5, binary_string); + } + + read_posn = test1 + 3; + } else { + /* Use general field encodation instead */ + strcat(binary_string, "0"); + read_posn = 0; + } + } + + /* Now encode the rest of the AI 90 data field */ + if (ai90_mode == 2) { + /* Alpha encodation (section 5.2.3) */ + do { + if ((source[read_posn] >= '0') && (source[read_posn] <= '9')) { + bin_append(source[read_posn] + 4, 5, binary_string); + } + + if ((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { + bin_append(source[read_posn] - 65, 6, binary_string); + } + + if (source[read_posn] == '[') { + bin_append(31, 5, binary_string); + } + + read_posn++; + } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0')); + alpha_pad = 1; /* This is overwritten if a general field is encoded */ + } + + if (ai90_mode == 1) { + /* Alphanumeric mode */ + do { + if ((source[read_posn] >= '0') && (source[read_posn] <= '9')) { + bin_append(source[read_posn] - 43, 5, binary_string); + } + + if ((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) { + bin_append(source[read_posn] - 33, 6, binary_string); + } + + switch (source[read_posn]) { + case '[': + bin_append(15, 5, binary_string); + break; + case '*': + bin_append(58, 6, binary_string); + break; + case ',': + bin_append(59, 6, binary_string); + break; + case '-': + bin_append(60, 6, binary_string); + break; + case '.': + bin_append(61, 6, binary_string); + break; + case '/': + bin_append(62, 6, binary_string); + break; + } + + read_posn++; + } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0')); + } + + read_posn += (2 * ai_crop); + + /* The compressed data field has been processed if appropriate - the + rest of the data (if any) goes into a general-purpose data compaction field */ + + j = 0; + if (fnc1_latch == 1) { + /* Encodation method "10" has been used but it is not followed by + AI 10, so a FNC1 character needs to be added */ + general_field[j] = '['; + j++; + } + + for (i = read_posn; i < (int) strlen(source); i++) { + general_field[j] = source[i]; + j++; + } + general_field[j] = '\0'; + + if (strlen(general_field) != 0) { + alpha_pad = 0; + } + + latch = 0; + for (i = 0; i < (int) strlen(general_field); i++) { + /* Table 13 - ISO/IEC 646 encodation */ + if ((general_field[i] < ' ') || (general_field[i] > 'z')) { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } else { + general_field_type[i] = ISOIEC; + } + + if (general_field[i] == '#') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == '$') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == '@') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == 92) { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == '^') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == 96) { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + + /* Table 12 - Alphanumeric encodation */ + if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '*') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == ',') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '-') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '.') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '/') { + general_field_type[i] = ALPHA_OR_ISO; + } + + /* Numeric encodation */ + if ((general_field[i] >= '0') && (general_field[i] <= '9')) { + general_field_type[i] = ANY_ENC; + } + if (general_field[i] == '[') { + /* FNC1 can be encoded in any system */ + general_field_type[i] = ANY_ENC; + } + + } + + general_field_type[strlen(general_field)] = '\0'; + + if (latch == 1) { + /* Invalid characters in input data */ + strcpy(symbol->errtxt, "441: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + + for (i = 0; i < (int) strlen(general_field); i++) { + if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ISOIEC; + } + } + + for (i = 0; i < (int) strlen(general_field); i++) { + if ((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ALPHA_OR_ISO; + } + } + + latch = general_rules(general_field, general_field_type); + + i = 0; + do { + switch (general_field_type[i]) { + case NUMERIC: + + if (i != 0) { + if ((general_field_type[i - 1] != NUMERIC) && (general_field[i - 1] != '[')) { + bin_append(0, 3, binary_string); /* Numeric latch */ + } + } + + if (general_field[i] != '[') { + d1 = ctoi(general_field[i]); + } else { + d1 = 10; + } + + if (general_field[i + 1] != '[') { + d2 = ctoi(general_field[i + 1]); + } else { + d2 = 10; + } + + bin_append((11 * d1) + d2 + 8, 7, binary_string); + + i += 2; + break; + + case ALPHA: + + if (i != 0) { + if ((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) { + bin_append(0, 4, binary_string); /* Alphanumeric latch */ + } + if (general_field_type[i - 1] == ISOIEC) { + bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */ + } + } + + if ((general_field[i] >= '0') && (general_field[i] <= '9')) { + bin_append(general_field[i] - 43, 5, binary_string); + } + + if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + bin_append(general_field[i] - 33, 6, binary_string); + } + + switch (general_field[i]) { + case '[': + bin_append(15, 5, binary_string); + break; + case '*': + bin_append(58, 6, binary_string); + break; + case ',': + bin_append(59, 6, binary_string); + break; + case '-': + bin_append(60, 6, binary_string); + break; + case '.': + bin_append(61, 6, binary_string); + break; + case '/': + bin_append(62, 6, binary_string); + break; + } + + i++; + break; + + case ISOIEC: + + if (i != 0) { + if ((general_field_type[i - 1] == NUMERIC) || (general_field[i - 1] == '[')) { + bin_append(0, 4, binary_string); /* Alphanumeric latch */ + bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */ + } + if (general_field_type[i - 1] == ALPHA) { + bin_append(4, 5, binary_string);; /* ISO/IEC 646 latch */ + } + } + + if ((general_field[i] >= '0') && (general_field[i] <= '9')) { + bin_append(general_field[i] - 43, 5, binary_string); + } + + if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + bin_append(general_field[i] - 1, 7, binary_string); + } + + if ((general_field[i] >= 'a') && (general_field[i] <= 'z')) { + bin_append(general_field[i] - 7, 7, binary_string); + } + + if (general_field[i] == '[') strcat(binary_string, "01111"); /* FNC1/Numeric latch */ + if (general_field[i] == '!') strcat(binary_string, "11101000"); /* exclamation mark */ + if (general_field[i] == 34) strcat(binary_string, "11101001"); /* quotation mark */ + if (general_field[i] == 37) strcat(binary_string, "11101010"); /* percent sign */ + if (general_field[i] == '&') strcat(binary_string, "11101011"); /* ampersand */ + if (general_field[i] == 39) strcat(binary_string, "11101100"); /* apostrophe */ + if (general_field[i] == '(') strcat(binary_string, "11101101"); /* left parenthesis */ + if (general_field[i] == ')') strcat(binary_string, "11101110"); /* right parenthesis */ + if (general_field[i] == '*') strcat(binary_string, "11101111"); /* asterisk */ + if (general_field[i] == '+') strcat(binary_string, "11110000"); /* plus sign */ + if (general_field[i] == ',') strcat(binary_string, "11110001"); /* comma */ + if (general_field[i] == '-') strcat(binary_string, "11110010"); /* minus or hyphen */ + if (general_field[i] == '.') strcat(binary_string, "11110011"); /* period or full stop */ + if (general_field[i] == '/') strcat(binary_string, "11110100"); /* slash or solidus */ + if (general_field[i] == ':') strcat(binary_string, "11110101"); /* colon */ + if (general_field[i] == ';') strcat(binary_string, "11110110"); /* semicolon */ + if (general_field[i] == '<') strcat(binary_string, "11110111"); /* less-than sign */ + if (general_field[i] == '=') strcat(binary_string, "11111000"); /* equals sign */ + if (general_field[i] == '>') strcat(binary_string, "11111001"); /* greater-than sign */ + if (general_field[i] == '?') strcat(binary_string, "11111010"); /* question mark */ + if (general_field[i] == '_') strcat(binary_string, "11111011"); /* underline or low line */ + if (general_field[i] == ' ') strcat(binary_string, "11111100"); /* space */ + + i++; + break; + } + } while (i + latch < (int) strlen(general_field)); + + binary_length = (int)strlen(binary_string); + switch (cc_mode) { + case 1: + target_bitsize = calc_padding_cca(binary_length, *(cc_width)); + break; + case 2: + target_bitsize = calc_padding_ccb(binary_length, *(cc_width)); + break; + case 3: + target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc); + break; + } + + if (target_bitsize == 0) { + strcpy(symbol->errtxt, "442: Input too long for selected 2d component"); + return ZINT_ERROR_TOO_LONG; + } + + remainder = target_bitsize - binary_length; + + if (latch == 1) { + i = 0; + /* There is still one more numeric digit to encode */ + + if ((remainder >= 4) && (remainder <= 6)) { + bin_append(ctoi(general_field[i]) + 1, 4, binary_string); + } else { + bin_append((11 * ctoi(general_field[i])) + 18, 7, binary_string); + /* This may push the symbol up to the next size */ + } + } + + if (strlen(binary_string) > 11805) { /* (2361 * 5) */ + strcpy(symbol->errtxt, "443: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + + binary_length = (int)strlen(binary_string); + switch (cc_mode) { + case 1: + target_bitsize = calc_padding_cca(binary_length, *(cc_width)); + break; + case 2: + target_bitsize = calc_padding_ccb(binary_length, *(cc_width)); + break; + case 3: + target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc); + break; + } + + if (target_bitsize == 0) { + strcpy(symbol->errtxt, "444: Input too long for selected 2d component"); + return ZINT_ERROR_TOO_LONG; + } + + if (binary_length < target_bitsize) { + /* Now add padding to binary string */ + if (alpha_pad == 1) { + strcat(binary_string, "11111"); + alpha_pad = 0; + /* Extra FNC1 character required after Alpha encodation (section 5.2.3) */ + } + + if ((strlen(general_field) != 0) && (general_field_type[strlen(general_field) - 1] == NUMERIC)) { + strcat(binary_string, "0000"); + } + + while (strlen(binary_string) < (unsigned int) target_bitsize) { + strcat(binary_string, "00100"); + } + + if (strlen(binary_string) > (unsigned int) target_bitsize) { + binary_string[target_bitsize] = '\0'; + } + } + + return 0; +} + +int linear_dummy_run(unsigned char *source, int length) { + struct zint_symbol *dummy; + int error_number; + int linear_width; + + dummy = ZBarcode_Create(); + dummy->symbology = BARCODE_EAN128_CC; + dummy->option_1 = 3; + error_number = ean_128(dummy, source, length); + linear_width = dummy->width; + ZBarcode_Delete(dummy); + + if (error_number == 0) { + return linear_width; + } else { + return 0; + } +} + +int composite(struct zint_symbol *symbol, unsigned char source[], int length) { + int error_number, cc_mode, cc_width, ecc_level; + int j, i, k; + unsigned int rs = length + 1; + unsigned int bs = 20 * rs; + unsigned int pri_len; +#ifndef _MSC_VER + char reduced[rs]; + char binary_string[bs]; +#else + char* reduced = (char*) _alloca(rs); + char* binary_string = (char*) _alloca(bs); +#endif + struct zint_symbol *linear; + int top_shift, bottom_shift; + int linear_width = 0; + + /* Perform sanity checks on input options first */ + error_number = 0; + pri_len = (int)strlen(symbol->primary); + if (pri_len == 0) { + strcpy(symbol->errtxt, "445: No primary (linear) message in 2D composite"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (length > 2990) { + strcpy(symbol->errtxt, "446: 2D component input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + cc_mode = symbol->option_1; + if ((cc_mode == 3) && (symbol->symbology != BARCODE_EAN128_CC)) { + /* CC-C can only be used with a GS1-128 linear part */ + strcpy(symbol->errtxt, "447: Invalid mode (CC-C only valid with GS1-128 linear component)"); + return ZINT_ERROR_INVALID_OPTION; + } + + error_number = gs1_verify(symbol, source, length, reduced); + if (error_number != 0) { + return error_number; + } + + if (symbol->symbology == BARCODE_EAN128_CC) { + /* Do a test run of encoding the linear component to establish its width */ + linear_width = linear_dummy_run((unsigned char *) symbol->primary, pri_len); + if (linear_width == 0) { + strcpy(symbol->errtxt, "448: Invalid data"); + return ZINT_ERROR_INVALID_DATA; + } + } + + switch (symbol->symbology) { + /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */ + case BARCODE_EANX_CC: + switch (pri_len) { + case 7: /* EAN-8 */ + case 10: /* EAN-8 + 2 */ + case 13: /* EAN-8 + 5 */ + cc_width = 3; + break; + case 12: /* EAN-13 */ + case 15: /* EAN-13 + 2 */ + case 18: /* EAN-13 + 5 */ + cc_width = 4; + break; + } + break; + case BARCODE_EAN128_CC: cc_width = 4; + break; + case BARCODE_RSS14_CC: cc_width = 4; + break; + case BARCODE_RSS_LTD_CC: cc_width = 3; + break; + case BARCODE_RSS_EXP_CC: cc_width = 4; + break; + case BARCODE_UPCA_CC: cc_width = 4; + break; + case BARCODE_UPCE_CC: cc_width = 2; + break; + case BARCODE_RSS14STACK_CC: cc_width = 2; + break; + case BARCODE_RSS14_OMNI_CC: cc_width = 2; + break; + case BARCODE_RSS_EXPSTACK_CC: cc_width = 4; + break; + } + + memset(binary_string, 0, bs); + + if (cc_mode < 1 || cc_mode > 3) { + cc_mode = 1; + } + + if (cc_mode == 1) { + i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + if (i == ZINT_ERROR_TOO_LONG) { + cc_mode = 2; + } + } + + if (cc_mode == 2) { + /* If the data didn't fit into CC-A it is recalculated for CC-B */ + i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + if (i == ZINT_ERROR_TOO_LONG) { + if (symbol->symbology != BARCODE_EAN128_CC) { + return ZINT_ERROR_TOO_LONG; + } else { + cc_mode = 3; + } + } + } + + if (cc_mode == 3) { + /* If the data didn't fit in CC-B (and linear part is GS1-128) it is recalculated for CC-C */ + i = cc_binary_string(symbol, reduced, binary_string, cc_mode, &cc_width, &ecc_level, linear_width); + if (i == ZINT_ERROR_TOO_LONG) { + return ZINT_ERROR_TOO_LONG; + } + } + + switch (cc_mode) { + /* Note that ecc_level is only relevant to CC-C */ + case 1: error_number = cc_a(symbol, binary_string, cc_width); + break; + case 2: error_number = cc_b(symbol, binary_string, cc_width); + break; + case 3: error_number = cc_c(symbol, binary_string, cc_width, ecc_level); + break; + } + + if (error_number != 0) { + return ZINT_ERROR_ENCODING_PROBLEM; + } + + /* 2D component done, now calculate linear component */ + linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */ + + linear->symbology = symbol->symbology; + + if (linear->symbology != BARCODE_EAN128_CC) { + /* Set the "component linkage" flag in the linear component */ + linear->option_1 = 2; + } else { + /* GS1-128 needs to know which type of 2D component is used */ + linear->option_1 = cc_mode; + } + + switch (symbol->symbology) { + case BARCODE_EANX_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_EAN128_CC: error_number = ean_128(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_RSS14_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_RSS_LTD_CC: error_number = rsslimited(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_RSS_EXP_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_UPCA_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_UPCE_CC: error_number = eanx(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_RSS14STACK_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_RSS14_OMNI_CC: error_number = rss14(linear, (unsigned char *) symbol->primary, pri_len); + break; + case BARCODE_RSS_EXPSTACK_CC: error_number = rssexpanded(linear, (unsigned char *) symbol->primary, pri_len); + break; + } + + if (error_number != 0) { + strcpy(symbol->errtxt, linear->errtxt); + strcat(symbol->errtxt, " in linear component "); + ZBarcode_Delete(linear); + return error_number; + } + + /* Merge the linear component with the 2D component */ + + top_shift = 0; + bottom_shift = 0; + + switch (symbol->symbology) { + /* Determine horizontal alignment (according to section 12.3) */ + case BARCODE_EANX_CC: + switch (pri_len) { + case 7: /* EAN-8 */ + case 10: /* EAN-8 + 2 */ + case 13: /* EAN-8 + 5 */ + bottom_shift = 13; + break; + case 12: /* EAN-13 */ + case 15: /* EAN-13 + 2 */ + case 18: /* EAN-13 + 5 */ + bottom_shift = 2; + break; + } + break; + case BARCODE_EAN128_CC: if (cc_mode == 3) { + bottom_shift = 7; + } + break; + case BARCODE_RSS14_CC: bottom_shift = 4; + break; + case BARCODE_RSS_LTD_CC: bottom_shift = 9; + break; + case BARCODE_RSS_EXP_CC: k = 1; + while ((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) { + k++; + } + top_shift = k; + break; + case BARCODE_UPCA_CC: bottom_shift = 2; + break; + case BARCODE_UPCE_CC: bottom_shift = 2; + break; + case BARCODE_RSS14STACK_CC: top_shift = 1; + break; + case BARCODE_RSS14_OMNI_CC: top_shift = 1; + break; + case BARCODE_RSS_EXPSTACK_CC: k = 1; + while ((!(module_is_set(linear, 1, k - 1))) && module_is_set(linear, 1, k)) { + k++; + } + top_shift = k; + break; + } + + if (top_shift != 0) { + /* Move the 2d component of the symbol horizontally */ + for (i = 0; i <= symbol->rows; i++) { + for (j = (symbol->width + top_shift); j >= top_shift; j--) { + if (module_is_set(symbol, i, j - top_shift)) { + set_module(symbol, i, j); + } else { + unset_module(symbol, i, j); + } + } + for (j = 0; j < top_shift; j++) { + unset_module(symbol, i, j); + } + } + } + + /* Merge linear and 2D components into one structure */ + for (i = 0; i <= linear->rows; i++) { + symbol->row_height[symbol->rows + i] = linear->row_height[i]; + for (j = 0; j <= linear->width; j++) { + if (module_is_set(linear, i, j)) { + set_module(symbol, i + symbol->rows, j + bottom_shift); + } else { + unset_module(symbol, i + symbol->rows, j + bottom_shift); + } + } + } + if ((linear->width + bottom_shift) > symbol->width) { + symbol->width = linear->width + bottom_shift; + } + if ((symbol->width + top_shift) > symbol->width) { + symbol->width += top_shift; + } + symbol->rows += linear->rows; + ustrcpy(symbol->text, (unsigned char *) linear->text); + + ZBarcode_Delete(linear); + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/composite.h b/3rdparty/zint-2.6.1/backend/composite.h new file mode 100644 index 0000000..c03c11b --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/composite.h @@ -0,0 +1,73 @@ +/* composite.c - Tables for UCC.EAN Composite Symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define NUMERIC 110 +#define ALPHA 97 +#define ISOIEC 105 +#define INVALID_CHAR 100 +#define ANY_ENC 120 +#define ALPHA_OR_ISO 121 + +/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */ +static const unsigned short int ccaCoeffs[30] = { + /* k = 4 */ + 522, 568, 723, 809, + + /* k = 5 */ + 427, 919, 460, 155, 566, + + /* k = 6 */ + 861, 285, 19, 803, 17, 766, + + /* k = 7 */ + 76, 925, 537, 597, 784, 691, 437, + + /* k = 8 */ + 237, 308, 436, 284, 646, 653, 428, 379 +}; + +/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */ +static const char ccaVariants[51] = { + 5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, + 4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8, + 0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22 +}; + +/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables 10 and 11 */ +static const char aRAPTable[68] = { + 39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29, + 0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 26, 14, 9, + 19, 33, 12, 40, 46, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41, + 6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3 +}; + +/* Row Address Patterns are as defined in pdf417.h */ diff --git a/3rdparty/zint-2.4.4/backend/dllversion.c b/3rdparty/zint-2.6.1/backend/dllversion.c similarity index 99% rename from 3rdparty/zint-2.4.4/backend/dllversion.c rename to 3rdparty/zint-2.6.1/backend/dllversion.c index 0500863..d59725e 100644 --- a/3rdparty/zint-2.4.4/backend/dllversion.c +++ b/3rdparty/zint-2.6.1/backend/dllversion.c @@ -18,14 +18,14 @@ HRESULT DllGetVersion (DLLVERSIONINFO2* pdvi) { if (!pdvi || (sizeof(*pdvi) != pdvi->info1.cbSize)) return (E_INVALIDARG); - + pdvi->info1.dwMajorVersion = 2; pdvi->info1.dwMinorVersion = 2; pdvi->info1.dwBuildNumber = 1; pdvi->info1.dwPlatformID = DLLVER_PLATFORM_WINDOWS; if (sizeof(DLLVERSIONINFO2) == pdvi->info1.cbSize) pdvi->ullVersion = MAKEDLLVERULL(2, 2, 1, 0); - + return S_OK; } #endif /* _WIN32 */ diff --git a/3rdparty/zint-2.6.1/backend/dmatrix.c b/3rdparty/zint-2.6.1/backend/dmatrix.c new file mode 100644 index 0000000..0fc281d --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/dmatrix.c @@ -0,0 +1,1318 @@ +/* dmatrix.c Handles Data Matrix ECC 200 symbols */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + developed from and including some functions from: + IEC16022 bar code generation + Adrian Kennard, Andrews & Arnold Ltd + with help from Cliff Hones on the RS coding + + (c) 2004 Adrian Kennard, Andrews & Arnold Ltd + (c) 2006 Stefan Schmidt + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#include +/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */ +#if _MSC_VER < 1800 +#define ceilf ceil +#endif +#endif +#include "reedsol.h" +#include "common.h" +#include "dmatrix.h" + +/* Annex M placement alorithm low level */ +static void ecc200placementbit(int *array, const int NR, const int NC, int r, int c, const int p, const char b) { + if (r < 0) { + r += NR; + c += 4 - ((NR + 4) % 8); + } + if (c < 0) { + c += NC; + r += 4 - ((NC + 4) % 8); + } + // Necessary for 26x32,26x40,26x48,36x120,36x144,72x120,72x144 + if (r >= NR) { +#ifdef DEBUG + fprintf(stderr, "r >= NR:%i,%i at r=%i->", p, b, r); +#endif + r -= NR; +#ifdef DEBUG + fprintf(stderr, "%i,c=%i\n", r, c); +#endif + } +#ifdef DEBUG + if (0 != array[r * NC + c]) { + int a = array[r * NC + c]; + fprintf(stderr, "Double:%i,%i->%i,%i at r=%i,c=%i\n", a >> 3, a & 7, p, b, r, c); + return; + } +#endif + // Check index limits + assert(r < NR); + assert(c < NC); + // Check double-assignment + assert(0 == array[r * NC + c]); + array[r * NC + c] = (p << 3) + b; +} + +static void ecc200placementblock(int *array, const int NR, const int NC, const int r, + const int c, const int p) { + ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7); + ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6); + ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5); + ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4); + ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3); + ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2); + ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1); + ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0); +} + +static void ecc200placementcornerA(int *array, const int NR, const int NC, const int p) { + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6); + ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2); + ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1); + ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0); +} + +static void ecc200placementcornerB(int *array, const int NR, const int NC, const int p) { + ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6); + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0); +} + +static void ecc200placementcornerC(int *array, const int NR, const int NC, const int p) { + ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6); + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2); + ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1); + ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0); +} + +static void ecc200placementcornerD(int *array, const int NR, const int NC, const int p) { + ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7); + ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6); + ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5); + ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4); + ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3); + ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2); + ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1); + ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0); +} + +/* Annex M placement alorithm main function */ +static void ecc200placement(int *array, const int NR, const int NC) { + int r, c, p; + // invalidate + for (r = 0; r < NR; r++) + for (c = 0; c < NC; c++) + array[r * NC + c] = 0; + // start + p = 1; + r = 4; + c = 0; + do { + // check corner + if (r == NR && !c) + ecc200placementcornerA(array, NR, NC, p++); + if (r == NR - 2 && !c && NC % 4) + ecc200placementcornerB(array, NR, NC, p++); + if (r == NR - 2 && !c && (NC % 8) == 4) + ecc200placementcornerC(array, NR, NC, p++); + if (r == NR + 4 && c == 2 && !(NC % 8)) + ecc200placementcornerD(array, NR, NC, p++); + // up/right + do { + if (r < NR && c >= 0 && !array[r * NC + c]) + ecc200placementblock(array, NR, NC, r, c, p++); + r -= 2; + c += 2; + } while (r >= 0 && c < NC); + r++; + c += 3; + // down/left + do { + if (r >= 0 && c < NC && !array[r * NC + c]) + ecc200placementblock(array, NR, NC, r, c, p++); + r += 2; + c -= 2; + } while (r < NR && c >= 0); + r += 3; + c++; + } while (r < NR || c < NC); + // unfilled corner + if (!array[NR * NC - 1]) + array[NR * NC - 1] = array[NR * NC - NC - 2] = 1; +} + +/* calculate and append ecc code, and if necessary interleave */ +static void ecc200(unsigned char *binary, const int bytes, const int datablock, const int rsblock, const int skew) { + int blocks = (bytes + 2) / datablock, b; + int n, p; + rs_init_gf(0x12d); + rs_init_code(rsblock, 1); + for (b = 0; b < blocks; b++) { + unsigned char buf[256], ecc[256]; + p = 0; + for (n = b; n < bytes; n += blocks) + buf[p++] = binary[n]; + rs_encode(p, buf, ecc); + p = rsblock - 1; // comes back reversed + for (n = b; n < rsblock * blocks; n += blocks) { + if (skew) { + /* Rotate ecc data to make 144x144 size symbols acceptable */ + /* See http://groups.google.com/group/postscriptbarcode/msg/5ae8fda7757477da */ + if (b < 8) { + binary[bytes + n + 2] = ecc[p--]; + } else { + binary[bytes + n - 8] = ecc[p--]; + } + } else { + binary[bytes + n] = ecc[p--]; + } + } + } + rs_free(); +} + +/* Return true (1) if a character is valid in X12 set */ +static int isX12(const int source) { + + switch(source) { + case 13: // CR + case 42: // * + case 62: // > + case 32: // space + return 1; + } + + if ((source >= '0') && (source <= '9')) { + return 1; + } + if ((source >= 'A') && (source <= 'Z')) { + return 1; + } + + return 0; +} + +/* Insert a character into the middle of a string at position posn */ +static void dminsert(char binary_string[], const int posn, const char newbit) { + int i, end; + + end = (int) strlen(binary_string); + for (i = end + 1; i > posn; i--) { + binary_string[i] = binary_string[i - 1]; + } + binary_string[posn] = newbit; +} + +static void insert_value(unsigned char binary_stream[], const int posn, const int streamlen, const int newbit) { + int i; + + for(i = (int)streamlen; i > posn; i--) { + binary_stream[i] = binary_stream[i - 1]; + } + binary_stream[posn] = (unsigned char) newbit; +} + +static int p_r_6_2_1(const unsigned char inputData[], const size_t position, const size_t sourcelen) { + /* Annex P section (r)(6)(ii)(I) + "If one of the three X12 terminator/separator characters first + occurs in the yet to be processed data before a non-X12 character..." + */ + + size_t i; + size_t nonX12Position = 0; + size_t specialX12Position = 0; + int retval = 0; + + for (i = position; i < sourcelen; i++) { + if (nonX12Position == 0) { + if (isX12(inputData[i]) != 1) { + nonX12Position = i; + } + } + + if (specialX12Position == 0) { + if ((inputData[i] == (char) 13) || + (inputData[i] == '*') || + (inputData[i] == '>')) { + specialX12Position = i; + } + } + } + + if ((nonX12Position != 0) && (specialX12Position != 0)) { + if (specialX12Position < nonX12Position) { + retval = 1; + } + } + + return retval; +} + +/* 'look ahead test' from Annex P */ +static int look_ahead_test(const unsigned char inputData[], const size_t sourcelen, const size_t position, const int current_mode, const int gs1) { + float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count; + const float stiction = (1.0F / 24.0F); // smallest change to act on, to get around floating point inaccuracies + int best_scheme; + size_t sp; + + best_scheme = DM_NULL; + + /* step (j) */ + if (current_mode == DM_ASCII) { + ascii_count = 0.0F; + c40_count = 1.0F; + text_count = 1.0F; + x12_count = 1.0F; + edf_count = 1.0F; + b256_count = 1.25F; + } else { + ascii_count = 1.0F; + c40_count = 2.0F; + text_count = 2.0F; + x12_count = 2.0F; + edf_count = 2.0F; + b256_count = 2.25F; + } + + switch (current_mode) { + case DM_C40: c40_count = 0.0F; + break; + case DM_TEXT: text_count = 0.0F; + break; + case DM_X12: x12_count = 0.0F; + break; + case DM_EDIFACT: edf_count = 0.0F; + break; + case DM_BASE256: b256_count = 0.0F; + break; + } + + sp = position; + + do { + if (sp == sourcelen) { + /* At the end of data ... step (k) */ + ascii_count = ceilf(ascii_count); + b256_count = ceilf(b256_count); + edf_count = ceilf(edf_count); + text_count = ceilf(text_count); + x12_count = ceilf(x12_count); + c40_count = ceilf(c40_count); + + best_count = c40_count; + best_scheme = DM_C40; // (k)(7) + + if (x12_count < (best_count - stiction)) { + best_count = x12_count; + best_scheme = DM_X12; // (k)(6) + } + + if (text_count < (best_count - stiction)) { + best_count = text_count; + best_scheme = DM_TEXT; // (k)(5) + } + + if (edf_count < (best_count - stiction)) { + best_count = edf_count; + best_scheme = DM_EDIFACT; // (k)(4) + } + + if (b256_count < (best_count - stiction)) { + best_count = b256_count; + best_scheme = DM_BASE256; // (k)(3) + } + + if (ascii_count <= (best_count + stiction)) { + best_scheme = DM_ASCII; // (k)(2) + } + } else { + + /* ascii ... step (l) */ + if ((inputData[sp] >= '0') && (inputData[sp] <= '9')) { + ascii_count += 0.5F; // (l)(1) + } else { + if (inputData[sp] > 127) { + ascii_count = ceilf(ascii_count) + 2.0F; // (l)(2) + } else { + ascii_count = ceilf(ascii_count) + 1.0F; // (l)(3) + } + } + + /* c40 ... step (m) */ + if ((inputData[sp] == ' ') || + (((inputData[sp] >= '0') && (inputData[sp] <= '9')) || + ((inputData[sp] >= 'A') && (inputData[sp] <= 'Z')))) { + c40_count += (2.0F / 3.0F); // (m)(1) + } else { + if (inputData[sp] > 127) { + c40_count += (8.0F / 3.0F); // (m)(2) + } else { + c40_count += (4.0F / 3.0F); // (m)(3) + } + } + + /* text ... step (n) */ + if ((inputData[sp] == ' ') || + (((inputData[sp] >= '0') && (inputData[sp] <= '9')) || + ((inputData[sp] >= 'a') && (inputData[sp] <= 'z')))) { + text_count += (2.0F / 3.0F); // (n)(1) + } else { + if (inputData[sp] > 127) { + text_count += (8.0F / 3.0F); // (n)(2) + } else { + text_count += (4.0F / 3.0F); // (n)(3) + } + } + + /* x12 ... step (o) */ + if (isX12(inputData[sp])) { + x12_count += (2.0F / 3.0F); // (o)(1) + } else { + if (inputData[sp] > 127) { + x12_count += (13.0F / 3.0F); // (o)(2) + } else { + x12_count += (10.0F / 3.0F); // (o)(3) + } + } + + /* edifact ... step (p) */ + if ((inputData[sp] >= ' ') && (inputData[sp] <= '^')) { + edf_count += (3.0F / 4.0F); // (p)(1) + } else { + if (inputData[sp] > 127) { + edf_count += 17.0F; // (p)(2) > Value changed from ISO + } else { + edf_count += 13.0F; // (p)(3) > Value changed from ISO + } + } + if ((gs1 == 1) && (inputData[sp] == '[')) { + edf_count += 13.0F; // > Value changed from ISO + } + + /* base 256 ... step (q) */ + if ((gs1 == 1) && (inputData[sp] == '[')) { + b256_count += 4.0F; // (q)(1) + } else { + b256_count += 1.0F; // (q)(2) + } + } + + + if (sp > (position + 3)) { + /* 4 data characters processed ... step (r) */ + + /* step (r)(6) */ + if (((c40_count + 1.0F) < (ascii_count - stiction)) && + ((c40_count + 1.0F) < (b256_count - stiction)) && + ((c40_count + 1.0F) < (edf_count - stiction)) && + ((c40_count + 1.0F) < (text_count - stiction))) { + + if (c40_count < (x12_count - stiction)) { + best_scheme = DM_C40; + } + + if ((c40_count >= (x12_count - stiction)) + && (c40_count <= (x12_count + stiction))) { + if (p_r_6_2_1(inputData, sp, sourcelen) == 1) { + // Test (r)(6)(ii)(i) + best_scheme = DM_X12; + } else { + best_scheme = DM_C40; + } + } + } + + /* step (r)(5) */ + if (((x12_count + 1.0F) < (ascii_count - stiction)) && + ((x12_count + 1.0F) < (b256_count - stiction)) && + ((x12_count + 1.0F) < (edf_count - stiction)) && + ((x12_count + 1.0F) < (text_count - stiction)) && + ((x12_count + 1.0F) < (c40_count - stiction))) { + best_scheme = DM_X12; + } + + /* step (r)(4) */ + if (((text_count + 1.0F) < (ascii_count - stiction)) && + ((text_count + 1.0F) < (b256_count - stiction)) && + ((text_count + 1.0F) < (edf_count - stiction)) && + ((text_count + 1.0F) < (x12_count - stiction)) && + ((text_count + 1.0F) < (c40_count - stiction))) { + best_scheme = DM_TEXT; + } + + /* step (r)(3) */ + if (((edf_count + 1.0F) < (ascii_count - stiction)) && + ((edf_count + 1.0F) < (b256_count - stiction)) && + ((edf_count + 1.0F) < (text_count - stiction)) && + ((edf_count + 1.0F) < (x12_count - stiction)) && + ((edf_count + 1.0F) < (c40_count - stiction))) { + best_scheme = DM_EDIFACT; + } + + /* step (r)(2) */ + if (((b256_count + 1.0F) <= (ascii_count + stiction)) || + (((b256_count + 1.0F) < (edf_count - stiction)) && + ((b256_count + 1.0F) < (text_count - stiction)) && + ((b256_count + 1.0F) < (x12_count - stiction)) && + ((b256_count + 1.0F) < (c40_count - stiction)))) { + best_scheme = DM_BASE256; + } + + /* step (r)(1) */ + if (((ascii_count + 1.0F) <= (b256_count + stiction)) && + ((ascii_count + 1.0F) <= (edf_count + stiction)) && + ((ascii_count + 1.0F) <= (text_count + stiction)) && + ((ascii_count + 1.0F) <= (x12_count + stiction)) && + ((ascii_count + 1.0F) <= (c40_count + stiction))) { + best_scheme = DM_ASCII; + } + } + + sp++; + } while (best_scheme == DM_NULL); // step (s) + + return best_scheme; +} + +/* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate + Supports encoding FNC1 in supporting systems */ +static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], int *last_mode, size_t *length_p, int process_buffer[], int *process_p) { + + size_t sp; + int tp, i, gs1; + int current_mode, next_mode; + size_t inputlen = *length_p; + int debug = symbol->debug; +#ifndef _MSC_VER + char binary[2 * inputlen]; +#else + char* binary = (char*) _alloca(2 * inputlen); +#endif + + sp = 0; + tp = 0; + memset(process_buffer, 0, 8); + *process_p = 0; + strcpy(binary, ""); + + /* step (a) */ + current_mode = DM_ASCII; + next_mode = DM_ASCII; + + if (symbol->input_mode == GS1_MODE) { + gs1 = 1; + } else { + gs1 = 0; + } + + if (gs1) { + target[tp] = 232; + tp++; + strcat(binary, " "); + if (debug) printf("FN1 "); + } /* FNC1 */ + + if (symbol->output_options & READER_INIT) { + if (gs1) { + strcpy(symbol->errtxt, "519: Cannot encode in GS1 mode and Reader Initialisation at the same time"); + return ZINT_ERROR_INVALID_OPTION; + } else { + target[tp] = 234; + tp++; /* Reader Programming */ + strcat(binary, " "); + if (debug) printf("RP "); + } + } + + if (symbol->eci > 3) { + /* Encode ECI numbers according to Table 6 */ + target[tp] = 241; /* ECI Character */ + tp++; + if (symbol->eci <= 126) { + target[tp] = (unsigned char) symbol->eci + 1; + tp++; + } + if ((symbol->eci >= 127) && (symbol->eci <= 16382)) { + target[tp] = (unsigned char) ((symbol->eci - 127) / 254) + 128; + tp++; + target[tp] = (unsigned char) ((symbol->eci - 127) % 254) + 1; + tp++; + } + if (symbol->eci >= 16383) { + target[tp] = (unsigned char) ((symbol->eci - 16383) / 64516) + 192; + tp++; + target[tp] = (unsigned char) (((symbol->eci - 16383) / 254) % 254) + 1; + tp++; + target[tp] = (unsigned char) ((symbol->eci - 16383) % 254) + 1; + tp++; + } + if (debug) printf("ECI %d ", symbol->eci + 1); + } + + /* Check for Macro05/Macro06 */ + /* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */ + /* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */ + if (tp == 0 && sp == 0 && inputlen >= 9 + && source[0] == '[' && source[1] == ')' && source[2] == '>' + && source[3] == '\x1e' && source[4] == '0' + && (source[5] == '5' || source[5] == '6') + && source[6] == '\x1d' + && source[inputlen - 2] == '\x1e' && source[inputlen - 1] == '\x04') { + /* Output macro Codeword */ + if (source[5] == '5') { + target[tp] = 236; + if (debug) printf("Macro05 "); + } else { + target[tp] = 237; + if (debug) printf("Macro06 "); + } + tp++; + strcat(binary, " "); + /* Remove macro characters from input string */ + sp = 7; + inputlen -= 2; + *length_p -= 2; + } + + + while (sp < inputlen) { + + current_mode = next_mode; + + /* step (b) - ASCII encodation */ + if (current_mode == DM_ASCII) { + next_mode = DM_ASCII; + + if (istwodigits(source, sp) && ((sp + 1) != inputlen)) { + target[tp] = (unsigned char) ((10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130); + if (debug) printf("N%d ", target[tp] - 130); + tp++; + strcat(binary, " "); + sp += 2; + } else { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + + if (next_mode != DM_ASCII) { + switch (next_mode) { + case DM_C40: target[tp] = 230; + tp++; + strcat(binary, " "); + if (debug) printf("C40 "); + break; + case DM_TEXT: target[tp] = 239; + tp++; + strcat(binary, " "); + if (debug) printf("TEX "); + break; + case DM_X12: target[tp] = 238; + tp++; + strcat(binary, " "); + if (debug) printf("X12 "); + break; + case DM_EDIFACT: target[tp] = 240; + tp++; + strcat(binary, " "); + if (debug) printf("EDI "); + break; + case DM_BASE256: target[tp] = 231; + tp++; + strcat(binary, " "); + if (debug) printf("BAS "); + break; + } + } else { + if (source[sp] > 127) { + target[tp] = 235; /* FNC4 */ + if (debug) printf("FN4 "); + tp++; + target[tp] = (source[sp] - 128) + 1; + if (debug) printf("A%02X ", target[tp] - 1); + tp++; + strcat(binary, " "); + } else { + if (gs1 && (source[sp] == '[')) { + target[tp] = 232; /* FNC1 */ + if (debug) printf("FN1 "); + } else { + target[tp] = source[sp] + 1; + if (debug) printf("A%02X ", target[tp] - 1); + } + tp++; + strcat(binary, " "); + } + sp++; + } + } + + } + + /* step (c) C40 encodation */ + if (current_mode == DM_C40) { + int shift_set, value; + + next_mode = DM_C40; + if (*process_p == 0) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if (next_mode != DM_C40) { + target[tp] = 254; + tp++; + strcat(binary, " "); /* Unlatch */ + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } else { + if (source[sp] > 127) { + process_buffer[*process_p] = 1; + (*process_p)++; + process_buffer[*process_p] = 30; + (*process_p)++; /* Upper Shift */ + shift_set = c40_shift[source[sp] - 128]; + value = c40_value[source[sp] - 128]; + } else { + shift_set = c40_shift[source[sp]]; + value = c40_value[source[sp]]; + } + + if (gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if (shift_set != 0) { + process_buffer[*process_p] = shift_set - 1; + (*process_p)++; + } + process_buffer[*process_p] = value; + (*process_p)++; + + if (*process_p >= 3) { + int iv; + + iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1; + target[tp] = (unsigned char) (iv / 256); + tp++; + target[tp] = iv % 256; + tp++; + strcat(binary, " "); + if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]); + + process_buffer[0] = process_buffer[3]; + process_buffer[1] = process_buffer[4]; + process_buffer[2] = process_buffer[5]; + process_buffer[3] = 0; + process_buffer[4] = 0; + process_buffer[5] = 0; + *process_p -= 3; + } + sp++; + } + } + + /* step (d) Text encodation */ + if (current_mode == DM_TEXT) { + int shift_set, value; + + next_mode = DM_TEXT; + if (*process_p == 0) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if (next_mode != DM_TEXT) { + target[tp] = 254; + tp++; + strcat(binary, " "); /* Unlatch */ + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } else { + if (source[sp] > 127) { + process_buffer[*process_p] = 1; + (*process_p)++; + process_buffer[*process_p] = 30; + (*process_p)++; /* Upper Shift */ + shift_set = text_shift[source[sp] - 128]; + value = text_value[source[sp] - 128]; + } else { + shift_set = text_shift[source[sp]]; + value = text_value[source[sp]]; + } + + if (gs1 && (source[sp] == '[')) { + shift_set = 2; + value = 27; /* FNC1 */ + } + + if (shift_set != 0) { + process_buffer[*process_p] = shift_set - 1; + (*process_p)++; + } + process_buffer[*process_p] = value; + (*process_p)++; + + if (*process_p >= 3) { + int iv; + + iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1; + target[tp] = (unsigned char) (iv / 256); + tp++; + target[tp] = iv % 256; + tp++; + strcat(binary, " "); + if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]); + + process_buffer[0] = process_buffer[3]; + process_buffer[1] = process_buffer[4]; + process_buffer[2] = process_buffer[5]; + process_buffer[3] = 0; + process_buffer[4] = 0; + process_buffer[5] = 0; + *process_p -= 3; + } + sp++; + } + } + + /* step (e) X12 encodation */ + if (current_mode == DM_X12) { + int value = 0; + + next_mode = DM_X12; + if (*process_p == 0) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if (next_mode != DM_X12) { + target[tp] = 254; + tp++; + strcat(binary, " "); /* Unlatch */ + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } else { + if (source[sp] == 13) { + value = 0; + } + if (source[sp] == '*') { + value = 1; + } + if (source[sp] == '>') { + value = 2; + } + if (source[sp] == ' ') { + value = 3; + } + if ((source[sp] >= '0') && (source[sp] <= '9')) { + value = (source[sp] - '0') + 4; + } + if ((source[sp] >= 'A') && (source[sp] <= 'Z')) { + value = (source[sp] - 'A') + 14; + } + + process_buffer[*process_p] = value; + (*process_p)++; + + if (*process_p >= 3) { + int iv; + + iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1; + target[tp] = (unsigned char) (iv / 256); + tp++; + target[tp] = iv % 256; + tp++; + strcat(binary, " "); + if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]); + + process_buffer[0] = process_buffer[3]; + process_buffer[1] = process_buffer[4]; + process_buffer[2] = process_buffer[5]; + process_buffer[3] = 0; + process_buffer[4] = 0; + process_buffer[5] = 0; + *process_p -= 3; + } + sp++; + } + } + + /* step (f) EDIFACT encodation */ + if (current_mode == DM_EDIFACT) { + int value = 0; + + next_mode = DM_EDIFACT; + if (*process_p == 3) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + } + + if (next_mode != DM_EDIFACT) { + process_buffer[*process_p] = 31; + (*process_p)++; + next_mode = DM_ASCII; + } else { + value = source[sp]; + + if (source[sp] >= 64) { // '@' + value -= 64; + } + + process_buffer[*process_p] = value; + (*process_p)++; + sp++; + } + + if (*process_p >= 4) { + target[tp] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4)); + tp++; + target[tp] = ((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2); + tp++; + target[tp] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + process_buffer[3]); + tp++; + strcat(binary, " "); + if (debug) printf("[%d %d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2], process_buffer[3]); + + process_buffer[0] = process_buffer[4]; + process_buffer[1] = process_buffer[5]; + process_buffer[2] = process_buffer[6]; + process_buffer[3] = process_buffer[7]; + process_buffer[4] = 0; + process_buffer[5] = 0; + process_buffer[6] = 0; + process_buffer[7] = 0; + *process_p -= 4; + } + } + + /* step (g) Base 256 encodation */ + if (current_mode == DM_BASE256) { + next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1); + + if (next_mode == DM_BASE256) { + target[tp] = source[sp]; + if (debug) printf("B%02X ", target[tp]); + tp++; + sp++; + strcat(binary, "b"); + } else { + next_mode = DM_ASCII; + if (debug) printf("ASC "); + } + } + + if (tp > 1558) { + return 0; + } + + } /* while */ + + /* Add length and randomising algorithm to b256 */ + i = 0; + while (i < tp) { + if (binary[i] == 'b') { + if ((i == 0) || (binary[i - 1] != 'b')) { + /* start of binary data */ + int binary_count; /* length of b256 data */ + + for (binary_count = 0; binary_count + i < tp && binary[binary_count + i] == 'b'; binary_count++); + + if (binary_count <= 249) { + dminsert(binary, i, 'b'); + insert_value(target, i, tp, binary_count); + tp++; + } else { + dminsert(binary, i, 'b'); + dminsert(binary, i + 1, 'b'); + insert_value(target, i, tp, (binary_count / 250) + 249); + tp++; + insert_value(target, i + 1, tp, binary_count % 250); + tp++; + } + } + } + i++; + } + + for (i = 0; i < tp; i++) { + if (binary[i] == 'b') { + int prn, temp; + + prn = ((149 * (i + 1)) % 255) + 1; + temp = target[i] + prn; + if (temp <= 255) { + target[i] = (unsigned char) (temp); + } else { + target[i] = (unsigned char) (temp - 256); + } + } + } + + *(last_mode) = current_mode; + return tp; +} + +static int dm200encode_remainder(unsigned char target[], int target_length, const unsigned char source[], const size_t inputlen, const int last_mode, const int process_buffer[], const int process_p, const int symbols_left) { + int debug = 0; + + switch (last_mode) { + case DM_C40: + case DM_TEXT: + if (process_p == 1) // 1 data character left to encode. + { + if (symbols_left > 1) { + target[target_length] = 254; + target_length++; // Unlatch and encode remaining data in ascii. + } + target[target_length] = source[inputlen - 1] + 1; + target_length++; + } else if (process_p == 2) // 2 data characters left to encode. + { + // Pad with shift 1 value (0) and encode as double. + int intValue = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + 1; // ie (0 + 1). + target[target_length] = (unsigned char) (intValue / 256); + target_length++; + target[target_length] = (unsigned char) (intValue % 256); + target_length++; + if (symbols_left > 2) { + target[target_length] = 254; // Unlatch + target_length++; + } + } else { + if (symbols_left > 0) { + target[target_length] = 254; // Unlatch + target_length++; + } + } + break; + + case DM_X12: + if ((symbols_left == process_p) && (process_p == 1)) { + // Unlatch not required! + target[target_length] = source[inputlen - 1] + 1; + target_length++; + } else { + target[target_length] = (254); + target_length++; // Unlatch. + + if (process_p == 1) { + target[target_length] = source[inputlen - 1] + 1; + target_length++; + } + + if (process_p == 2) { + target[target_length] = source[inputlen - 2] + 1; + target_length++; + target[target_length] = source[inputlen - 1] + 1; + target_length++; + } + } + break; + + case DM_EDIFACT: + if (symbols_left <= 2) // Unlatch not required! + { + if (process_p == 1) { + target[target_length] = source[inputlen - 1] + 1; + target_length++; + } + + if (process_p == 2) { + target[target_length] = source[inputlen - 2] + 1; + target_length++; + target[target_length] = source[inputlen - 1] + 1; + target_length++; + } + } else { + // Append edifact unlatch value (31) and empty buffer + if (process_p == 0) { + target[target_length] = (unsigned char) (31 << 2); + target_length++; + } + + if (process_p == 1) { + target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((31 & 0x30) >> 4)); + target_length++; + target[target_length] = (unsigned char) ((31 & 0x0f) << 4); + target_length++; + } + + if (process_p == 2) { + target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4)); + target_length++; + target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((31 & 0x3c) >> 2)); + target_length++; + target[target_length] = (unsigned char) (((31 & 0x03) << 6)); + target_length++; + } + + if (process_p == 3) { + target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4)); + target_length++; + target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2)); + target_length++; + target[target_length] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + 31); + target_length++; + } + } + break; + } + + if (debug) { + int i; + printf("\n\n"); + for (i = 0; i < target_length; i++) + printf("%03d ", target[i]); + + printf("\n"); + } + + return target_length; +} + +/* add pad bits */ +static void add_tail(unsigned char target[], int tp, const int tail_length) { + int i, prn, temp; + + for (i = tail_length; i > 0; i--) { + if (i == tail_length) { + target[tp] = 129; + tp++; /* Pad */ + } else { + prn = ((149 * (tp + 1)) % 253) + 1; + temp = 129 + prn; + if (temp <= 254) { + target[tp] = (unsigned char) (temp); + tp++; + } else { + target[tp] = (unsigned char) (temp - 254); + tp++; + } + } + } +} + +int data_matrix_200(struct zint_symbol *symbol,const unsigned char source[], const size_t in_length) { + int i, skew = 0; + size_t inputlen=in_length; + unsigned char binary[2200]; + int binlen; + int process_buffer[8]; /* holds remaining data to finalised */ + int process_p; /* number of characters left to finalise */ + int symbolsize, optionsize, calcsize; + int taillength, error_number = 0; + int H, W, FH, FW, datablock, bytes, rsblock; + int last_mode = DM_ASCII; + unsigned char *grid = 0; + int symbols_left; + + /* inputlen may be decremented by 2 if macro character is used */ + binlen = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p); + + if (binlen == 0) { + strcpy(symbol->errtxt, "520: Data too long to fit in symbol"); + return ZINT_ERROR_TOO_LONG; + } + + if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) { + optionsize = intsymbol[symbol->option_2 - 1]; + } else { + optionsize = -1; + } + + calcsize = DMSIZESCOUNT - 1; + for (i = DMSIZESCOUNT - 1; i > -1; i--) { + if (matrixbytes[i] >= (binlen + process_p)) { + // Allow for the remaining data characters + calcsize = i; + } + } + + if (symbol->option_3 == DM_SQUARE) { + /* Skip rectangular symbols in square only mode */ + while (matrixH[calcsize] != matrixW[calcsize]) { + calcsize++; + } + if (optionsize != -1) { + strcpy(symbol->errtxt, "521: Can not force square symbols when symbol size is selected"); + error_number = ZINT_WARN_INVALID_OPTION; + } + } else if (symbol->option_3 != DM_DMRE) { + /* Skip DMRE symbols */ + while (isDMRE[calcsize]) { + calcsize++; + } + } + + symbolsize = optionsize; + if (calcsize > optionsize) { + symbolsize = calcsize; + if (optionsize != -1) { + strcpy(symbol->errtxt, "522: Input too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + } + + // Now we know the symbol size we can handle the remaining data in the process buffer. + symbols_left = matrixbytes[symbolsize] - binlen; + binlen = dm200encode_remainder(binary, binlen, source, inputlen, last_mode, process_buffer, process_p, symbols_left); + + if (binlen > matrixbytes[symbolsize]) { + strcpy(symbol->errtxt, "523: Data too long to fit in symbol"); + return ZINT_ERROR_TOO_LONG; + } + + H = matrixH[symbolsize]; + W = matrixW[symbolsize]; + FH = matrixFH[symbolsize]; + FW = matrixFW[symbolsize]; + bytes = matrixbytes[symbolsize]; + datablock = matrixdatablock[symbolsize]; + rsblock = matrixrsblock[symbolsize]; + + taillength = bytes - binlen; + + if (taillength != 0) { + add_tail(binary, binlen, taillength); + } + + // ecc code + if (symbolsize == INTSYMBOL144) { + skew = 1; + } + ecc200(binary, bytes, datablock, rsblock, skew); + // Print Codewords +#ifdef DEBUG + { + int CWCount; + int posCur; + if (skew) + CWCount = 1558 + 620; + else + CWCount = bytes + rsblock * (bytes / datablock); + printf("Codewords (%i):", CWCount); + for (posCur = 0; posCur < CWCount; posCur++) + printf(" %3i", binary[posCur]); + puts("\n"); + } +#endif + { // placement + int x, y, NC, NR, *places; + NC = W - 2 * (W / FW); + NR = H - 2 * (H / FH); + places = (int*) malloc(NC * NR * sizeof (int)); + ecc200placement(places, NR, NC); + grid = (unsigned char*) malloc(W * H); + memset(grid, 0, W * H); + for (y = 0; y < H; y += FH) { + for (x = 0; x < W; x++) + grid[y * W + x] = 1; + for (x = 0; x < W; x += 2) + grid[(y + FH - 1) * W + x] = 1; + } + for (x = 0; x < W; x += FW) { + for (y = 0; y < H; y++) + grid[y * W + x] = 1; + for (y = 0; y < H; y += 2) + grid[y * W + x + FW - 1] = 1; + } +#ifdef DEBUG + // Print position matrix as in standard + for (y = NR - 1; y >= 0; y--) { + for (x = 0; x < NC; x++) { + int v; + if (x != 0) + fprintf(stderr, "|"); + v = places[(NR - y - 1) * NC + x]; + fprintf(stderr, "%3d.%2d", (v >> 3), 8 - (v & 7)); + } + fprintf(stderr, "\n"); + } +#endif + for (y = 0; y < NR; y++) { + for (x = 0; x < NC; x++) { + int v = places[(NR - y - 1) * NC + x]; + //fprintf (stderr, "%4d", v); + if (v == 1 || (v > 7 && (binary[(v >> 3) - 1] & (1 << (v & 7))))) + grid[(1 + y + 2 * (y / (FH - 2))) * W + 1 + x + 2 * (x / (FW - 2))] = 1; + } + //fprintf (stderr, "\n"); + } + for (y = H - 1; y >= 0; y--) { + int x; + for (x = 0; x < W; x++) { + if (grid[W * y + x]) { + set_module(symbol, (H - y) - 1, x); + } + } + symbol->row_height[(H - y) - 1] = 1; + } + free(grid); + free(places); + } + + symbol->rows = H; + symbol->width = W; + + return error_number; +} + +int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) { + int error_number; + + if (symbol->option_1 <= 1) { + /* ECC 200 */ + error_number = data_matrix_200(symbol, source, in_length); + } else { + /* ECC 000 - 140 */ + strcpy(symbol->errtxt, "524: Older Data Matrix standards are no longer supported"); + error_number = ZINT_ERROR_INVALID_OPTION; + } + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/dmatrix.h b/3rdparty/zint-2.6.1/backend/dmatrix.h new file mode 100644 index 0000000..7d1f641 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/dmatrix.h @@ -0,0 +1,237 @@ +/* dmatrix.h - Handles Data Matrix ECC 200 */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* + Containes Extended Rectangular Data Matrix (DMRE) + See http://www.dmre.info for information + Contact: harald.oehlmann@eurodatacouncil.org + */ + +#include "common.h" + +#ifndef __IEC16022ECC200_H +#define __IEC16022ECC200_H +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern int data_matrix_200(struct zint_symbol *symbol, const unsigned char source[], const size_t length); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#define MAXBARCODE 3116 + +#define DM_NULL 0 +#define DM_ASCII 1 +#define DM_C40 2 +#define DM_TEXT 3 +#define DM_X12 4 +#define DM_EDIFACT 5 +#define DM_BASE256 6 + +static const char c40_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +static const char c40_value[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 15, 16, 17, 18, 19, 20, 21, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 22, 23, 24, 25, 26, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +static const char text_shift[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 +}; + +static const char text_value[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 15, 16, 17, 18, 19, 20, 21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 22, 23, 24, 25, 26, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 27, 28, 29, 30, 31 +}; + +// Position in option array [symbol option value - 1] +// The position in the option array is by increasing total data codewords with square first +// The last comment value is the total data codewords value. +// The index of this array is the --vers parameter value -1 and is given as forst comment value + +static const unsigned short int intsymbol[] = { + 0, /* 1: 10x10 , 3*/ 1, /* 2: 12x12 , 5*/ 3, /* 3: 14x14 , 8*/ 5, /* 4: 16x16 , 12*/ + 7, /* 5: 18x18 , 18*/ 9, /* 6: 20x20 , 22*/ 12, /* 7: 22x22 , 30*/ 14, /* 8: 24x24 , 36*/ + 16, /* 9: 26x26 , 44*/ 18, /* 10: 32x32 , 62*/ 21, /* 11: 36x36 , 86*/ 24, /* 12: 40x40 ,114*/ + 26, /* 13: 44x44 ,144*/ 27, /* 14: 48x48 ,174*/ 28, /* 15: 52x52 ,204*/ 29, /* 16: 64x64 ,280*/ + 30, /* 17: 72x72 ,368*/ 31, /* 18: 80x80 ,456*/ 32, /* 19: 88x88 ,576*/ 33, /* 20: 96x96 ,696*/ + 34, /* 21:104x104,816*/ 35, /* 22:120x120,1050*/36, /* 23:132x132,1304*/37, /* 24:144x144,1558*/ + 2, /* 25: 8x18 , 5*/ 4, /* 26: 8x32 , 10*/ 6, /* 27: 12x26 , 16*/ 10, /* 28: 12x36 , 22*/ + 13, /* 29: 16x36 , 32*/ 17, /* 30: 16x48 , 49*/ 8, /* 31: 8x48 , 18*/ 11, /* 32: 8x64 , 24*/ + 15, /* 33: 12x64 , 43*/ 19, /* 34: 16x64 , 62*/ 20, /* 37: 24x48 , 80*/ 23, /* 38: 24x64 ,108*/ + 22, /* 41: 26x48 , 90*/ 25, /* 42: 26x64 ,118*/ + 0 +}; + +// Number of DM Sizes +#define DMSIZESCOUNT 38 +// Number of 144x144 for special interlace +#define INTSYMBOL144 37 + +// Is the current code a DMRE code ? +// This is the case, if intsymbol index >= 30 + +static const char isDMRE[] = { + /* 0*/ 0, /* 10x10, 3 */ 0, /* 12x12 , 5 */ 0, /* 8x18 , 5 */ 0, /* 14x14 , 8 */ + /* 4*/ 0, /* 8x32 ,10 */ 0, /* 16x16 ,12 */ 0, /* 12x26 ,16 */ 0, /* 18x18 ,18 */ + /* 8*/ 1, /* 8x48 ,18 */ 0, /* 20x20 ,22 */ 0, /* 12x36 ,22 */ 1, /* 8x64 ,24 */ + /*12*/ 0, /* 22x22 ,30 */ 0, /* 16x36 ,32 */ 0, /* 24x24 ,36 */ 1, /* 12x64 ,43 */ + /*16*/ 0, /* 26x26 ,44 */ 0, /* 16x48 ,49 */ 0, /* 32x32 ,62 */ 1, /* 16x64 ,62 */ + /*20*/ 1, /* 24x48 ,80 */ 0, /* 36x36 ,86 */ 1, /* 26x48 ,90 */ 1, /* 24x64 ,108*/ + /*24*/ 0, /* 40x40 ,114*/ 1, /* 26x64 ,118*/ 0, /* 44x44 ,144*/ 0, /* 48x48,174 */ + /*28*/ 0, /* 52x52,204 */ 0, /* 64x64,280 */ 0, /* 72x72,368 */ 0, /* 80x80,456 */ + /*32*/ 0, /* 88x88,576 */ 0, /* 96x96,696 */ 0, /*104x104,816*/ 0, /*120x120,1050*/ + /*36*/ 0, /*132x132,1304*/0 /*144x144,1558*/ +}; + +// Horizontal matrix size + +static const unsigned short int matrixH[] = { + /* 0*/ 10, /* 10x10 , 3 */ 12, /* 12x12 , 5 */ 8, /* 8x18 , 5 */ 14, /* 14x14 , 8 */ + /* 4*/ 8, /* 8x32 ,10 */ 16, /* 16x16 ,12 */ 12, /* 12x26 ,16 */ 18, /* 18x18 ,18 */ + /* 8*/ 8, /* 8x48 ,18 */ 20, /* 20x20 ,22 */ 12, /* 12x36 ,22 */ 8, /* 8x64 ,24 */ + /*12*/ 22, /* 22x22 ,30 */ 16, /* 16x36 ,32 */ 24, /* 24x24 ,36 */ 12, /* 12x64 ,43 */ + /*16*/ 26, /* 26x26 ,44 */ 16, /* 16x48 ,49 */ 32, /* 32x32 ,62 */ 16, /* 16x64 ,62 */ + /*20*/ 24, /* 24x48 ,80 */ 36, /* 36x36 ,86 */ 26, /* 26x48 ,90 */ 24, /* 24x64 ,108*/ + /*24*/ 40, /* 40x40 ,114*/ 26, /* 26x64 ,118*/ 44, /* 44x44 ,144*/ 48, /* 48x48,174 */ + /*28*/ 52, /* 52x52,204 */ 64, /* 64x64,280 */ 72, /* 72x72,368 */ 80, /* 80x80,456 */ + /*32*/ 88, /* 88x88,576 */ 96, /* 96x96,696 */ 104, /*104x104,816*/ 120, /*120x120,1050*/ + /*36*/ 132,/*132x132,1304*/144 /*144x144,1558*/ +}; + +// Vertical matrix sizes + +static const unsigned short int matrixW[] = { + /* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */ + /* 4*/ 32, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */ + /* 8*/ 48, /* 8x48 */ 20, /* 20x20 */ 36, /* 12x36 */ 64, /* 8x64 */ + /*12*/ 22, /* 22x22 */ 36, /* 16x36 */ 24, /* 24x24 */ 64, /* 12x64 */ + /*16*/ 26, /* 26x26 */ 48, /* 16x48 */ 32, /* 32x32 */ 64, /* 16x64 */ + /*20*/ 48, /* 24x48 */ 36, /* 36x36 */ 48, /* 26x48 */ 64, /* 24x64 */ + /*24*/ 40, /* 40x40 */ 64, /* 26x64 */ 44, /* 44x44 */ 48, /* 48x48 */ + /*28*/ 52, /* 52x52 */ 64, /* 64x64 */ 72, /* 72x72 */ 80, /* 80x80 */ + /*32*/ 88, /* 88x88 */ 96, /* 96x96 */ 104,/*104x104*/ 120,/*120x120*/ + /*36*/132, /*132x132*/144 /*144x144*/ +}; + +// Horizontal submodule size (including subfinder) + +static const unsigned short int matrixFH[] = { + /* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 8, /* 8x18 */ 14, /* 14x14 */ + /* 4*/ 8, /* 8x32 */ 16, /* 16x16 */ 12, /* 12x26 */ 18, /* 18x18 */ + /* 8*/ 8, /* 8x48 */ 20, /* 20x20 */ 12, /* 12x36 */ 8, /* 8x64 */ + /*12*/ 22, /* 22x22 */ 16, /* 16x36 */ 24, /* 24x24 */ 12, /* 12x64 */ + /*16*/ 26, /* 26x26 */ 16, /* 16x48 */ 16, /* 32x32 */ 16, /* 16x64 */ + /*20*/ 24, /* 24x48 */ 18, /* 36x36 */ 26, /* 26x48 */ 24, /* 24x64 */ + /*24*/ 20, /* 40x40 */ 26, /* 26x64 */ 22, /* 44x44 */ 24, /* 48x48 */ + /*28*/ 26, /* 52x52 */ 16, /* 64x64 */ 18, /* 72x72 */ 20, /* 80x80 */ + /*32*/ 22, /* 88x88 */ 24, /* 96x96 */ 26, /*104x104*/ 20, /*120x120*/ + /*36*/ 22, /*132x132*/ 24 /*144x144*/ +}; + +// Vertical submodule size (including subfinder) + +static const unsigned short int matrixFW[] = { + /* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */ + /* 4*/ 16, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */ + /* 8*/ 24, /* 8x48 */ 20, /* 20x20 */ 18, /* 12x36 */ 16, /* 8x64 */ + /*12*/ 22, /* 22x22 */ 18, /* 16x36 */ 24, /* 24x24 */ 16, /* 12x64 */ + /*16*/ 26, /* 26x26 */ 24, /* 16x48 */ 16, /* 32x32 */ 16, /* 16x64 */ + /*20*/ 24, /* 24x48 */ 18, /* 36x36 */ 24, /* 26x48 */ 16, /* 24x64 */ + /*24*/ 20, /* 40x40 */ 16, /* 26x64 */ 22, /* 44x44 */ 24, /* 48x48 */ + /*28*/ 26, /* 52x52 */ 16, /* 64x64 */ 18, /* 72x72 */ 20, /* 80x80 */ + /*32*/ 22, /* 88x88 */ 24, /* 96x96 */ 26, /*104x104*/ 20, /*120x120*/ + /*36*/ 22, /*132x132*/ 24 /*144x144*/ +}; + +// Total Data Codewords + +static const unsigned short int matrixbytes[] = { + /* 0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */ + /* 4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */ + /* 8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */ + /*12*/ 30, /* 22x22 */ 32, /* 16x36 */ 36, /* 24x24 */ 43, /* 12x64 */ + /*16*/ 44, /* 26x26 */ 49, /* 16x48 */ 62, /* 32x32 */ 62, /* 16x64 */ + /*20*/ 80, /* 24x48 */ 86, /* 36x36 */ 90, /* 26x48 */ 108, /* 24x64 */ + /*24*/ 114, /* 40x40 */ 118, /* 26x64 */ 144, /* 44x44 */ 174, /* 48x48 */ + /*28*/ 204, /* 52x52 */ 280, /* 64x64 */ 368, /* 72x72 */ 456, /* 80x80 */ + /*32*/ 576, /* 88x88 */ 696, /* 96x96 */ 816, /*104x104*/1050, /*120x120*/ + /*36*/1304, /*132x132*/1558 /*144x144*/ +}; + +// Data Codewords per RS-Block + +static const unsigned short int matrixdatablock[] = { + /* 0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */ + /* 4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */ + /* 8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */ + /*12*/ 30, /* 22x22 */ 32, /* 16x36 */ 36, /* 24x24 */ 43, /* 12x64 */ + /*16*/ 44, /* 26x26 */ 49, /* 16x48 */ 62, /* 32x32 */ 62, /* 16x64 */ + /*20*/ 80, /* 24x48 */ 86, /* 36x36 */ 90, /* 26x48 */ 108, /* 24x64 */ + /*24*/ 114, /* 40x40 */ 118, /* 26x64 */ 144, /* 44x44 */ 174, /* 48x48 */ + /*28*/ 102, /* 52x52 */ 140, /* 64x64 */ 92, /* 72x72 */ 114, /* 80x80 */ + /*32*/ 144, /* 88x88 */ 174, /* 96x96 */ 136, /*104x104*/ 175, /*120x120*/ + /*36*/ 163, /*132x132*/ 156 /* 144x144*/ +}; + +// ECC Codewords per RS-Block + +static const unsigned short int matrixrsblock[] = { + /* 0*/ 5, /* 10x10 */ 7, /* 12x12 */ 7, /* 8x18 */ 10, /* 14x14 */ + /* 4*/ 11, /* 8x32 */ 12, /* 16x16 */ 14, /* 12x26 */ 14, /* 18x18 */ + /* 8*/ 15, /* 8x48 */ 18, /* 20x20 */ 18, /* 12x36 */ 18, /* 8x64 */ + /*12*/ 20, /* 22x22 */ 24, /* 16x36 */ 24, /* 24x24 */ 27, /* 12x64 */ + /*16*/ 28, /* 26x26 */ 28, /* 16x48 */ 36, /* 32x32 */ 36, /* 16x64 */ + /*20*/ 41, /* 24x48 */ 42, /* 36x36 */ 42, /* 26x48 */ 46, /* 24x64 */ + /*24*/ 48, /* 40x40 */ 50, /* 26x64 */ 56, /* 44x44 */ 68, /* 48x48 */ + /*28*/ 42, /* 52x52 */ 56, /* 64x64 */ 36, /* 72x72 */ 48, /* 80x80 */ + /*32*/ 56, /* 88x88 */ 68, /* 96x96 */ 56, /*104x104*/ 68, /*120x120*/ + /*36*/ 62, /*132x132*/ 62 /*144x144*/ +}; + + +#endif diff --git a/3rdparty/zint-2.6.1/backend/dotcode.c b/3rdparty/zint-2.6.1/backend/dotcode.c new file mode 100644 index 0000000..ce2219a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/dotcode.c @@ -0,0 +1,1463 @@ +/* dotcode.c - Handles DotCode */ + +/* + libzint - the open source barcode library + Copyright (C) 2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* + * Attempts to encode DotCode according to AIMD013 Rev 1.34a, dated Feb 19, 2009 + */ + +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#else +#include "ms_stdint.h" +#include +#endif +#include "common.h" +#include "gs1.h" + +#define GF 113 +#define PM 3 + +/* DotCode symbol character dot patterns, from Annex C */ +static const unsigned short int dot_patterns[113] = { + 0x155, 0x0ab, 0x0ad, 0x0b5, 0x0d5, 0x156, 0x15a, 0x16a, 0x1aa, 0x0ae, + 0x0b6, 0x0ba, 0x0d6, 0x0da, 0x0ea, 0x12b, 0x12d, 0x135, 0x14b, 0x14d, + 0x153, 0x159, 0x165, 0x169, 0x195, 0x1a5, 0x1a9, 0x057, 0x05b, 0x05d, + 0x06b, 0x06d, 0x075, 0x097, 0x09b, 0x09d, 0x0a7, 0x0b3, 0x0b9, 0x0cb, + 0x0cd, 0x0d3, 0x0d9, 0x0e5, 0x0e9, 0x12e, 0x136, 0x13a, 0x14e, 0x15c, + 0x166, 0x16c, 0x172, 0x174, 0x196, 0x19a, 0x1a6, 0x1ac, 0x1b2, 0x1b4, + 0x1ca, 0x1d2, 0x1d4, 0x05e, 0x06e, 0x076, 0x07a, 0x09e, 0x0bc, 0x0ce, + 0x0dc, 0x0e6, 0x0ec, 0x0f2, 0x0f4, 0x117, 0x11b, 0x11d, 0x127, 0x133, + 0x139, 0x147, 0x163, 0x171, 0x18b, 0x18d, 0x193, 0x199, 0x1a3, 0x1b1, + 0x1c5, 0x1c9, 0x1d1, 0x02f, 0x037, 0x03b, 0x03d, 0x04f, 0x067, 0x073, + 0x079, 0x08f, 0x0c7, 0x0e3, 0x0f1, 0x11e, 0x13c, 0x178, 0x18e, 0x19c, + 0x1b8, 0x1c6, 0x1cc +}; + +static int get_dot(char Dots[], const int Hgt, const int Wid, const int x, const int y) { + int retval = 0; + + if ((x >= 0) && (x < Wid) && (y >= 0) && (y < Hgt)) { + if (Dots[(y * Wid) + x] == '1') { + retval = 1; + } + } + + return retval; +} + +static int clr_col(char *Dots, const int Hgt, const int Wid, const int x) { + int y; + for (y = x & 1; y < Hgt; y += 2) { + if (get_dot(Dots, Hgt, Wid, x, y)) { + return 0; + } + } + + return 1; +} + +static int clr_row(char *Dots, const int Hgt, const int Wid, const int y) { + int x; + for (x = y & 1; x < Wid; x += 2) { + if (get_dot(Dots, Hgt, Wid, x, y)) { + return 0; + } + } + + return 1; +} + +/* Dot pattern scoring routine from Annex A */ +const int score_array(char Dots[], int Hgt, int Wid) { + int x, y, worstedge, first, last, sum; + int penalty_local = 0; + int penalty = 0; + + // first, guard against "pathelogical" gaps in the array + if (Hgt & 1) { + if (Hgt < 12) { + sum = 0; + for (x = 1; x < Wid - 1; x++) { + if (!(clr_col(Dots, Hgt, Wid, x))) { + sum = 0; + if (penalty_local) { + penalty += penalty_local; + penalty_local = 0; + } + } else { + sum++; + if (sum == 1) { + penalty_local = Hgt; + } else { + penalty_local *= Hgt; + } + } + } + } + } else { + if (Wid < 12) { + sum = 0; + for (y = 1; y < Hgt - 1; y++) { + if (!(clr_row(Dots, Hgt, Wid, y))) { + sum = 0; + if (penalty_local) { + penalty += penalty_local; + penalty_local = 0; + } + } else { + sum++; + if (sum == 1) { + penalty_local = Wid; + } else { + penalty_local *= Wid; + } + } + } + } + } + + sum = 0; + first = -1; + last = -1; + + // across the top edge, count printed dots and measure their extent + for (x = 0; x < Wid; x += 2) + if (get_dot(Dots, Hgt, Wid, x, 0)) { + if (first < 0) { + first = x; + } + last = x; + sum++; + } + worstedge = sum + last - first; + worstedge *= Hgt; + + sum = 0; + first = -1; + last = -1; + + //across the bottom edge, ditto + for (x = Wid & 1; x < Wid; x += 2) + if (get_dot(Dots, Hgt, Wid, x, Hgt - 1)) { + if (first < 0) { + first = x; + } + last = x; + sum++; + } + sum += last - first; + sum *= Hgt; + if (sum < worstedge) { + worstedge = sum; + } + + sum = 0; + first = -1; + last = -1; + + //down the left edge, ditto + for (y = 0; y < Hgt; y += 2) + if (get_dot(Dots, Hgt, Wid, 0, y)) { + if (first < 0) { + first = y; + } + last = y; + sum++; + } + sum += last - first; + sum *= Wid; + if (sum < worstedge) { + worstedge = sum; + } + + sum = 0; + first = -1; + last = -1; + + //down the right edge, ditto + for (y = Hgt & 1; y < Hgt; y += 2) + if (get_dot(Dots, Hgt, Wid, Wid - 1, y)) { + if (first < 0) { + first = y; + } + last = y; + sum++; + } + sum += last - first; + sum *= Wid; + if (sum < worstedge) { + worstedge = sum; + } + + // throughout the array, count the # of unprinted 5-somes (cross patterns) + // plus the # of printed dots surrounded by 8 unprinted neighbors + sum = 0; + for (y = 0; y < Hgt; y++) { + for (x = y & 1; x < Wid; x += 2) { + if ((!get_dot(Dots, Hgt, Wid, x - 1, y - 1)) + && (!get_dot(Dots, Hgt, Wid, x + 1, y - 1)) + && (!get_dot(Dots, Hgt, Wid, x - 1, y + 1)) + && (!get_dot(Dots, Hgt, Wid, x + 1, y + 1)) + && ((!get_dot(Dots, Hgt, Wid, x, y)) + || ((!get_dot(Dots, Hgt, Wid, x - 2, y)) + && (!get_dot(Dots, Hgt, Wid, x, y - 2)) + && (!get_dot(Dots, Hgt, Wid, x + 2, y)) + && (!get_dot(Dots, Hgt, Wid, x, y + 2))))) { + sum++; + } + } + } + + return (worstedge - sum * sum - penalty); +} + +//------------------------------------------------------------------------- +// "rsencode(nd,nc)" adds "nc" R-S check words to "nd" data words in wd[] +// employing Galois Field GF, where GF is prime, with a prime modulus of PM +//------------------------------------------------------------------------- + +void rsencode(int nd, int nc, unsigned char *wd) { + int i, j, k, nw, start, step, root[GF], c[GF]; + + // Start by generating "nc" roots (antilogs): + root[0] = 1; + for (i = 1; (i <= nc) && (i < GF); i++) + root[i] = (PM * root[i - 1]) % GF; + + // Here we compute how many interleaved R-S blocks will be needed + nw = nd + nc; + step = (nw + GF - 2) / (GF - 1); + + // ...& then for each such block: + for (start = 0; start < step; start++) { + int ND = (nd - start + step - 1) / step, NW = (nw - start + step - 1) / step, NC = NW - ND; + + // first compute the generator polynomial "c" of order "NC": + for (i = 1; i <= NC; i++) + c[i] = 0; + c[0] = 1; + + for (i = 1; i <= NC; i++) { + for (j = NC; j >= 1; j--) { + c[j] = (GF + c[j] - (root[i] * c[j - 1]) % GF) % GF; + } + } + + // & then compute the corresponding checkword values into wd[] + // ... (a) starting at wd[start] & (b) stepping by step + for (i = ND; i < NW; i++) + wd[start + i * step] = 0; + for (i = 0; i < ND; i++) { + k = (wd[start + i * step] + wd[start + ND * step]) % GF; + for (j = 0; j < NC - 1; j++) { + wd[start + (ND + j) * step] = (GF - ((c[j + 1] * k) % GF) + wd[start + (ND + j + 1) * step]) % GF; + } + wd[start + (ND + NC - 1) * step] = (GF - ((c[NC] * k) % GF)) % GF; + } + for (i = ND; i < NW; i++) + wd[start + i * step] = (GF - wd[start + i * step]) % GF; + } +} + +/* Check if the next character is directly encodable in code set A (Annex F.II.D) */ +int datum_a(const unsigned char source[], int position, int length) { + int retval = 0; + + if (position < length) { + if (source[position] <= 95) { + retval = 1; + } + } + + return retval; +} + +/* Check if the next character is directly encodable in code set B (Annex F.II.D) */ +int datum_b(const unsigned char source[], int position, int length) { + int retval = 0; + + if (position < length) { + if ((source[position] >= 32) && (source[position] <= 127)) { + retval = 1; + } + + switch (source[position]) { + case 9: // HT + case 28: // FS + case 29: // GS + case 30: // RS + retval = 1; + } + + if (position != length - 2) { + if ((source[position] == 13) && (source[position + 1] == 10)) { // CRLF + retval = 1; + } + } + } + + return retval; +} + +/* Check if the next characters are directly encodable in code set C (Annex F.II.D) */ +int datum_c(const unsigned char source[], int position, int length) { + int retval = 0; + + if (position <= length - 2) { + if (((source[position] >= '0') && (source[position] <= '9')) + && ((source[position + 1] >= '0') && (source[position + 1] <= '9'))) + retval = 1; + } + + return retval; +} + +/* Returns how many consecutive digits lie immediately ahead (Annex F.II.A) */ +int n_digits(const unsigned char source[], int position, int length) { + int i; + + for (i = position; ((source[i] >= '0') && (source[i] <= '9')) && (i < length); i++); + + return i - position; +} + +/* checks ahead for 10 or more digits starting "17xxxxxx10..." (Annex F.II.B) */ +int seventeen_ten(const unsigned char source[], int position, int length) { + int found = 0; + + if (n_digits(source, position, length) >= 10) { + if (((source[position] == '1') && (source[position + 1] == '7')) + && ((source[position + 8] == '1') && (source[position + 9] == '0'))) { + found = 1; + } + } + + return found; +} + +/* checks how many characters ahead can be reached while datum_c is true, + * returning the resulting number of codewords (Annex F.II.E) + */ +int ahead_c(const unsigned char source[], int position, int length) { + int count = 0; + int i; + + for (i = position; (i < length) && datum_c(source, i, length); i += 2) { + count++; + } + + return count; +} + +/* Annex F.II.F */ +int try_c(const unsigned char source[], int position, int length) { + int retval = 0; + + if (n_digits(source, position, length) > 0) { + if (ahead_c(source, position, length) > ahead_c(source, position + 1, length)) { + retval = ahead_c(source, position, length); + } + } + + return retval; +} + +/* Annex F.II.G */ +int ahead_a(const unsigned char source[], int position, int length) { + int count = 0; + int i; + + for (i = position; ((i < length) && datum_a(source, i, length)) + && (try_c(source, i, length) < 2); i++) { + count++; + } + + return count; +} + +/* Annex F.II.H */ +int ahead_b(const unsigned char source[], int position, int length) { + int count = 0; + int i; + + for (i = position; ((i < length) && datum_b(source, i, length)) + && (try_c(source, i, length) < 2); i++) { + count++; + } + + return count; +} + +/* checks if the next character is in the range 128 to 255 (Annex F.II.I) */ +int binary(const unsigned char source[], int position) { + int retval = 0; + + if (source[position] >= 128) { + retval = 1; + } + + return retval; +} + +/* Analyse input data stream and encode using algorithm from Annex F */ +int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char *codeword_array, int *binary_finish) { + int input_position, array_length, i; + char encoding_mode; + int inside_macro, done; + int debug = symbol->debug; + int binary_buffer_size = 0; + int lawrencium[6]; // Reversed radix 103 values + +#if defined(_MSC_VER) && _MSC_VER == 1200 + uint64_t binary_buffer = 0; +#else + uint64_t binary_buffer = 0ULL; +#endif + + input_position = 0; + array_length = 0; + encoding_mode = 'C'; + inside_macro = 0; + + if (symbol->output_options & READER_INIT) { + codeword_array[array_length] = 109; // FNC3 + array_length++; + } + + if (symbol->input_mode != GS1_MODE) { + if (length > 2) { + if (((source[input_position] >= '0') && (source[input_position] <= '9')) && + ((source[input_position + 1] >= '0') && (source[input_position + 1] <= '9'))) { + codeword_array[array_length] = 107; // FNC1 + array_length++; + } + } + } + + if (symbol->eci > 3) { + codeword_array[array_length] = 108; // FNC2 + array_length++; + if (symbol->eci <= 39) { + codeword_array[array_length] = symbol->eci; + array_length++; + } else { + // the next three codewords valued A, B & C encode the ECI value of + // (A - 40) * 12769 + B * 113 + C + 40 (Section 5.2.1) + int a, b, c; + a = (symbol->eci - 40) % 12769; + b = ((symbol->eci - 40) - (12769 * a)) % 113; + c = (symbol->eci - 40) - (12769 * a) - (113 * b); + + codeword_array[array_length] = a + 40; + array_length++; + codeword_array[array_length] = b; + array_length++; + codeword_array[array_length] = c; + array_length++; + } + } + + // Prevent encodation as a macro if a special character is in first position + if (source[input_position] == 9) { + codeword_array[array_length] = 101; // Latch A + array_length++; + codeword_array[array_length] = 73; // HT + array_length++; + encoding_mode = 'A'; + } + + if (source[input_position] == 28) { + codeword_array[array_length] = 101; // Latch A + array_length++; + codeword_array[array_length] = 92; // FS + array_length++; + encoding_mode = 'A'; + } + + if (source[input_position] == 29) { + codeword_array[array_length] = 101; // Latch A + array_length++; + codeword_array[array_length] = 93; // GS + array_length++; + encoding_mode = 'A'; + } + + if (source[input_position] == 30) { + codeword_array[array_length] = 101; // Latch A + array_length++; + codeword_array[array_length] = 94; // RS + array_length++; + encoding_mode = 'A'; + } + + do { + done = 0; + /* Step A */ + if ((input_position == length - 2) && (inside_macro != 0) && (inside_macro != 100)) { + // inside_macro only gets set to 97, 98 or 99 if the last two characters are RS/EOT + input_position += 2; + done = 1; + if (debug) { + printf("A "); + } + } + + if ((input_position == length - 1) && (inside_macro == 100)) { + // inside_macro only gets set to 100 if the last character is EOT + input_position++; + done = 1; + if (debug) { + printf("A "); + } + } + + /* Step B1 */ + if ((!done) && (encoding_mode == 'C')) { + if ((array_length == 0) && (length > 9)) { + if ((source[input_position] == '[') + && (source[input_position + 1] == ')') + && (source[input_position + 2] == '>') + && (source[input_position + 3] == 30) // RS + && (source[length - 1] == 04)) { // EOT + + + if ((source[input_position + 6] == 29) && (source[length - 2] == 30)) { // GS/RS + if ((source[input_position + 4] == '0') && (source[input_position + 5] == '5')) { + codeword_array[array_length] = 102; // Shift B + array_length++; + codeword_array[array_length] = 97; // Macro + array_length++; + input_position += 7; + inside_macro = 97; + done = 1; + if (debug) { + printf("B1/1 "); + } + } + + if ((source[input_position + 4] == '0') && (source[input_position + 5] == '6')) { + codeword_array[array_length] = 102; // Shift B + array_length++; + codeword_array[array_length] = 98; // Macro + array_length++; + input_position += 7; + inside_macro = 98; + done = 1; + if (debug) { + printf("B1/2 "); + } + } + + if ((source[input_position + 4] == '1') && (source[input_position + 5] == '2')) { + codeword_array[array_length] = 102; // Shift B + array_length++; + codeword_array[array_length] = 99; // Macro + array_length++; + input_position += 7; + inside_macro = 99; + done = 1; + if (debug) { + printf("B1/3 "); + } + } + } + + if ((!done) && (source[input_position] >= '0') && (source[input_position] <= '9') && + (source[input_position + 1] >= '0') && (source[input_position + 1] <= '9')) { + codeword_array[array_length] = 102; // Shift B + array_length++; + codeword_array[array_length] = 100; // Macro + array_length++; + input_position += 4; + inside_macro = 100; + done = 1; + if (debug) { + printf("B1/4 "); + } + } + } + } + } + + /* Step B2 */ + if ((!done) && (encoding_mode == 'C')) { + if (seventeen_ten(source, input_position, length)) { + codeword_array[array_length] = 100; // (17)...(10) + array_length++; + codeword_array[array_length] = ((source[input_position + 2] - '0') * 10) + (source[input_position + 3] - '0'); + array_length++; + codeword_array[array_length] = ((source[input_position + 4] - '0') * 10) + (source[input_position + 5] - '0'); + array_length++; + codeword_array[array_length] = ((source[input_position + 6] - '0') * 10) + (source[input_position + 7] - '0'); + array_length++; + input_position += 10; + done = 1; + if (debug) { + printf("B2/1 "); + } + } + } + + if ((!done) && (encoding_mode == 'C')) { + if (datum_c(source, input_position, length) || ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE))) { + if (source[input_position] == '[') { + codeword_array[array_length] = 107; // FNC1 + input_position++; + } else { + codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); + input_position += 2; + } + array_length++; + done = 1; + if (debug) { + printf("B2/2 "); + } + } + } + + /* Setp B3 */ + if ((!done) && (encoding_mode == 'C')) { + if (binary(source, input_position)) { + if (n_digits(source, input_position + 1, length) > 0) { + if ((source[input_position] - 128) < 32) { + codeword_array[array_length] = 110; // Bin Shift A + array_length++; + codeword_array[array_length] = source[input_position] - 128 + 64; + array_length++; + } else { + codeword_array[array_length] = 111; // Bin Shift B + array_length++; + codeword_array[array_length] = source[input_position] - 128 - 32; + array_length++; + } + input_position++; + } else { + codeword_array[array_length] = 112; // Bin Latch + array_length++; + encoding_mode = 'X'; + } + done = 1; + if (debug) { + printf("B3 "); + } + } + } + + /* Step B4 */ + if ((!done) && (encoding_mode == 'C')) { + int m = ahead_a(source, input_position, length); + int n = ahead_b(source, input_position, length); + if (m > n) { + codeword_array[array_length] = 101; // Latch A + array_length++; + encoding_mode = 'A'; + } else { + if (n <= 4) { + codeword_array[array_length] = 101 + n; // nx Shift B + array_length++; + + for (i = 0; i < n; i++) { + codeword_array[array_length] = source[input_position] - 32; + array_length++; + input_position++; + } + } else { + codeword_array[array_length] = 106; // Latch B + array_length++; + encoding_mode = 'B'; + } + } + done = 1; + if (debug) { + printf("B4 "); + } + } + + /* Step C1 */ + if ((!done) && (encoding_mode == 'B')) { + int n = try_c(source, input_position, length); + + if (n >= 2) { + if (n <= 4) { + codeword_array[array_length] = 103 + (n - 2); // nx Shift C + array_length++; + for (i = 0; i < n; i++) { + codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); + array_length++; + input_position += 2; + } + } else { + codeword_array[array_length] = 106; // Latch C + array_length++; + encoding_mode = 'C'; + } + done = 1; + if (debug) { + printf("C1 "); + } + } + } + + /* Step C2 */ + if ((!done) && (encoding_mode == 'B')) { + if ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE)) { + codeword_array[array_length] = 107; // FNC1 + array_length++; + input_position++; + done = 1; + if (debug) { + printf("C2/1 "); + } + } else { + if (datum_b(source, input_position, length)) { + + if ((source[input_position] >= 32) && (source[input_position] <= 127)) { + codeword_array[array_length] = source[input_position] - 32; + done = 1; + + } else if (source[input_position] == 13) { + /* CR/LF */ + codeword_array[array_length] = 96; + input_position++; + done = 1; + + } else if (input_position != 0) { + /* HT, FS, GS and RS in the first data position would be interpreted as a macro (see table 2) */ + switch(source[input_position]) { + case 9: // HT + codeword_array[array_length] = 97; + break; + case 28: // FS + codeword_array[array_length] = 98; + break; + case 29: // GS + codeword_array[array_length] = 99; + break; + case 30: // RS + codeword_array[array_length] = 100; + break; + } + done = 1; + } + + if (done == 1) { + array_length++; + input_position++; + if (debug) { + printf("C2/2 "); + } + } + } + } + } + + /* Step C3 */ + if ((!done) && (encoding_mode == 'B')) { + if (binary(source, input_position)) { + if (datum_b(source, input_position + 1, length)) { + if ((source[input_position] - 128) < 32) { + codeword_array[array_length] = 110; // Bin Shift A + array_length++; + codeword_array[array_length] = source[input_position] - 128 + 64; + array_length++; + } else { + codeword_array[array_length] = 111; // Bin Shift B + array_length++; + codeword_array[array_length] = source[input_position] - 128 - 32; + array_length++; + } + input_position++; + } else { + codeword_array[array_length] = 112; // Bin Latch + array_length++; + encoding_mode = 'X'; + } + done = 1; + if (debug) { + printf("C3 "); + } + } + } + + /* Step C4 */ + if ((!done) && (encoding_mode == 'B')) { + if (ahead_a(source, input_position, length) == 1) { + codeword_array[array_length] = 101; // Shift A + array_length++; + if (source[input_position] < 32) { + codeword_array[array_length] = source[input_position] + 64; + } else { + codeword_array[array_length] = source[input_position] - 32; + } + array_length++; + input_position++; + } else { + codeword_array[array_length] = 102; // Latch A + array_length++; + encoding_mode = 'A'; + } + done = 1; + if (debug) { + printf("C4 "); + } + } + + /* Step D1 */ + if ((!done) && (encoding_mode == 'A')) { + int n = try_c(source, input_position, length); + if (n >= 2) { + if (n <= 4) { + codeword_array[array_length] = 103 + (n - 2); // nx Shift C + array_length++; + for (i = 0; i < n; i++) { + codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); + array_length++; + input_position += 2; + } + } else { + codeword_array[array_length] = 106; // Latch C + array_length++; + encoding_mode = 'C'; + } + done = 1; + if (debug) { + printf("D1 "); + } + } + } + + /* Step D2 */ + if ((!done) && (encoding_mode == 'A')) { + if ((source[input_position] == '[') && (symbol->input_mode == GS1_MODE)) { + codeword_array[array_length] = 107; // FNC1 + array_length++; + input_position++; + done = 1; + if (debug) { + printf("D2/1 "); + } + } else { + if (datum_a(source, input_position, length)) { + if (source[input_position] < 32) { + codeword_array[array_length] = source[input_position] + 64; + } else { + codeword_array[array_length] = source[input_position] - 32; + } + array_length++; + input_position++; + done = 1; + if (debug) { + printf("D2/2 "); + } + } + } + } + + /* Step D3 */ + if ((!done) && (encoding_mode == 'A')) { + if (binary(source, input_position)) { + if (datum_a(source, input_position + 1, length)) { + if ((source[input_position] - 128) < 32) { + codeword_array[array_length] = 110; // Bin Shift A + array_length++; + codeword_array[array_length] = source[input_position] - 128 + 64; + array_length++; + } else { + codeword_array[array_length] = 111; // Bin Shift B + array_length++; + codeword_array[array_length] = source[input_position] - 128 - 32; + array_length++; + } + input_position++; + } else { + codeword_array[array_length] = 112; // Bin Latch + array_length++; + encoding_mode = 'X'; + } + done = 1; + if (debug) { + printf("D3 "); + } + } + } + + /* Step D4 */ + if ((!done) && (encoding_mode == 'A')) { + int n = ahead_b(source, input_position, length); + + if (n <= 6) { + codeword_array[array_length] = 95 + n; // nx Shift B + array_length++; + for (i = 0; i < n; i++) { + codeword_array[array_length] = source[input_position] - 32; + array_length++; + input_position++; + } + } else { + codeword_array[array_length] = 102; // Latch B + array_length++; + encoding_mode = 'B'; + } + done = 1; + if (debug) { + printf("D4 "); + } + } + + /* Step E1 */ + if ((!done) && (encoding_mode == 'X')) { + int n = try_c(source, input_position, length); + + if (n >= 2) { + /* Empty binary buffer */ + for (i = 0; i < (binary_buffer_size + 1); i++) { + lawrencium[i] = binary_buffer % 103; + binary_buffer /= 103; + } + + for (i = 0; i < (binary_buffer_size + 1); i++) { + codeword_array[array_length] = lawrencium[binary_buffer_size - i]; + array_length++; + } + binary_buffer = 0; + binary_buffer_size = 0; + + if (n <= 7) { + codeword_array[array_length] = 101 + n; // Interrupt for nx Shift C + array_length++; + for (i = 0; i < n; i++) { + codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0'); + array_length++; + input_position += 2; + } + } else { + codeword_array[array_length] = 111; // Terminate with Latch to C + array_length++; + encoding_mode = 'C'; + } + done = 1; + if (debug) { + printf("E1 "); + } + } + } + + /* Step E2 */ + /* Section 5.2.1.1 para D.2.i states: + * "Groups of six codewords, each valued between 0 and 102, are radix converted from + * base 103 into five base 259 values..." + */ + if ((!done) && (encoding_mode == 'X')) { + if (binary(source, input_position) + || binary(source, input_position + 1) + || binary(source, input_position + 2) + || binary(source, input_position + 3)) { + binary_buffer *= 259; + binary_buffer += source[input_position]; + binary_buffer_size++; + + if (binary_buffer_size == 5) { + for (i = 0; i < 6; i++) { + lawrencium[i] = binary_buffer % 103; + binary_buffer /= 103; + } + + for (i = 0; i < 6; i++) { + codeword_array[array_length] = lawrencium[5 - i]; + array_length++; + } + binary_buffer = 0; + binary_buffer_size = 0; + } + input_position++; + done = 1; + if (debug) { + printf("E2 "); + } + } + } + + /* Step E3 */ + if ((!done) && (encoding_mode == 'X')) { + /* Empty binary buffer */ + for (i = 0; i < (binary_buffer_size + 1); i++) { + lawrencium[i] = binary_buffer % 103; + binary_buffer /= 103; + } + + for (i = 0; i < (binary_buffer_size + 1); i++) { + codeword_array[array_length] = lawrencium[binary_buffer_size - i]; + array_length++; + } + binary_buffer = 0; + binary_buffer_size = 0; + + if (ahead_a(source, input_position, length) > ahead_b(source, input_position, length)) { + codeword_array[array_length] = 109; // Terminate with Latch to A + encoding_mode = 'A'; + } else { + codeword_array[array_length] = 110; // Terminate with Latch to B + encoding_mode = 'B'; + } + array_length++; + done = 1; + if (debug) { + printf("E3 "); + } + } + } while (input_position < length); + + if (encoding_mode == 'X') { + if (binary_buffer_size != 0) { + /* Empty binary buffer */ + for (i = 0; i < (binary_buffer_size + 1); i++) { + lawrencium[i] = binary_buffer % 103; + binary_buffer /= 103; + } + + for (i = 0; i < (binary_buffer_size + 1); i++) { + codeword_array[array_length] = lawrencium[binary_buffer_size - i]; + array_length++; + } + } + *(binary_finish) = 1; + } + + if (debug) { + printf("\n\n"); + } + + return array_length; +} + +/* Convert codewords to binary data stream */ +static size_t make_dotstream(unsigned char masked_array[], int array_length, char dot_stream[]) { + int i; + + dot_stream[0] = '\0'; + + /* Mask value is encoded as two dots */ + bin_append(masked_array[0], 2, dot_stream); + + /* The rest of the data uses 9-bit dot patterns from Annex C */ + for (i = 1; i < array_length; i++) { + bin_append(dot_patterns[masked_array[i]], 9, dot_stream); + } + + return strlen(dot_stream); +} + +/* Determines if a given dot is a reserved corner dot + * to be used by one of the last six bits + */ +int is_corner(int column, int row, int width, int height) { + int corner = 0; + + /* Top Left */ + if ((column == 0) && (row == 0)) { + corner = 1; + } + + /* Top Right */ + if (height % 2) { + if (((column == width - 2) && (row == 0)) + || ((column == width - 1) && (row == 1))) { + corner = 1; + } + } else { + if ((column == width - 1) && (row == 0)) { + corner = 1; + } + } + + /* Bottom Left */ + if (height % 2) { + if ((column == 0) && (row == height - 1)) { + corner = 1; + } + } else { + if (((column == 0) && (row == height - 2)) + || ((column == 1) && (row == height - 1))) { + corner = 1; + } + } + + /* Bottom Right */ + if (((column == width - 2) && (row == height - 1)) + || ((column == width - 1) && (row == height - 2))) { + corner = 1; + } + + return corner; +} + +/* Place the dots in the symbol*/ +void fold_dotstream(char dot_stream[], int width, int height, char dot_array[]) { + int column, row; + int input_position = 0; + + if (height % 2) { + /* Horizontal folding */ + for (row = 0; row < height; row++) { + for (column = 0; column < width; column++) { + if (!((column + row) % 2)) { + if (is_corner(column, row, width, height)) { + dot_array[(row * width) + column] = 'C'; + } else { + dot_array[((height - row - 1) * width) + column] = dot_stream[input_position]; + input_position++; + } + } else { + dot_array[((height - row - 1) * width) + column] = ' '; // Non-data position + } + } + } + + /* Corners */ + dot_array[width - 2] = dot_stream[input_position]; + input_position++; + dot_array[(height * width) - 2] = dot_stream[input_position]; + input_position++; + dot_array[(width * 2) - 1] = dot_stream[input_position]; + input_position++; + dot_array[((height - 1) * width) - 1] = dot_stream[input_position]; + input_position++; + dot_array[0] = dot_stream[input_position]; + input_position++; + dot_array[(height - 1) * width] = dot_stream[input_position]; + } else { + /* Vertical folding */ + for (column = 0; column < width; column++) { + for (row = 0; row < height; row++) { + if (!((column + row) % 2)) { + if (is_corner(column, row, width, height)) { + dot_array[(row * width) + column] = 'C'; + } else { + dot_array[(row * width) + column] = dot_stream[input_position]; + input_position++; + } + } else { + dot_array[(row * width) + column] = ' '; // Non-data position + } + } + } + + /* Corners */ + dot_array[((height - 1) * width) - 1] = dot_stream[input_position]; + input_position++; + dot_array[(height - 2) * width] = dot_stream[input_position]; + input_position++; + dot_array[(height * width) - 2] = dot_stream[input_position]; + input_position++; + dot_array[((height - 1) * width) + 1] = dot_stream[input_position]; + input_position++; + dot_array[width - 1] = dot_stream[input_position]; + input_position++; + dot_array[0] = dot_stream[input_position]; + } +} + +int dotcode(struct zint_symbol *symbol, const unsigned char source[], int length) { + int i, j, k; + size_t jc, n_dots; + int data_length, ecc_length; + int min_dots, min_area; + int height, width; + int mask_score[4]; + int weight; + size_t dot_stream_length; + int high_score, best_mask; + int binary_finish = 0; + int debug = 0; + int padding_dots, is_first; +#ifdef _MSC_VER + unsigned char* masked_codeword_array; +#endif + +#ifndef _MSC_VER + unsigned char codeword_array[length * 3]; +#else + char* dot_stream; + char* dot_array; + unsigned char* codeword_array = (unsigned char *) _alloca(length * 3 * sizeof (unsigned char)); +#endif /* _MSC_VER */ + + if (symbol->eci > 811799) { + strcpy(symbol->errtxt, "525: Invalid ECI"); + return ZINT_ERROR_INVALID_OPTION; + } + + data_length = dotcode_encode_message(symbol, source, length, codeword_array, &binary_finish); + + ecc_length = 3 + (data_length / 2); + + if (debug) { + printf("Codeword length = %d, ECC length = %d\n", data_length, ecc_length); + } + + min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2; + min_area = min_dots * 2; + + if (symbol->option_2 == 0) { + /* Automatic sizing */ + /* Following Rule 3 (Section 5.2.2) and applying a recommended width to height ratio 3:2 */ + /* Eliminates under sized symbols */ + + float h = (float) (sqrt(min_area * 0.666)); + float w = (float) (sqrt(min_area * 1.5)); + + height = (int) h; + width = (int) w; + + if ((width + height) % 2 == 1) { + if ((width * height) < min_area) { + width++; + height++; + } + } else { + if ((h * width) < (w * height)) { + width++; + if ((width * height) < min_area) { + width--; + height++; + if ((width * height) < min_area) { + width += 2; + } + } + } else { + height++; + if ((width * height) < min_area) { + width++; + height--; + if ((width * height) < min_area) { + height += 2; + } + } + } + } + + } else { + /* User defined width */ + /* Eliminates under sized symbols */ + + width = symbol->option_2; + height = (min_area + (width - 1)) / width; + + if (!((width + height) % 2)) { + height++; + } + } + + if ((height > 200) || (width > 200)) { + strcpy(symbol->errtxt, "526: Specified symbol size is too large (E20)"); + return ZINT_ERROR_INVALID_OPTION; + } + + n_dots = (height * width) / 2; + +#ifndef _MSC_VER + char dot_stream[height * width * 3]; + char dot_array[width * height * sizeof (char) ]; +#else + dot_stream = (char *) _alloca(height * width * 3); + if (!dot_stream) return ZINT_ERROR_MEMORY; + + dot_array = (char *) _alloca(width * height * sizeof (char)); + if (!dot_array) return ZINT_ERROR_MEMORY; +#endif + + /* Add pad characters */ + padding_dots = n_dots - min_dots; /* get the number of free dots available for padding */ + is_first = 1; /* first padding character flag */ + + while (padding_dots >= 9) { + if (padding_dots < 18 && ((data_length % 2) == 0)) + padding_dots -= 9; + + else if (padding_dots >= 18) { + if ((data_length % 2) == 0) + padding_dots -= 9; + else + padding_dots -= 18; + } else + break; /* not enough padding dots left for padding */ + + if ((is_first == 1) && (binary_finish == 1)) + codeword_array[data_length] = 109; + else + codeword_array[data_length] = 106; + + data_length++; + is_first = 0; + } + + ecc_length = 3 + (data_length / 2); + +#ifndef _MSC_VER + unsigned char masked_codeword_array[data_length + 1 + ecc_length]; +#else + masked_codeword_array = (unsigned char *) _alloca((data_length + 1 + ecc_length) * sizeof (unsigned char)); +#endif /* _MSC_VER */ + + /* Evaluate data mask options */ + for (i = 0; i < 4; i++) { + switch (i) { + case 0: + masked_codeword_array[0] = 0; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = codeword_array[j]; + } + break; + case 1: + weight = 0; + masked_codeword_array[0] = 1; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; + weight += 3; + } + break; + case 2: + weight = 0; + masked_codeword_array[0] = 2; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; + weight += 7; + } + break; + case 3: + weight = 0; + masked_codeword_array[0] = 3; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; + weight += 17; + } + break; + } + + rsencode(data_length + 1, ecc_length, masked_codeword_array); + + dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream); + + /* Add pad bits */ + for (jc = dot_stream_length; jc < n_dots; jc++) { + strcat(dot_stream, "1"); + } + + fold_dotstream(dot_stream, width, height, dot_array); + + mask_score[i] = score_array(dot_array, height, width); + + if (debug) { + printf("Mask %d score is %d\n", i, mask_score[i]); + } + } + + high_score = mask_score[0]; + best_mask = 0; + + for (i = 1; i < 4; i++) { + if (mask_score[i] > high_score) { + high_score = mask_score[i]; + best_mask = i; + } + } + + if (best_mask != 3) { + /* Reprocess to get symbol with best mask */ + switch (best_mask) { + case 0: + masked_codeword_array[0] = 0; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = codeword_array[j]; + } + break; + case 1: + weight = 0; + masked_codeword_array[0] = 1; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; + weight += 3; + } + break; + case 2: + weight = 0; + masked_codeword_array[0] = 2; + for (j = 0; j < data_length; j++) { + masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113; + weight += 7; + } + break; + } + + rsencode(data_length + 1, ecc_length, masked_codeword_array); + dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream); + + /* Add pad bits */ + for (jc = dot_stream_length; jc < n_dots; jc++) { + strcat(dot_stream, "1"); + } + + fold_dotstream(dot_stream, width, height, dot_array); + } /* else { the version with the best mask is already in memory } */ + + if (debug) { + for (k = 0; k < height; k++) { + for (j = 0; j < width; j++) { + printf("%c", dot_array[(k * width) + j]); + } + printf("\n"); + } + } + + /* Copy values to symbol */ + symbol->width = width; + symbol->rows = height; + + for (k = 0; k < height; k++) { + for (j = 0; j < width; j++) { + if (dot_array[(k * width) + j] == '1') { + set_module(symbol, k, j); + } + } + symbol->row_height[k] = 1; + } + + if (!(symbol->output_options & BARCODE_DOTTY_MODE)) { + symbol->output_options += BARCODE_DOTTY_MODE; + } + + return 0; +} \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/eci.c b/3rdparty/zint-2.6.1/backend/eci.c new file mode 100644 index 0000000..4545613 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/eci.c @@ -0,0 +1,309 @@ +/* eci.c - Extended Channel Interpretations + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "eci.h" +#include "zint.h" +#ifdef _MSC_VER +#include +#endif + +/* Convert Unicode to other character encodings */ +int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length) { + int glyph; + int bytelen; + int in_posn; + int out_posn; + int ext; + int done; + + if (eci == 26) { + /* Unicode mode, do not process - just copy data across */ + for (in_posn = 0; in_posn < *length; in_posn++) { + dest[in_posn] = source[in_posn]; + } + dest[*length] = '\0'; + return 0; + } + + in_posn = 0; + out_posn = 0; + do { + /* Single byte (ASCII) character */ + bytelen = 1; + glyph = (int) source[in_posn]; + + if ((source[in_posn] >= 0x80) && (source[in_posn] < 0xc0)) { + /* Something has gone wrong, abort */ + return ZINT_ERROR_INVALID_DATA; + } + + if ((source[in_posn] >= 0xc0) && (source[in_posn] < 0xe0)) { + /* Two-byte character */ + bytelen = 2; + glyph = (source[in_posn] & 0x1f) << 6; + + if (*length < (in_posn + 2)) { + return ZINT_ERROR_INVALID_DATA; + } + + if (source[in_posn + 1] > 0xc0) { + return ZINT_ERROR_INVALID_DATA; + } + + glyph += (source[in_posn + 1] & 0x3f); + } + + if ((source[in_posn] >= 0xe0) && (source[in_posn] < 0xf0)) { + /* Three-byte character */ + bytelen = 3; + glyph = (source[in_posn] & 0x0f) << 12; + + if (*length < (in_posn + 2)) { + return ZINT_ERROR_INVALID_DATA; + } + + if (*length < (in_posn + 3)) { + return ZINT_ERROR_INVALID_DATA; + } + + if (source[in_posn + 1] > 0xc0) { + return ZINT_ERROR_INVALID_DATA; + } + + if (source[in_posn + 2] > 0xc0) { + return ZINT_ERROR_INVALID_DATA; + } + + glyph += (source[in_posn + 1] & 0x3f) << 6; + glyph += (source[in_posn + 2] & 0x3f); + } + + if ((source[in_posn] >= 0xf0) && (source[in_posn] < 0xf7)) { + /* Four-byte character */ + bytelen = 4; + glyph = (source[in_posn] & 0x07) << 18; + + if (*length < (in_posn + 2)) { + return ZINT_ERROR_INVALID_DATA; + } + + if (*length < (in_posn + 3)) { + return ZINT_ERROR_INVALID_DATA; + } + + if (*length < (in_posn + 4)) { + return ZINT_ERROR_INVALID_DATA; + } + + if (source[in_posn + 1] > 0xc0) { + return ZINT_ERROR_INVALID_DATA; + } + + if (source[in_posn + 2] > 0xc0) { + return ZINT_ERROR_INVALID_DATA; + } + + if (source[in_posn + 3] > 0xc0) { + return ZINT_ERROR_INVALID_DATA; + } + + glyph += (source[in_posn + 1] & 0x3f) << 12; + glyph += (source[in_posn + 2] & 0x3f) << 6; + glyph += (source[in_posn + 3] & 0x3f); + } + + if (source[in_posn] >= 0xf7) { + /* More than 4 bytes not supported */ + return ZINT_ERROR_INVALID_DATA; + } + + if (glyph < 128) { + dest[out_posn] = glyph; + } else { + done = 0; + for (ext = 0; ext < 128; ext++) { + switch (eci) { + case 3: // Latin-1 + if (glyph == iso_8859_1[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 4: // Latin-2 + if (glyph == iso_8859_2[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 5: // Latin-3 + if (glyph == iso_8859_3[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 6: // Latin-4 + if (glyph == iso_8859_4[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 7: // Latin/Cyrillic + if (glyph == iso_8859_5[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 8: // Latin/Arabic + if (glyph == iso_8859_6[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 9: // Latin/Greek + if (glyph == iso_8859_7[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 10: // Latin/Hebrew + if (glyph == iso_8859_8[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 11: // Latin-5 + if (glyph == iso_8859_9[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 12: // Latin-6 + if (glyph == iso_8859_10[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 13: // Latin/Thai + if (glyph == iso_8859_11[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 15: // Latin-7 + if (glyph == iso_8859_13[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 16: // Latin-8 + if (glyph == iso_8859_14[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 17: // Latin-9 + if (glyph == iso_8859_15[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 18: // Latin-10 + if (glyph == iso_8859_16[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 21: // Windows-1250 + if (glyph == windows_1250[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 22: // Windows-1251 + if (glyph == windows_1251[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 23: // Windows-1252 + if (glyph == windows_1252[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + case 24: // Windows-1256 + if (glyph == windows_1256[ext]) { + dest[out_posn] = ext + 128; + done = 1; + } + break; + default: + break; + } + } + + if (!(done)) { + return ZINT_ERROR_INVALID_DATA; + } + } + + in_posn += bytelen; + out_posn++; + } while (in_posn < *length); + dest[out_posn] = '\0'; + *length = out_posn; + + return 0; +} + +/* Find the lowest ECI mode which will encode a given set of Unicode text */ +int get_best_eci(unsigned char source[], size_t length) { + int eci = 3; + +#ifndef _MSC_VER + unsigned char local_source[length + 1]; +#else + unsigned char *local_source = (unsigned char*) _alloca(length + 1); +#endif + + do { + if (utf_to_eci(eci, source, local_source, &length) == 0) { + return eci; + } + eci++; + } while (eci < 25); + + return 26; // If all of these fail, use Unicode! +} + diff --git a/3rdparty/zint-2.6.1/backend/eci.h b/3rdparty/zint-2.6.1/backend/eci.h new file mode 100644 index 0000000..380dd6a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/eci.h @@ -0,0 +1,252 @@ +/* eci.c - Extended Channel Interpretations to Unicode tables + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#ifndef ECI_H +#define ECI_H + +#ifdef __cplusplus +extern "C" { +#endif + +static const unsigned short int iso_8859_1[] = {// Latin alphabet No. 1 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +static const unsigned short int iso_8859_2[] = {// Latin alphabet No. 2 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +static const unsigned short int iso_8859_3[] = {// Latin alphabet No. 3 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b, + 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c, + 0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9 +}; + +static const unsigned short int iso_8859_4[] = {// Latin alphabet No. 4 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x012b, 0x013b, 0x00a7, 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, + 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, + 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9 +}; + +static const unsigned short int iso_8859_5[] = {// Latin/Cyrillic alphabet + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f +}; + +static const unsigned short int iso_8859_6[] = {// Latin/Arabic alphabet + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static const unsigned short int iso_8859_7[] = {// Latin/Greek alphabet + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000 +}; + +static const unsigned short int iso_8859_8[] = {// Latin/Hebrew alphabet + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000 +}; + +static const unsigned short int iso_8859_9[] = {// Latin alphabet No. 5 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; + +static const unsigned short int iso_8859_10[] = {// Latin alphabet No. 6 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x012b, 0x0136, 0x00a7, 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, + 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b, + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138 +}; + +static const unsigned short int iso_8859_11[] = {// Latin/Thai alphabet + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e36, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f, + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static const unsigned short int iso_8859_13[] = {// Latin alphabet No. 7 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019 +}; + +static const unsigned short int iso_8859_14[] = {// Latin alphabet No. 8 (Celtic) + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178, + 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff +}; + +static const unsigned short int iso_8859_15[] = {// Latin alphabet No. 9 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +static const unsigned short int iso_8859_16[] = {// Latin alphabet No. 10 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b, + 0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c, + 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff +}; + +static const unsigned short int windows_1250[] = { + 0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + 0x00a0, 0x02c7, 0x02db, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +static const unsigned short int windows_1251[] = { + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f +}; + +static const unsigned short int windows_1252[] = { + 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +static const unsigned short int windows_1256[] = { + 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba, + 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f, + 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, + 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, + 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ECI_H */ + diff --git a/3rdparty/zint-2.6.1/backend/emf.c b/3rdparty/zint-2.6.1/backend/emf.c new file mode 100644 index 0000000..8e9ba0f --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/emf.c @@ -0,0 +1,1225 @@ +/* emf.c - Support for Microsoft Enhanced Metafile Format + + libzint - the open source barcode library + Copyright (C) 2016-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* Developed according to [MS-EMF] - v20160714, Released July 14, 2016 + * and [MS-WMF] - v20160714, Released July 14, 2016 */ + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "emf.h" + +#define SSET "0123456789ABCDEF" + +int count_rectangles(struct zint_symbol *symbol) { + int rectangles = 0; + int this_row; + int latch, i; + + if ((symbol->symbology != BARCODE_MAXICODE) && + ((symbol->output_options & BARCODE_DOTTY_MODE) == 0)) { + for(this_row = 0; this_row < symbol->rows; this_row++) { + latch = 0; + for(i = 0; i < symbol->width; i++) { + if ((module_is_set(symbol, this_row, i)) && (latch == 0)) { + latch = 1; + rectangles++; + } + + if ((!(module_is_set(symbol, this_row, i))) && (latch == 1)) { + latch = 0; + } + } + } + } + + return rectangles; +} + +int count_circles(struct zint_symbol *symbol) { + int circles = 0; + int this_row; + int i; + + if ((symbol->symbology != BARCODE_MAXICODE) && + ((symbol->output_options & BARCODE_DOTTY_MODE) != 0)) { + for(this_row = 0; this_row < symbol->rows; this_row++) { + for(i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, this_row, i)) { + circles++; + } + } + } + } + + return circles; +} + +int count_hexagons(struct zint_symbol *symbol) { + int hexagons = 0; + int this_row; + int i; + + if (symbol->symbology == BARCODE_MAXICODE) { + for(this_row = 0; this_row < symbol->rows; this_row++) { + for(i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, this_row, i)) { + hexagons++; + } + } + } + } + + return hexagons; +} + +void utfle_copy(unsigned char *output, unsigned char *input, int length) { + int i; + int o; + + /* Convert UTF-8 to UTF-16LE - only needs to handle characters <= U+00FF */ + i = 0; + o = 0; + do { + if(input[i] <= 0x7f) { + /* 1 byte mode (7-bit ASCII) */ + output[o] = input[i]; + output[o + 1] = 0x00; + o += 2; + i++; + } else { + /* 2 byte mode */ + output[o] = ((input[i] & 0x1f) << 6) + (input[i + 1] & 0x3f); + output[o + 1] = 0x00; + o += 2; + i += 2; + } + } while (i < length); +} + +int bump_up(int input) { + /* Strings length must be a multiple of 4 bytes */ + if ((input % 2) == 1) { + input++; + } + return input; +} + +int emf_plot(struct zint_symbol *symbol) { + int i, block_width, latch, this_row; + float large_bar_height, preset_height, row_height, row_posn; + FILE *emf_file; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + int error_number = 0; + int textoffset, xoffset, yoffset, textdone; + int large_bar_count, comp_offset; + float scaler = symbol->scale * 10; + int rectangle_count, this_rectangle; + int circle_count, this_circle; + int hexagon_count, this_hexagon; + int bytecount, recordcount; + int upcean = 0; + unsigned char regw[7]; + unsigned char regx[7]; + unsigned char regy[7]; + unsigned char regz[7]; + unsigned char output_buffer[12]; + uint32_t dx; + + emr_header_t emr_header; + emr_eof_t emr_eof; + emr_createbrushindirect_t emr_createbrushindirect_fg; + emr_createbrushindirect_t emr_createbrushindirect_bg; + emr_selectobject_t emr_selectobject_fgbrush; + emr_selectobject_t emr_selectobject_bgbrush; + emr_createpen_t emr_createpen; + emr_selectobject_t emr_selectobject_pen; + emr_rectangle_t background; + emr_ellipse_t bullseye[6]; + emr_extcreatefontindirectw_t emr_extcreatefontindirectw; + emr_selectobject_t emr_selectobject_font; + emr_exttextoutw_t emr_exttextoutw[6]; + emr_extcreatefontindirectw_t emr_extcreatefontindirectw_big; + emr_selectobject_t emr_selectobject_font_big; + + box_t box; + +#ifndef _MSC_VER + unsigned char local_text[bump_up(ustrlen(symbol->text) + 1)]; + unsigned char string_buffer[2 * bump_up(ustrlen(symbol->text) + 1)]; +#else + unsigned char* local_text; + unsigned char* string_buffer; + emr_rectangle_t *rectangle, *row_binding; + emr_ellipse_t* circle; + emr_polygon_t* hexagon; + local_text = (unsigned char*) _alloca(bump_up(ustrlen(symbol->text) + 1) * sizeof (unsigned char)); + string_buffer = (unsigned char*) _alloca(2 * bump_up(ustrlen(symbol->text) + 1) * sizeof (unsigned char)); +#endif + + row_height = 0; + textdone = 0; + comp_offset = 0; + this_rectangle = 0; + this_circle = 0; + this_hexagon = 0; + dx = 0; + latch = 0; + + for(i = 0; i < 6; i++) { + regw[i] = '\0'; + regx[i] = '\0'; + regy[i] = '\0'; + regz[i] = '\0'; + } + + if (symbol->show_hrt != 0) { + /* Copy text from symbol */ + ustrcpy(local_text, symbol->text); + } else { + /* No text needed */ + switch (symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CC: + case BARCODE_ISBNX: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + /* For these symbols use dummy text to ensure formatting is done + * properly even if no text is required */ + for (i = 0; i < ustrlen(symbol->text); i++) { + if (symbol->text[i] == '+') { + local_text[i] = '+'; + } else { + local_text[i] = ' '; + } + local_text[ustrlen(symbol->text)] = '\0'; + } + break; + default: + /* For everything else, just remove the text */ + local_text[0] = '\0'; + break; + } + } + + /* sort out colour options */ + to_upper((unsigned char*) symbol->fgcolour); + to_upper((unsigned char*) symbol->bgcolour); + + if (strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "641: Malformed foreground colour target"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "642: Malformed background colour target"); + return ZINT_ERROR_INVALID_OPTION; + } + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for (i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if (symbol->row_height[i] == 0) { + large_bar_count++; + } + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if (large_bar_count == 0) { + symbol->height = preset_height; + } + + while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch (ustrlen(local_text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + break; + } + upcean = 1; + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + upcean = 1; + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + upcean = 1; + } + + if (ustrlen(local_text) != 0) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + rectangle_count = count_rectangles(symbol); + circle_count = count_circles(symbol); + hexagon_count = count_hexagons(symbol); + +#ifndef _MSC_VER + emr_rectangle_t rectangle[rectangle_count]; + emr_rectangle_t row_binding[symbol->rows - 1]; + emr_ellipse_t circle[circle_count]; + emr_polygon_t hexagon[hexagon_count]; +#else + rectangle = (emr_rectangle_t*) _alloca(rectangle_count*sizeof(emr_rectangle_t)); + row_binding = (emr_rectangle_t*) _alloca((symbol->rows - 1)*sizeof(emr_rectangle_t)); + circle = (emr_ellipse_t*) _alloca(circle_count*sizeof(emr_ellipse_t)); + hexagon = (emr_polygon_t*) _alloca(hexagon_count*sizeof(emr_polygon_t)); +#endif + + /* Header */ + emr_header.type = 0x00000001; // EMR_HEADER + emr_header.size = 88; // Assuming no additional data in header + emr_header.emf_header.bounds.left = 0; + if (symbol->symbology != BARCODE_MAXICODE) { + emr_header.emf_header.bounds.right = ceil((symbol->width + xoffset + xoffset) * scaler); + emr_header.emf_header.bounds.bottom = ceil((symbol->height + textoffset + yoffset + yoffset) * scaler); + } else { + emr_header.emf_header.bounds.right = ceil((74.0F + xoffset + xoffset) * scaler); + emr_header.emf_header.bounds.bottom = ceil((72.0F + yoffset + yoffset) * scaler); + } + emr_header.emf_header.bounds.top = 0; + emr_header.emf_header.frame.left = 0; + emr_header.emf_header.frame.right = emr_header.emf_header.bounds.right * 30; + emr_header.emf_header.frame.top = 0; + emr_header.emf_header.frame.bottom = emr_header.emf_header.bounds.bottom * 30; + emr_header.emf_header.record_signature = 0x464d4520; // ENHMETA_SIGNATURE + emr_header.emf_header.version = 0x00010000;; + emr_header.emf_header.handles = 6; // Number of graphics objects + emr_header.emf_header.reserved = 0x0000; + emr_header.emf_header.n_description = 0; + emr_header.emf_header.off_description = 0; + emr_header.emf_header.n_pal_entries = 0; + emr_header.emf_header.device.cx = 1000; + emr_header.emf_header.device.cy = 1000; + emr_header.emf_header.millimeters.cx = 300; + emr_header.emf_header.millimeters.cy = 300; + bytecount = 88; + recordcount = 1; + + /* Create Brushes */ + emr_createbrushindirect_fg.type = 0x00000027; // EMR_CREATEBRUSHINDIRECT + emr_createbrushindirect_fg.size = 24; + emr_createbrushindirect_fg.ih_brush = 1; + emr_createbrushindirect_fg.log_brush.brush_style = 0x0000; // BS_SOLID + emr_createbrushindirect_fg.log_brush.color.red = fgred; + emr_createbrushindirect_fg.log_brush.color.green = fggrn; + emr_createbrushindirect_fg.log_brush.color.blue = fgblu; + emr_createbrushindirect_fg.log_brush.color.reserved = 0; + emr_createbrushindirect_fg.log_brush.brush_hatch = 0; // ignored + bytecount += 24; + recordcount++; + + emr_createbrushindirect_bg.type = 0x00000027; // EMR_CREATEBRUSHINDIRECT + emr_createbrushindirect_bg.size = 24; + emr_createbrushindirect_bg.ih_brush = 2; + emr_createbrushindirect_bg.log_brush.brush_style = 0x0000; // BS_SOLID + emr_createbrushindirect_bg.log_brush.color.red = bgred; + emr_createbrushindirect_bg.log_brush.color.green = bggrn; + emr_createbrushindirect_bg.log_brush.color.blue = bgblu; + emr_createbrushindirect_bg.log_brush.color.reserved = 0; + emr_createbrushindirect_bg.log_brush.brush_hatch = 0; // ignored + bytecount += 24; + recordcount++; + + emr_selectobject_fgbrush.type = 0x00000025; // EMR_SELECTOBJECT + emr_selectobject_fgbrush.size = 12; + emr_selectobject_fgbrush.ih_object = 1; + bytecount += 12; + recordcount++; + + emr_selectobject_bgbrush.type = 0x00000025; // EMR_SELECTOBJECT + emr_selectobject_bgbrush.size = 12; + emr_selectobject_bgbrush.ih_object = 2; + bytecount += 12; + recordcount++; + + /* Create Pens */ + emr_createpen.type = 0x00000026; // EMR_CREATEPEN + emr_createpen.size = 28; + emr_createpen.ih_pen = 3; + emr_createpen.log_pen.pen_style = 0x00000005; // PS_NULL + emr_createpen.log_pen.width.x = 1; + emr_createpen.log_pen.width.y = 0; // ignored + emr_createpen.log_pen.color_ref.red = 0; + emr_createpen.log_pen.color_ref.green = 0; + emr_createpen.log_pen.color_ref.blue = 0; + emr_createpen.log_pen.color_ref.reserved = 0; + bytecount += 28; + recordcount++; + + emr_selectobject_pen.type = 0x00000025; // EMR_SELECTOBJECT + emr_selectobject_pen.size = 12; + emr_selectobject_pen.ih_object = 3; + bytecount += 12; + recordcount++; + + /* Create font records */ + if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { + emr_extcreatefontindirectw.type = 0x00000052; // EMR_EXTCREATEFONTINDIRECTW + emr_extcreatefontindirectw.size = 104; + emr_extcreatefontindirectw.ih_fonts = 4; + emr_extcreatefontindirectw.elw.height = (8 * scaler); + emr_extcreatefontindirectw.elw.width = 0; // automatic + emr_extcreatefontindirectw.elw.escapement = 0; + emr_extcreatefontindirectw.elw.orientation = 0; + emr_extcreatefontindirectw.elw.weight = 400; + emr_extcreatefontindirectw.elw.italic = 0x00; + emr_extcreatefontindirectw.elw.underline = 0x00; + emr_extcreatefontindirectw.elw.strike_out = 0x00; + emr_extcreatefontindirectw.elw.char_set = 0x01; + emr_extcreatefontindirectw.elw.out_precision = 0x00; // OUT_DEFAULT_PRECIS + emr_extcreatefontindirectw.elw.clip_precision = 0x00; // CLIP_DEFAULT_PRECIS + emr_extcreatefontindirectw.elw.quality = 0x00; + emr_extcreatefontindirectw.elw.pitch_and_family = 0x00; + for(i = 0; i < 64; i++) { + emr_extcreatefontindirectw.elw.facename[i] = '\0'; + } + utfle_copy(emr_extcreatefontindirectw.elw.facename, (unsigned char*) "sans-serif", 10); + + emr_selectobject_font.type = 0x00000025; // EMR_SELECTOBJECT + emr_selectobject_font.size = 12; + emr_selectobject_font.ih_object = 4; + + if (!((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX))) { + bytecount += 104; + recordcount++; + bytecount += 12; + recordcount++; + } + + if (upcean) { + emr_extcreatefontindirectw_big.type = 0x00000052; // EMR_EXTCREATEFONTINDIRECTW + emr_extcreatefontindirectw_big.size = 104; + if (!((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX))) { + emr_extcreatefontindirectw_big.ih_fonts = 4; + } else { + emr_extcreatefontindirectw_big.ih_fonts = 5; + } + emr_extcreatefontindirectw_big.elw.height = (11 * scaler); + emr_extcreatefontindirectw_big.elw.width = 0; // automatic + emr_extcreatefontindirectw_big.elw.escapement = 0; + emr_extcreatefontindirectw_big.elw.orientation = 0; + emr_extcreatefontindirectw_big.elw.weight = 400; + emr_extcreatefontindirectw_big.elw.italic = 0x00; + emr_extcreatefontindirectw_big.elw.underline = 0x00; + emr_extcreatefontindirectw_big.elw.strike_out = 0x00; + emr_extcreatefontindirectw_big.elw.char_set = 0x01; + emr_extcreatefontindirectw_big.elw.out_precision = 0x00; // OUT_DEFAULT_PRECIS + emr_extcreatefontindirectw_big.elw.clip_precision = 0x00; // CLIP_DEFAULT_PRECIS + emr_extcreatefontindirectw_big.elw.quality = 0x00; + emr_extcreatefontindirectw_big.elw.pitch_and_family = 0x00; + for(i = 0; i < 64; i++) { + emr_extcreatefontindirectw_big.elw.facename[i] = '\0'; + } + utfle_copy(emr_extcreatefontindirectw_big.elw.facename, (unsigned char*) "sans-serif", 10); + bytecount += 104; + recordcount++; + + emr_selectobject_font_big.type = 0x00000025; // EMR_SELECTOBJECT + emr_selectobject_font_big.size = 12; + emr_selectobject_font_big.ih_object = 5; + bytecount += 12; + recordcount++; + } + } + + /* Text */ + if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { + + if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) { + latch = ustrlen(local_text); + for(i = 0; i < ustrlen(local_text); i++) { + if (local_text[i] == '+') { + latch = i; + } + } + if (latch > 8) { + // EAN-13 + for(i = 1; i <= 6; i++) { + regw[i - 1] = local_text[i]; + regx[i - 1] = local_text[i + 6]; + } + if (ustrlen(local_text) > latch) { + // With add-on + for (i = (latch + 1); i <= ustrlen(local_text); i++) { + regz[i - (latch + 1)] = local_text[i]; + } + } + local_text[1] = '\0'; + } else if (latch > 5) { + // EAN-8 + for(i = 0; i <= 3; i++) { + regw[i] = local_text[i + 4]; + } + if (ustrlen(local_text) > latch) { + // With add-on + for (i = (latch + 1); i <= ustrlen(local_text); i++) { + regz[i - (latch + 1)] = local_text[i]; + } + } + local_text[4] = '\0'; + } + + } + + if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CC)) { + latch = ustrlen(local_text); + for(i = 0; i < ustrlen(local_text); i++) { + if (local_text[i] == '+') { + latch = i; + } + } + if (ustrlen(local_text) > latch) { + // With add-on + for (i = (latch + 1); i <= ustrlen(local_text); i++) { + regz[i - (latch + 1)] = local_text[i]; + } + } + for(i = 1; i <= 5; i++) { + regw[i - 1] = local_text[i]; + regx[i - 1] = local_text[i + 6]; + } + regy[0] = local_text[11]; + local_text[1] = '\0'; + } + + if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CC)) { + latch = ustrlen(local_text); + for(i = 0; i < ustrlen(local_text); i++) { + if (local_text[i] == '+') { + latch = i; + } + } + if (ustrlen(local_text) > latch) { + // With add-on + for (i = (latch + 1); i <= ustrlen(local_text); i++) { + regz[i - (latch + 1)] = local_text[i]; + } + } + for(i = 1; i <= 6; i++) { + regw[i - 1] = local_text[i]; + } + regx[0] = local_text[7]; + local_text[1] = '\0'; + } + + for(i = 0; i <= 5; i++) { + emr_exttextoutw[i].type = 0x00000054; // EMR_EXTTEXTOUTW + emr_exttextoutw[i].bounds.top = 0; // ignored + emr_exttextoutw[i].bounds.left = 0; // ignoredemr_header.emf_header.bytes += + emr_exttextoutw[i].bounds.right = 0xffffffff; // ignored + emr_exttextoutw[i].bounds.bottom = 0xffffffff; // ignored + emr_exttextoutw[i].i_graphics_mode = 0x00000001; // GM_COMPATIBLE + emr_exttextoutw[i].ex_scale = 1.0; + emr_exttextoutw[i].ey_scale = 1.0; + emr_exttextoutw[i].w_emr_text.off_string = 76; + emr_exttextoutw[i].w_emr_text.options = 0; + emr_exttextoutw[i].w_emr_text.rectangle.top = 0; + emr_exttextoutw[i].w_emr_text.rectangle.left = 0; + emr_exttextoutw[i].w_emr_text.rectangle.right = 0xffffffff; + emr_exttextoutw[i].w_emr_text.rectangle.bottom = 0xffffffff; + if (i > 0) { + emr_exttextoutw[i].size = 76 + (6 * 6); + emr_exttextoutw[i].w_emr_text.off_dx = 76 + (2 * 6); + } + } + + emr_exttextoutw[0].w_emr_text.chars = ustrlen(local_text); + emr_exttextoutw[0].size = 76 + (6 * bump_up(ustrlen(local_text) + 1)); + emr_exttextoutw[0].w_emr_text.reference.x = (emr_header.emf_header.bounds.right - (ustrlen(local_text) * 5.3 * scaler)) / 2; // text left + emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler); // text top + emr_exttextoutw[0].w_emr_text.off_dx = 76 + (2 * bump_up(ustrlen(local_text) + 1)); + for (i = 0; i < bump_up(ustrlen(local_text) + 1) * 2; i++) { + string_buffer[i] = '\0'; + } + utfle_copy(string_buffer, local_text, ustrlen(local_text)); + bytecount += 76 + (6 * bump_up(ustrlen(local_text) + 1)); + recordcount++; + + emr_exttextoutw[1].w_emr_text.chars = ustrlen(regw); + emr_exttextoutw[2].w_emr_text.chars = ustrlen(regx); + emr_exttextoutw[3].w_emr_text.chars = ustrlen(regy); + emr_exttextoutw[4].w_emr_text.chars = ustrlen(regz); + + if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) { + if (latch > 8) { + /* EAN-13 */ + emr_exttextoutw[0].w_emr_text.reference.x = (xoffset - 9) * scaler; + emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[1].w_emr_text.reference.x = (8 + xoffset) * scaler; + emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[2].w_emr_text.reference.x = (55 + xoffset) * scaler; + emr_exttextoutw[2].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + if (ustrlen(regz) > 2) { + emr_exttextoutw[4].w_emr_text.reference.x = (115 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } else if (ustrlen(regz) != 0) { + emr_exttextoutw[4].w_emr_text.reference.x = (109 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } + emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); + bytecount += 2 * 112; + recordcount += 2; + } else if (latch > 5) { + /* EAN-8 */ + emr_exttextoutw[0].w_emr_text.reference.x = (7 + xoffset) * scaler; + emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[1].w_emr_text.reference.x = (40 + xoffset) * scaler; + emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + if (ustrlen(regz) > 2) { + emr_exttextoutw[4].w_emr_text.reference.x = (87 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } else if (ustrlen(regz) != 0) { + emr_exttextoutw[4].w_emr_text.reference.x = (81 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } + emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); + bytecount += 112; + recordcount++; + } + } + + if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CC)) { + emr_exttextoutw[0].w_emr_text.reference.x = (xoffset - 7) * scaler; + emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[1].w_emr_text.reference.x = (14 + xoffset) * scaler; + emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[2].w_emr_text.reference.x = (55 + xoffset) * scaler; + emr_exttextoutw[2].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[3].w_emr_text.reference.x = (98 + xoffset) * scaler; + emr_exttextoutw[3].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + if (ustrlen(regz) > 2) { + emr_exttextoutw[4].w_emr_text.reference.x = (117 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } else if (ustrlen(regz) != 0) { + emr_exttextoutw[4].w_emr_text.reference.x = (111 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } + emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); + bytecount += (3 * 112) + 12; + recordcount += 4; + } + + if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CC)) { + emr_exttextoutw[0].w_emr_text.reference.x = (xoffset - 7) * scaler; + emr_exttextoutw[0].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[1].w_emr_text.reference.x = (8 + xoffset) * scaler; + emr_exttextoutw[1].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + emr_exttextoutw[2].w_emr_text.reference.x = (53 + xoffset) * scaler; + emr_exttextoutw[2].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - (9 * scaler);; + if (ustrlen(regz) > 2) { + emr_exttextoutw[4].w_emr_text.reference.x = (71 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } else if (ustrlen(regz) != 0) { + emr_exttextoutw[4].w_emr_text.reference.x = (65 + xoffset) * scaler; + bytecount += 112; + recordcount++; + } + emr_exttextoutw[4].w_emr_text.reference.y = emr_header.emf_header.bounds.bottom - ((large_bar_height + 9) * scaler); + bytecount += (2 * 112) + 12; + recordcount += 3; + } + } + + /* Make background from a rectangle */ + background.type = 0x0000002b; // EMR_RECTANGLE; + background.size = 24; + background.box.top = 0; + background.box.left = 0; + background.box.right = emr_header.emf_header.bounds.right; + background.box.bottom = emr_header.emf_header.bounds.bottom; + bytecount += 24; + recordcount++; + + /* Make bind and box rectangles if needed */ + if ((symbol->output_options & BARCODE_BIND) || (symbol->output_options & BARCODE_BOX)) { + box.top.type = 0x0000002b; // EMR_RECTANGLE; + box.top.size = 24; + box.top.box.top = 0; + box.top.box.bottom = symbol->border_width * scaler; + box.top.box.left = symbol->border_width * scaler; + box.top.box.right = emr_header.emf_header.bounds.right - (symbol->border_width * scaler); + bytecount += 24; + recordcount++; + + box.bottom.type = 0x0000002b; // EMR_RECTANGLE; + box.bottom.size = 24; + box.bottom.box.top = emr_header.emf_header.bounds.bottom - ((symbol->border_width + textoffset) * scaler); + box.bottom.box.bottom = emr_header.emf_header.bounds.bottom - (textoffset * scaler); + box.bottom.box.left = symbol->border_width * scaler; + box.bottom.box.right = emr_header.emf_header.bounds.right - (symbol->border_width * scaler); + bytecount += 24; + recordcount++; + + if (symbol->output_options & BARCODE_BOX) { + box.left.type = 0x0000002b; // EMR_RECTANGLE; + box.left.size = 24; + box.left.box.top = 0; + box.left.box.bottom = emr_header.emf_header.bounds.bottom - (textoffset * scaler); + box.left.box.left = 0; + box.left.box.right = symbol->border_width * scaler; + bytecount += 24; + recordcount++; + + box.right.type = 0x0000002b; // EMR_RECTANGLE; + box.right.size = 24; + box.right.box.top = 0; + box.right.box.bottom = emr_header.emf_header.bounds.bottom - (textoffset * scaler); + box.right.box.left = emr_header.emf_header.bounds.right - (symbol->border_width * scaler); + box.right.box.right = emr_header.emf_header.bounds.right; + bytecount += 24; + recordcount++; + } + } + + /* Make image rectangles, circles, hexagons */ + for (this_row = 0; this_row < symbol->rows; this_row++) { + + if (symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for (i = 0; i < this_row; i++) { + if (symbol->row_height[i] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[i]; + } + } + row_posn += yoffset; + + if (symbol->symbology != BARCODE_MAXICODE) { + if ((symbol->output_options & BARCODE_DOTTY_MODE) != 0) { + // Use dots (circles) + for(i = 0; i < symbol->width; i++) { + if(module_is_set(symbol, this_row, i)) { + circle[this_circle].type = 0x0000002a; // EMR_ELLIPSE + circle[this_circle].size = 24; + circle[this_circle].box.top = this_row * scaler; + circle[this_circle].box.bottom = (this_row + 1) * scaler; + circle[this_circle].box.left = (i + xoffset) * scaler; + circle[this_circle].box.right = (i + xoffset + 1) * scaler; + this_circle++; + bytecount += 24; + recordcount++; + } + } + } else { + // Normal mode, with rectangles + i = 0; + if (module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + + if (latch == 1) { + /* a bar */ + rectangle[this_rectangle].type = 0x0000002b; // EMR_RECTANGLE; + rectangle[this_rectangle].size = 24; + rectangle[this_rectangle].box.top = row_posn * scaler; + rectangle[this_rectangle].box.bottom = (row_posn + row_height) * scaler; + rectangle[this_rectangle].box.left = (i + xoffset) * scaler; + rectangle[this_rectangle].box.right = (i + xoffset + block_width) * scaler; + bytecount += 24; + recordcount++; + + if (this_row == symbol->rows - 1) { + /* Last row, extend bars if needed */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || + (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions for EAN8 and EAN13 */ + if (ustrlen(regx) != 0) { + /* EAN-13 */ + switch (i) { + case 0: + case 2: + case 46: + case 48: + case 92: + case 94: + rectangle[this_rectangle].box.bottom += (5 * scaler); + break; + } + if (i > 94) { + /* Add-on */ + rectangle[this_rectangle].box.top += (10 * scaler); + rectangle[this_rectangle].box.bottom += (5 * scaler); + } + } else if (ustrlen(regw) != 0) { + /* EAN-8 */ + switch (i) { + case 0: + case 2: + case 32: + case 34: + case 64: + case 66: + rectangle[this_rectangle].box.bottom += (5 * scaler); + break; + } + if (i > 66) { + /* Add-on */ + rectangle[this_rectangle].box.top += (10 * scaler); + rectangle[this_rectangle].box.bottom += (5 * scaler); + } + } + } + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions for UPCA */ + if (((i >= 0) && (i <= 11)) || ((i >= 85) && (i <= 96))) { + rectangle[this_rectangle].box.bottom += (5 * scaler); + } + if ((i == 46) || (i == 48)) { + rectangle[this_rectangle].box.bottom += (5 * scaler); + } + if (i > 96) { + /* Add-on */ + rectangle[this_rectangle].box.top += (10 * scaler); + rectangle[this_rectangle].box.bottom += (5 * scaler); + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions for UPCE */ + switch (i) { + case 0: + case 2: + case 46: + case 48: + case 50: + rectangle[this_rectangle].box.bottom += (5 * scaler); + break; + } + if (i > 50) { + /* Add-on */ + rectangle[this_rectangle].box.top += (10 * scaler); + rectangle[this_rectangle].box.bottom += (5 * scaler); + } + } + } + + this_rectangle++; + latch = 0; + } else { + /* a space */ + latch = 1; + } + + + i += block_width; + } while (i < symbol->width); + } + } else { + float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; + /* Maxicode, use hexagons */ + + /* Calculate bullseye */ + for(i = 0; i < 6; i++) { + bullseye[i].type = 0x0000002a; // EMR_ELLIPSE + bullseye[i].size = 24; + } + bullseye[0].box.top = (35.60 - 10.85) * scaler; + bullseye[0].box.bottom = (35.60 + 10.85) * scaler; + bullseye[0].box.left = (35.76 - 10.85) * scaler; + bullseye[0].box.right = (35.76 + 10.85) * scaler; + bullseye[1].box.top = (35.60 - 8.97) * scaler; + bullseye[1].box.bottom = (35.60 + 8.97) * scaler; + bullseye[1].box.left = (35.76 - 8.97) * scaler; + bullseye[1].box.right = (35.76 + 8.97) * scaler; + bullseye[2].box.top = (35.60 - 7.10) * scaler; + bullseye[2].box.bottom = (35.60 + 7.10) * scaler; + bullseye[2].box.left = (35.76 - 7.10) * scaler; + bullseye[2].box.right = (35.76 + 7.10) * scaler; + bullseye[3].box.top = (35.60 - 5.22) * scaler; + bullseye[3].box.bottom = (35.60 + 5.22) * scaler; + bullseye[3].box.left = (35.76 - 5.22) * scaler; + bullseye[3].box.right = (35.76 + 5.22) * scaler; + bullseye[4].box.top = (35.60 - 3.31) * scaler; + bullseye[4].box.bottom = (35.60 + 3.31) * scaler; + bullseye[4].box.left = (35.76 - 3.31) * scaler; + bullseye[4].box.right = (35.76 + 3.31) * scaler; + bullseye[5].box.top = (35.60 - 1.43) * scaler; + bullseye[5].box.bottom = (35.60 + 1.43) * scaler; + bullseye[5].box.left = (35.76 - 1.43) * scaler; + bullseye[5].box.right = (35.76 + 1.43) * scaler; + + /* Plot hexagons */ + for(i = 0; i < symbol->width; i++) { + if(module_is_set(symbol, this_row, i)) { + hexagon[this_hexagon].type = 0x00000003; // EMR_POLYGON + hexagon[this_hexagon].size = 76; + hexagon[this_hexagon].count = 6; + + my = this_row * 2.135 + 1.43; + ay = my + 1.0 + yoffset; + by = my + 0.5 + yoffset; + cy = my - 0.5 + yoffset; + dy = my - 1.0 + yoffset; + ey = my - 0.5 + yoffset; + fy = my + 0.5 + yoffset; + if (this_row & 1) { + mx = (2.46 * i) + 1.23 + 1.23; + } else { + mx = (2.46 * i) + 1.23; + } + ax = mx + xoffset; + bx = mx + 0.86 + xoffset; + cx = mx + 0.86 + xoffset; + dx = mx + xoffset; + ex = mx - 0.86 + xoffset; + fx = mx - 0.86 + xoffset; + + hexagon[this_hexagon].a_points_a.x = ax * scaler; + hexagon[this_hexagon].a_points_a.y = ay * scaler; + hexagon[this_hexagon].a_points_b.x = bx * scaler; + hexagon[this_hexagon].a_points_b.y = by * scaler; + hexagon[this_hexagon].a_points_c.x = cx * scaler; + hexagon[this_hexagon].a_points_c.y = cy * scaler; + hexagon[this_hexagon].a_points_d.x = dx * scaler; + hexagon[this_hexagon].a_points_d.y = dy * scaler; + hexagon[this_hexagon].a_points_e.x = ex * scaler; + hexagon[this_hexagon].a_points_e.y = ey * scaler; + hexagon[this_hexagon].a_points_f.x = fx * scaler; + hexagon[this_hexagon].a_points_f.y = fy * scaler; + + hexagon[this_hexagon].bounds.top = hexagon[this_hexagon].a_points_d.y; + hexagon[this_hexagon].bounds.bottom = hexagon[this_hexagon].a_points_a.y; + hexagon[this_hexagon].bounds.left = hexagon[this_hexagon].a_points_e.x; + hexagon[this_hexagon].bounds.right = hexagon[this_hexagon].a_points_c.x; + this_hexagon++; + bytecount += 76; + recordcount++; + } + } + } + } + + if (symbol->output_options & BARCODE_BIND) { + if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + for (i = 1; i < symbol->rows; i++) { + row_binding[i - 1].type = 0x0000002b; // EMR_RECTANGLE; + row_binding[i - 1].size = 24; + row_binding[i - 1].box.top = ((i * row_height) + yoffset - 1) * scaler; + row_binding[i - 1].box.bottom = row_binding[i - 1].box.top + (2 * scaler); + + if (symbol->symbology != BARCODE_CODABLOCKF) { + row_binding[i - 1].box.left = xoffset * scaler; + row_binding[i - 1].box.right = emr_header.emf_header.bounds.right - (xoffset * scaler); + } else { + row_binding[i - 1].box.left = (xoffset + 11) * scaler; + row_binding[i - 1].box.right = emr_header.emf_header.bounds.right - ((xoffset + 14) * scaler); + } + bytecount += 24; + recordcount++; + } + } + } + + /* Create EOF record */ + emr_eof.type = 0x0000000e; // EMR_EOF + emr_eof.size = 18; // Assuming no palette entries + emr_eof.n_pal_entries = 0; + emr_eof.off_pal_entries = 0; + emr_eof.size_last = emr_eof.size; + bytecount += 18; + recordcount++; + + /* Put final counts in header */ + emr_header.emf_header.bytes = bytecount; + emr_header.emf_header.records = recordcount; + + /* Send EMF data to file */ + if (symbol->output_options & BARCODE_STDOUT) { + emf_file = stdout; + } else { + emf_file = fopen(symbol->outfile, "w"); + } + if (emf_file == NULL) { + strcpy(symbol->errtxt, "640: Could not open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + + fwrite(&emr_header, sizeof(emr_header_t), 1, emf_file); + + fwrite(&emr_createbrushindirect_fg, sizeof(emr_createbrushindirect_t), 1, emf_file); + fwrite(&emr_createbrushindirect_bg, sizeof(emr_createbrushindirect_t), 1, emf_file); + fwrite(&emr_createpen, sizeof(emr_createpen_t), 1, emf_file); + + if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { + fwrite(&emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw_t), 1, emf_file); + } + + fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_pen, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&background, sizeof(emr_rectangle_t), 1, emf_file); + + fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); + + for (i = 0; i < rectangle_count; i++) { + fwrite(&rectangle[i], sizeof(emr_rectangle_t), 1, emf_file); + } + for (i = 0; i < circle_count; i++) { + fwrite(&circle[i], sizeof(emr_ellipse_t), 1, emf_file); + } + for (i = 0; i < hexagon_count; i++) { + fwrite(&hexagon[i], sizeof(emr_polygon_t), 1, emf_file); + } + + if ((symbol->output_options & BARCODE_BIND) || (symbol->output_options & BARCODE_BOX)) { + fwrite(&box.top, sizeof(emr_rectangle_t), 1, emf_file); + fwrite(&box.bottom, sizeof(emr_rectangle_t), 1, emf_file); + if (symbol->output_options & BARCODE_BOX) { + fwrite(&box.left, sizeof(emr_rectangle_t), 1, emf_file); + fwrite(&box.right, sizeof(emr_rectangle_t), 1, emf_file); + } + } + + if (symbol->output_options & BARCODE_BIND) { + if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + for(i = 0; i < symbol->rows - 1; i++) { + fwrite(&row_binding[i], sizeof(emr_rectangle_t), 1, emf_file); + } + } + } + + if(symbol->symbology == BARCODE_MAXICODE) { + fwrite(&bullseye[0], sizeof(emr_ellipse_t), 1, emf_file); + fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&bullseye[1], sizeof(emr_ellipse_t), 1, emf_file); + fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&bullseye[2], sizeof(emr_ellipse_t), 1, emf_file); + fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&bullseye[3], sizeof(emr_ellipse_t), 1, emf_file); + fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&bullseye[4], sizeof(emr_ellipse_t), 1, emf_file); + fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&bullseye[5], sizeof(emr_ellipse_t), 1, emf_file); + } + + if ((symbol->show_hrt != 0) && (ustrlen(local_text) != 0)) { + if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CC) || (symbol->symbology == BARCODE_ISBNX)) { + if (ustrlen(regx) != 0) { + /* EAN-13 */ + fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); + fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); + for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regw, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_exttextoutw[2], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regx, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + if (ustrlen(regz) != 0) { + fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regz, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + } + textdone = 1; + } else if (ustrlen(regw) != 0) { + /* EAN-8 */ + fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); + fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); + for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regw, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + if (ustrlen(regz) != 0) { + fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regz, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + } + textdone = 1; + } + } + if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CC)) { + fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); + fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); + for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_exttextoutw[3], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regy, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_selectobject_font_big, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regw, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_exttextoutw[2], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regx, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + if (ustrlen(regz) != 0) { + fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regz, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + } + textdone = 1; + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); + fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); + for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_exttextoutw[2], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regx, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + fwrite(&emr_selectobject_font_big, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[1], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regw, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + if (ustrlen(regz) != 0) { + fwrite(&emr_exttextoutw[4], sizeof(emr_exttextoutw_t), 1, emf_file); + utfle_copy(output_buffer, regz, 6); + fwrite(&output_buffer, 12, 1, emf_file); + for (i = 0; i < 6; i++) { + fwrite(&dx, 4, 1, emf_file); + } + } + textdone = 1; + } + + if (textdone == 0) { + fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_exttextoutw[0], sizeof(emr_exttextoutw_t), 1, emf_file); + fwrite(&string_buffer, 2 * bump_up(ustrlen(local_text) + 1), 1, emf_file); + for (i = 0; i < bump_up(ustrlen(local_text) + 1); i++) { + fwrite(&dx, 4, 1, emf_file); + } + } + } + + fwrite(&emr_eof, sizeof(emr_eof_t), 1, emf_file); + + if (symbol->output_options & BARCODE_STDOUT) { + fflush(emf_file); + } else { + fclose(emf_file); + } + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/emf.h b/3rdparty/zint-2.6.1/backend/emf.h new file mode 100644 index 0000000..da68522 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/emf.h @@ -0,0 +1,216 @@ +/* emf.h - header structure for Microsoft EMF + + libzint - the open source barcode library + Copyright (C) 2016-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#ifndef EMF_H +#define EMF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#include +#include "stdint_msvc.h" +#else +#include +#endif + +#pragma pack(1) + + typedef struct rect_l { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; + } rect_l_t; + + typedef struct size_l { + uint32_t cx; + uint32_t cy; + } size_l_t; + + typedef struct point_l { + int32_t x; + int32_t y; + } point_l_t; + + typedef struct color_ref { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t reserved; + } color_ref_t; + + typedef struct log_brush_ex { + uint32_t brush_style; + color_ref_t color; + uint32_t brush_hatch; + } log_brush_ex_t; + + typedef struct log_pen { + uint32_t pen_style; + point_l_t width; + color_ref_t color_ref; + } log_pen_t; + + typedef struct log_font { + int32_t height; + int32_t width; + int32_t escapement; + int32_t orientation; + int32_t weight; + uint8_t italic; + uint8_t underline; + uint8_t strike_out; + uint8_t char_set; + uint8_t out_precision; + uint8_t clip_precision; + uint8_t quality; + uint8_t pitch_and_family; + unsigned char facename[64]; + } log_font_t; + + typedef struct emr_text { + point_l_t reference; + uint32_t chars; + uint32_t off_string; + uint32_t options; + rect_l_t rectangle; + uint32_t off_dx; + } emr_text_t; + + typedef struct emf_header { + rect_l_t bounds; + rect_l_t frame; + uint32_t record_signature; + uint32_t version; + uint32_t bytes; + uint32_t records; + uint16_t handles; + uint16_t reserved; + uint32_t n_description; + uint32_t off_description; + uint32_t n_pal_entries; + size_l_t device; + size_l_t millimeters; + } emf_header_t; + + typedef struct emr_header { + uint32_t type; + uint32_t size; + emf_header_t emf_header; + } emr_header_t; + + typedef struct emr_createbrushindirect { + uint32_t type; + uint32_t size; + uint32_t ih_brush; + log_brush_ex_t log_brush; + } emr_createbrushindirect_t; + + typedef struct emr_createpen { + uint32_t type; + uint32_t size; + uint32_t ih_pen; + log_pen_t log_pen; + } emr_createpen_t; + + typedef struct emr_selectobject { + uint32_t type; + uint32_t size; + uint32_t ih_object; + } emr_selectobject_t; + + typedef struct emr_rectangle { + uint32_t type; + uint32_t size; + rect_l_t box; + } emr_rectangle_t; + + typedef struct emr_ellipse { + uint32_t type; + uint32_t size; + rect_l_t box; + } emr_ellipse_t; + + typedef struct emr_polygon { + uint32_t type; + uint32_t size; + rect_l_t bounds; + uint32_t count; + point_l_t a_points_a; + point_l_t a_points_b; + point_l_t a_points_c; + point_l_t a_points_d; + point_l_t a_points_e; + point_l_t a_points_f; + } emr_polygon_t; + + typedef struct emr_extcreatefontindirectw { + uint32_t type; + uint32_t size; + uint32_t ih_fonts; + log_font_t elw; + } emr_extcreatefontindirectw_t; + + typedef struct emr_exttextoutw { + uint32_t type; + uint32_t size; + rect_l_t bounds; + uint32_t i_graphics_mode; + float ex_scale; + float ey_scale; + emr_text_t w_emr_text; + } emr_exttextoutw_t; + + typedef struct emr_eof { + uint32_t type; + uint32_t size; + uint32_t n_pal_entries; + uint32_t off_pal_entries; + uint32_t size_last; + } emr_eof_t; + + typedef struct box { + emr_rectangle_t top; + emr_rectangle_t bottom; + emr_rectangle_t left; + emr_rectangle_t right; + } box_t; + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* EMF_H */ + diff --git a/3rdparty/zint-2.6.1/backend/font.h b/3rdparty/zint-2.6.1/backend/font.h new file mode 100644 index 0000000..021efac --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/font.h @@ -0,0 +1,419 @@ +/* font.h - Font for PNG images */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +static const char ascii_font[] = { + /* Each character is 7 x 14 pixels */ + 0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 0, 0, /* ! */ + 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* " */ + 0, 0, 20, 20, 20, 62, 20, 20, 62, 20, 20, 20, 0, 0, /* # */ + 0, 0, 8, 60, 74, 74, 40, 28, 10, 74, 74, 60, 8, 0, /* $ */ + 0, 0, 50, 74, 76, 56, 8, 16, 28, 50, 82, 76, 0, 0, /* % */ + 0, 0, 24, 36, 36, 36, 24, 50, 74, 68, 76, 50, 0, 0, /* & */ + 0, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ' */ + 0, 2, 4, 8, 8, 16, 16, 16, 16, 16, 8, 8, 4, 2, /* ( */ + 0, 32, 16, 8, 8, 4, 4, 4, 4, 4, 8, 8, 16, 32, /* ) */ + 0, 0, 0, 0, 8, 42, 28, 8, 28, 42, 8, 0, 0, 0, /* * */ + 0, 0, 0, 0, 8, 8, 8, 62, 8, 8, 8, 0, 0, 0, /* + */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 16, /* , */ + 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, /* - */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 28, 8, 0, /* . */ + 0, 2, 2, 4, 4, 8, 8, 8, 16, 16, 32, 32, 64, 64, /* / */ + 0, 0, 24, 36, 66, 66, 66, 66, 66, 66, 36, 24, 0, 0, /* 0 */ + 0, 0, 8, 24, 40, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* 1 */ + 0, 0, 60, 66, 66, 2, 4, 4, 8, 16, 32, 126, 0, 0, /* 2 */ + 0, 0, 126, 2, 4, 8, 28, 2, 2, 66, 66, 60, 0, 0, /* 3 */ + 0, 0, 4, 12, 20, 20, 36, 36, 68, 126, 4, 4, 0, 0, /* 4 */ + 0, 0, 126, 64, 64, 124, 66, 2, 2, 66, 66, 60, 0, 0, /* 5 */ + 0, 0, 28, 32, 64, 64, 92, 98, 66, 66, 66, 60, 0, 0, /* 6 */ + 0, 0, 126, 2, 4, 4, 8, 8, 16, 16, 32, 32, 0, 0, /* 7 */ + 0, 0, 60, 66, 66, 36, 24, 36, 66, 66, 66, 60, 0, 0, /* 8 */ + 0, 0, 60, 66, 66, 66, 70, 58, 2, 66, 68, 56, 0, 0, /* 9 */ + 0, 0, 0, 0, 8, 28, 8, 0, 0, 8, 28, 8, 0, 0, /* : */ + 0, 0, 0, 0, 0, 24, 24, 0, 0, 24, 8, 8, 16, 0, /* ; */ + 0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0, /* < */ + 0, 0, 0, 0, 0, 126, 0, 0, 126, 0, 0, 0, 0, 0, /* = */ + 0, 0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0, /* > */ + 0, 0, 60, 66, 66, 4, 8, 8, 8, 0, 8, 8, 0, 0, /* ? */ + 0, 0, 28, 34, 78, 82, 82, 82, 82, 78, 32, 30, 0, 0, /* @ */ + 0, 0, 24, 36, 66, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* A */ + 0, 0, 120, 68, 66, 68, 120, 68, 66, 66, 68, 120, 0, 0, /* B */ + 0, 0, 60, 66, 66, 64, 64, 64, 64, 66, 66, 60, 0, 0, /* C */ + 0, 0, 120, 68, 66, 66, 66, 66, 66, 66, 68, 120, 0, 0, /* D */ + 0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 126, 0, 0, /* E */ + 0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 64, 0, 0, /* F */ + 0, 0, 60, 66, 66, 64, 64, 78, 66, 66, 70, 58, 0, 0, /* G */ + 0, 0, 66, 66, 66, 66, 126, 66, 66, 66, 66, 66, 0, 0, /* H */ + 0, 0, 62, 8, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* I */ + 0, 0, 14, 4, 4, 4, 4, 4, 4, 68, 68, 56, 0, 0, /* J */ + 0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 66, 0, 0, /* K */ + 0, 0, 64, 64, 64, 64, 64, 64, 64, 64, 64, 126, 0, 0, /* L */ + 0, 0, 66, 102, 102, 90, 90, 66, 66, 66, 66, 66, 0, 0, /* M */ + 0, 0, 66, 66, 98, 98, 82, 74, 70, 70, 66, 66, 0, 0, /* N */ + 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* O */ + 0, 0, 124, 66, 66, 66, 66, 124, 64, 64, 64, 64, 0, 0, /* P */ + 0, 0, 60, 66, 66, 66, 66, 66, 114, 74, 70, 60, 4, 2, /* Q */ + 0, 0, 124, 66, 66, 66, 66, 124, 72, 68, 66, 66, 0, 0, /* R */ + 0, 0, 60, 66, 66, 64, 48, 12, 2, 66, 66, 60, 0, 0, /* S */ + 0, 0, 127, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, /* T */ + 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* U */ + 0, 0, 66, 66, 66, 66, 36, 36, 36, 24, 24, 24, 0, 0, /* V */ + 0, 0, 34, 34, 34, 34, 34, 34, 42, 42, 42, 20, 0, 0, /* W */ + 0, 0, 66, 66, 36, 36, 24, 24, 36, 36, 66, 66, 0, 0, /* X */ + 0, 0, 34, 34, 34, 20, 20, 8, 8, 8, 8, 8, 0, 0, /* Y */ + 0, 0, 126, 2, 4, 8, 8, 16, 32, 32, 64, 126, 0, 0, /* Z */ + 0, 30, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 30, /* [ */ + 0, 64, 64, 32, 32, 16, 16, 16, 8, 8, 4, 4, 2, 2, /* \ */ + 0, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 60, /* ] */ + 0, 24, 36, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ^ */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, /* _ */ + 0, 16, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` */ + 0, 0, 0, 0, 0, 60, 66, 2, 62, 66, 66, 62, 0, 0, /* a */ + 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 98, 92, 0, 0, /* b */ + 0, 0, 0, 0, 0, 60, 66, 64, 64, 64, 66, 60, 0, 0, /* c */ + 0, 0, 2, 2, 2, 58, 70, 66, 66, 66, 70, 58, 0, 0, /* d */ + 0, 0, 0, 0, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* e */ + 0, 0, 12, 18, 16, 16, 124, 16, 16, 16, 16, 16, 0, 0, /* f */ + 0, 0, 0, 0, 0, 58, 68, 68, 68, 56, 32, 92, 66, 60, /* g */ + 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 66, 66, 0, 0, /* h */ + 0, 0, 8, 8, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* i */ + 0, 0, 2, 2, 0, 6, 2, 2, 2, 2, 2, 34, 34, 28, /* j */ + 0, 0, 64, 64, 64, 68, 72, 80, 112, 72, 68, 66, 0, 0, /* k */ + 0, 0, 24, 8, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* l */ + 0, 0, 0, 0, 0, 52, 42, 42, 42, 42, 42, 34, 0, 0, /* m */ + 0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 66, 66, 0, 0, /* n */ + 0, 0, 0, 0, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* o */ + 0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 98, 92, 64, 64, /* p */ + 0, 0, 0, 0, 0, 58, 70, 66, 66, 66, 70, 58, 2, 2, /* q */ + 0, 0, 0, 0, 0, 92, 98, 66, 64, 64, 64, 64, 0, 0, /* r */ + 0, 0, 0, 0, 0, 60, 66, 32, 24, 4, 66, 60, 0, 0, /* s */ + 0, 0, 16, 16, 16, 124, 16, 16, 16, 16, 18, 12, 0, 0, /* t */ + 0, 0, 0, 0, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* u */ + 0, 0, 0, 0, 0, 34, 34, 34, 20, 20, 8, 8, 0, 0, /* v */ + 0, 0, 0, 0, 0, 34, 34, 42, 42, 42, 42, 20, 0, 0, /* w */ + 0, 0, 0, 0, 0, 66, 66, 36, 24, 36, 66, 66, 0, 0, /* x */ + 0, 0, 0, 0, 0, 66, 66, 66, 66, 70, 58, 2, 66, 60, /* y */ + 0, 0, 0, 0, 0, 126, 4, 8, 16, 16, 32, 126, 0, 0, /* z */ + 0, 6, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 6, /* { */ + 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* | */ + 0, 48, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 48, /* } */ + 0, 32, 82, 74, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ~ */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  */ + 0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0, /* ¡ */ + 0, 0, 0, 0, 16, 60, 82, 80, 80, 80, 82, 60, 16, 0, /* ¢ */ + 0, 0, 0, 12, 18, 16, 16, 60, 16, 16, 60, 18, 0, 0, /* £ */ + 0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0, 0, /* ¤ */ + 0, 0, 34, 20, 20, 8, 62, 8, 62, 8, 8, 8, 0, 0, /* ¥ */ + 0, 0, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0, /* ¦ */ + 0, 60, 66, 32, 24, 36, 66, 36, 24, 4, 66, 60, 0, 0, /* § */ + 0, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ¨ */ + 0, 60, 66, 90, 102, 98, 98, 98, 102, 90, 66, 60, 0, 0, /* © */ + 0, 28, 34, 30, 34, 38, 26, 0, 62, 0, 0, 0, 0, 0, /* ª */ + 0, 0, 0, 0, 0, 10, 20, 40, 80, 40, 20, 10, 0, 0, /* « */ + 0, 0, 0, 0, 0, 0, 0, 0, 62, 2, 2, 2, 0, 0, /* ¬ */ + 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, /* ­ */ + 0, 60, 66, 122, 102, 102, 122, 102, 102, 102, 66, 60, 0, 0, /* ® */ + 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ¯ */ + 0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ° */ + 0, 0, 0, 0, 0, 0, 8, 8, 62, 8, 8, 62, 0, 0, /* ± */ + 0, 24, 36, 4, 8, 16, 32, 60, 0, 0, 0, 0, 0, 0, /* ² */ + 0, 24, 36, 4, 24, 4, 36, 24, 0, 0, 0, 0, 0, 0, /* ³ */ + 0, 4, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ´ */ + 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 54, 42, 32, 32, /* µ */ + 0, 0, 30, 42, 42, 42, 42, 26, 10, 10, 10, 10, 10, 14, /* ¶ */ + 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, /* · */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 16, /* ¸ */ + 0, 8, 24, 8, 8, 8, 8, 28, 0, 0, 0, 0, 0, 0, /* ¹ */ + 0, 0, 24, 36, 36, 24, 0, 60, 0, 0, 0, 0, 0, 0, /* º */ + 0, 0, 0, 0, 0, 80, 40, 20, 10, 20, 40, 80, 0, 0, /* » */ + 0, 0, 32, 98, 36, 36, 40, 18, 22, 42, 78, 66, 0, 0, /* ¼ */ + 0, 0, 32, 98, 36, 36, 40, 20, 26, 34, 68, 78, 0, 0, /* ½ */ + 0, 0, 98, 18, 36, 24, 104, 18, 38, 42, 78, 2, 0, 0, /* ¾ */ + 0, 0, 0, 16, 16, 0, 16, 16, 16, 16, 32, 66, 66, 60, /* ¿ */ + 16, 8, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* À */ + 8, 16, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Á */ + 24, 36, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Â */ + 50, 76, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Ã */ + 0, 36, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Ä */ + 0, 24, 36, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Å */ + 0, 0, 30, 40, 72, 72, 126, 72, 72, 72, 72, 78, 0, 0, /* Æ */ + 0, 0, 60, 66, 66, 64, 64, 64, 64, 66, 66, 60, 8, 16, /* Ç */ + 16, 8, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* È */ + 8, 16, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* É */ + 24, 36, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* Ê */ + 0, 36, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* Ë */ + 16, 8, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Ì */ + 4, 8, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Í */ + 8, 20, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Î */ + 0, 20, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Ï */ + 0, 0, 60, 34, 33, 33, 121, 33, 33, 33, 34, 60, 0, 0, /* Ð */ + 50, 76, 0, 98, 98, 82, 82, 74, 74, 74, 70, 70, 0, 0, /* Ñ */ + 16, 8, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ò */ + 8, 16, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ó */ + 24, 36, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ô */ + 50, 76, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Õ */ + 0, 36, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ö */ + 0, 0, 0, 0, 0, 65, 34, 20, 8, 20, 34, 65, 0, 0, /* × */ + 2, 2, 60, 70, 74, 74, 74, 82, 82, 82, 98, 60, 64, 64, /* Ø */ + 16, 8, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ù */ + 8, 16, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ú */ + 24, 36, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Û */ + 0, 36, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ü */ + 4, 8, 0, 34, 34, 20, 20, 8, 8, 8, 8, 8, 0, 0, /* Ý */ + 0, 0, 64, 64, 124, 66, 66, 66, 66, 124, 64, 64, 0, 0, /* Þ */ + 0, 0, 24, 36, 36, 36, 56, 36, 34, 34, 34, 124, 0, 0, /* ß */ + 0, 0, 16, 8, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* à */ + 0, 0, 4, 8, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* á */ + 0, 0, 24, 36, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* â */ + 0, 0, 50, 76, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* ã */ + 0, 0, 0, 36, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* ä */ + 0, 24, 36, 24, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* å */ + 0, 0, 0, 0, 0, 62, 73, 25, 47, 72, 73, 62, 0, 0, /* æ */ + 0, 0, 0, 0, 0, 60, 66, 64, 64, 64, 66, 60, 8, 16, /* ç */ + 0, 0, 16, 8, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* è */ + 0, 0, 8, 16, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* é */ + 0, 0, 24, 36, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* ê */ + 0, 0, 0, 36, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* ë */ + 0, 0, 16, 8, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* ì */ + 0, 0, 4, 8, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* í */ + 0, 0, 24, 36, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* î */ + 0, 0, 0, 20, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* ï */ + 0, 20, 8, 20, 2, 30, 34, 34, 34, 34, 34, 28, 0, 0, /* ð */ + 0, 0, 50, 76, 0, 92, 98, 66, 66, 66, 66, 66, 0, 0, /* ñ */ + 0, 0, 16, 8, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ò */ + 0, 0, 8, 16, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ó */ + 0, 0, 24, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ô */ + 0, 0, 50, 76, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* õ */ + 0, 0, 0, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ö */ + 0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0, /* ÷ */ + 0, 0, 0, 2, 4, 60, 74, 74, 82, 82, 98, 60, 64, 64, /* ø */ + 0, 0, 16, 8, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* ù */ + 0, 0, 8, 16, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* ú */ + 0, 0, 24, 36, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* û */ + 0, 0, 0, 36, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* ü */ + 0, 0, 8, 16, 0, 66, 66, 34, 36, 20, 28, 8, 72, 48, /* ý */ + 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 98, 92, 64, 64, /* þ */ + 0, 0, 0, 36, 0, 66, 66, 34, 36, 20, 28, 8, 72, 48, /* ÿ */ +}; + +static const char small_font[] = { + /* Each character is 5 x 9 pixels */ + 0, 2, 2, 2, 2, 0, 2, 0, 0, /* ! */ + 0, 5, 5, 5, 0, 0, 0, 0, 0, /* " */ + 0, 0, 5, 15, 5, 15, 5, 0, 0, /* # */ + 0, 0, 7, 26, 7, 18, 7, 0, 0, /* $ */ + 0, 8, 9, 2, 4, 25, 1, 0, 0, /* % */ + 0, 0, 4, 10, 4, 10, 5, 0, 0, /* & */ + 0, 2, 2, 2, 0, 0, 0, 0, 0, /* ' */ + 0, 2, 4, 4, 4, 4, 2, 0, 0, /* ( */ + 0, 4, 2, 2, 2, 2, 4, 0, 0, /* ) */ + 0, 0, 5, 2, 7, 2, 5, 0, 0, /* * */ + 0, 0, 2, 2, 15, 2, 2, 0, 0, /* + */ + 0, 0, 0, 0, 16, 3, 2, 4, 0, /* , */ + 0, 0, 0, 0, 15, 0, 0, 0, 0, /* - */ + 0, 0, 0, 0, 0, 6, 6, 0, 0, /* . */ + 0, 0, 1, 2, 4, 8, 0, 0, 0, /* / */ + 0, 2, 5, 5, 5, 5, 2, 0, 0, /* 0 */ + 0, 2, 6, 2, 2, 2, 7, 0, 0, /* 1 */ + 0, 6, 9, 1, 2, 4, 15, 0, 0, /* 2 */ + 0, 15, 1, 6, 1, 9, 6, 0, 0, /* 3 */ + 0, 2, 6, 10, 15, 2, 2, 0, 0, /* 4 */ + 0, 15, 8, 14, 1, 9, 6, 0, 0, /* 5 */ + 0, 6, 8, 14, 9, 9, 6, 0, 0, /* 6 */ + 0, 15, 1, 2, 2, 4, 4, 0, 0, /* 7 */ + 0, 6, 9, 6, 9, 9, 6, 0, 0, /* 8 */ + 0, 6, 9, 9, 7, 1, 6, 0, 0, /* 9 */ + 0, 0, 6, 6, 0, 6, 6, 0, 0, /* : */ + 0, 0, 6, 6, 0, 6, 4, 8, 0, /* ; */ + 0, 0, 1, 2, 4, 2, 1, 0, 0, /* < */ + 0, 0, 0, 15, 0, 15, 0, 0, 0, /* = */ + 0, 0, 4, 2, 1, 2, 4, 0, 0, /* > */ + 0, 2, 5, 1, 2, 0, 2, 0, 0, /* ? */ + 0, 6, 9, 11, 11, 8, 6, 0, 0, /* @ */ + 0, 6, 9, 9, 15, 9, 9, 0, 0, /* A */ + 0, 14, 9, 14, 9, 9, 14, 0, 0, /* B */ + 0, 6, 9, 8, 8, 9, 6, 0, 0, /* C */ + 0, 14, 9, 9, 9, 9, 14, 0, 0, /* D */ + 0, 15, 8, 14, 8, 8, 15, 0, 0, /* E */ + 0, 15, 8, 14, 8, 8, 8, 0, 0, /* F */ + 0, 6, 9, 8, 11, 9, 7, 0, 0, /* G */ + 0, 9, 9, 15, 9, 9, 9, 0, 0, /* H */ + 0, 7, 2, 2, 2, 2, 7, 0, 0, /* I */ + 0, 1, 1, 1, 1, 9, 6, 0, 0, /* J */ + 0, 9, 10, 12, 12, 10, 9, 0, 0, /* K */ + 0, 8, 8, 8, 8, 8, 15, 0, 0, /* L */ + 0, 9, 15, 15, 9, 9, 9, 0, 0, /* M */ + 0, 9, 13, 13, 11, 11, 9, 0, 0, /* N */ + 0, 6, 9, 9, 9, 9, 6, 0, 0, /* O */ + 0, 14, 9, 9, 14, 8, 8, 0, 0, /* P */ + 0, 6, 9, 9, 9, 13, 6, 1, 0, /* Q */ + 0, 14, 9, 9, 14, 10, 9, 0, 0, /* R */ + 0, 6, 9, 4, 2, 9, 6, 0, 0, /* S */ + 0, 7, 2, 2, 2, 2, 2, 0, 0, /* T */ + 0, 9, 9, 9, 9, 9, 6, 0, 0, /* U */ + 0, 9, 9, 9, 9, 6, 6, 0, 0, /* V */ + 0, 9, 9, 9, 15, 15, 9, 0, 0, /* W */ + 0, 9, 9, 6, 6, 9, 9, 0, 0, /* X */ + 0, 5, 5, 5, 2, 2, 2, 0, 0, /* Y */ + 0, 15, 1, 2, 4, 8, 15, 0, 0, /* Z */ + 0, 7, 4, 4, 4, 4, 7, 0, 0, /* [ */ + 0, 0, 8, 4, 2, 1, 0, 0, 0, /* \ */ + 0, 7, 1, 1, 1, 1, 7, 0, 0, /* ] */ + 0, 2, 5, 0, 0, 0, 0, 0, 0, /* ^ */ + 0, 0, 0, 0, 0, 0, 15, 0, 0, /* _ */ + 0, 4, 2, 0, 0, 0, 0, 0, 0, /* ` */ + 0, 0, 0, 7, 9, 11, 5, 0, 0, /* a */ + 0, 8, 8, 14, 9, 9, 14, 0, 0, /* b */ + 0, 0, 0, 6, 8, 8, 6, 0, 0, /* c */ + 0, 1, 1, 7, 9, 9, 7, 0, 0, /* d */ + 0, 0, 0, 6, 11, 12, 6, 0, 0, /* e */ + 0, 2, 5, 4, 14, 4, 4, 0, 0, /* f */ + 0, 0, 0, 7, 9, 6, 8, 7, 0, /* g */ + 0, 8, 8, 14, 9, 9, 9, 0, 0, /* h */ + 0, 2, 0, 6, 2, 2, 7, 0, 0, /* i */ + 0, 1, 0, 1, 1, 1, 5, 2, 0, /* j */ + 0, 8, 8, 10, 12, 10, 9, 0, 0, /* k */ + 0, 6, 2, 2, 2, 2, 7, 0, 0, /* l */ + 0, 0, 0, 10, 15, 9, 9, 0, 0, /* m */ + 0, 0, 0, 14, 9, 9, 9, 0, 0, /* n */ + 0, 0, 0, 6, 9, 9, 6, 0, 0, /* o */ + 0, 0, 0, 14, 9, 9, 14, 8, 0, /* p */ + 0, 0, 0, 7, 9, 9, 7, 1, 0, /* q */ + 0, 0, 0, 14, 9, 8, 8, 0, 0, /* r */ + 0, 0, 0, 7, 12, 3, 14, 0, 0, /* s */ + 0, 4, 4, 14, 4, 4, 3, 0, 0, /* t */ + 0, 0, 0, 9, 9, 9, 7, 0, 0, /* u */ + 0, 0, 0, 5, 5, 5, 2, 0, 0, /* v */ + 0, 0, 0, 9, 9, 15, 15, 0, 0, /* w */ + 0, 0, 0, 9, 6, 6, 9, 0, 0, /* x */ + 0, 0, 0, 9, 9, 5, 2, 4, 0, /* y */ + 0, 0, 0, 15, 2, 4, 15, 0, 0, /* z */ + 0, 1, 2, 6, 2, 2, 1, 0, 0, /* { */ + 0, 2, 2, 2, 2, 2, 2, 0, 0, /* | */ + 0, 4, 2, 3, 2, 2, 4, 0, 0, /* } */ + 0, 5, 10, 0, 0, 0, 0, 0, 0, /* ~ */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  */ + 0, 2, 0, 2, 2, 2, 2, 0, 0, /* ¡ */ + 0, 0, 2, 7, 10, 10, 7, 2, 0, /* ¢ */ + 0, 0, 3, 4, 14, 4, 11, 0, 0, /* £ */ + 0, 0, 8, 7, 5, 7, 8, 0, 0, /* ¤ */ + 0, 5, 21, 2, 7, 2, 18, 0, 0, /* ¥ */ + 0, 0, 2, 2, 0, 2, 2, 0, 0, /* ¦ */ + 0, 3, 4, 6, 5, 3, 1, 6, 0, /* § */ + 0, 5, 0, 0, 0, 0, 0, 0, 0, /* ¨ */ + 0, 7, 8, 10, 12, 10, 8, 7, 0, /* © */ + 0, 6, 26, 22, 16, 16, 16, 0, 0, /* ª */ + 0, 0, 0, 4, 9, 4, 0, 0, 0, /* « */ + 0, 0, 0, 16, 15, 17, 0, 0, 0, /* ¬ */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ­ */ + 0, 7, 8, 14, 12, 12, 8, 7, 0, /* ® */ + 0, 15, 16, 16, 16, 16, 16, 0, 0, /* ¯ */ + 0, 2, 5, 2, 0, 0, 0, 0, 0, /* ° */ + 0, 2, 2, 15, 2, 2, 15, 0, 0, /* ± */ + 0, 6, 2, 20, 6, 0, 16, 0, 0, /* ² */ + 0, 6, 6, 2, 6, 0, 0, 0, 0, /* ³ */ + 0, 2, 4, 0, 0, 0, 0, 0, 0, /* ´ */ + 0, 0, 0, 9, 9, 9, 14, 8, 0, /* µ */ + 0, 7, 13, 13, 5, 5, 5, 0, 0, /* ¶ */ + 0, 0, 0, 6, 6, 0, 0, 0, 0, /* · */ + 0, 0, 0, 0, 0, 0, 2, 4, 0, /* ¸ */ + 0, 2, 6, 2, 7, 0, 0, 0, 0, /* ¹ */ + 0, 4, 10, 4, 0, 0, 0, 0, 0, /* º */ + 0, 0, 0, 9, 4, 9, 0, 0, 0, /* » */ + 0, 8, 8, 8, 25, 3, 7, 1, 0, /* ¼ */ + 0, 8, 8, 8, 11, 1, 2, 3, 0, /* ½ */ + 0, 12, 12, 4, 13, 3, 7, 1, 0, /* ¾ */ + 0, 2, 0, 2, 4, 5, 2, 0, 0, /* ¿ */ + 0, 6, 9, 9, 15, 9, 9, 0, 0, /* À */ + 0, 6, 9, 9, 15, 9, 9, 0, 0, /* Á */ + 0, 6, 9, 9, 15, 9, 9, 0, 0, /* Â */ + 0, 6, 9, 9, 15, 9, 9, 0, 0, /* Ã */ + 0, 9, 6, 9, 15, 9, 9, 0, 0, /* Ä */ + 0, 6, 6, 9, 15, 9, 9, 0, 0, /* Å */ + 0, 7, 10, 11, 14, 10, 11, 0, 0, /* Æ */ + 0, 6, 9, 8, 8, 9, 6, 4, 0, /* Ç */ + 0, 15, 8, 14, 8, 8, 15, 0, 0, /* È */ + 0, 15, 8, 14, 8, 8, 15, 0, 0, /* É */ + 0, 15, 8, 14, 8, 8, 15, 0, 0, /* Ê */ + 0, 15, 8, 14, 8, 8, 15, 0, 0, /* Ë */ + 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Ì */ + 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Í */ + 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Î */ + 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Ï */ + 0, 14, 5, 13, 5, 5, 14, 0, 0, /* Ð */ + 0, 11, 9, 13, 11, 11, 9, 0, 0, /* Ñ */ + 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Ò */ + 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Ó */ + 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Ô */ + 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Õ */ + 0, 9, 6, 9, 9, 9, 6, 0, 0, /* Ö */ + 0, 0, 0, 9, 6, 6, 9, 0, 0, /* × */ + 0, 7, 11, 11, 13, 13, 14, 0, 0, /* Ø */ + 0, 9, 9, 9, 9, 9, 6, 0, 0, /* Ù */ + 0, 9, 9, 9, 9, 9, 6, 0, 0, /* Ú */ + 0, 9, 9, 9, 9, 9, 6, 0, 0, /* Û */ + 0, 9, 0, 9, 9, 9, 6, 0, 0, /* Ü */ + 0, 5, 5, 5, 2, 2, 2, 0, 0, /* Ý */ + 0, 8, 14, 9, 14, 8, 8, 0, 0, /* Þ */ + 0, 6, 9, 10, 9, 9, 10, 0, 0, /* ß */ + 0, 4, 2, 7, 9, 11, 5, 0, 0, /* à */ + 0, 2, 4, 7, 9, 11, 5, 0, 0, /* á */ + 0, 2, 5, 7, 9, 11, 5, 0, 0, /* â */ + 0, 5, 10, 7, 9, 11, 5, 0, 0, /* ã */ + 0, 5, 0, 7, 9, 11, 5, 0, 0, /* ä */ + 0, 6, 6, 7, 9, 11, 5, 0, 0, /* å */ + 0, 0, 0, 7, 11, 10, 7, 0, 0, /* æ */ + 0, 0, 0, 3, 4, 4, 3, 2, 0, /* ç */ + 0, 4, 2, 6, 11, 12, 6, 0, 0, /* è */ + 0, 2, 4, 6, 11, 12, 6, 0, 0, /* é */ + 0, 4, 10, 6, 11, 12, 6, 0, 0, /* ê */ + 0, 10, 0, 6, 11, 12, 6, 0, 0, /* ë */ + 0, 4, 2, 6, 2, 2, 7, 0, 0, /* ì */ + 0, 2, 4, 6, 2, 2, 7, 0, 0, /* í */ + 0, 2, 5, 6, 2, 2, 7, 0, 0, /* î */ + 0, 5, 0, 6, 2, 2, 7, 0, 0, /* ï */ + 0, 4, 3, 6, 9, 9, 6, 0, 0, /* ð */ + 0, 5, 10, 14, 9, 9, 9, 0, 0, /* ñ */ + 0, 4, 2, 6, 9, 9, 6, 0, 0, /* ò */ + 0, 2, 4, 6, 9, 9, 6, 0, 0, /* ó */ + 0, 6, 0, 6, 9, 9, 6, 0, 0, /* ô */ + 0, 5, 10, 6, 9, 9, 6, 0, 0, /* õ */ + 0, 5, 0, 6, 9, 9, 6, 0, 0, /* ö */ + 0, 0, 6, 0, 15, 0, 6, 0, 0, /* ÷ */ + 0, 0, 0, 7, 11, 13, 14, 0, 0, /* ø */ + 0, 4, 2, 9, 9, 9, 7, 0, 0, /* ù */ + 0, 2, 4, 9, 9, 9, 7, 0, 0, /* ú */ + 0, 6, 0, 9, 9, 9, 7, 0, 0, /* û */ + 0, 5, 0, 9, 9, 9, 7, 0, 0, /* ü */ + 0, 2, 4, 9, 9, 5, 2, 4, 0, /* ý */ + 0, 0, 8, 14, 9, 9, 14, 8, 0, /* þ */ + 0, 5, 0, 9, 9, 5, 2, 4, 0, /* ÿ */ +}; diff --git a/3rdparty/zint-2.6.1/backend/gb18030.h b/3rdparty/zint-2.6.1/backend/gb18030.h new file mode 100644 index 0000000..131aab9 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gb18030.h @@ -0,0 +1,23324 @@ +/* gb18030.h - Unicode to GB 18030 lookup table + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +static const unsigned short int gb18030_twobyte_lookup[] = { + 0x0144, 0xA8BD, + 0x0148, 0xA8BE, + 0x01F9, 0xA8BF, + 0x0251, 0xA8BB, + 0x0261, 0xA8C0, + 0x02CA, 0xA840, + 0x02CB, 0xA841, + 0x02D9, 0xA842, + 0x2010, 0xA95C, + 0x2013, 0xA843, + 0x2015, 0xA844, + 0x2025, 0xA845, + 0x2035, 0xA846, + 0x20AC, 0xA2E3, + 0x2105, 0xA847, + 0x2109, 0xA848, + 0x2121, 0xA959, + 0x2170, 0xA2A1, + 0x2171, 0xA2A2, + 0x2172, 0xA2A3, + 0x2173, 0xA2A4, + 0x2174, 0xA2A5, + 0x2175, 0xA2A6, + 0x2176, 0xA2A7, + 0x2177, 0xA2A8, + 0x2178, 0xA2A9, + 0x2179, 0xA2AA, + 0x2196, 0xA849, + 0x2197, 0xA84A, + 0x2198, 0xA84B, + 0x2199, 0xA84C, + 0x2215, 0xA84D, + 0x221F, 0xA84E, + 0x2223, 0xA84F, + 0x2252, 0xA850, + 0x2266, 0xA851, + 0x2267, 0xA852, + 0x2295, 0xA892, + 0x22BF, 0xA853, + 0x2550, 0xA854, + 0x2551, 0xA855, + 0x2552, 0xA856, + 0x2553, 0xA857, + 0x2554, 0xA858, + 0x2555, 0xA859, + 0x2556, 0xA85A, + 0x2557, 0xA85B, + 0x2558, 0xA85C, + 0x2559, 0xA85D, + 0x255A, 0xA85E, + 0x255B, 0xA85F, + 0x255C, 0xA860, + 0x255D, 0xA861, + 0x255E, 0xA862, + 0x255F, 0xA863, + 0x2560, 0xA864, + 0x2561, 0xA865, + 0x2562, 0xA866, + 0x2563, 0xA867, + 0x2564, 0xA868, + 0x2565, 0xA869, + 0x2566, 0xA86A, + 0x2567, 0xA86B, + 0x2568, 0xA86C, + 0x2569, 0xA86D, + 0x256A, 0xA86E, + 0x256B, 0xA86F, + 0x256C, 0xA870, + 0x256D, 0xA871, + 0x256E, 0xA872, + 0x256F, 0xA873, + 0x2570, 0xA874, + 0x2571, 0xA875, + 0x2572, 0xA876, + 0x2573, 0xA877, + 0x2581, 0xA878, + 0x2582, 0xA879, + 0x2583, 0xA87A, + 0x2584, 0xA87B, + 0x2585, 0xA87C, + 0x2586, 0xA87D, + 0x2587, 0xA87E, + 0x2588, 0xA880, + 0x2589, 0xA881, + 0x258A, 0xA882, + 0x258B, 0xA883, + 0x258C, 0xA884, + 0x258D, 0xA885, + 0x258E, 0xA886, + 0x258F, 0xA887, + 0x2593, 0xA888, + 0x2594, 0xA889, + 0x2595, 0xA88A, + 0x25BC, 0xA88B, + 0x25BD, 0xA88C, + 0x25E2, 0xA88D, + 0x25E3, 0xA88E, + 0x25E4, 0xA88F, + 0x25E5, 0xA890, + 0x2609, 0xA891, + 0x2E81, 0xFE50, + 0x2E84, 0xFE54, + 0x2E88, 0xFE57, + 0x2E8B, 0xFE58, + 0x2E8C, 0xFE5D, + 0x2E97, 0xFE5E, + 0x2EA7, 0xFE6B, + 0x2EAA, 0xFE6E, + 0x2EAE, 0xFE71, + 0x2EB3, 0xFE73, + 0x2EB6, 0xFE74, + 0x2EB7, 0xFE75, + 0x2EBB, 0xFE79, + 0x2ECA, 0xFE84, + 0x2FF0, 0xA98A, + 0x2FF1, 0xA98B, + 0x2FF2, 0xA98C, + 0x2FF3, 0xA98D, + 0x2FF4, 0xA98E, + 0x2FF5, 0xA98F, + 0x2FF6, 0xA990, + 0x2FF7, 0xA991, + 0x2FF8, 0xA992, + 0x2FF9, 0xA993, + 0x2FFA, 0xA994, + 0x2FFB, 0xA995, + 0x3006, 0xA965, + 0x3007, 0xA996, + 0x3012, 0xA893, + 0x301D, 0xA894, + 0x301E, 0xA895, + 0x3021, 0xA940, + 0x3022, 0xA941, + 0x3023, 0xA942, + 0x3024, 0xA943, + 0x3025, 0xA944, + 0x3026, 0xA945, + 0x3027, 0xA946, + 0x3028, 0xA947, + 0x3029, 0xA948, + 0x303E, 0xA989, + 0x309B, 0xA961, + 0x309C, 0xA962, + 0x309D, 0xA966, + 0x309E, 0xA967, + 0x30FC, 0xA960, + 0x30FD, 0xA963, + 0x30FE, 0xA964, + 0x3231, 0xA95A, + 0x32A3, 0xA949, + 0x338E, 0xA94A, + 0x338F, 0xA94B, + 0x339C, 0xA94C, + 0x339D, 0xA94D, + 0x339E, 0xA94E, + 0x33A1, 0xA94F, + 0x33C4, 0xA950, + 0x33CE, 0xA951, + 0x33D1, 0xA952, + 0x33D2, 0xA953, + 0x33D5, 0xA954, + 0x3447, 0xFE56, + 0x3473, 0xFE55, + 0x359E, 0xFE5A, + 0x360E, 0xFE5C, + 0x361A, 0xFE5B, + 0x3918, 0xFE60, + 0x396E, 0xFE5F, + 0x39CF, 0xFE62, + 0x39D0, 0xFE65, + 0x39DF, 0xFE63, + 0x3A73, 0xFE64, + 0x3B4E, 0xFE68, + 0x3C6E, 0xFE69, + 0x3CE0, 0xFE6A, + 0x4056, 0xFE6F, + 0x415F, 0xFE70, + 0x4337, 0xFE72, + 0x43AC, 0xFE78, + 0x43B1, 0xFE77, + 0x43DD, 0xFE7A, + 0x44D6, 0xFE7B, + 0x464C, 0xFE7D, + 0x4661, 0xFE7C, + 0x4723, 0xFE80, + 0x4729, 0xFE81, + 0x477C, 0xFE82, + 0x478D, 0xFE83, + 0x4947, 0xFE85, + 0x497A, 0xFE86, + 0x497D, 0xFE87, + 0x4982, 0xFE88, + 0x4983, 0xFE89, + 0x4985, 0xFE8A, + 0x4986, 0xFE8B, + 0x499B, 0xFE8D, + 0x499F, 0xFE8C, + 0x49B6, 0xFE8F, + 0x49B7, 0xFE8E, + 0x4C77, 0xFE96, + 0x4C9F, 0xFE93, + 0x4CA0, 0xFE94, + 0x4CA1, 0xFE95, + 0x4CA2, 0xFE97, + 0x4CA3, 0xFE92, + 0x4D13, 0xFE98, + 0x4D14, 0xFE99, + 0x4D15, 0xFE9A, + 0x4D16, 0xFE9B, + 0x4D17, 0xFE9C, + 0x4D18, 0xFE9D, + 0x4D19, 0xFE9E, + 0x4DAE, 0xFE9F, + 0x4E02, 0x8140, + 0x4E04, 0x8141, + 0x4E05, 0x8142, + 0x4E06, 0x8143, + 0x4E0F, 0x8144, + 0x4E12, 0x8145, + 0x4E17, 0x8146, + 0x4E1F, 0x8147, + 0x4E20, 0x8148, + 0x4E21, 0x8149, + 0x4E23, 0x814A, + 0x4E26, 0x814B, + 0x4E29, 0x814C, + 0x4E2E, 0x814D, + 0x4E2F, 0x814E, + 0x4E31, 0x814F, + 0x4E33, 0x8150, + 0x4E35, 0x8151, + 0x4E37, 0x8152, + 0x4E3C, 0x8153, + 0x4E40, 0x8154, + 0x4E41, 0x8155, + 0x4E42, 0x8156, + 0x4E44, 0x8157, + 0x4E46, 0x8158, + 0x4E4A, 0x8159, + 0x4E51, 0x815A, + 0x4E55, 0x815B, + 0x4E57, 0x815C, + 0x4E5A, 0x815D, + 0x4E5B, 0x815E, + 0x4E62, 0x815F, + 0x4E63, 0x8160, + 0x4E64, 0x8161, + 0x4E65, 0x8162, + 0x4E67, 0x8163, + 0x4E68, 0x8164, + 0x4E6A, 0x8165, + 0x4E6B, 0x8166, + 0x4E6C, 0x8167, + 0x4E6D, 0x8168, + 0x4E6E, 0x8169, + 0x4E6F, 0x816A, + 0x4E72, 0x816B, + 0x4E74, 0x816C, + 0x4E75, 0x816D, + 0x4E76, 0x816E, + 0x4E77, 0x816F, + 0x4E78, 0x8170, + 0x4E79, 0x8171, + 0x4E7A, 0x8172, + 0x4E7B, 0x8173, + 0x4E7C, 0x8174, + 0x4E7D, 0x8175, + 0x4E7F, 0x8176, + 0x4E80, 0x8177, + 0x4E81, 0x8178, + 0x4E82, 0x8179, + 0x4E83, 0x817A, + 0x4E84, 0x817B, + 0x4E85, 0x817C, + 0x4E87, 0x817D, + 0x4E8A, 0x817E, + 0x4E90, 0x8180, + 0x4E96, 0x8181, + 0x4E97, 0x8182, + 0x4E99, 0x8183, + 0x4E9C, 0x8184, + 0x4E9D, 0x8185, + 0x4E9E, 0x8186, + 0x4EA3, 0x8187, + 0x4EAA, 0x8188, + 0x4EAF, 0x8189, + 0x4EB0, 0x818A, + 0x4EB1, 0x818B, + 0x4EB4, 0x818C, + 0x4EB6, 0x818D, + 0x4EB7, 0x818E, + 0x4EB8, 0x818F, + 0x4EB9, 0x8190, + 0x4EBC, 0x8191, + 0x4EBD, 0x8192, + 0x4EBE, 0x8193, + 0x4EC8, 0x8194, + 0x4ECC, 0x8195, + 0x4ECF, 0x8196, + 0x4ED0, 0x8197, + 0x4ED2, 0x8198, + 0x4EDA, 0x8199, + 0x4EDB, 0x819A, + 0x4EDC, 0x819B, + 0x4EE0, 0x819C, + 0x4EE2, 0x819D, + 0x4EE6, 0x819E, + 0x4EE7, 0x819F, + 0x4EE9, 0x81A0, + 0x4EED, 0x81A1, + 0x4EEE, 0x81A2, + 0x4EEF, 0x81A3, + 0x4EF1, 0x81A4, + 0x4EF4, 0x81A5, + 0x4EF8, 0x81A6, + 0x4EF9, 0x81A7, + 0x4EFA, 0x81A8, + 0x4EFC, 0x81A9, + 0x4EFE, 0x81AA, + 0x4F00, 0x81AB, + 0x4F02, 0x81AC, + 0x4F03, 0x81AD, + 0x4F04, 0x81AE, + 0x4F05, 0x81AF, + 0x4F06, 0x81B0, + 0x4F07, 0x81B1, + 0x4F08, 0x81B2, + 0x4F0B, 0x81B3, + 0x4F0C, 0x81B4, + 0x4F12, 0x81B5, + 0x4F13, 0x81B6, + 0x4F14, 0x81B7, + 0x4F15, 0x81B8, + 0x4F16, 0x81B9, + 0x4F1C, 0x81BA, + 0x4F1D, 0x81BB, + 0x4F21, 0x81BC, + 0x4F23, 0x81BD, + 0x4F28, 0x81BE, + 0x4F29, 0x81BF, + 0x4F2C, 0x81C0, + 0x4F2D, 0x81C1, + 0x4F2E, 0x81C2, + 0x4F31, 0x81C3, + 0x4F33, 0x81C4, + 0x4F35, 0x81C5, + 0x4F37, 0x81C6, + 0x4F39, 0x81C7, + 0x4F3B, 0x81C8, + 0x4F3E, 0x81C9, + 0x4F3F, 0x81CA, + 0x4F40, 0x81CB, + 0x4F41, 0x81CC, + 0x4F42, 0x81CD, + 0x4F44, 0x81CE, + 0x4F45, 0x81CF, + 0x4F47, 0x81D0, + 0x4F48, 0x81D1, + 0x4F49, 0x81D2, + 0x4F4A, 0x81D3, + 0x4F4B, 0x81D4, + 0x4F4C, 0x81D5, + 0x4F52, 0x81D6, + 0x4F54, 0x81D7, + 0x4F56, 0x81D8, + 0x4F61, 0x81D9, + 0x4F62, 0x81DA, + 0x4F66, 0x81DB, + 0x4F68, 0x81DC, + 0x4F6A, 0x81DD, + 0x4F6B, 0x81DE, + 0x4F6D, 0x81DF, + 0x4F6E, 0x81E0, + 0x4F71, 0x81E1, + 0x4F72, 0x81E2, + 0x4F75, 0x81E3, + 0x4F77, 0x81E4, + 0x4F78, 0x81E5, + 0x4F79, 0x81E6, + 0x4F7A, 0x81E7, + 0x4F7D, 0x81E8, + 0x4F80, 0x81E9, + 0x4F81, 0x81EA, + 0x4F82, 0x81EB, + 0x4F85, 0x81EC, + 0x4F86, 0x81ED, + 0x4F87, 0x81EE, + 0x4F8A, 0x81EF, + 0x4F8C, 0x81F0, + 0x4F8E, 0x81F1, + 0x4F90, 0x81F2, + 0x4F92, 0x81F3, + 0x4F93, 0x81F4, + 0x4F95, 0x81F5, + 0x4F96, 0x81F6, + 0x4F98, 0x81F7, + 0x4F99, 0x81F8, + 0x4F9A, 0x81F9, + 0x4F9C, 0x81FA, + 0x4F9E, 0x81FB, + 0x4F9F, 0x81FC, + 0x4FA1, 0x81FD, + 0x4FA2, 0x81FE, + 0x4FA4, 0x8240, + 0x4FAB, 0x8241, + 0x4FAD, 0x8242, + 0x4FB0, 0x8243, + 0x4FB1, 0x8244, + 0x4FB2, 0x8245, + 0x4FB3, 0x8246, + 0x4FB4, 0x8247, + 0x4FB6, 0x8248, + 0x4FB7, 0x8249, + 0x4FB8, 0x824A, + 0x4FB9, 0x824B, + 0x4FBA, 0x824C, + 0x4FBB, 0x824D, + 0x4FBC, 0x824E, + 0x4FBD, 0x824F, + 0x4FBE, 0x8250, + 0x4FC0, 0x8251, + 0x4FC1, 0x8252, + 0x4FC2, 0x8253, + 0x4FC6, 0x8254, + 0x4FC7, 0x8255, + 0x4FC8, 0x8256, + 0x4FC9, 0x8257, + 0x4FCB, 0x8258, + 0x4FCC, 0x8259, + 0x4FCD, 0x825A, + 0x4FD2, 0x825B, + 0x4FD3, 0x825C, + 0x4FD4, 0x825D, + 0x4FD5, 0x825E, + 0x4FD6, 0x825F, + 0x4FD9, 0x8260, + 0x4FDB, 0x8261, + 0x4FE0, 0x8262, + 0x4FE2, 0x8263, + 0x4FE4, 0x8264, + 0x4FE5, 0x8265, + 0x4FE7, 0x8266, + 0x4FEB, 0x8267, + 0x4FEC, 0x8268, + 0x4FF0, 0x8269, + 0x4FF2, 0x826A, + 0x4FF4, 0x826B, + 0x4FF5, 0x826C, + 0x4FF6, 0x826D, + 0x4FF7, 0x826E, + 0x4FF9, 0x826F, + 0x4FFB, 0x8270, + 0x4FFC, 0x8271, + 0x4FFD, 0x8272, + 0x4FFF, 0x8273, + 0x5000, 0x8274, + 0x5001, 0x8275, + 0x5002, 0x8276, + 0x5003, 0x8277, + 0x5004, 0x8278, + 0x5005, 0x8279, + 0x5006, 0x827A, + 0x5007, 0x827B, + 0x5008, 0x827C, + 0x5009, 0x827D, + 0x500A, 0x827E, + 0x500B, 0x8280, + 0x500E, 0x8281, + 0x5010, 0x8282, + 0x5011, 0x8283, + 0x5013, 0x8284, + 0x5015, 0x8285, + 0x5016, 0x8286, + 0x5017, 0x8287, + 0x501B, 0x8288, + 0x501D, 0x8289, + 0x501E, 0x828A, + 0x5020, 0x828B, + 0x5022, 0x828C, + 0x5023, 0x828D, + 0x5024, 0x828E, + 0x5027, 0x828F, + 0x502B, 0x8290, + 0x502F, 0x8291, + 0x5030, 0x8292, + 0x5031, 0x8293, + 0x5032, 0x8294, + 0x5033, 0x8295, + 0x5034, 0x8296, + 0x5035, 0x8297, + 0x5036, 0x8298, + 0x5037, 0x8299, + 0x5038, 0x829A, + 0x5039, 0x829B, + 0x503B, 0x829C, + 0x503D, 0x829D, + 0x503F, 0x829E, + 0x5040, 0x829F, + 0x5041, 0x82A0, + 0x5042, 0x82A1, + 0x5044, 0x82A2, + 0x5045, 0x82A3, + 0x5046, 0x82A4, + 0x5049, 0x82A5, + 0x504A, 0x82A6, + 0x504B, 0x82A7, + 0x504D, 0x82A8, + 0x5050, 0x82A9, + 0x5051, 0x82AA, + 0x5052, 0x82AB, + 0x5053, 0x82AC, + 0x5054, 0x82AD, + 0x5056, 0x82AE, + 0x5057, 0x82AF, + 0x5058, 0x82B0, + 0x5059, 0x82B1, + 0x505B, 0x82B2, + 0x505D, 0x82B3, + 0x505E, 0x82B4, + 0x505F, 0x82B5, + 0x5060, 0x82B6, + 0x5061, 0x82B7, + 0x5062, 0x82B8, + 0x5063, 0x82B9, + 0x5064, 0x82BA, + 0x5066, 0x82BB, + 0x5067, 0x82BC, + 0x5068, 0x82BD, + 0x5069, 0x82BE, + 0x506A, 0x82BF, + 0x506B, 0x82C0, + 0x506D, 0x82C1, + 0x506E, 0x82C2, + 0x506F, 0x82C3, + 0x5070, 0x82C4, + 0x5071, 0x82C5, + 0x5072, 0x82C6, + 0x5073, 0x82C7, + 0x5074, 0x82C8, + 0x5075, 0x82C9, + 0x5078, 0x82CA, + 0x5079, 0x82CB, + 0x507A, 0x82CC, + 0x507C, 0x82CD, + 0x507D, 0x82CE, + 0x5081, 0x82CF, + 0x5082, 0x82D0, + 0x5083, 0x82D1, + 0x5084, 0x82D2, + 0x5086, 0x82D3, + 0x5087, 0x82D4, + 0x5089, 0x82D5, + 0x508A, 0x82D6, + 0x508B, 0x82D7, + 0x508C, 0x82D8, + 0x508E, 0x82D9, + 0x508F, 0x82DA, + 0x5090, 0x82DB, + 0x5091, 0x82DC, + 0x5092, 0x82DD, + 0x5093, 0x82DE, + 0x5094, 0x82DF, + 0x5095, 0x82E0, + 0x5096, 0x82E1, + 0x5097, 0x82E2, + 0x5098, 0x82E3, + 0x5099, 0x82E4, + 0x509A, 0x82E5, + 0x509B, 0x82E6, + 0x509C, 0x82E7, + 0x509D, 0x82E8, + 0x509E, 0x82E9, + 0x509F, 0x82EA, + 0x50A0, 0x82EB, + 0x50A1, 0x82EC, + 0x50A2, 0x82ED, + 0x50A4, 0x82EE, + 0x50A6, 0x82EF, + 0x50AA, 0x82F0, + 0x50AB, 0x82F1, + 0x50AD, 0x82F2, + 0x50AE, 0x82F3, + 0x50AF, 0x82F4, + 0x50B0, 0x82F5, + 0x50B1, 0x82F6, + 0x50B3, 0x82F7, + 0x50B4, 0x82F8, + 0x50B5, 0x82F9, + 0x50B6, 0x82FA, + 0x50B7, 0x82FB, + 0x50B8, 0x82FC, + 0x50B9, 0x82FD, + 0x50BC, 0x82FE, + 0x50BD, 0x8340, + 0x50BE, 0x8341, + 0x50BF, 0x8342, + 0x50C0, 0x8343, + 0x50C1, 0x8344, + 0x50C2, 0x8345, + 0x50C3, 0x8346, + 0x50C4, 0x8347, + 0x50C5, 0x8348, + 0x50C6, 0x8349, + 0x50C7, 0x834A, + 0x50C8, 0x834B, + 0x50C9, 0x834C, + 0x50CA, 0x834D, + 0x50CB, 0x834E, + 0x50CC, 0x834F, + 0x50CD, 0x8350, + 0x50CE, 0x8351, + 0x50D0, 0x8352, + 0x50D1, 0x8353, + 0x50D2, 0x8354, + 0x50D3, 0x8355, + 0x50D4, 0x8356, + 0x50D5, 0x8357, + 0x50D7, 0x8358, + 0x50D8, 0x8359, + 0x50D9, 0x835A, + 0x50DB, 0x835B, + 0x50DC, 0x835C, + 0x50DD, 0x835D, + 0x50DE, 0x835E, + 0x50DF, 0x835F, + 0x50E0, 0x8360, + 0x50E1, 0x8361, + 0x50E2, 0x8362, + 0x50E3, 0x8363, + 0x50E4, 0x8364, + 0x50E5, 0x8365, + 0x50E8, 0x8366, + 0x50E9, 0x8367, + 0x50EA, 0x8368, + 0x50EB, 0x8369, + 0x50EF, 0x836A, + 0x50F0, 0x836B, + 0x50F1, 0x836C, + 0x50F2, 0x836D, + 0x50F4, 0x836E, + 0x50F6, 0x836F, + 0x50F7, 0x8370, + 0x50F8, 0x8371, + 0x50F9, 0x8372, + 0x50FA, 0x8373, + 0x50FC, 0x8374, + 0x50FD, 0x8375, + 0x50FE, 0x8376, + 0x50FF, 0x8377, + 0x5100, 0x8378, + 0x5101, 0x8379, + 0x5102, 0x837A, + 0x5103, 0x837B, + 0x5104, 0x837C, + 0x5105, 0x837D, + 0x5108, 0x837E, + 0x5109, 0x8380, + 0x510A, 0x8381, + 0x510C, 0x8382, + 0x510D, 0x8383, + 0x510E, 0x8384, + 0x510F, 0x8385, + 0x5110, 0x8386, + 0x5111, 0x8387, + 0x5113, 0x8388, + 0x5114, 0x8389, + 0x5115, 0x838A, + 0x5116, 0x838B, + 0x5117, 0x838C, + 0x5118, 0x838D, + 0x5119, 0x838E, + 0x511A, 0x838F, + 0x511B, 0x8390, + 0x511C, 0x8391, + 0x511D, 0x8392, + 0x511E, 0x8393, + 0x511F, 0x8394, + 0x5120, 0x8395, + 0x5122, 0x8396, + 0x5123, 0x8397, + 0x5124, 0x8398, + 0x5125, 0x8399, + 0x5126, 0x839A, + 0x5127, 0x839B, + 0x5128, 0x839C, + 0x5129, 0x839D, + 0x512A, 0x839E, + 0x512B, 0x839F, + 0x512C, 0x83A0, + 0x512D, 0x83A1, + 0x512E, 0x83A2, + 0x512F, 0x83A3, + 0x5130, 0x83A4, + 0x5131, 0x83A5, + 0x5132, 0x83A6, + 0x5133, 0x83A7, + 0x5134, 0x83A8, + 0x5135, 0x83A9, + 0x5136, 0x83AA, + 0x5137, 0x83AB, + 0x5138, 0x83AC, + 0x5139, 0x83AD, + 0x513A, 0x83AE, + 0x513B, 0x83AF, + 0x513C, 0x83B0, + 0x513D, 0x83B1, + 0x513E, 0x83B2, + 0x5142, 0x83B3, + 0x5147, 0x83B4, + 0x514A, 0x83B5, + 0x514C, 0x83B6, + 0x514E, 0x83B7, + 0x514F, 0x83B8, + 0x5150, 0x83B9, + 0x5152, 0x83BA, + 0x5153, 0x83BB, + 0x5157, 0x83BC, + 0x5158, 0x83BD, + 0x5159, 0x83BE, + 0x515B, 0x83BF, + 0x515D, 0x83C0, + 0x515E, 0x83C1, + 0x515F, 0x83C2, + 0x5160, 0x83C3, + 0x5161, 0x83C4, + 0x5163, 0x83C5, + 0x5164, 0x83C6, + 0x5166, 0x83C7, + 0x5167, 0x83C8, + 0x5169, 0x83C9, + 0x516A, 0x83CA, + 0x516F, 0x83CB, + 0x5172, 0x83CC, + 0x517A, 0x83CD, + 0x517E, 0x83CE, + 0x517F, 0x83CF, + 0x5183, 0x83D0, + 0x5184, 0x83D1, + 0x5186, 0x83D2, + 0x5187, 0x83D3, + 0x518A, 0x83D4, + 0x518B, 0x83D5, + 0x518E, 0x83D6, + 0x518F, 0x83D7, + 0x5190, 0x83D8, + 0x5191, 0x83D9, + 0x5193, 0x83DA, + 0x5194, 0x83DB, + 0x5198, 0x83DC, + 0x519A, 0x83DD, + 0x519D, 0x83DE, + 0x519E, 0x83DF, + 0x519F, 0x83E0, + 0x51A1, 0x83E1, + 0x51A3, 0x83E2, + 0x51A6, 0x83E3, + 0x51A7, 0x83E4, + 0x51A8, 0x83E5, + 0x51A9, 0x83E6, + 0x51AA, 0x83E7, + 0x51AD, 0x83E8, + 0x51AE, 0x83E9, + 0x51B4, 0x83EA, + 0x51B8, 0x83EB, + 0x51B9, 0x83EC, + 0x51BA, 0x83ED, + 0x51BE, 0x83EE, + 0x51BF, 0x83EF, + 0x51C1, 0x83F0, + 0x51C2, 0x83F1, + 0x51C3, 0x83F2, + 0x51C5, 0x83F3, + 0x51C8, 0x83F4, + 0x51CA, 0x83F5, + 0x51CD, 0x83F6, + 0x51CE, 0x83F7, + 0x51D0, 0x83F8, + 0x51D2, 0x83F9, + 0x51D3, 0x83FA, + 0x51D4, 0x83FB, + 0x51D5, 0x83FC, + 0x51D6, 0x83FD, + 0x51D7, 0x83FE, + 0x51D8, 0x8440, + 0x51D9, 0x8441, + 0x51DA, 0x8442, + 0x51DC, 0x8443, + 0x51DE, 0x8444, + 0x51DF, 0x8445, + 0x51E2, 0x8446, + 0x51E3, 0x8447, + 0x51E5, 0x8448, + 0x51E6, 0x8449, + 0x51E7, 0x844A, + 0x51E8, 0x844B, + 0x51E9, 0x844C, + 0x51EA, 0x844D, + 0x51EC, 0x844E, + 0x51EE, 0x844F, + 0x51F1, 0x8450, + 0x51F2, 0x8451, + 0x51F4, 0x8452, + 0x51F7, 0x8453, + 0x51FE, 0x8454, + 0x5204, 0x8455, + 0x5205, 0x8456, + 0x5209, 0x8457, + 0x520B, 0x8458, + 0x520C, 0x8459, + 0x520F, 0x845A, + 0x5210, 0x845B, + 0x5213, 0x845C, + 0x5214, 0x845D, + 0x5215, 0x845E, + 0x521C, 0x845F, + 0x521E, 0x8460, + 0x521F, 0x8461, + 0x5221, 0x8462, + 0x5222, 0x8463, + 0x5223, 0x8464, + 0x5225, 0x8465, + 0x5226, 0x8466, + 0x5227, 0x8467, + 0x522A, 0x8468, + 0x522C, 0x8469, + 0x522F, 0x846A, + 0x5231, 0x846B, + 0x5232, 0x846C, + 0x5234, 0x846D, + 0x5235, 0x846E, + 0x523C, 0x846F, + 0x523E, 0x8470, + 0x5244, 0x8471, + 0x5245, 0x8472, + 0x5246, 0x8473, + 0x5247, 0x8474, + 0x5248, 0x8475, + 0x5249, 0x8476, + 0x524B, 0x8477, + 0x524E, 0x8478, + 0x524F, 0x8479, + 0x5252, 0x847A, + 0x5253, 0x847B, + 0x5255, 0x847C, + 0x5257, 0x847D, + 0x5258, 0x847E, + 0x5259, 0x8480, + 0x525A, 0x8481, + 0x525B, 0x8482, + 0x525D, 0x8483, + 0x525F, 0x8484, + 0x5260, 0x8485, + 0x5262, 0x8486, + 0x5263, 0x8487, + 0x5264, 0x8488, + 0x5266, 0x8489, + 0x5268, 0x848A, + 0x526B, 0x848B, + 0x526C, 0x848C, + 0x526D, 0x848D, + 0x526E, 0x848E, + 0x5270, 0x848F, + 0x5271, 0x8490, + 0x5273, 0x8491, + 0x5274, 0x8492, + 0x5275, 0x8493, + 0x5276, 0x8494, + 0x5277, 0x8495, + 0x5278, 0x8496, + 0x5279, 0x8497, + 0x527A, 0x8498, + 0x527B, 0x8499, + 0x527C, 0x849A, + 0x527E, 0x849B, + 0x5280, 0x849C, + 0x5283, 0x849D, + 0x5284, 0x849E, + 0x5285, 0x849F, + 0x5286, 0x84A0, + 0x5287, 0x84A1, + 0x5289, 0x84A2, + 0x528A, 0x84A3, + 0x528B, 0x84A4, + 0x528C, 0x84A5, + 0x528D, 0x84A6, + 0x528E, 0x84A7, + 0x528F, 0x84A8, + 0x5291, 0x84A9, + 0x5292, 0x84AA, + 0x5294, 0x84AB, + 0x5295, 0x84AC, + 0x5296, 0x84AD, + 0x5297, 0x84AE, + 0x5298, 0x84AF, + 0x5299, 0x84B0, + 0x529A, 0x84B1, + 0x529C, 0x84B2, + 0x52A4, 0x84B3, + 0x52A5, 0x84B4, + 0x52A6, 0x84B5, + 0x52A7, 0x84B6, + 0x52AE, 0x84B7, + 0x52AF, 0x84B8, + 0x52B0, 0x84B9, + 0x52B4, 0x84BA, + 0x52B5, 0x84BB, + 0x52B6, 0x84BC, + 0x52B7, 0x84BD, + 0x52B8, 0x84BE, + 0x52B9, 0x84BF, + 0x52BA, 0x84C0, + 0x52BB, 0x84C1, + 0x52BC, 0x84C2, + 0x52BD, 0x84C3, + 0x52C0, 0x84C4, + 0x52C1, 0x84C5, + 0x52C2, 0x84C6, + 0x52C4, 0x84C7, + 0x52C5, 0x84C8, + 0x52C6, 0x84C9, + 0x52C8, 0x84CA, + 0x52CA, 0x84CB, + 0x52CC, 0x84CC, + 0x52CD, 0x84CD, + 0x52CE, 0x84CE, + 0x52CF, 0x84CF, + 0x52D1, 0x84D0, + 0x52D3, 0x84D1, + 0x52D4, 0x84D2, + 0x52D5, 0x84D3, + 0x52D7, 0x84D4, + 0x52D9, 0x84D5, + 0x52DA, 0x84D6, + 0x52DB, 0x84D7, + 0x52DC, 0x84D8, + 0x52DD, 0x84D9, + 0x52DE, 0x84DA, + 0x52E0, 0x84DB, + 0x52E1, 0x84DC, + 0x52E2, 0x84DD, + 0x52E3, 0x84DE, + 0x52E5, 0x84DF, + 0x52E6, 0x84E0, + 0x52E7, 0x84E1, + 0x52E8, 0x84E2, + 0x52E9, 0x84E3, + 0x52EA, 0x84E4, + 0x52EB, 0x84E5, + 0x52EC, 0x84E6, + 0x52ED, 0x84E7, + 0x52EE, 0x84E8, + 0x52EF, 0x84E9, + 0x52F1, 0x84EA, + 0x52F2, 0x84EB, + 0x52F3, 0x84EC, + 0x52F4, 0x84ED, + 0x52F5, 0x84EE, + 0x52F6, 0x84EF, + 0x52F7, 0x84F0, + 0x52F8, 0x84F1, + 0x52FB, 0x84F2, + 0x52FC, 0x84F3, + 0x52FD, 0x84F4, + 0x5301, 0x84F5, + 0x5302, 0x84F6, + 0x5303, 0x84F7, + 0x5304, 0x84F8, + 0x5307, 0x84F9, + 0x5309, 0x84FA, + 0x530A, 0x84FB, + 0x530B, 0x84FC, + 0x530C, 0x84FD, + 0x530E, 0x84FE, + 0x5311, 0x8540, + 0x5312, 0x8541, + 0x5313, 0x8542, + 0x5314, 0x8543, + 0x5318, 0x8544, + 0x531B, 0x8545, + 0x531C, 0x8546, + 0x531E, 0x8547, + 0x531F, 0x8548, + 0x5322, 0x8549, + 0x5324, 0x854A, + 0x5325, 0x854B, + 0x5327, 0x854C, + 0x5328, 0x854D, + 0x5329, 0x854E, + 0x532B, 0x854F, + 0x532C, 0x8550, + 0x532D, 0x8551, + 0x532F, 0x8552, + 0x5330, 0x8553, + 0x5331, 0x8554, + 0x5332, 0x8555, + 0x5333, 0x8556, + 0x5334, 0x8557, + 0x5335, 0x8558, + 0x5336, 0x8559, + 0x5337, 0x855A, + 0x5338, 0x855B, + 0x533C, 0x855C, + 0x533D, 0x855D, + 0x5340, 0x855E, + 0x5342, 0x855F, + 0x5344, 0x8560, + 0x5346, 0x8561, + 0x534B, 0x8562, + 0x534C, 0x8563, + 0x534D, 0x8564, + 0x5350, 0x8565, + 0x5354, 0x8566, + 0x5358, 0x8567, + 0x5359, 0x8568, + 0x535B, 0x8569, + 0x535D, 0x856A, + 0x5365, 0x856B, + 0x5368, 0x856C, + 0x536A, 0x856D, + 0x536C, 0x856E, + 0x536D, 0x856F, + 0x5372, 0x8570, + 0x5376, 0x8571, + 0x5379, 0x8572, + 0x537B, 0x8573, + 0x537C, 0x8574, + 0x537D, 0x8575, + 0x537E, 0x8576, + 0x5380, 0x8577, + 0x5381, 0x8578, + 0x5383, 0x8579, + 0x5387, 0x857A, + 0x5388, 0x857B, + 0x538A, 0x857C, + 0x538E, 0x857D, + 0x538F, 0x857E, + 0x5390, 0x8580, + 0x5391, 0x8581, + 0x5392, 0x8582, + 0x5393, 0x8583, + 0x5394, 0x8584, + 0x5396, 0x8585, + 0x5397, 0x8586, + 0x5399, 0x8587, + 0x539B, 0x8588, + 0x539C, 0x8589, + 0x539E, 0x858A, + 0x53A0, 0x858B, + 0x53A1, 0x858C, + 0x53A4, 0x858D, + 0x53A7, 0x858E, + 0x53AA, 0x858F, + 0x53AB, 0x8590, + 0x53AC, 0x8591, + 0x53AD, 0x8592, + 0x53AF, 0x8593, + 0x53B0, 0x8594, + 0x53B1, 0x8595, + 0x53B2, 0x8596, + 0x53B3, 0x8597, + 0x53B4, 0x8598, + 0x53B5, 0x8599, + 0x53B7, 0x859A, + 0x53B8, 0x859B, + 0x53B9, 0x859C, + 0x53BA, 0x859D, + 0x53BC, 0x859E, + 0x53BD, 0x859F, + 0x53BE, 0x85A0, + 0x53C0, 0x85A1, + 0x53C3, 0x85A2, + 0x53C4, 0x85A3, + 0x53C5, 0x85A4, + 0x53C6, 0x85A5, + 0x53C7, 0x85A6, + 0x53CE, 0x85A7, + 0x53CF, 0x85A8, + 0x53D0, 0x85A9, + 0x53D2, 0x85AA, + 0x53D3, 0x85AB, + 0x53D5, 0x85AC, + 0x53DA, 0x85AD, + 0x53DC, 0x85AE, + 0x53DD, 0x85AF, + 0x53DE, 0x85B0, + 0x53E1, 0x85B1, + 0x53E2, 0x85B2, + 0x53E7, 0x85B3, + 0x53F4, 0x85B4, + 0x53FA, 0x85B5, + 0x53FE, 0x85B6, + 0x53FF, 0x85B7, + 0x5400, 0x85B8, + 0x5402, 0x85B9, + 0x5405, 0x85BA, + 0x5407, 0x85BB, + 0x540B, 0x85BC, + 0x5414, 0x85BD, + 0x5418, 0x85BE, + 0x5419, 0x85BF, + 0x541A, 0x85C0, + 0x541C, 0x85C1, + 0x5422, 0x85C2, + 0x5424, 0x85C3, + 0x5425, 0x85C4, + 0x542A, 0x85C5, + 0x5430, 0x85C6, + 0x5433, 0x85C7, + 0x5436, 0x85C8, + 0x5437, 0x85C9, + 0x543A, 0x85CA, + 0x543D, 0x85CB, + 0x543F, 0x85CC, + 0x5441, 0x85CD, + 0x5442, 0x85CE, + 0x5444, 0x85CF, + 0x5445, 0x85D0, + 0x5447, 0x85D1, + 0x5449, 0x85D2, + 0x544C, 0x85D3, + 0x544D, 0x85D4, + 0x544E, 0x85D5, + 0x544F, 0x85D6, + 0x5451, 0x85D7, + 0x545A, 0x85D8, + 0x545D, 0x85D9, + 0x545E, 0x85DA, + 0x545F, 0x85DB, + 0x5460, 0x85DC, + 0x5461, 0x85DD, + 0x5463, 0x85DE, + 0x5465, 0x85DF, + 0x5467, 0x85E0, + 0x5469, 0x85E1, + 0x546A, 0x85E2, + 0x546B, 0x85E3, + 0x546C, 0x85E4, + 0x546D, 0x85E5, + 0x546E, 0x85E6, + 0x546F, 0x85E7, + 0x5470, 0x85E8, + 0x5474, 0x85E9, + 0x5479, 0x85EA, + 0x547A, 0x85EB, + 0x547E, 0x85EC, + 0x547F, 0x85ED, + 0x5481, 0x85EE, + 0x5483, 0x85EF, + 0x5485, 0x85F0, + 0x5487, 0x85F1, + 0x5488, 0x85F2, + 0x5489, 0x85F3, + 0x548A, 0x85F4, + 0x548D, 0x85F5, + 0x5491, 0x85F6, + 0x5493, 0x85F7, + 0x5497, 0x85F8, + 0x5498, 0x85F9, + 0x549C, 0x85FA, + 0x549E, 0x85FB, + 0x549F, 0x85FC, + 0x54A0, 0x85FD, + 0x54A1, 0x85FE, + 0x54A2, 0x8640, + 0x54A5, 0x8641, + 0x54AE, 0x8642, + 0x54B0, 0x8643, + 0x54B2, 0x8644, + 0x54B5, 0x8645, + 0x54B6, 0x8646, + 0x54B7, 0x8647, + 0x54B9, 0x8648, + 0x54BA, 0x8649, + 0x54BC, 0x864A, + 0x54BE, 0x864B, + 0x54C3, 0x864C, + 0x54C5, 0x864D, + 0x54CA, 0x864E, + 0x54CB, 0x864F, + 0x54D6, 0x8650, + 0x54D8, 0x8651, + 0x54DB, 0x8652, + 0x54E0, 0x8653, + 0x54E1, 0x8654, + 0x54E2, 0x8655, + 0x54E3, 0x8656, + 0x54E4, 0x8657, + 0x54EB, 0x8658, + 0x54EC, 0x8659, + 0x54EF, 0x865A, + 0x54F0, 0x865B, + 0x54F1, 0x865C, + 0x54F4, 0x865D, + 0x54F5, 0x865E, + 0x54F6, 0x865F, + 0x54F7, 0x8660, + 0x54F8, 0x8661, + 0x54F9, 0x8662, + 0x54FB, 0x8663, + 0x54FE, 0x8664, + 0x5500, 0x8665, + 0x5502, 0x8666, + 0x5503, 0x8667, + 0x5504, 0x8668, + 0x5505, 0x8669, + 0x5508, 0x866A, + 0x550A, 0x866B, + 0x550B, 0x866C, + 0x550C, 0x866D, + 0x550D, 0x866E, + 0x550E, 0x866F, + 0x5512, 0x8670, + 0x5513, 0x8671, + 0x5515, 0x8672, + 0x5516, 0x8673, + 0x5517, 0x8674, + 0x5518, 0x8675, + 0x5519, 0x8676, + 0x551A, 0x8677, + 0x551C, 0x8678, + 0x551D, 0x8679, + 0x551E, 0x867A, + 0x551F, 0x867B, + 0x5521, 0x867C, + 0x5525, 0x867D, + 0x5526, 0x867E, + 0x5528, 0x8680, + 0x5529, 0x8681, + 0x552B, 0x8682, + 0x552D, 0x8683, + 0x5532, 0x8684, + 0x5534, 0x8685, + 0x5535, 0x8686, + 0x5536, 0x8687, + 0x5538, 0x8688, + 0x5539, 0x8689, + 0x553A, 0x868A, + 0x553B, 0x868B, + 0x553D, 0x868C, + 0x5540, 0x868D, + 0x5542, 0x868E, + 0x5545, 0x868F, + 0x5547, 0x8690, + 0x5548, 0x8691, + 0x554B, 0x8692, + 0x554C, 0x8693, + 0x554D, 0x8694, + 0x554E, 0x8695, + 0x554F, 0x8696, + 0x5551, 0x8697, + 0x5552, 0x8698, + 0x5553, 0x8699, + 0x5554, 0x869A, + 0x5557, 0x869B, + 0x5558, 0x869C, + 0x5559, 0x869D, + 0x555A, 0x869E, + 0x555B, 0x869F, + 0x555D, 0x86A0, + 0x555E, 0x86A1, + 0x555F, 0x86A2, + 0x5560, 0x86A3, + 0x5562, 0x86A4, + 0x5563, 0x86A5, + 0x5568, 0x86A6, + 0x5569, 0x86A7, + 0x556B, 0x86A8, + 0x556F, 0x86A9, + 0x5570, 0x86AA, + 0x5571, 0x86AB, + 0x5572, 0x86AC, + 0x5573, 0x86AD, + 0x5574, 0x86AE, + 0x5579, 0x86AF, + 0x557A, 0x86B0, + 0x557D, 0x86B1, + 0x557F, 0x86B2, + 0x5585, 0x86B3, + 0x5586, 0x86B4, + 0x558C, 0x86B5, + 0x558D, 0x86B6, + 0x558E, 0x86B7, + 0x5590, 0x86B8, + 0x5592, 0x86B9, + 0x5593, 0x86BA, + 0x5595, 0x86BB, + 0x5596, 0x86BC, + 0x5597, 0x86BD, + 0x559A, 0x86BE, + 0x559B, 0x86BF, + 0x559E, 0x86C0, + 0x55A0, 0x86C1, + 0x55A1, 0x86C2, + 0x55A2, 0x86C3, + 0x55A3, 0x86C4, + 0x55A4, 0x86C5, + 0x55A5, 0x86C6, + 0x55A6, 0x86C7, + 0x55A8, 0x86C8, + 0x55A9, 0x86C9, + 0x55AA, 0x86CA, + 0x55AB, 0x86CB, + 0x55AC, 0x86CC, + 0x55AD, 0x86CD, + 0x55AE, 0x86CE, + 0x55AF, 0x86CF, + 0x55B0, 0x86D0, + 0x55B2, 0x86D1, + 0x55B4, 0x86D2, + 0x55B6, 0x86D3, + 0x55B8, 0x86D4, + 0x55BA, 0x86D5, + 0x55BC, 0x86D6, + 0x55BF, 0x86D7, + 0x55C0, 0x86D8, + 0x55C1, 0x86D9, + 0x55C2, 0x86DA, + 0x55C3, 0x86DB, + 0x55C6, 0x86DC, + 0x55C7, 0x86DD, + 0x55C8, 0x86DE, + 0x55CA, 0x86DF, + 0x55CB, 0x86E0, + 0x55CE, 0x86E1, + 0x55CF, 0x86E2, + 0x55D0, 0x86E3, + 0x55D5, 0x86E4, + 0x55D7, 0x86E5, + 0x55D8, 0x86E6, + 0x55D9, 0x86E7, + 0x55DA, 0x86E8, + 0x55DB, 0x86E9, + 0x55DE, 0x86EA, + 0x55E0, 0x86EB, + 0x55E2, 0x86EC, + 0x55E7, 0x86ED, + 0x55E9, 0x86EE, + 0x55ED, 0x86EF, + 0x55EE, 0x86F0, + 0x55F0, 0x86F1, + 0x55F1, 0x86F2, + 0x55F4, 0x86F3, + 0x55F6, 0x86F4, + 0x55F8, 0x86F5, + 0x55F9, 0x86F6, + 0x55FA, 0x86F7, + 0x55FB, 0x86F8, + 0x55FC, 0x86F9, + 0x55FF, 0x86FA, + 0x5602, 0x86FB, + 0x5603, 0x86FC, + 0x5604, 0x86FD, + 0x5605, 0x86FE, + 0x5606, 0x8740, + 0x5607, 0x8741, + 0x560A, 0x8742, + 0x560B, 0x8743, + 0x560D, 0x8744, + 0x5610, 0x8745, + 0x5611, 0x8746, + 0x5612, 0x8747, + 0x5613, 0x8748, + 0x5614, 0x8749, + 0x5615, 0x874A, + 0x5616, 0x874B, + 0x5617, 0x874C, + 0x5619, 0x874D, + 0x561A, 0x874E, + 0x561C, 0x874F, + 0x561D, 0x8750, + 0x5620, 0x8751, + 0x5621, 0x8752, + 0x5622, 0x8753, + 0x5625, 0x8754, + 0x5626, 0x8755, + 0x5628, 0x8756, + 0x5629, 0x8757, + 0x562A, 0x8758, + 0x562B, 0x8759, + 0x562E, 0x875A, + 0x562F, 0x875B, + 0x5630, 0x875C, + 0x5633, 0x875D, + 0x5635, 0x875E, + 0x5637, 0x875F, + 0x5638, 0x8760, + 0x563A, 0x8761, + 0x563C, 0x8762, + 0x563D, 0x8763, + 0x563E, 0x8764, + 0x5640, 0x8765, + 0x5641, 0x8766, + 0x5642, 0x8767, + 0x5643, 0x8768, + 0x5644, 0x8769, + 0x5645, 0x876A, + 0x5646, 0x876B, + 0x5647, 0x876C, + 0x5648, 0x876D, + 0x5649, 0x876E, + 0x564A, 0x876F, + 0x564B, 0x8770, + 0x564F, 0x8771, + 0x5650, 0x8772, + 0x5651, 0x8773, + 0x5652, 0x8774, + 0x5653, 0x8775, + 0x5655, 0x8776, + 0x5656, 0x8777, + 0x565A, 0x8778, + 0x565B, 0x8779, + 0x565D, 0x877A, + 0x565E, 0x877B, + 0x565F, 0x877C, + 0x5660, 0x877D, + 0x5661, 0x877E, + 0x5663, 0x8780, + 0x5665, 0x8781, + 0x5666, 0x8782, + 0x5667, 0x8783, + 0x566D, 0x8784, + 0x566E, 0x8785, + 0x566F, 0x8786, + 0x5670, 0x8787, + 0x5672, 0x8788, + 0x5673, 0x8789, + 0x5674, 0x878A, + 0x5675, 0x878B, + 0x5677, 0x878C, + 0x5678, 0x878D, + 0x5679, 0x878E, + 0x567A, 0x878F, + 0x567D, 0x8790, + 0x567E, 0x8791, + 0x567F, 0x8792, + 0x5680, 0x8793, + 0x5681, 0x8794, + 0x5682, 0x8795, + 0x5683, 0x8796, + 0x5684, 0x8797, + 0x5687, 0x8798, + 0x5688, 0x8799, + 0x5689, 0x879A, + 0x568A, 0x879B, + 0x568B, 0x879C, + 0x568C, 0x879D, + 0x568D, 0x879E, + 0x5690, 0x879F, + 0x5691, 0x87A0, + 0x5692, 0x87A1, + 0x5694, 0x87A2, + 0x5695, 0x87A3, + 0x5696, 0x87A4, + 0x5697, 0x87A5, + 0x5698, 0x87A6, + 0x5699, 0x87A7, + 0x569A, 0x87A8, + 0x569B, 0x87A9, + 0x569C, 0x87AA, + 0x569D, 0x87AB, + 0x569E, 0x87AC, + 0x569F, 0x87AD, + 0x56A0, 0x87AE, + 0x56A1, 0x87AF, + 0x56A2, 0x87B0, + 0x56A4, 0x87B1, + 0x56A5, 0x87B2, + 0x56A6, 0x87B3, + 0x56A7, 0x87B4, + 0x56A8, 0x87B5, + 0x56A9, 0x87B6, + 0x56AA, 0x87B7, + 0x56AB, 0x87B8, + 0x56AC, 0x87B9, + 0x56AD, 0x87BA, + 0x56AE, 0x87BB, + 0x56B0, 0x87BC, + 0x56B1, 0x87BD, + 0x56B2, 0x87BE, + 0x56B3, 0x87BF, + 0x56B4, 0x87C0, + 0x56B5, 0x87C1, + 0x56B6, 0x87C2, + 0x56B8, 0x87C3, + 0x56B9, 0x87C4, + 0x56BA, 0x87C5, + 0x56BB, 0x87C6, + 0x56BD, 0x87C7, + 0x56BE, 0x87C8, + 0x56BF, 0x87C9, + 0x56C0, 0x87CA, + 0x56C1, 0x87CB, + 0x56C2, 0x87CC, + 0x56C3, 0x87CD, + 0x56C4, 0x87CE, + 0x56C5, 0x87CF, + 0x56C6, 0x87D0, + 0x56C7, 0x87D1, + 0x56C8, 0x87D2, + 0x56C9, 0x87D3, + 0x56CB, 0x87D4, + 0x56CC, 0x87D5, + 0x56CD, 0x87D6, + 0x56CE, 0x87D7, + 0x56CF, 0x87D8, + 0x56D0, 0x87D9, + 0x56D1, 0x87DA, + 0x56D2, 0x87DB, + 0x56D3, 0x87DC, + 0x56D5, 0x87DD, + 0x56D6, 0x87DE, + 0x56D8, 0x87DF, + 0x56D9, 0x87E0, + 0x56DC, 0x87E1, + 0x56E3, 0x87E2, + 0x56E5, 0x87E3, + 0x56E6, 0x87E4, + 0x56E7, 0x87E5, + 0x56E8, 0x87E6, + 0x56E9, 0x87E7, + 0x56EA, 0x87E8, + 0x56EC, 0x87E9, + 0x56EE, 0x87EA, + 0x56EF, 0x87EB, + 0x56F2, 0x87EC, + 0x56F3, 0x87ED, + 0x56F6, 0x87EE, + 0x56F7, 0x87EF, + 0x56F8, 0x87F0, + 0x56FB, 0x87F1, + 0x56FC, 0x87F2, + 0x5700, 0x87F3, + 0x5701, 0x87F4, + 0x5702, 0x87F5, + 0x5705, 0x87F6, + 0x5707, 0x87F7, + 0x570B, 0x87F8, + 0x570C, 0x87F9, + 0x570D, 0x87FA, + 0x570E, 0x87FB, + 0x570F, 0x87FC, + 0x5710, 0x87FD, + 0x5711, 0x87FE, + 0x5712, 0x8840, + 0x5713, 0x8841, + 0x5714, 0x8842, + 0x5715, 0x8843, + 0x5716, 0x8844, + 0x5717, 0x8845, + 0x5718, 0x8846, + 0x5719, 0x8847, + 0x571A, 0x8848, + 0x571B, 0x8849, + 0x571D, 0x884A, + 0x571E, 0x884B, + 0x5720, 0x884C, + 0x5721, 0x884D, + 0x5722, 0x884E, + 0x5724, 0x884F, + 0x5725, 0x8850, + 0x5726, 0x8851, + 0x5727, 0x8852, + 0x572B, 0x8853, + 0x5731, 0x8854, + 0x5732, 0x8855, + 0x5734, 0x8856, + 0x5735, 0x8857, + 0x5736, 0x8858, + 0x5737, 0x8859, + 0x5738, 0x885A, + 0x573C, 0x885B, + 0x573D, 0x885C, + 0x573F, 0x885D, + 0x5741, 0x885E, + 0x5743, 0x885F, + 0x5744, 0x8860, + 0x5745, 0x8861, + 0x5746, 0x8862, + 0x5748, 0x8863, + 0x5749, 0x8864, + 0x574B, 0x8865, + 0x5752, 0x8866, + 0x5753, 0x8867, + 0x5754, 0x8868, + 0x5755, 0x8869, + 0x5756, 0x886A, + 0x5758, 0x886B, + 0x5759, 0x886C, + 0x5762, 0x886D, + 0x5763, 0x886E, + 0x5765, 0x886F, + 0x5767, 0x8870, + 0x576C, 0x8871, + 0x576E, 0x8872, + 0x5770, 0x8873, + 0x5771, 0x8874, + 0x5772, 0x8875, + 0x5774, 0x8876, + 0x5775, 0x8877, + 0x5778, 0x8878, + 0x5779, 0x8879, + 0x577A, 0x887A, + 0x577D, 0x887B, + 0x577E, 0x887C, + 0x577F, 0x887D, + 0x5780, 0x887E, + 0x5781, 0x8880, + 0x5787, 0x8881, + 0x5788, 0x8882, + 0x5789, 0x8883, + 0x578A, 0x8884, + 0x578D, 0x8885, + 0x578E, 0x8886, + 0x578F, 0x8887, + 0x5790, 0x8888, + 0x5791, 0x8889, + 0x5794, 0x888A, + 0x5795, 0x888B, + 0x5796, 0x888C, + 0x5797, 0x888D, + 0x5798, 0x888E, + 0x5799, 0x888F, + 0x579A, 0x8890, + 0x579C, 0x8891, + 0x579D, 0x8892, + 0x579E, 0x8893, + 0x579F, 0x8894, + 0x57A5, 0x8895, + 0x57A8, 0x8896, + 0x57AA, 0x8897, + 0x57AC, 0x8898, + 0x57AF, 0x8899, + 0x57B0, 0x889A, + 0x57B1, 0x889B, + 0x57B3, 0x889C, + 0x57B5, 0x889D, + 0x57B6, 0x889E, + 0x57B7, 0x889F, + 0x57B9, 0x88A0, + 0x57BA, 0x88A1, + 0x57BB, 0x88A2, + 0x57BC, 0x88A3, + 0x57BD, 0x88A4, + 0x57BE, 0x88A5, + 0x57BF, 0x88A6, + 0x57C0, 0x88A7, + 0x57C1, 0x88A8, + 0x57C4, 0x88A9, + 0x57C5, 0x88AA, + 0x57C6, 0x88AB, + 0x57C7, 0x88AC, + 0x57C8, 0x88AD, + 0x57C9, 0x88AE, + 0x57CA, 0x88AF, + 0x57CC, 0x88B0, + 0x57CD, 0x88B1, + 0x57D0, 0x88B2, + 0x57D1, 0x88B3, + 0x57D3, 0x88B4, + 0x57D6, 0x88B5, + 0x57D7, 0x88B6, + 0x57DB, 0x88B7, + 0x57DC, 0x88B8, + 0x57DE, 0x88B9, + 0x57E1, 0x88BA, + 0x57E2, 0x88BB, + 0x57E3, 0x88BC, + 0x57E5, 0x88BD, + 0x57E6, 0x88BE, + 0x57E7, 0x88BF, + 0x57E8, 0x88C0, + 0x57E9, 0x88C1, + 0x57EA, 0x88C2, + 0x57EB, 0x88C3, + 0x57EC, 0x88C4, + 0x57EE, 0x88C5, + 0x57F0, 0x88C6, + 0x57F1, 0x88C7, + 0x57F2, 0x88C8, + 0x57F3, 0x88C9, + 0x57F5, 0x88CA, + 0x57F6, 0x88CB, + 0x57F7, 0x88CC, + 0x57FB, 0x88CD, + 0x57FC, 0x88CE, + 0x57FE, 0x88CF, + 0x57FF, 0x88D0, + 0x5801, 0x88D1, + 0x5803, 0x88D2, + 0x5804, 0x88D3, + 0x5805, 0x88D4, + 0x5808, 0x88D5, + 0x5809, 0x88D6, + 0x580A, 0x88D7, + 0x580C, 0x88D8, + 0x580E, 0x88D9, + 0x580F, 0x88DA, + 0x5810, 0x88DB, + 0x5812, 0x88DC, + 0x5813, 0x88DD, + 0x5814, 0x88DE, + 0x5816, 0x88DF, + 0x5817, 0x88E0, + 0x5818, 0x88E1, + 0x581A, 0x88E2, + 0x581B, 0x88E3, + 0x581C, 0x88E4, + 0x581D, 0x88E5, + 0x581F, 0x88E6, + 0x5822, 0x88E7, + 0x5823, 0x88E8, + 0x5825, 0x88E9, + 0x5826, 0x88EA, + 0x5827, 0x88EB, + 0x5828, 0x88EC, + 0x5829, 0x88ED, + 0x582B, 0x88EE, + 0x582C, 0x88EF, + 0x582D, 0x88F0, + 0x582E, 0x88F1, + 0x582F, 0x88F2, + 0x5831, 0x88F3, + 0x5832, 0x88F4, + 0x5833, 0x88F5, + 0x5834, 0x88F6, + 0x5836, 0x88F7, + 0x5837, 0x88F8, + 0x5838, 0x88F9, + 0x5839, 0x88FA, + 0x583A, 0x88FB, + 0x583B, 0x88FC, + 0x583C, 0x88FD, + 0x583D, 0x88FE, + 0x583E, 0x8940, + 0x583F, 0x8941, + 0x5840, 0x8942, + 0x5841, 0x8943, + 0x5842, 0x8944, + 0x5843, 0x8945, + 0x5845, 0x8946, + 0x5846, 0x8947, + 0x5847, 0x8948, + 0x5848, 0x8949, + 0x5849, 0x894A, + 0x584A, 0x894B, + 0x584B, 0x894C, + 0x584E, 0x894D, + 0x584F, 0x894E, + 0x5850, 0x894F, + 0x5852, 0x8950, + 0x5853, 0x8951, + 0x5855, 0x8952, + 0x5856, 0x8953, + 0x5857, 0x8954, + 0x5859, 0x8955, + 0x585A, 0x8956, + 0x585B, 0x8957, + 0x585C, 0x8958, + 0x585D, 0x8959, + 0x585F, 0x895A, + 0x5860, 0x895B, + 0x5861, 0x895C, + 0x5862, 0x895D, + 0x5863, 0x895E, + 0x5864, 0x895F, + 0x5866, 0x8960, + 0x5867, 0x8961, + 0x5868, 0x8962, + 0x5869, 0x8963, + 0x586A, 0x8964, + 0x586D, 0x8965, + 0x586E, 0x8966, + 0x586F, 0x8967, + 0x5870, 0x8968, + 0x5871, 0x8969, + 0x5872, 0x896A, + 0x5873, 0x896B, + 0x5874, 0x896C, + 0x5875, 0x896D, + 0x5876, 0x896E, + 0x5877, 0x896F, + 0x5878, 0x8970, + 0x5879, 0x8971, + 0x587A, 0x8972, + 0x587B, 0x8973, + 0x587C, 0x8974, + 0x587D, 0x8975, + 0x587F, 0x8976, + 0x5882, 0x8977, + 0x5884, 0x8978, + 0x5886, 0x8979, + 0x5887, 0x897A, + 0x5888, 0x897B, + 0x588A, 0x897C, + 0x588B, 0x897D, + 0x588C, 0x897E, + 0x588D, 0x8980, + 0x588E, 0x8981, + 0x588F, 0x8982, + 0x5890, 0x8983, + 0x5891, 0x8984, + 0x5894, 0x8985, + 0x5895, 0x8986, + 0x5896, 0x8987, + 0x5897, 0x8988, + 0x5898, 0x8989, + 0x589B, 0x898A, + 0x589C, 0x898B, + 0x589D, 0x898C, + 0x58A0, 0x898D, + 0x58A1, 0x898E, + 0x58A2, 0x898F, + 0x58A3, 0x8990, + 0x58A4, 0x8991, + 0x58A5, 0x8992, + 0x58A6, 0x8993, + 0x58A7, 0x8994, + 0x58AA, 0x8995, + 0x58AB, 0x8996, + 0x58AC, 0x8997, + 0x58AD, 0x8998, + 0x58AE, 0x8999, + 0x58AF, 0x899A, + 0x58B0, 0x899B, + 0x58B1, 0x899C, + 0x58B2, 0x899D, + 0x58B3, 0x899E, + 0x58B4, 0x899F, + 0x58B5, 0x89A0, + 0x58B6, 0x89A1, + 0x58B7, 0x89A2, + 0x58B8, 0x89A3, + 0x58B9, 0x89A4, + 0x58BA, 0x89A5, + 0x58BB, 0x89A6, + 0x58BD, 0x89A7, + 0x58BE, 0x89A8, + 0x58BF, 0x89A9, + 0x58C0, 0x89AA, + 0x58C2, 0x89AB, + 0x58C3, 0x89AC, + 0x58C4, 0x89AD, + 0x58C6, 0x89AE, + 0x58C7, 0x89AF, + 0x58C8, 0x89B0, + 0x58C9, 0x89B1, + 0x58CA, 0x89B2, + 0x58CB, 0x89B3, + 0x58CC, 0x89B4, + 0x58CD, 0x89B5, + 0x58CE, 0x89B6, + 0x58CF, 0x89B7, + 0x58D0, 0x89B8, + 0x58D2, 0x89B9, + 0x58D3, 0x89BA, + 0x58D4, 0x89BB, + 0x58D6, 0x89BC, + 0x58D7, 0x89BD, + 0x58D8, 0x89BE, + 0x58D9, 0x89BF, + 0x58DA, 0x89C0, + 0x58DB, 0x89C1, + 0x58DC, 0x89C2, + 0x58DD, 0x89C3, + 0x58DE, 0x89C4, + 0x58DF, 0x89C5, + 0x58E0, 0x89C6, + 0x58E1, 0x89C7, + 0x58E2, 0x89C8, + 0x58E3, 0x89C9, + 0x58E5, 0x89CA, + 0x58E6, 0x89CB, + 0x58E7, 0x89CC, + 0x58E8, 0x89CD, + 0x58E9, 0x89CE, + 0x58EA, 0x89CF, + 0x58ED, 0x89D0, + 0x58EF, 0x89D1, + 0x58F1, 0x89D2, + 0x58F2, 0x89D3, + 0x58F4, 0x89D4, + 0x58F5, 0x89D5, + 0x58F7, 0x89D6, + 0x58F8, 0x89D7, + 0x58FA, 0x89D8, + 0x58FB, 0x89D9, + 0x58FC, 0x89DA, + 0x58FD, 0x89DB, + 0x58FE, 0x89DC, + 0x58FF, 0x89DD, + 0x5900, 0x89DE, + 0x5901, 0x89DF, + 0x5903, 0x89E0, + 0x5905, 0x89E1, + 0x5906, 0x89E2, + 0x5908, 0x89E3, + 0x5909, 0x89E4, + 0x590A, 0x89E5, + 0x590B, 0x89E6, + 0x590C, 0x89E7, + 0x590E, 0x89E8, + 0x5910, 0x89E9, + 0x5911, 0x89EA, + 0x5912, 0x89EB, + 0x5913, 0x89EC, + 0x5917, 0x89ED, + 0x5918, 0x89EE, + 0x591B, 0x89EF, + 0x591D, 0x89F0, + 0x591E, 0x89F1, + 0x5920, 0x89F2, + 0x5921, 0x89F3, + 0x5922, 0x89F4, + 0x5923, 0x89F5, + 0x5926, 0x89F6, + 0x5928, 0x89F7, + 0x592C, 0x89F8, + 0x5930, 0x89F9, + 0x5932, 0x89FA, + 0x5933, 0x89FB, + 0x5935, 0x89FC, + 0x5936, 0x89FD, + 0x593B, 0x89FE, + 0x593D, 0x8A40, + 0x593E, 0x8A41, + 0x593F, 0x8A42, + 0x5940, 0x8A43, + 0x5943, 0x8A44, + 0x5945, 0x8A45, + 0x5946, 0x8A46, + 0x594A, 0x8A47, + 0x594C, 0x8A48, + 0x594D, 0x8A49, + 0x5950, 0x8A4A, + 0x5952, 0x8A4B, + 0x5953, 0x8A4C, + 0x5959, 0x8A4D, + 0x595B, 0x8A4E, + 0x595C, 0x8A4F, + 0x595D, 0x8A50, + 0x595E, 0x8A51, + 0x595F, 0x8A52, + 0x5961, 0x8A53, + 0x5963, 0x8A54, + 0x5964, 0x8A55, + 0x5966, 0x8A56, + 0x5967, 0x8A57, + 0x5968, 0x8A58, + 0x5969, 0x8A59, + 0x596A, 0x8A5A, + 0x596B, 0x8A5B, + 0x596C, 0x8A5C, + 0x596D, 0x8A5D, + 0x596E, 0x8A5E, + 0x596F, 0x8A5F, + 0x5970, 0x8A60, + 0x5971, 0x8A61, + 0x5972, 0x8A62, + 0x5975, 0x8A63, + 0x5977, 0x8A64, + 0x597A, 0x8A65, + 0x597B, 0x8A66, + 0x597C, 0x8A67, + 0x597E, 0x8A68, + 0x597F, 0x8A69, + 0x5980, 0x8A6A, + 0x5985, 0x8A6B, + 0x5989, 0x8A6C, + 0x598B, 0x8A6D, + 0x598C, 0x8A6E, + 0x598E, 0x8A6F, + 0x598F, 0x8A70, + 0x5990, 0x8A71, + 0x5991, 0x8A72, + 0x5994, 0x8A73, + 0x5995, 0x8A74, + 0x5998, 0x8A75, + 0x599A, 0x8A76, + 0x599B, 0x8A77, + 0x599C, 0x8A78, + 0x599D, 0x8A79, + 0x599F, 0x8A7A, + 0x59A0, 0x8A7B, + 0x59A1, 0x8A7C, + 0x59A2, 0x8A7D, + 0x59A6, 0x8A7E, + 0x59A7, 0x8A80, + 0x59AC, 0x8A81, + 0x59AD, 0x8A82, + 0x59B0, 0x8A83, + 0x59B1, 0x8A84, + 0x59B3, 0x8A85, + 0x59B4, 0x8A86, + 0x59B5, 0x8A87, + 0x59B6, 0x8A88, + 0x59B7, 0x8A89, + 0x59B8, 0x8A8A, + 0x59BA, 0x8A8B, + 0x59BC, 0x8A8C, + 0x59BD, 0x8A8D, + 0x59BF, 0x8A8E, + 0x59C0, 0x8A8F, + 0x59C1, 0x8A90, + 0x59C2, 0x8A91, + 0x59C3, 0x8A92, + 0x59C4, 0x8A93, + 0x59C5, 0x8A94, + 0x59C7, 0x8A95, + 0x59C8, 0x8A96, + 0x59C9, 0x8A97, + 0x59CC, 0x8A98, + 0x59CD, 0x8A99, + 0x59CE, 0x8A9A, + 0x59CF, 0x8A9B, + 0x59D5, 0x8A9C, + 0x59D6, 0x8A9D, + 0x59D9, 0x8A9E, + 0x59DB, 0x8A9F, + 0x59DE, 0x8AA0, + 0x59DF, 0x8AA1, + 0x59E0, 0x8AA2, + 0x59E1, 0x8AA3, + 0x59E2, 0x8AA4, + 0x59E4, 0x8AA5, + 0x59E6, 0x8AA6, + 0x59E7, 0x8AA7, + 0x59E9, 0x8AA8, + 0x59EA, 0x8AA9, + 0x59EB, 0x8AAA, + 0x59ED, 0x8AAB, + 0x59EE, 0x8AAC, + 0x59EF, 0x8AAD, + 0x59F0, 0x8AAE, + 0x59F1, 0x8AAF, + 0x59F2, 0x8AB0, + 0x59F3, 0x8AB1, + 0x59F4, 0x8AB2, + 0x59F5, 0x8AB3, + 0x59F6, 0x8AB4, + 0x59F7, 0x8AB5, + 0x59F8, 0x8AB6, + 0x59FA, 0x8AB7, + 0x59FC, 0x8AB8, + 0x59FD, 0x8AB9, + 0x59FE, 0x8ABA, + 0x5A00, 0x8ABB, + 0x5A02, 0x8ABC, + 0x5A0A, 0x8ABD, + 0x5A0B, 0x8ABE, + 0x5A0D, 0x8ABF, + 0x5A0E, 0x8AC0, + 0x5A0F, 0x8AC1, + 0x5A10, 0x8AC2, + 0x5A12, 0x8AC3, + 0x5A14, 0x8AC4, + 0x5A15, 0x8AC5, + 0x5A16, 0x8AC6, + 0x5A17, 0x8AC7, + 0x5A19, 0x8AC8, + 0x5A1A, 0x8AC9, + 0x5A1B, 0x8ACA, + 0x5A1D, 0x8ACB, + 0x5A1E, 0x8ACC, + 0x5A21, 0x8ACD, + 0x5A22, 0x8ACE, + 0x5A24, 0x8ACF, + 0x5A26, 0x8AD0, + 0x5A27, 0x8AD1, + 0x5A28, 0x8AD2, + 0x5A2A, 0x8AD3, + 0x5A2B, 0x8AD4, + 0x5A2C, 0x8AD5, + 0x5A2D, 0x8AD6, + 0x5A2E, 0x8AD7, + 0x5A2F, 0x8AD8, + 0x5A30, 0x8AD9, + 0x5A33, 0x8ADA, + 0x5A35, 0x8ADB, + 0x5A37, 0x8ADC, + 0x5A38, 0x8ADD, + 0x5A39, 0x8ADE, + 0x5A3A, 0x8ADF, + 0x5A3B, 0x8AE0, + 0x5A3D, 0x8AE1, + 0x5A3E, 0x8AE2, + 0x5A3F, 0x8AE3, + 0x5A41, 0x8AE4, + 0x5A42, 0x8AE5, + 0x5A43, 0x8AE6, + 0x5A44, 0x8AE7, + 0x5A45, 0x8AE8, + 0x5A47, 0x8AE9, + 0x5A48, 0x8AEA, + 0x5A4B, 0x8AEB, + 0x5A4C, 0x8AEC, + 0x5A4D, 0x8AED, + 0x5A4E, 0x8AEE, + 0x5A4F, 0x8AEF, + 0x5A50, 0x8AF0, + 0x5A51, 0x8AF1, + 0x5A52, 0x8AF2, + 0x5A53, 0x8AF3, + 0x5A54, 0x8AF4, + 0x5A56, 0x8AF5, + 0x5A57, 0x8AF6, + 0x5A58, 0x8AF7, + 0x5A59, 0x8AF8, + 0x5A5B, 0x8AF9, + 0x5A5C, 0x8AFA, + 0x5A5D, 0x8AFB, + 0x5A5E, 0x8AFC, + 0x5A5F, 0x8AFD, + 0x5A60, 0x8AFE, + 0x5A61, 0x8B40, + 0x5A63, 0x8B41, + 0x5A64, 0x8B42, + 0x5A65, 0x8B43, + 0x5A66, 0x8B44, + 0x5A68, 0x8B45, + 0x5A69, 0x8B46, + 0x5A6B, 0x8B47, + 0x5A6C, 0x8B48, + 0x5A6D, 0x8B49, + 0x5A6E, 0x8B4A, + 0x5A6F, 0x8B4B, + 0x5A70, 0x8B4C, + 0x5A71, 0x8B4D, + 0x5A72, 0x8B4E, + 0x5A73, 0x8B4F, + 0x5A78, 0x8B50, + 0x5A79, 0x8B51, + 0x5A7B, 0x8B52, + 0x5A7C, 0x8B53, + 0x5A7D, 0x8B54, + 0x5A7E, 0x8B55, + 0x5A80, 0x8B56, + 0x5A81, 0x8B57, + 0x5A82, 0x8B58, + 0x5A83, 0x8B59, + 0x5A84, 0x8B5A, + 0x5A85, 0x8B5B, + 0x5A86, 0x8B5C, + 0x5A87, 0x8B5D, + 0x5A88, 0x8B5E, + 0x5A89, 0x8B5F, + 0x5A8A, 0x8B60, + 0x5A8B, 0x8B61, + 0x5A8C, 0x8B62, + 0x5A8D, 0x8B63, + 0x5A8E, 0x8B64, + 0x5A8F, 0x8B65, + 0x5A90, 0x8B66, + 0x5A91, 0x8B67, + 0x5A93, 0x8B68, + 0x5A94, 0x8B69, + 0x5A95, 0x8B6A, + 0x5A96, 0x8B6B, + 0x5A97, 0x8B6C, + 0x5A98, 0x8B6D, + 0x5A99, 0x8B6E, + 0x5A9C, 0x8B6F, + 0x5A9D, 0x8B70, + 0x5A9E, 0x8B71, + 0x5A9F, 0x8B72, + 0x5AA0, 0x8B73, + 0x5AA1, 0x8B74, + 0x5AA2, 0x8B75, + 0x5AA3, 0x8B76, + 0x5AA4, 0x8B77, + 0x5AA5, 0x8B78, + 0x5AA6, 0x8B79, + 0x5AA7, 0x8B7A, + 0x5AA8, 0x8B7B, + 0x5AA9, 0x8B7C, + 0x5AAB, 0x8B7D, + 0x5AAC, 0x8B7E, + 0x5AAD, 0x8B80, + 0x5AAE, 0x8B81, + 0x5AAF, 0x8B82, + 0x5AB0, 0x8B83, + 0x5AB1, 0x8B84, + 0x5AB4, 0x8B85, + 0x5AB6, 0x8B86, + 0x5AB7, 0x8B87, + 0x5AB9, 0x8B88, + 0x5ABA, 0x8B89, + 0x5ABB, 0x8B8A, + 0x5ABC, 0x8B8B, + 0x5ABD, 0x8B8C, + 0x5ABF, 0x8B8D, + 0x5AC0, 0x8B8E, + 0x5AC3, 0x8B8F, + 0x5AC4, 0x8B90, + 0x5AC5, 0x8B91, + 0x5AC6, 0x8B92, + 0x5AC7, 0x8B93, + 0x5AC8, 0x8B94, + 0x5ACA, 0x8B95, + 0x5ACB, 0x8B96, + 0x5ACD, 0x8B97, + 0x5ACE, 0x8B98, + 0x5ACF, 0x8B99, + 0x5AD0, 0x8B9A, + 0x5AD1, 0x8B9B, + 0x5AD3, 0x8B9C, + 0x5AD5, 0x8B9D, + 0x5AD7, 0x8B9E, + 0x5AD9, 0x8B9F, + 0x5ADA, 0x8BA0, + 0x5ADB, 0x8BA1, + 0x5ADD, 0x8BA2, + 0x5ADE, 0x8BA3, + 0x5ADF, 0x8BA4, + 0x5AE2, 0x8BA5, + 0x5AE4, 0x8BA6, + 0x5AE5, 0x8BA7, + 0x5AE7, 0x8BA8, + 0x5AE8, 0x8BA9, + 0x5AEA, 0x8BAA, + 0x5AEC, 0x8BAB, + 0x5AED, 0x8BAC, + 0x5AEE, 0x8BAD, + 0x5AEF, 0x8BAE, + 0x5AF0, 0x8BAF, + 0x5AF2, 0x8BB0, + 0x5AF3, 0x8BB1, + 0x5AF4, 0x8BB2, + 0x5AF5, 0x8BB3, + 0x5AF6, 0x8BB4, + 0x5AF7, 0x8BB5, + 0x5AF8, 0x8BB6, + 0x5AF9, 0x8BB7, + 0x5AFA, 0x8BB8, + 0x5AFB, 0x8BB9, + 0x5AFC, 0x8BBA, + 0x5AFD, 0x8BBB, + 0x5AFE, 0x8BBC, + 0x5AFF, 0x8BBD, + 0x5B00, 0x8BBE, + 0x5B01, 0x8BBF, + 0x5B02, 0x8BC0, + 0x5B03, 0x8BC1, + 0x5B04, 0x8BC2, + 0x5B05, 0x8BC3, + 0x5B06, 0x8BC4, + 0x5B07, 0x8BC5, + 0x5B08, 0x8BC6, + 0x5B0A, 0x8BC7, + 0x5B0B, 0x8BC8, + 0x5B0C, 0x8BC9, + 0x5B0D, 0x8BCA, + 0x5B0E, 0x8BCB, + 0x5B0F, 0x8BCC, + 0x5B10, 0x8BCD, + 0x5B11, 0x8BCE, + 0x5B12, 0x8BCF, + 0x5B13, 0x8BD0, + 0x5B14, 0x8BD1, + 0x5B15, 0x8BD2, + 0x5B18, 0x8BD3, + 0x5B19, 0x8BD4, + 0x5B1A, 0x8BD5, + 0x5B1B, 0x8BD6, + 0x5B1C, 0x8BD7, + 0x5B1D, 0x8BD8, + 0x5B1E, 0x8BD9, + 0x5B1F, 0x8BDA, + 0x5B20, 0x8BDB, + 0x5B21, 0x8BDC, + 0x5B22, 0x8BDD, + 0x5B23, 0x8BDE, + 0x5B24, 0x8BDF, + 0x5B25, 0x8BE0, + 0x5B26, 0x8BE1, + 0x5B27, 0x8BE2, + 0x5B28, 0x8BE3, + 0x5B29, 0x8BE4, + 0x5B2A, 0x8BE5, + 0x5B2B, 0x8BE6, + 0x5B2C, 0x8BE7, + 0x5B2D, 0x8BE8, + 0x5B2E, 0x8BE9, + 0x5B2F, 0x8BEA, + 0x5B30, 0x8BEB, + 0x5B31, 0x8BEC, + 0x5B33, 0x8BED, + 0x5B35, 0x8BEE, + 0x5B36, 0x8BEF, + 0x5B38, 0x8BF0, + 0x5B39, 0x8BF1, + 0x5B3A, 0x8BF2, + 0x5B3B, 0x8BF3, + 0x5B3C, 0x8BF4, + 0x5B3D, 0x8BF5, + 0x5B3E, 0x8BF6, + 0x5B3F, 0x8BF7, + 0x5B41, 0x8BF8, + 0x5B42, 0x8BF9, + 0x5B43, 0x8BFA, + 0x5B44, 0x8BFB, + 0x5B45, 0x8BFC, + 0x5B46, 0x8BFD, + 0x5B47, 0x8BFE, + 0x5B48, 0x8C40, + 0x5B49, 0x8C41, + 0x5B4A, 0x8C42, + 0x5B4B, 0x8C43, + 0x5B4C, 0x8C44, + 0x5B4D, 0x8C45, + 0x5B4E, 0x8C46, + 0x5B4F, 0x8C47, + 0x5B52, 0x8C48, + 0x5B56, 0x8C49, + 0x5B5E, 0x8C4A, + 0x5B60, 0x8C4B, + 0x5B61, 0x8C4C, + 0x5B67, 0x8C4D, + 0x5B68, 0x8C4E, + 0x5B6B, 0x8C4F, + 0x5B6D, 0x8C50, + 0x5B6E, 0x8C51, + 0x5B6F, 0x8C52, + 0x5B72, 0x8C53, + 0x5B74, 0x8C54, + 0x5B76, 0x8C55, + 0x5B77, 0x8C56, + 0x5B78, 0x8C57, + 0x5B79, 0x8C58, + 0x5B7B, 0x8C59, + 0x5B7C, 0x8C5A, + 0x5B7E, 0x8C5B, + 0x5B7F, 0x8C5C, + 0x5B82, 0x8C5D, + 0x5B86, 0x8C5E, + 0x5B8A, 0x8C5F, + 0x5B8D, 0x8C60, + 0x5B8E, 0x8C61, + 0x5B90, 0x8C62, + 0x5B91, 0x8C63, + 0x5B92, 0x8C64, + 0x5B94, 0x8C65, + 0x5B96, 0x8C66, + 0x5B9F, 0x8C67, + 0x5BA7, 0x8C68, + 0x5BA8, 0x8C69, + 0x5BA9, 0x8C6A, + 0x5BAC, 0x8C6B, + 0x5BAD, 0x8C6C, + 0x5BAE, 0x8C6D, + 0x5BAF, 0x8C6E, + 0x5BB1, 0x8C6F, + 0x5BB2, 0x8C70, + 0x5BB7, 0x8C71, + 0x5BBA, 0x8C72, + 0x5BBB, 0x8C73, + 0x5BBC, 0x8C74, + 0x5BC0, 0x8C75, + 0x5BC1, 0x8C76, + 0x5BC3, 0x8C77, + 0x5BC8, 0x8C78, + 0x5BC9, 0x8C79, + 0x5BCA, 0x8C7A, + 0x5BCB, 0x8C7B, + 0x5BCD, 0x8C7C, + 0x5BCE, 0x8C7D, + 0x5BCF, 0x8C7E, + 0x5BD1, 0x8C80, + 0x5BD4, 0x8C81, + 0x5BD5, 0x8C82, + 0x5BD6, 0x8C83, + 0x5BD7, 0x8C84, + 0x5BD8, 0x8C85, + 0x5BD9, 0x8C86, + 0x5BDA, 0x8C87, + 0x5BDB, 0x8C88, + 0x5BDC, 0x8C89, + 0x5BE0, 0x8C8A, + 0x5BE2, 0x8C8B, + 0x5BE3, 0x8C8C, + 0x5BE6, 0x8C8D, + 0x5BE7, 0x8C8E, + 0x5BE9, 0x8C8F, + 0x5BEA, 0x8C90, + 0x5BEB, 0x8C91, + 0x5BEC, 0x8C92, + 0x5BED, 0x8C93, + 0x5BEF, 0x8C94, + 0x5BF1, 0x8C95, + 0x5BF2, 0x8C96, + 0x5BF3, 0x8C97, + 0x5BF4, 0x8C98, + 0x5BF5, 0x8C99, + 0x5BF6, 0x8C9A, + 0x5BF7, 0x8C9B, + 0x5BFD, 0x8C9C, + 0x5BFE, 0x8C9D, + 0x5C00, 0x8C9E, + 0x5C02, 0x8C9F, + 0x5C03, 0x8CA0, + 0x5C05, 0x8CA1, + 0x5C07, 0x8CA2, + 0x5C08, 0x8CA3, + 0x5C0B, 0x8CA4, + 0x5C0C, 0x8CA5, + 0x5C0D, 0x8CA6, + 0x5C0E, 0x8CA7, + 0x5C10, 0x8CA8, + 0x5C12, 0x8CA9, + 0x5C13, 0x8CAA, + 0x5C17, 0x8CAB, + 0x5C19, 0x8CAC, + 0x5C1B, 0x8CAD, + 0x5C1E, 0x8CAE, + 0x5C1F, 0x8CAF, + 0x5C20, 0x8CB0, + 0x5C21, 0x8CB1, + 0x5C23, 0x8CB2, + 0x5C26, 0x8CB3, + 0x5C28, 0x8CB4, + 0x5C29, 0x8CB5, + 0x5C2A, 0x8CB6, + 0x5C2B, 0x8CB7, + 0x5C2D, 0x8CB8, + 0x5C2E, 0x8CB9, + 0x5C2F, 0x8CBA, + 0x5C30, 0x8CBB, + 0x5C32, 0x8CBC, + 0x5C33, 0x8CBD, + 0x5C35, 0x8CBE, + 0x5C36, 0x8CBF, + 0x5C37, 0x8CC0, + 0x5C43, 0x8CC1, + 0x5C44, 0x8CC2, + 0x5C46, 0x8CC3, + 0x5C47, 0x8CC4, + 0x5C4C, 0x8CC5, + 0x5C4D, 0x8CC6, + 0x5C52, 0x8CC7, + 0x5C53, 0x8CC8, + 0x5C54, 0x8CC9, + 0x5C56, 0x8CCA, + 0x5C57, 0x8CCB, + 0x5C58, 0x8CCC, + 0x5C5A, 0x8CCD, + 0x5C5B, 0x8CCE, + 0x5C5C, 0x8CCF, + 0x5C5D, 0x8CD0, + 0x5C5F, 0x8CD1, + 0x5C62, 0x8CD2, + 0x5C64, 0x8CD3, + 0x5C67, 0x8CD4, + 0x5C68, 0x8CD5, + 0x5C69, 0x8CD6, + 0x5C6A, 0x8CD7, + 0x5C6B, 0x8CD8, + 0x5C6C, 0x8CD9, + 0x5C6D, 0x8CDA, + 0x5C70, 0x8CDB, + 0x5C72, 0x8CDC, + 0x5C73, 0x8CDD, + 0x5C74, 0x8CDE, + 0x5C75, 0x8CDF, + 0x5C76, 0x8CE0, + 0x5C77, 0x8CE1, + 0x5C78, 0x8CE2, + 0x5C7B, 0x8CE3, + 0x5C7C, 0x8CE4, + 0x5C7D, 0x8CE5, + 0x5C7E, 0x8CE6, + 0x5C80, 0x8CE7, + 0x5C83, 0x8CE8, + 0x5C84, 0x8CE9, + 0x5C85, 0x8CEA, + 0x5C86, 0x8CEB, + 0x5C87, 0x8CEC, + 0x5C89, 0x8CED, + 0x5C8A, 0x8CEE, + 0x5C8B, 0x8CEF, + 0x5C8E, 0x8CF0, + 0x5C8F, 0x8CF1, + 0x5C92, 0x8CF2, + 0x5C93, 0x8CF3, + 0x5C95, 0x8CF4, + 0x5C9D, 0x8CF5, + 0x5C9E, 0x8CF6, + 0x5C9F, 0x8CF7, + 0x5CA0, 0x8CF8, + 0x5CA1, 0x8CF9, + 0x5CA4, 0x8CFA, + 0x5CA5, 0x8CFB, + 0x5CA6, 0x8CFC, + 0x5CA7, 0x8CFD, + 0x5CA8, 0x8CFE, + 0x5CAA, 0x8D40, + 0x5CAE, 0x8D41, + 0x5CAF, 0x8D42, + 0x5CB0, 0x8D43, + 0x5CB2, 0x8D44, + 0x5CB4, 0x8D45, + 0x5CB6, 0x8D46, + 0x5CB9, 0x8D47, + 0x5CBA, 0x8D48, + 0x5CBB, 0x8D49, + 0x5CBC, 0x8D4A, + 0x5CBE, 0x8D4B, + 0x5CC0, 0x8D4C, + 0x5CC2, 0x8D4D, + 0x5CC3, 0x8D4E, + 0x5CC5, 0x8D4F, + 0x5CC6, 0x8D50, + 0x5CC7, 0x8D51, + 0x5CC8, 0x8D52, + 0x5CC9, 0x8D53, + 0x5CCA, 0x8D54, + 0x5CCC, 0x8D55, + 0x5CCD, 0x8D56, + 0x5CCE, 0x8D57, + 0x5CCF, 0x8D58, + 0x5CD0, 0x8D59, + 0x5CD1, 0x8D5A, + 0x5CD3, 0x8D5B, + 0x5CD4, 0x8D5C, + 0x5CD5, 0x8D5D, + 0x5CD6, 0x8D5E, + 0x5CD7, 0x8D5F, + 0x5CD8, 0x8D60, + 0x5CDA, 0x8D61, + 0x5CDB, 0x8D62, + 0x5CDC, 0x8D63, + 0x5CDD, 0x8D64, + 0x5CDE, 0x8D65, + 0x5CDF, 0x8D66, + 0x5CE0, 0x8D67, + 0x5CE2, 0x8D68, + 0x5CE3, 0x8D69, + 0x5CE7, 0x8D6A, + 0x5CE9, 0x8D6B, + 0x5CEB, 0x8D6C, + 0x5CEC, 0x8D6D, + 0x5CEE, 0x8D6E, + 0x5CEF, 0x8D6F, + 0x5CF1, 0x8D70, + 0x5CF2, 0x8D71, + 0x5CF3, 0x8D72, + 0x5CF4, 0x8D73, + 0x5CF5, 0x8D74, + 0x5CF6, 0x8D75, + 0x5CF7, 0x8D76, + 0x5CF8, 0x8D77, + 0x5CF9, 0x8D78, + 0x5CFA, 0x8D79, + 0x5CFC, 0x8D7A, + 0x5CFD, 0x8D7B, + 0x5CFE, 0x8D7C, + 0x5CFF, 0x8D7D, + 0x5D00, 0x8D7E, + 0x5D01, 0x8D80, + 0x5D04, 0x8D81, + 0x5D05, 0x8D82, + 0x5D08, 0x8D83, + 0x5D09, 0x8D84, + 0x5D0A, 0x8D85, + 0x5D0B, 0x8D86, + 0x5D0C, 0x8D87, + 0x5D0D, 0x8D88, + 0x5D0F, 0x8D89, + 0x5D10, 0x8D8A, + 0x5D11, 0x8D8B, + 0x5D12, 0x8D8C, + 0x5D13, 0x8D8D, + 0x5D15, 0x8D8E, + 0x5D17, 0x8D8F, + 0x5D18, 0x8D90, + 0x5D19, 0x8D91, + 0x5D1A, 0x8D92, + 0x5D1C, 0x8D93, + 0x5D1D, 0x8D94, + 0x5D1F, 0x8D95, + 0x5D20, 0x8D96, + 0x5D21, 0x8D97, + 0x5D22, 0x8D98, + 0x5D23, 0x8D99, + 0x5D25, 0x8D9A, + 0x5D28, 0x8D9B, + 0x5D2A, 0x8D9C, + 0x5D2B, 0x8D9D, + 0x5D2C, 0x8D9E, + 0x5D2F, 0x8D9F, + 0x5D30, 0x8DA0, + 0x5D31, 0x8DA1, + 0x5D32, 0x8DA2, + 0x5D33, 0x8DA3, + 0x5D35, 0x8DA4, + 0x5D36, 0x8DA5, + 0x5D37, 0x8DA6, + 0x5D38, 0x8DA7, + 0x5D39, 0x8DA8, + 0x5D3A, 0x8DA9, + 0x5D3B, 0x8DAA, + 0x5D3C, 0x8DAB, + 0x5D3F, 0x8DAC, + 0x5D40, 0x8DAD, + 0x5D41, 0x8DAE, + 0x5D42, 0x8DAF, + 0x5D43, 0x8DB0, + 0x5D44, 0x8DB1, + 0x5D45, 0x8DB2, + 0x5D46, 0x8DB3, + 0x5D48, 0x8DB4, + 0x5D49, 0x8DB5, + 0x5D4D, 0x8DB6, + 0x5D4E, 0x8DB7, + 0x5D4F, 0x8DB8, + 0x5D50, 0x8DB9, + 0x5D51, 0x8DBA, + 0x5D52, 0x8DBB, + 0x5D53, 0x8DBC, + 0x5D54, 0x8DBD, + 0x5D55, 0x8DBE, + 0x5D56, 0x8DBF, + 0x5D57, 0x8DC0, + 0x5D59, 0x8DC1, + 0x5D5A, 0x8DC2, + 0x5D5C, 0x8DC3, + 0x5D5E, 0x8DC4, + 0x5D5F, 0x8DC5, + 0x5D60, 0x8DC6, + 0x5D61, 0x8DC7, + 0x5D62, 0x8DC8, + 0x5D63, 0x8DC9, + 0x5D64, 0x8DCA, + 0x5D65, 0x8DCB, + 0x5D66, 0x8DCC, + 0x5D67, 0x8DCD, + 0x5D68, 0x8DCE, + 0x5D6A, 0x8DCF, + 0x5D6D, 0x8DD0, + 0x5D6E, 0x8DD1, + 0x5D70, 0x8DD2, + 0x5D71, 0x8DD3, + 0x5D72, 0x8DD4, + 0x5D73, 0x8DD5, + 0x5D75, 0x8DD6, + 0x5D76, 0x8DD7, + 0x5D77, 0x8DD8, + 0x5D78, 0x8DD9, + 0x5D79, 0x8DDA, + 0x5D7A, 0x8DDB, + 0x5D7B, 0x8DDC, + 0x5D7C, 0x8DDD, + 0x5D7D, 0x8DDE, + 0x5D7E, 0x8DDF, + 0x5D7F, 0x8DE0, + 0x5D80, 0x8DE1, + 0x5D81, 0x8DE2, + 0x5D83, 0x8DE3, + 0x5D84, 0x8DE4, + 0x5D85, 0x8DE5, + 0x5D86, 0x8DE6, + 0x5D87, 0x8DE7, + 0x5D88, 0x8DE8, + 0x5D89, 0x8DE9, + 0x5D8A, 0x8DEA, + 0x5D8B, 0x8DEB, + 0x5D8C, 0x8DEC, + 0x5D8D, 0x8DED, + 0x5D8E, 0x8DEE, + 0x5D8F, 0x8DEF, + 0x5D90, 0x8DF0, + 0x5D91, 0x8DF1, + 0x5D92, 0x8DF2, + 0x5D93, 0x8DF3, + 0x5D94, 0x8DF4, + 0x5D95, 0x8DF5, + 0x5D96, 0x8DF6, + 0x5D97, 0x8DF7, + 0x5D98, 0x8DF8, + 0x5D9A, 0x8DF9, + 0x5D9B, 0x8DFA, + 0x5D9C, 0x8DFB, + 0x5D9E, 0x8DFC, + 0x5D9F, 0x8DFD, + 0x5DA0, 0x8DFE, + 0x5DA1, 0x8E40, + 0x5DA2, 0x8E41, + 0x5DA3, 0x8E42, + 0x5DA4, 0x8E43, + 0x5DA5, 0x8E44, + 0x5DA6, 0x8E45, + 0x5DA7, 0x8E46, + 0x5DA8, 0x8E47, + 0x5DA9, 0x8E48, + 0x5DAA, 0x8E49, + 0x5DAB, 0x8E4A, + 0x5DAC, 0x8E4B, + 0x5DAD, 0x8E4C, + 0x5DAE, 0x8E4D, + 0x5DAF, 0x8E4E, + 0x5DB0, 0x8E4F, + 0x5DB1, 0x8E50, + 0x5DB2, 0x8E51, + 0x5DB3, 0x8E52, + 0x5DB4, 0x8E53, + 0x5DB5, 0x8E54, + 0x5DB6, 0x8E55, + 0x5DB8, 0x8E56, + 0x5DB9, 0x8E57, + 0x5DBA, 0x8E58, + 0x5DBB, 0x8E59, + 0x5DBC, 0x8E5A, + 0x5DBD, 0x8E5B, + 0x5DBE, 0x8E5C, + 0x5DBF, 0x8E5D, + 0x5DC0, 0x8E5E, + 0x5DC1, 0x8E5F, + 0x5DC2, 0x8E60, + 0x5DC3, 0x8E61, + 0x5DC4, 0x8E62, + 0x5DC6, 0x8E63, + 0x5DC7, 0x8E64, + 0x5DC8, 0x8E65, + 0x5DC9, 0x8E66, + 0x5DCA, 0x8E67, + 0x5DCB, 0x8E68, + 0x5DCC, 0x8E69, + 0x5DCE, 0x8E6A, + 0x5DCF, 0x8E6B, + 0x5DD0, 0x8E6C, + 0x5DD1, 0x8E6D, + 0x5DD2, 0x8E6E, + 0x5DD3, 0x8E6F, + 0x5DD4, 0x8E70, + 0x5DD5, 0x8E71, + 0x5DD6, 0x8E72, + 0x5DD7, 0x8E73, + 0x5DD8, 0x8E74, + 0x5DD9, 0x8E75, + 0x5DDA, 0x8E76, + 0x5DDC, 0x8E77, + 0x5DDF, 0x8E78, + 0x5DE0, 0x8E79, + 0x5DE3, 0x8E7A, + 0x5DE4, 0x8E7B, + 0x5DEA, 0x8E7C, + 0x5DEC, 0x8E7D, + 0x5DED, 0x8E7E, + 0x5DF0, 0x8E80, + 0x5DF5, 0x8E81, + 0x5DF6, 0x8E82, + 0x5DF8, 0x8E83, + 0x5DF9, 0x8E84, + 0x5DFA, 0x8E85, + 0x5DFB, 0x8E86, + 0x5DFC, 0x8E87, + 0x5DFF, 0x8E88, + 0x5E00, 0x8E89, + 0x5E04, 0x8E8A, + 0x5E07, 0x8E8B, + 0x5E09, 0x8E8C, + 0x5E0A, 0x8E8D, + 0x5E0B, 0x8E8E, + 0x5E0D, 0x8E8F, + 0x5E0E, 0x8E90, + 0x5E12, 0x8E91, + 0x5E13, 0x8E92, + 0x5E17, 0x8E93, + 0x5E1E, 0x8E94, + 0x5E1F, 0x8E95, + 0x5E20, 0x8E96, + 0x5E21, 0x8E97, + 0x5E22, 0x8E98, + 0x5E23, 0x8E99, + 0x5E24, 0x8E9A, + 0x5E25, 0x8E9B, + 0x5E28, 0x8E9C, + 0x5E29, 0x8E9D, + 0x5E2A, 0x8E9E, + 0x5E2B, 0x8E9F, + 0x5E2C, 0x8EA0, + 0x5E2F, 0x8EA1, + 0x5E30, 0x8EA2, + 0x5E32, 0x8EA3, + 0x5E33, 0x8EA4, + 0x5E34, 0x8EA5, + 0x5E35, 0x8EA6, + 0x5E36, 0x8EA7, + 0x5E39, 0x8EA8, + 0x5E3A, 0x8EA9, + 0x5E3E, 0x8EAA, + 0x5E3F, 0x8EAB, + 0x5E40, 0x8EAC, + 0x5E41, 0x8EAD, + 0x5E43, 0x8EAE, + 0x5E46, 0x8EAF, + 0x5E47, 0x8EB0, + 0x5E48, 0x8EB1, + 0x5E49, 0x8EB2, + 0x5E4A, 0x8EB3, + 0x5E4B, 0x8EB4, + 0x5E4D, 0x8EB5, + 0x5E4E, 0x8EB6, + 0x5E4F, 0x8EB7, + 0x5E50, 0x8EB8, + 0x5E51, 0x8EB9, + 0x5E52, 0x8EBA, + 0x5E53, 0x8EBB, + 0x5E56, 0x8EBC, + 0x5E57, 0x8EBD, + 0x5E58, 0x8EBE, + 0x5E59, 0x8EBF, + 0x5E5A, 0x8EC0, + 0x5E5C, 0x8EC1, + 0x5E5D, 0x8EC2, + 0x5E5F, 0x8EC3, + 0x5E60, 0x8EC4, + 0x5E63, 0x8EC5, + 0x5E64, 0x8EC6, + 0x5E65, 0x8EC7, + 0x5E66, 0x8EC8, + 0x5E67, 0x8EC9, + 0x5E68, 0x8ECA, + 0x5E69, 0x8ECB, + 0x5E6A, 0x8ECC, + 0x5E6B, 0x8ECD, + 0x5E6C, 0x8ECE, + 0x5E6D, 0x8ECF, + 0x5E6E, 0x8ED0, + 0x5E6F, 0x8ED1, + 0x5E70, 0x8ED2, + 0x5E71, 0x8ED3, + 0x5E75, 0x8ED4, + 0x5E77, 0x8ED5, + 0x5E79, 0x8ED6, + 0x5E7E, 0x8ED7, + 0x5E81, 0x8ED8, + 0x5E82, 0x8ED9, + 0x5E83, 0x8EDA, + 0x5E85, 0x8EDB, + 0x5E88, 0x8EDC, + 0x5E89, 0x8EDD, + 0x5E8C, 0x8EDE, + 0x5E8D, 0x8EDF, + 0x5E8E, 0x8EE0, + 0x5E92, 0x8EE1, + 0x5E98, 0x8EE2, + 0x5E9B, 0x8EE3, + 0x5E9D, 0x8EE4, + 0x5EA1, 0x8EE5, + 0x5EA2, 0x8EE6, + 0x5EA3, 0x8EE7, + 0x5EA4, 0x8EE8, + 0x5EA8, 0x8EE9, + 0x5EA9, 0x8EEA, + 0x5EAA, 0x8EEB, + 0x5EAB, 0x8EEC, + 0x5EAC, 0x8EED, + 0x5EAE, 0x8EEE, + 0x5EAF, 0x8EEF, + 0x5EB0, 0x8EF0, + 0x5EB1, 0x8EF1, + 0x5EB2, 0x8EF2, + 0x5EB4, 0x8EF3, + 0x5EBA, 0x8EF4, + 0x5EBB, 0x8EF5, + 0x5EBC, 0x8EF6, + 0x5EBD, 0x8EF7, + 0x5EBF, 0x8EF8, + 0x5EC0, 0x8EF9, + 0x5EC1, 0x8EFA, + 0x5EC2, 0x8EFB, + 0x5EC3, 0x8EFC, + 0x5EC4, 0x8EFD, + 0x5EC5, 0x8EFE, + 0x5EC6, 0x8F40, + 0x5EC7, 0x8F41, + 0x5EC8, 0x8F42, + 0x5ECB, 0x8F43, + 0x5ECC, 0x8F44, + 0x5ECD, 0x8F45, + 0x5ECE, 0x8F46, + 0x5ECF, 0x8F47, + 0x5ED0, 0x8F48, + 0x5ED4, 0x8F49, + 0x5ED5, 0x8F4A, + 0x5ED7, 0x8F4B, + 0x5ED8, 0x8F4C, + 0x5ED9, 0x8F4D, + 0x5EDA, 0x8F4E, + 0x5EDC, 0x8F4F, + 0x5EDD, 0x8F50, + 0x5EDE, 0x8F51, + 0x5EDF, 0x8F52, + 0x5EE0, 0x8F53, + 0x5EE1, 0x8F54, + 0x5EE2, 0x8F55, + 0x5EE3, 0x8F56, + 0x5EE4, 0x8F57, + 0x5EE5, 0x8F58, + 0x5EE6, 0x8F59, + 0x5EE7, 0x8F5A, + 0x5EE9, 0x8F5B, + 0x5EEB, 0x8F5C, + 0x5EEC, 0x8F5D, + 0x5EED, 0x8F5E, + 0x5EEE, 0x8F5F, + 0x5EEF, 0x8F60, + 0x5EF0, 0x8F61, + 0x5EF1, 0x8F62, + 0x5EF2, 0x8F63, + 0x5EF3, 0x8F64, + 0x5EF5, 0x8F65, + 0x5EF8, 0x8F66, + 0x5EF9, 0x8F67, + 0x5EFB, 0x8F68, + 0x5EFC, 0x8F69, + 0x5EFD, 0x8F6A, + 0x5F05, 0x8F6B, + 0x5F06, 0x8F6C, + 0x5F07, 0x8F6D, + 0x5F09, 0x8F6E, + 0x5F0C, 0x8F6F, + 0x5F0D, 0x8F70, + 0x5F0E, 0x8F71, + 0x5F10, 0x8F72, + 0x5F12, 0x8F73, + 0x5F14, 0x8F74, + 0x5F16, 0x8F75, + 0x5F19, 0x8F76, + 0x5F1A, 0x8F77, + 0x5F1C, 0x8F78, + 0x5F1D, 0x8F79, + 0x5F1E, 0x8F7A, + 0x5F21, 0x8F7B, + 0x5F22, 0x8F7C, + 0x5F23, 0x8F7D, + 0x5F24, 0x8F7E, + 0x5F28, 0x8F80, + 0x5F2B, 0x8F81, + 0x5F2C, 0x8F82, + 0x5F2E, 0x8F83, + 0x5F30, 0x8F84, + 0x5F32, 0x8F85, + 0x5F33, 0x8F86, + 0x5F34, 0x8F87, + 0x5F35, 0x8F88, + 0x5F36, 0x8F89, + 0x5F37, 0x8F8A, + 0x5F38, 0x8F8B, + 0x5F3B, 0x8F8C, + 0x5F3D, 0x8F8D, + 0x5F3E, 0x8F8E, + 0x5F3F, 0x8F8F, + 0x5F41, 0x8F90, + 0x5F42, 0x8F91, + 0x5F43, 0x8F92, + 0x5F44, 0x8F93, + 0x5F45, 0x8F94, + 0x5F46, 0x8F95, + 0x5F47, 0x8F96, + 0x5F48, 0x8F97, + 0x5F49, 0x8F98, + 0x5F4A, 0x8F99, + 0x5F4B, 0x8F9A, + 0x5F4C, 0x8F9B, + 0x5F4D, 0x8F9C, + 0x5F4E, 0x8F9D, + 0x5F4F, 0x8F9E, + 0x5F51, 0x8F9F, + 0x5F54, 0x8FA0, + 0x5F59, 0x8FA1, + 0x5F5A, 0x8FA2, + 0x5F5B, 0x8FA3, + 0x5F5C, 0x8FA4, + 0x5F5E, 0x8FA5, + 0x5F5F, 0x8FA6, + 0x5F60, 0x8FA7, + 0x5F63, 0x8FA8, + 0x5F65, 0x8FA9, + 0x5F67, 0x8FAA, + 0x5F68, 0x8FAB, + 0x5F6B, 0x8FAC, + 0x5F6E, 0x8FAD, + 0x5F6F, 0x8FAE, + 0x5F72, 0x8FAF, + 0x5F74, 0x8FB0, + 0x5F75, 0x8FB1, + 0x5F76, 0x8FB2, + 0x5F78, 0x8FB3, + 0x5F7A, 0x8FB4, + 0x5F7D, 0x8FB5, + 0x5F7E, 0x8FB6, + 0x5F7F, 0x8FB7, + 0x5F83, 0x8FB8, + 0x5F86, 0x8FB9, + 0x5F8D, 0x8FBA, + 0x5F8E, 0x8FBB, + 0x5F8F, 0x8FBC, + 0x5F91, 0x8FBD, + 0x5F93, 0x8FBE, + 0x5F94, 0x8FBF, + 0x5F96, 0x8FC0, + 0x5F9A, 0x8FC1, + 0x5F9B, 0x8FC2, + 0x5F9D, 0x8FC3, + 0x5F9E, 0x8FC4, + 0x5F9F, 0x8FC5, + 0x5FA0, 0x8FC6, + 0x5FA2, 0x8FC7, + 0x5FA3, 0x8FC8, + 0x5FA4, 0x8FC9, + 0x5FA5, 0x8FCA, + 0x5FA6, 0x8FCB, + 0x5FA7, 0x8FCC, + 0x5FA9, 0x8FCD, + 0x5FAB, 0x8FCE, + 0x5FAC, 0x8FCF, + 0x5FAF, 0x8FD0, + 0x5FB0, 0x8FD1, + 0x5FB1, 0x8FD2, + 0x5FB2, 0x8FD3, + 0x5FB3, 0x8FD4, + 0x5FB4, 0x8FD5, + 0x5FB6, 0x8FD6, + 0x5FB8, 0x8FD7, + 0x5FB9, 0x8FD8, + 0x5FBA, 0x8FD9, + 0x5FBB, 0x8FDA, + 0x5FBE, 0x8FDB, + 0x5FBF, 0x8FDC, + 0x5FC0, 0x8FDD, + 0x5FC1, 0x8FDE, + 0x5FC2, 0x8FDF, + 0x5FC7, 0x8FE0, + 0x5FC8, 0x8FE1, + 0x5FCA, 0x8FE2, + 0x5FCB, 0x8FE3, + 0x5FCE, 0x8FE4, + 0x5FD3, 0x8FE5, + 0x5FD4, 0x8FE6, + 0x5FD5, 0x8FE7, + 0x5FDA, 0x8FE8, + 0x5FDB, 0x8FE9, + 0x5FDC, 0x8FEA, + 0x5FDE, 0x8FEB, + 0x5FDF, 0x8FEC, + 0x5FE2, 0x8FED, + 0x5FE3, 0x8FEE, + 0x5FE5, 0x8FEF, + 0x5FE6, 0x8FF0, + 0x5FE8, 0x8FF1, + 0x5FE9, 0x8FF2, + 0x5FEC, 0x8FF3, + 0x5FEF, 0x8FF4, + 0x5FF0, 0x8FF5, + 0x5FF2, 0x8FF6, + 0x5FF3, 0x8FF7, + 0x5FF4, 0x8FF8, + 0x5FF6, 0x8FF9, + 0x5FF7, 0x8FFA, + 0x5FF9, 0x8FFB, + 0x5FFA, 0x8FFC, + 0x5FFC, 0x8FFD, + 0x6007, 0x8FFE, + 0x6008, 0x9040, + 0x6009, 0x9041, + 0x600B, 0x9042, + 0x600C, 0x9043, + 0x6010, 0x9044, + 0x6011, 0x9045, + 0x6013, 0x9046, + 0x6017, 0x9047, + 0x6018, 0x9048, + 0x601A, 0x9049, + 0x601E, 0x904A, + 0x601F, 0x904B, + 0x6022, 0x904C, + 0x6023, 0x904D, + 0x6024, 0x904E, + 0x602C, 0x904F, + 0x602D, 0x9050, + 0x602E, 0x9051, + 0x6030, 0x9052, + 0x6031, 0x9053, + 0x6032, 0x9054, + 0x6033, 0x9055, + 0x6034, 0x9056, + 0x6036, 0x9057, + 0x6037, 0x9058, + 0x6038, 0x9059, + 0x6039, 0x905A, + 0x603A, 0x905B, + 0x603D, 0x905C, + 0x603E, 0x905D, + 0x6040, 0x905E, + 0x6044, 0x905F, + 0x6045, 0x9060, + 0x6046, 0x9061, + 0x6047, 0x9062, + 0x6048, 0x9063, + 0x6049, 0x9064, + 0x604A, 0x9065, + 0x604C, 0x9066, + 0x604E, 0x9067, + 0x604F, 0x9068, + 0x6051, 0x9069, + 0x6053, 0x906A, + 0x6054, 0x906B, + 0x6056, 0x906C, + 0x6057, 0x906D, + 0x6058, 0x906E, + 0x605B, 0x906F, + 0x605C, 0x9070, + 0x605E, 0x9071, + 0x605F, 0x9072, + 0x6060, 0x9073, + 0x6061, 0x9074, + 0x6065, 0x9075, + 0x6066, 0x9076, + 0x606E, 0x9077, + 0x6071, 0x9078, + 0x6072, 0x9079, + 0x6074, 0x907A, + 0x6075, 0x907B, + 0x6077, 0x907C, + 0x607E, 0x907D, + 0x6080, 0x907E, + 0x6081, 0x9080, + 0x6082, 0x9081, + 0x6085, 0x9082, + 0x6086, 0x9083, + 0x6087, 0x9084, + 0x6088, 0x9085, + 0x608A, 0x9086, + 0x608B, 0x9087, + 0x608E, 0x9088, + 0x608F, 0x9089, + 0x6090, 0x908A, + 0x6091, 0x908B, + 0x6093, 0x908C, + 0x6095, 0x908D, + 0x6097, 0x908E, + 0x6098, 0x908F, + 0x6099, 0x9090, + 0x609C, 0x9091, + 0x609E, 0x9092, + 0x60A1, 0x9093, + 0x60A2, 0x9094, + 0x60A4, 0x9095, + 0x60A5, 0x9096, + 0x60A7, 0x9097, + 0x60A9, 0x9098, + 0x60AA, 0x9099, + 0x60AE, 0x909A, + 0x60B0, 0x909B, + 0x60B3, 0x909C, + 0x60B5, 0x909D, + 0x60B6, 0x909E, + 0x60B7, 0x909F, + 0x60B9, 0x90A0, + 0x60BA, 0x90A1, + 0x60BD, 0x90A2, + 0x60BE, 0x90A3, + 0x60BF, 0x90A4, + 0x60C0, 0x90A5, + 0x60C1, 0x90A6, + 0x60C2, 0x90A7, + 0x60C3, 0x90A8, + 0x60C4, 0x90A9, + 0x60C7, 0x90AA, + 0x60C8, 0x90AB, + 0x60C9, 0x90AC, + 0x60CC, 0x90AD, + 0x60CD, 0x90AE, + 0x60CE, 0x90AF, + 0x60CF, 0x90B0, + 0x60D0, 0x90B1, + 0x60D2, 0x90B2, + 0x60D3, 0x90B3, + 0x60D4, 0x90B4, + 0x60D6, 0x90B5, + 0x60D7, 0x90B6, + 0x60D9, 0x90B7, + 0x60DB, 0x90B8, + 0x60DE, 0x90B9, + 0x60E1, 0x90BA, + 0x60E2, 0x90BB, + 0x60E3, 0x90BC, + 0x60E4, 0x90BD, + 0x60E5, 0x90BE, + 0x60EA, 0x90BF, + 0x60F1, 0x90C0, + 0x60F2, 0x90C1, + 0x60F5, 0x90C2, + 0x60F7, 0x90C3, + 0x60F8, 0x90C4, + 0x60FB, 0x90C5, + 0x60FC, 0x90C6, + 0x60FD, 0x90C7, + 0x60FE, 0x90C8, + 0x60FF, 0x90C9, + 0x6102, 0x90CA, + 0x6103, 0x90CB, + 0x6104, 0x90CC, + 0x6105, 0x90CD, + 0x6107, 0x90CE, + 0x610A, 0x90CF, + 0x610B, 0x90D0, + 0x610C, 0x90D1, + 0x6110, 0x90D2, + 0x6111, 0x90D3, + 0x6112, 0x90D4, + 0x6113, 0x90D5, + 0x6114, 0x90D6, + 0x6116, 0x90D7, + 0x6117, 0x90D8, + 0x6118, 0x90D9, + 0x6119, 0x90DA, + 0x611B, 0x90DB, + 0x611C, 0x90DC, + 0x611D, 0x90DD, + 0x611E, 0x90DE, + 0x6121, 0x90DF, + 0x6122, 0x90E0, + 0x6125, 0x90E1, + 0x6128, 0x90E2, + 0x6129, 0x90E3, + 0x612A, 0x90E4, + 0x612C, 0x90E5, + 0x612D, 0x90E6, + 0x612E, 0x90E7, + 0x612F, 0x90E8, + 0x6130, 0x90E9, + 0x6131, 0x90EA, + 0x6132, 0x90EB, + 0x6133, 0x90EC, + 0x6134, 0x90ED, + 0x6135, 0x90EE, + 0x6136, 0x90EF, + 0x6137, 0x90F0, + 0x6138, 0x90F1, + 0x6139, 0x90F2, + 0x613A, 0x90F3, + 0x613B, 0x90F4, + 0x613C, 0x90F5, + 0x613D, 0x90F6, + 0x613E, 0x90F7, + 0x6140, 0x90F8, + 0x6141, 0x90F9, + 0x6142, 0x90FA, + 0x6143, 0x90FB, + 0x6144, 0x90FC, + 0x6145, 0x90FD, + 0x6146, 0x90FE, + 0x6147, 0x9140, + 0x6149, 0x9141, + 0x614B, 0x9142, + 0x614D, 0x9143, + 0x614F, 0x9144, + 0x6150, 0x9145, + 0x6152, 0x9146, + 0x6153, 0x9147, + 0x6154, 0x9148, + 0x6156, 0x9149, + 0x6157, 0x914A, + 0x6158, 0x914B, + 0x6159, 0x914C, + 0x615A, 0x914D, + 0x615B, 0x914E, + 0x615C, 0x914F, + 0x615E, 0x9150, + 0x615F, 0x9151, + 0x6160, 0x9152, + 0x6161, 0x9153, + 0x6163, 0x9154, + 0x6164, 0x9155, + 0x6165, 0x9156, + 0x6166, 0x9157, + 0x6169, 0x9158, + 0x616A, 0x9159, + 0x616B, 0x915A, + 0x616C, 0x915B, + 0x616D, 0x915C, + 0x616E, 0x915D, + 0x616F, 0x915E, + 0x6171, 0x915F, + 0x6172, 0x9160, + 0x6173, 0x9161, + 0x6174, 0x9162, + 0x6176, 0x9163, + 0x6178, 0x9164, + 0x6179, 0x9165, + 0x617A, 0x9166, + 0x617B, 0x9167, + 0x617C, 0x9168, + 0x617D, 0x9169, + 0x617E, 0x916A, + 0x617F, 0x916B, + 0x6180, 0x916C, + 0x6181, 0x916D, + 0x6182, 0x916E, + 0x6183, 0x916F, + 0x6184, 0x9170, + 0x6185, 0x9171, + 0x6186, 0x9172, + 0x6187, 0x9173, + 0x6188, 0x9174, + 0x6189, 0x9175, + 0x618A, 0x9176, + 0x618C, 0x9177, + 0x618D, 0x9178, + 0x618F, 0x9179, + 0x6190, 0x917A, + 0x6191, 0x917B, + 0x6192, 0x917C, + 0x6193, 0x917D, + 0x6195, 0x917E, + 0x6196, 0x9180, + 0x6197, 0x9181, + 0x6198, 0x9182, + 0x6199, 0x9183, + 0x619A, 0x9184, + 0x619B, 0x9185, + 0x619C, 0x9186, + 0x619E, 0x9187, + 0x619F, 0x9188, + 0x61A0, 0x9189, + 0x61A1, 0x918A, + 0x61A2, 0x918B, + 0x61A3, 0x918C, + 0x61A4, 0x918D, + 0x61A5, 0x918E, + 0x61A6, 0x918F, + 0x61AA, 0x9190, + 0x61AB, 0x9191, + 0x61AD, 0x9192, + 0x61AE, 0x9193, + 0x61AF, 0x9194, + 0x61B0, 0x9195, + 0x61B1, 0x9196, + 0x61B2, 0x9197, + 0x61B3, 0x9198, + 0x61B4, 0x9199, + 0x61B5, 0x919A, + 0x61B6, 0x919B, + 0x61B8, 0x919C, + 0x61B9, 0x919D, + 0x61BA, 0x919E, + 0x61BB, 0x919F, + 0x61BC, 0x91A0, + 0x61BD, 0x91A1, + 0x61BF, 0x91A2, + 0x61C0, 0x91A3, + 0x61C1, 0x91A4, + 0x61C3, 0x91A5, + 0x61C4, 0x91A6, + 0x61C5, 0x91A7, + 0x61C6, 0x91A8, + 0x61C7, 0x91A9, + 0x61C9, 0x91AA, + 0x61CC, 0x91AB, + 0x61CD, 0x91AC, + 0x61CE, 0x91AD, + 0x61CF, 0x91AE, + 0x61D0, 0x91AF, + 0x61D3, 0x91B0, + 0x61D5, 0x91B1, + 0x61D6, 0x91B2, + 0x61D7, 0x91B3, + 0x61D8, 0x91B4, + 0x61D9, 0x91B5, + 0x61DA, 0x91B6, + 0x61DB, 0x91B7, + 0x61DC, 0x91B8, + 0x61DD, 0x91B9, + 0x61DE, 0x91BA, + 0x61DF, 0x91BB, + 0x61E0, 0x91BC, + 0x61E1, 0x91BD, + 0x61E2, 0x91BE, + 0x61E3, 0x91BF, + 0x61E4, 0x91C0, + 0x61E5, 0x91C1, + 0x61E7, 0x91C2, + 0x61E8, 0x91C3, + 0x61E9, 0x91C4, + 0x61EA, 0x91C5, + 0x61EB, 0x91C6, + 0x61EC, 0x91C7, + 0x61ED, 0x91C8, + 0x61EE, 0x91C9, + 0x61EF, 0x91CA, + 0x61F0, 0x91CB, + 0x61F1, 0x91CC, + 0x61F2, 0x91CD, + 0x61F3, 0x91CE, + 0x61F4, 0x91CF, + 0x61F6, 0x91D0, + 0x61F7, 0x91D1, + 0x61F8, 0x91D2, + 0x61F9, 0x91D3, + 0x61FA, 0x91D4, + 0x61FB, 0x91D5, + 0x61FC, 0x91D6, + 0x61FD, 0x91D7, + 0x61FE, 0x91D8, + 0x6200, 0x91D9, + 0x6201, 0x91DA, + 0x6202, 0x91DB, + 0x6203, 0x91DC, + 0x6204, 0x91DD, + 0x6205, 0x91DE, + 0x6207, 0x91DF, + 0x6209, 0x91E0, + 0x6213, 0x91E1, + 0x6214, 0x91E2, + 0x6219, 0x91E3, + 0x621C, 0x91E4, + 0x621D, 0x91E5, + 0x621E, 0x91E6, + 0x6220, 0x91E7, + 0x6223, 0x91E8, + 0x6226, 0x91E9, + 0x6227, 0x91EA, + 0x6228, 0x91EB, + 0x6229, 0x91EC, + 0x622B, 0x91ED, + 0x622D, 0x91EE, + 0x622F, 0x91EF, + 0x6230, 0x91F0, + 0x6231, 0x91F1, + 0x6232, 0x91F2, + 0x6235, 0x91F3, + 0x6236, 0x91F4, + 0x6238, 0x91F5, + 0x6239, 0x91F6, + 0x623A, 0x91F7, + 0x623B, 0x91F8, + 0x623C, 0x91F9, + 0x6242, 0x91FA, + 0x6244, 0x91FB, + 0x6245, 0x91FC, + 0x6246, 0x91FD, + 0x624A, 0x91FE, + 0x624F, 0x9240, + 0x6250, 0x9241, + 0x6255, 0x9242, + 0x6256, 0x9243, + 0x6257, 0x9244, + 0x6259, 0x9245, + 0x625A, 0x9246, + 0x625C, 0x9247, + 0x625D, 0x9248, + 0x625E, 0x9249, + 0x625F, 0x924A, + 0x6260, 0x924B, + 0x6261, 0x924C, + 0x6262, 0x924D, + 0x6264, 0x924E, + 0x6265, 0x924F, + 0x6268, 0x9250, + 0x6271, 0x9251, + 0x6272, 0x9252, + 0x6274, 0x9253, + 0x6275, 0x9254, + 0x6277, 0x9255, + 0x6278, 0x9256, + 0x627A, 0x9257, + 0x627B, 0x9258, + 0x627D, 0x9259, + 0x6281, 0x925A, + 0x6282, 0x925B, + 0x6283, 0x925C, + 0x6285, 0x925D, + 0x6286, 0x925E, + 0x6287, 0x925F, + 0x6288, 0x9260, + 0x628B, 0x9261, + 0x628C, 0x9262, + 0x628D, 0x9263, + 0x628E, 0x9264, + 0x628F, 0x9265, + 0x6290, 0x9266, + 0x6294, 0x9267, + 0x6299, 0x9268, + 0x629C, 0x9269, + 0x629D, 0x926A, + 0x629E, 0x926B, + 0x62A3, 0x926C, + 0x62A6, 0x926D, + 0x62A7, 0x926E, + 0x62A9, 0x926F, + 0x62AA, 0x9270, + 0x62AD, 0x9271, + 0x62AE, 0x9272, + 0x62AF, 0x9273, + 0x62B0, 0x9274, + 0x62B2, 0x9275, + 0x62B3, 0x9276, + 0x62B4, 0x9277, + 0x62B6, 0x9278, + 0x62B7, 0x9279, + 0x62B8, 0x927A, + 0x62BA, 0x927B, + 0x62BE, 0x927C, + 0x62C0, 0x927D, + 0x62C1, 0x927E, + 0x62C3, 0x9280, + 0x62CB, 0x9281, + 0x62CF, 0x9282, + 0x62D1, 0x9283, + 0x62D5, 0x9284, + 0x62DD, 0x9285, + 0x62DE, 0x9286, + 0x62E0, 0x9287, + 0x62E1, 0x9288, + 0x62E4, 0x9289, + 0x62EA, 0x928A, + 0x62EB, 0x928B, + 0x62F0, 0x928C, + 0x62F2, 0x928D, + 0x62F5, 0x928E, + 0x62F8, 0x928F, + 0x62F9, 0x9290, + 0x62FA, 0x9291, + 0x62FB, 0x9292, + 0x6300, 0x9293, + 0x6303, 0x9294, + 0x6304, 0x9295, + 0x6305, 0x9296, + 0x6306, 0x9297, + 0x630A, 0x9298, + 0x630B, 0x9299, + 0x630C, 0x929A, + 0x630D, 0x929B, + 0x630F, 0x929C, + 0x6310, 0x929D, + 0x6312, 0x929E, + 0x6313, 0x929F, + 0x6314, 0x92A0, + 0x6315, 0x92A1, + 0x6317, 0x92A2, + 0x6318, 0x92A3, + 0x6319, 0x92A4, + 0x631C, 0x92A5, + 0x6326, 0x92A6, + 0x6327, 0x92A7, + 0x6329, 0x92A8, + 0x632C, 0x92A9, + 0x632D, 0x92AA, + 0x632E, 0x92AB, + 0x6330, 0x92AC, + 0x6331, 0x92AD, + 0x6333, 0x92AE, + 0x6334, 0x92AF, + 0x6335, 0x92B0, + 0x6336, 0x92B1, + 0x6337, 0x92B2, + 0x6338, 0x92B3, + 0x633B, 0x92B4, + 0x633C, 0x92B5, + 0x633E, 0x92B6, + 0x633F, 0x92B7, + 0x6340, 0x92B8, + 0x6341, 0x92B9, + 0x6344, 0x92BA, + 0x6347, 0x92BB, + 0x6348, 0x92BC, + 0x634A, 0x92BD, + 0x6351, 0x92BE, + 0x6352, 0x92BF, + 0x6353, 0x92C0, + 0x6354, 0x92C1, + 0x6356, 0x92C2, + 0x6357, 0x92C3, + 0x6358, 0x92C4, + 0x6359, 0x92C5, + 0x635A, 0x92C6, + 0x635B, 0x92C7, + 0x635C, 0x92C8, + 0x635D, 0x92C9, + 0x6360, 0x92CA, + 0x6364, 0x92CB, + 0x6365, 0x92CC, + 0x6366, 0x92CD, + 0x6368, 0x92CE, + 0x636A, 0x92CF, + 0x636B, 0x92D0, + 0x636C, 0x92D1, + 0x636F, 0x92D2, + 0x6370, 0x92D3, + 0x6372, 0x92D4, + 0x6373, 0x92D5, + 0x6374, 0x92D6, + 0x6375, 0x92D7, + 0x6378, 0x92D8, + 0x6379, 0x92D9, + 0x637C, 0x92DA, + 0x637D, 0x92DB, + 0x637E, 0x92DC, + 0x637F, 0x92DD, + 0x6381, 0x92DE, + 0x6383, 0x92DF, + 0x6384, 0x92E0, + 0x6385, 0x92E1, + 0x6386, 0x92E2, + 0x638B, 0x92E3, + 0x638D, 0x92E4, + 0x6391, 0x92E5, + 0x6393, 0x92E6, + 0x6394, 0x92E7, + 0x6395, 0x92E8, + 0x6397, 0x92E9, + 0x6399, 0x92EA, + 0x639A, 0x92EB, + 0x639B, 0x92EC, + 0x639C, 0x92ED, + 0x639D, 0x92EE, + 0x639E, 0x92EF, + 0x639F, 0x92F0, + 0x63A1, 0x92F1, + 0x63A4, 0x92F2, + 0x63A6, 0x92F3, + 0x63AB, 0x92F4, + 0x63AF, 0x92F5, + 0x63B1, 0x92F6, + 0x63B2, 0x92F7, + 0x63B5, 0x92F8, + 0x63B6, 0x92F9, + 0x63B9, 0x92FA, + 0x63BB, 0x92FB, + 0x63BD, 0x92FC, + 0x63BF, 0x92FD, + 0x63C0, 0x92FE, + 0x63C1, 0x9340, + 0x63C2, 0x9341, + 0x63C3, 0x9342, + 0x63C5, 0x9343, + 0x63C7, 0x9344, + 0x63C8, 0x9345, + 0x63CA, 0x9346, + 0x63CB, 0x9347, + 0x63CC, 0x9348, + 0x63D1, 0x9349, + 0x63D3, 0x934A, + 0x63D4, 0x934B, + 0x63D5, 0x934C, + 0x63D7, 0x934D, + 0x63D8, 0x934E, + 0x63D9, 0x934F, + 0x63DA, 0x9350, + 0x63DB, 0x9351, + 0x63DC, 0x9352, + 0x63DD, 0x9353, + 0x63DF, 0x9354, + 0x63E2, 0x9355, + 0x63E4, 0x9356, + 0x63E5, 0x9357, + 0x63E6, 0x9358, + 0x63E7, 0x9359, + 0x63E8, 0x935A, + 0x63EB, 0x935B, + 0x63EC, 0x935C, + 0x63EE, 0x935D, + 0x63EF, 0x935E, + 0x63F0, 0x935F, + 0x63F1, 0x9360, + 0x63F3, 0x9361, + 0x63F5, 0x9362, + 0x63F7, 0x9363, + 0x63F9, 0x9364, + 0x63FA, 0x9365, + 0x63FB, 0x9366, + 0x63FC, 0x9367, + 0x63FE, 0x9368, + 0x6403, 0x9369, + 0x6404, 0x936A, + 0x6406, 0x936B, + 0x6407, 0x936C, + 0x6408, 0x936D, + 0x6409, 0x936E, + 0x640A, 0x936F, + 0x640D, 0x9370, + 0x640E, 0x9371, + 0x6411, 0x9372, + 0x6412, 0x9373, + 0x6415, 0x9374, + 0x6416, 0x9375, + 0x6417, 0x9376, + 0x6418, 0x9377, + 0x6419, 0x9378, + 0x641A, 0x9379, + 0x641D, 0x937A, + 0x641F, 0x937B, + 0x6422, 0x937C, + 0x6423, 0x937D, + 0x6424, 0x937E, + 0x6425, 0x9380, + 0x6427, 0x9381, + 0x6428, 0x9382, + 0x6429, 0x9383, + 0x642B, 0x9384, + 0x642E, 0x9385, + 0x642F, 0x9386, + 0x6430, 0x9387, + 0x6431, 0x9388, + 0x6432, 0x9389, + 0x6433, 0x938A, + 0x6435, 0x938B, + 0x6436, 0x938C, + 0x6437, 0x938D, + 0x6438, 0x938E, + 0x6439, 0x938F, + 0x643B, 0x9390, + 0x643C, 0x9391, + 0x643E, 0x9392, + 0x6440, 0x9393, + 0x6442, 0x9394, + 0x6443, 0x9395, + 0x6449, 0x9396, + 0x644B, 0x9397, + 0x644C, 0x9398, + 0x644D, 0x9399, + 0x644E, 0x939A, + 0x644F, 0x939B, + 0x6450, 0x939C, + 0x6451, 0x939D, + 0x6453, 0x939E, + 0x6455, 0x939F, + 0x6456, 0x93A0, + 0x6457, 0x93A1, + 0x6459, 0x93A2, + 0x645A, 0x93A3, + 0x645B, 0x93A4, + 0x645C, 0x93A5, + 0x645D, 0x93A6, + 0x645F, 0x93A7, + 0x6460, 0x93A8, + 0x6461, 0x93A9, + 0x6462, 0x93AA, + 0x6463, 0x93AB, + 0x6464, 0x93AC, + 0x6465, 0x93AD, + 0x6466, 0x93AE, + 0x6468, 0x93AF, + 0x646A, 0x93B0, + 0x646B, 0x93B1, + 0x646C, 0x93B2, + 0x646E, 0x93B3, + 0x646F, 0x93B4, + 0x6470, 0x93B5, + 0x6471, 0x93B6, + 0x6472, 0x93B7, + 0x6473, 0x93B8, + 0x6474, 0x93B9, + 0x6475, 0x93BA, + 0x6476, 0x93BB, + 0x6477, 0x93BC, + 0x647B, 0x93BD, + 0x647C, 0x93BE, + 0x647D, 0x93BF, + 0x647E, 0x93C0, + 0x647F, 0x93C1, + 0x6480, 0x93C2, + 0x6481, 0x93C3, + 0x6483, 0x93C4, + 0x6486, 0x93C5, + 0x6488, 0x93C6, + 0x6489, 0x93C7, + 0x648A, 0x93C8, + 0x648B, 0x93C9, + 0x648C, 0x93CA, + 0x648D, 0x93CB, + 0x648E, 0x93CC, + 0x648F, 0x93CD, + 0x6490, 0x93CE, + 0x6493, 0x93CF, + 0x6494, 0x93D0, + 0x6497, 0x93D1, + 0x6498, 0x93D2, + 0x649A, 0x93D3, + 0x649B, 0x93D4, + 0x649C, 0x93D5, + 0x649D, 0x93D6, + 0x649F, 0x93D7, + 0x64A0, 0x93D8, + 0x64A1, 0x93D9, + 0x64A2, 0x93DA, + 0x64A3, 0x93DB, + 0x64A5, 0x93DC, + 0x64A6, 0x93DD, + 0x64A7, 0x93DE, + 0x64A8, 0x93DF, + 0x64AA, 0x93E0, + 0x64AB, 0x93E1, + 0x64AF, 0x93E2, + 0x64B1, 0x93E3, + 0x64B2, 0x93E4, + 0x64B3, 0x93E5, + 0x64B4, 0x93E6, + 0x64B6, 0x93E7, + 0x64B9, 0x93E8, + 0x64BB, 0x93E9, + 0x64BD, 0x93EA, + 0x64BE, 0x93EB, + 0x64BF, 0x93EC, + 0x64C1, 0x93ED, + 0x64C3, 0x93EE, + 0x64C4, 0x93EF, + 0x64C6, 0x93F0, + 0x64C7, 0x93F1, + 0x64C8, 0x93F2, + 0x64C9, 0x93F3, + 0x64CA, 0x93F4, + 0x64CB, 0x93F5, + 0x64CC, 0x93F6, + 0x64CF, 0x93F7, + 0x64D1, 0x93F8, + 0x64D3, 0x93F9, + 0x64D4, 0x93FA, + 0x64D5, 0x93FB, + 0x64D6, 0x93FC, + 0x64D9, 0x93FD, + 0x64DA, 0x93FE, + 0x64DB, 0x9440, + 0x64DC, 0x9441, + 0x64DD, 0x9442, + 0x64DF, 0x9443, + 0x64E0, 0x9444, + 0x64E1, 0x9445, + 0x64E3, 0x9446, + 0x64E5, 0x9447, + 0x64E7, 0x9448, + 0x64E8, 0x9449, + 0x64E9, 0x944A, + 0x64EA, 0x944B, + 0x64EB, 0x944C, + 0x64EC, 0x944D, + 0x64ED, 0x944E, + 0x64EE, 0x944F, + 0x64EF, 0x9450, + 0x64F0, 0x9451, + 0x64F1, 0x9452, + 0x64F2, 0x9453, + 0x64F3, 0x9454, + 0x64F4, 0x9455, + 0x64F5, 0x9456, + 0x64F6, 0x9457, + 0x64F7, 0x9458, + 0x64F8, 0x9459, + 0x64F9, 0x945A, + 0x64FA, 0x945B, + 0x64FB, 0x945C, + 0x64FC, 0x945D, + 0x64FD, 0x945E, + 0x64FE, 0x945F, + 0x64FF, 0x9460, + 0x6501, 0x9461, + 0x6502, 0x9462, + 0x6503, 0x9463, + 0x6504, 0x9464, + 0x6505, 0x9465, + 0x6506, 0x9466, + 0x6507, 0x9467, + 0x6508, 0x9468, + 0x650A, 0x9469, + 0x650B, 0x946A, + 0x650C, 0x946B, + 0x650D, 0x946C, + 0x650E, 0x946D, + 0x650F, 0x946E, + 0x6510, 0x946F, + 0x6511, 0x9470, + 0x6513, 0x9471, + 0x6514, 0x9472, + 0x6515, 0x9473, + 0x6516, 0x9474, + 0x6517, 0x9475, + 0x6519, 0x9476, + 0x651A, 0x9477, + 0x651B, 0x9478, + 0x651C, 0x9479, + 0x651D, 0x947A, + 0x651E, 0x947B, + 0x651F, 0x947C, + 0x6520, 0x947D, + 0x6521, 0x947E, + 0x6522, 0x9480, + 0x6523, 0x9481, + 0x6524, 0x9482, + 0x6526, 0x9483, + 0x6527, 0x9484, + 0x6528, 0x9485, + 0x6529, 0x9486, + 0x652A, 0x9487, + 0x652C, 0x9488, + 0x652D, 0x9489, + 0x6530, 0x948A, + 0x6531, 0x948B, + 0x6532, 0x948C, + 0x6533, 0x948D, + 0x6537, 0x948E, + 0x653A, 0x948F, + 0x653C, 0x9490, + 0x653D, 0x9491, + 0x6540, 0x9492, + 0x6541, 0x9493, + 0x6542, 0x9494, + 0x6543, 0x9495, + 0x6544, 0x9496, + 0x6546, 0x9497, + 0x6547, 0x9498, + 0x654A, 0x9499, + 0x654B, 0x949A, + 0x654D, 0x949B, + 0x654E, 0x949C, + 0x6550, 0x949D, + 0x6552, 0x949E, + 0x6553, 0x949F, + 0x6554, 0x94A0, + 0x6557, 0x94A1, + 0x6558, 0x94A2, + 0x655A, 0x94A3, + 0x655C, 0x94A4, + 0x655F, 0x94A5, + 0x6560, 0x94A6, + 0x6561, 0x94A7, + 0x6564, 0x94A8, + 0x6565, 0x94A9, + 0x6567, 0x94AA, + 0x6568, 0x94AB, + 0x6569, 0x94AC, + 0x656A, 0x94AD, + 0x656D, 0x94AE, + 0x656E, 0x94AF, + 0x656F, 0x94B0, + 0x6571, 0x94B1, + 0x6573, 0x94B2, + 0x6575, 0x94B3, + 0x6576, 0x94B4, + 0x6578, 0x94B5, + 0x6579, 0x94B6, + 0x657A, 0x94B7, + 0x657B, 0x94B8, + 0x657C, 0x94B9, + 0x657D, 0x94BA, + 0x657E, 0x94BB, + 0x657F, 0x94BC, + 0x6580, 0x94BD, + 0x6581, 0x94BE, + 0x6582, 0x94BF, + 0x6583, 0x94C0, + 0x6584, 0x94C1, + 0x6585, 0x94C2, + 0x6586, 0x94C3, + 0x6588, 0x94C4, + 0x6589, 0x94C5, + 0x658A, 0x94C6, + 0x658D, 0x94C7, + 0x658E, 0x94C8, + 0x658F, 0x94C9, + 0x6592, 0x94CA, + 0x6594, 0x94CB, + 0x6595, 0x94CC, + 0x6596, 0x94CD, + 0x6598, 0x94CE, + 0x659A, 0x94CF, + 0x659D, 0x94D0, + 0x659E, 0x94D1, + 0x65A0, 0x94D2, + 0x65A2, 0x94D3, + 0x65A3, 0x94D4, + 0x65A6, 0x94D5, + 0x65A8, 0x94D6, + 0x65AA, 0x94D7, + 0x65AC, 0x94D8, + 0x65AE, 0x94D9, + 0x65B1, 0x94DA, + 0x65B2, 0x94DB, + 0x65B3, 0x94DC, + 0x65B4, 0x94DD, + 0x65B5, 0x94DE, + 0x65B6, 0x94DF, + 0x65B7, 0x94E0, + 0x65B8, 0x94E1, + 0x65BA, 0x94E2, + 0x65BB, 0x94E3, + 0x65BE, 0x94E4, + 0x65BF, 0x94E5, + 0x65C0, 0x94E6, + 0x65C2, 0x94E7, + 0x65C7, 0x94E8, + 0x65C8, 0x94E9, + 0x65C9, 0x94EA, + 0x65CA, 0x94EB, + 0x65CD, 0x94EC, + 0x65D0, 0x94ED, + 0x65D1, 0x94EE, + 0x65D3, 0x94EF, + 0x65D4, 0x94F0, + 0x65D5, 0x94F1, + 0x65D8, 0x94F2, + 0x65D9, 0x94F3, + 0x65DA, 0x94F4, + 0x65DB, 0x94F5, + 0x65DC, 0x94F6, + 0x65DD, 0x94F7, + 0x65DE, 0x94F8, + 0x65DF, 0x94F9, + 0x65E1, 0x94FA, + 0x65E3, 0x94FB, + 0x65E4, 0x94FC, + 0x65EA, 0x94FD, + 0x65EB, 0x94FE, + 0x65F2, 0x9540, + 0x65F3, 0x9541, + 0x65F4, 0x9542, + 0x65F5, 0x9543, + 0x65F8, 0x9544, + 0x65F9, 0x9545, + 0x65FB, 0x9546, + 0x65FC, 0x9547, + 0x65FD, 0x9548, + 0x65FE, 0x9549, + 0x65FF, 0x954A, + 0x6601, 0x954B, + 0x6604, 0x954C, + 0x6605, 0x954D, + 0x6607, 0x954E, + 0x6608, 0x954F, + 0x6609, 0x9550, + 0x660B, 0x9551, + 0x660D, 0x9552, + 0x6610, 0x9553, + 0x6611, 0x9554, + 0x6612, 0x9555, + 0x6616, 0x9556, + 0x6617, 0x9557, + 0x6618, 0x9558, + 0x661A, 0x9559, + 0x661B, 0x955A, + 0x661C, 0x955B, + 0x661E, 0x955C, + 0x6621, 0x955D, + 0x6622, 0x955E, + 0x6623, 0x955F, + 0x6624, 0x9560, + 0x6626, 0x9561, + 0x6629, 0x9562, + 0x662A, 0x9563, + 0x662B, 0x9564, + 0x662C, 0x9565, + 0x662E, 0x9566, + 0x6630, 0x9567, + 0x6632, 0x9568, + 0x6633, 0x9569, + 0x6637, 0x956A, + 0x6638, 0x956B, + 0x6639, 0x956C, + 0x663A, 0x956D, + 0x663B, 0x956E, + 0x663D, 0x956F, + 0x663F, 0x9570, + 0x6640, 0x9571, + 0x6642, 0x9572, + 0x6644, 0x9573, + 0x6645, 0x9574, + 0x6646, 0x9575, + 0x6647, 0x9576, + 0x6648, 0x9577, + 0x6649, 0x9578, + 0x664A, 0x9579, + 0x664D, 0x957A, + 0x664E, 0x957B, + 0x6650, 0x957C, + 0x6651, 0x957D, + 0x6658, 0x957E, + 0x6659, 0x9580, + 0x665B, 0x9581, + 0x665C, 0x9582, + 0x665D, 0x9583, + 0x665E, 0x9584, + 0x6660, 0x9585, + 0x6662, 0x9586, + 0x6663, 0x9587, + 0x6665, 0x9588, + 0x6667, 0x9589, + 0x6669, 0x958A, + 0x666A, 0x958B, + 0x666B, 0x958C, + 0x666C, 0x958D, + 0x666D, 0x958E, + 0x6671, 0x958F, + 0x6672, 0x9590, + 0x6673, 0x9591, + 0x6675, 0x9592, + 0x6678, 0x9593, + 0x6679, 0x9594, + 0x667B, 0x9595, + 0x667C, 0x9596, + 0x667D, 0x9597, + 0x667F, 0x9598, + 0x6680, 0x9599, + 0x6681, 0x959A, + 0x6683, 0x959B, + 0x6685, 0x959C, + 0x6686, 0x959D, + 0x6688, 0x959E, + 0x6689, 0x959F, + 0x668A, 0x95A0, + 0x668B, 0x95A1, + 0x668D, 0x95A2, + 0x668E, 0x95A3, + 0x668F, 0x95A4, + 0x6690, 0x95A5, + 0x6692, 0x95A6, + 0x6693, 0x95A7, + 0x6694, 0x95A8, + 0x6695, 0x95A9, + 0x6698, 0x95AA, + 0x6699, 0x95AB, + 0x669A, 0x95AC, + 0x669B, 0x95AD, + 0x669C, 0x95AE, + 0x669E, 0x95AF, + 0x669F, 0x95B0, + 0x66A0, 0x95B1, + 0x66A1, 0x95B2, + 0x66A2, 0x95B3, + 0x66A3, 0x95B4, + 0x66A4, 0x95B5, + 0x66A5, 0x95B6, + 0x66A6, 0x95B7, + 0x66A9, 0x95B8, + 0x66AA, 0x95B9, + 0x66AB, 0x95BA, + 0x66AC, 0x95BB, + 0x66AD, 0x95BC, + 0x66AF, 0x95BD, + 0x66B0, 0x95BE, + 0x66B1, 0x95BF, + 0x66B2, 0x95C0, + 0x66B3, 0x95C1, + 0x66B5, 0x95C2, + 0x66B6, 0x95C3, + 0x66B7, 0x95C4, + 0x66B8, 0x95C5, + 0x66BA, 0x95C6, + 0x66BB, 0x95C7, + 0x66BC, 0x95C8, + 0x66BD, 0x95C9, + 0x66BF, 0x95CA, + 0x66C0, 0x95CB, + 0x66C1, 0x95CC, + 0x66C2, 0x95CD, + 0x66C3, 0x95CE, + 0x66C4, 0x95CF, + 0x66C5, 0x95D0, + 0x66C6, 0x95D1, + 0x66C7, 0x95D2, + 0x66C8, 0x95D3, + 0x66C9, 0x95D4, + 0x66CA, 0x95D5, + 0x66CB, 0x95D6, + 0x66CC, 0x95D7, + 0x66CD, 0x95D8, + 0x66CE, 0x95D9, + 0x66CF, 0x95DA, + 0x66D0, 0x95DB, + 0x66D1, 0x95DC, + 0x66D2, 0x95DD, + 0x66D3, 0x95DE, + 0x66D4, 0x95DF, + 0x66D5, 0x95E0, + 0x66D6, 0x95E1, + 0x66D7, 0x95E2, + 0x66D8, 0x95E3, + 0x66DA, 0x95E4, + 0x66DE, 0x95E5, + 0x66DF, 0x95E6, + 0x66E0, 0x95E7, + 0x66E1, 0x95E8, + 0x66E2, 0x95E9, + 0x66E3, 0x95EA, + 0x66E4, 0x95EB, + 0x66E5, 0x95EC, + 0x66E7, 0x95ED, + 0x66E8, 0x95EE, + 0x66EA, 0x95EF, + 0x66EB, 0x95F0, + 0x66EC, 0x95F1, + 0x66ED, 0x95F2, + 0x66EE, 0x95F3, + 0x66EF, 0x95F4, + 0x66F1, 0x95F5, + 0x66F5, 0x95F6, + 0x66F6, 0x95F7, + 0x66F8, 0x95F8, + 0x66FA, 0x95F9, + 0x66FB, 0x95FA, + 0x66FD, 0x95FB, + 0x6701, 0x95FC, + 0x6702, 0x95FD, + 0x6703, 0x95FE, + 0x6704, 0x9640, + 0x6705, 0x9641, + 0x6706, 0x9642, + 0x6707, 0x9643, + 0x670C, 0x9644, + 0x670E, 0x9645, + 0x670F, 0x9646, + 0x6711, 0x9647, + 0x6712, 0x9648, + 0x6713, 0x9649, + 0x6716, 0x964A, + 0x6718, 0x964B, + 0x6719, 0x964C, + 0x671A, 0x964D, + 0x671C, 0x964E, + 0x671E, 0x964F, + 0x6720, 0x9650, + 0x6721, 0x9651, + 0x6722, 0x9652, + 0x6723, 0x9653, + 0x6724, 0x9654, + 0x6725, 0x9655, + 0x6727, 0x9656, + 0x6729, 0x9657, + 0x672E, 0x9658, + 0x6730, 0x9659, + 0x6732, 0x965A, + 0x6733, 0x965B, + 0x6736, 0x965C, + 0x6737, 0x965D, + 0x6738, 0x965E, + 0x6739, 0x965F, + 0x673B, 0x9660, + 0x673C, 0x9661, + 0x673E, 0x9662, + 0x673F, 0x9663, + 0x6741, 0x9664, + 0x6744, 0x9665, + 0x6745, 0x9666, + 0x6747, 0x9667, + 0x674A, 0x9668, + 0x674B, 0x9669, + 0x674D, 0x966A, + 0x6752, 0x966B, + 0x6754, 0x966C, + 0x6755, 0x966D, + 0x6757, 0x966E, + 0x6758, 0x966F, + 0x6759, 0x9670, + 0x675A, 0x9671, + 0x675B, 0x9672, + 0x675D, 0x9673, + 0x6762, 0x9674, + 0x6763, 0x9675, + 0x6764, 0x9676, + 0x6766, 0x9677, + 0x6767, 0x9678, + 0x676B, 0x9679, + 0x676C, 0x967A, + 0x676E, 0x967B, + 0x6771, 0x967C, + 0x6774, 0x967D, + 0x6776, 0x967E, + 0x6778, 0x9680, + 0x6779, 0x9681, + 0x677A, 0x9682, + 0x677B, 0x9683, + 0x677D, 0x9684, + 0x6780, 0x9685, + 0x6782, 0x9686, + 0x6783, 0x9687, + 0x6785, 0x9688, + 0x6786, 0x9689, + 0x6788, 0x968A, + 0x678A, 0x968B, + 0x678C, 0x968C, + 0x678D, 0x968D, + 0x678E, 0x968E, + 0x678F, 0x968F, + 0x6791, 0x9690, + 0x6792, 0x9691, + 0x6793, 0x9692, + 0x6794, 0x9693, + 0x6796, 0x9694, + 0x6799, 0x9695, + 0x679B, 0x9696, + 0x679F, 0x9697, + 0x67A0, 0x9698, + 0x67A1, 0x9699, + 0x67A4, 0x969A, + 0x67A6, 0x969B, + 0x67A9, 0x969C, + 0x67AC, 0x969D, + 0x67AE, 0x969E, + 0x67B1, 0x969F, + 0x67B2, 0x96A0, + 0x67B4, 0x96A1, + 0x67B9, 0x96A2, + 0x67BA, 0x96A3, + 0x67BB, 0x96A4, + 0x67BC, 0x96A5, + 0x67BD, 0x96A6, + 0x67BE, 0x96A7, + 0x67BF, 0x96A8, + 0x67C0, 0x96A9, + 0x67C2, 0x96AA, + 0x67C5, 0x96AB, + 0x67C6, 0x96AC, + 0x67C7, 0x96AD, + 0x67C8, 0x96AE, + 0x67C9, 0x96AF, + 0x67CA, 0x96B0, + 0x67CB, 0x96B1, + 0x67CC, 0x96B2, + 0x67CD, 0x96B3, + 0x67CE, 0x96B4, + 0x67D5, 0x96B5, + 0x67D6, 0x96B6, + 0x67D7, 0x96B7, + 0x67DB, 0x96B8, + 0x67DF, 0x96B9, + 0x67E1, 0x96BA, + 0x67E3, 0x96BB, + 0x67E4, 0x96BC, + 0x67E6, 0x96BD, + 0x67E7, 0x96BE, + 0x67E8, 0x96BF, + 0x67EA, 0x96C0, + 0x67EB, 0x96C1, + 0x67ED, 0x96C2, + 0x67EE, 0x96C3, + 0x67F2, 0x96C4, + 0x67F5, 0x96C5, + 0x67F6, 0x96C6, + 0x67F7, 0x96C7, + 0x67F8, 0x96C8, + 0x67F9, 0x96C9, + 0x67FA, 0x96CA, + 0x67FB, 0x96CB, + 0x67FC, 0x96CC, + 0x67FE, 0x96CD, + 0x6801, 0x96CE, + 0x6802, 0x96CF, + 0x6803, 0x96D0, + 0x6804, 0x96D1, + 0x6806, 0x96D2, + 0x680D, 0x96D3, + 0x6810, 0x96D4, + 0x6812, 0x96D5, + 0x6814, 0x96D6, + 0x6815, 0x96D7, + 0x6818, 0x96D8, + 0x6819, 0x96D9, + 0x681A, 0x96DA, + 0x681B, 0x96DB, + 0x681C, 0x96DC, + 0x681E, 0x96DD, + 0x681F, 0x96DE, + 0x6820, 0x96DF, + 0x6822, 0x96E0, + 0x6823, 0x96E1, + 0x6824, 0x96E2, + 0x6825, 0x96E3, + 0x6826, 0x96E4, + 0x6827, 0x96E5, + 0x6828, 0x96E6, + 0x682B, 0x96E7, + 0x682C, 0x96E8, + 0x682D, 0x96E9, + 0x682E, 0x96EA, + 0x682F, 0x96EB, + 0x6830, 0x96EC, + 0x6831, 0x96ED, + 0x6834, 0x96EE, + 0x6835, 0x96EF, + 0x6836, 0x96F0, + 0x683A, 0x96F1, + 0x683B, 0x96F2, + 0x683F, 0x96F3, + 0x6847, 0x96F4, + 0x684B, 0x96F5, + 0x684D, 0x96F6, + 0x684F, 0x96F7, + 0x6852, 0x96F8, + 0x6856, 0x96F9, + 0x6857, 0x96FA, + 0x6858, 0x96FB, + 0x6859, 0x96FC, + 0x685A, 0x96FD, + 0x685B, 0x96FE, + 0x685C, 0x9740, + 0x685D, 0x9741, + 0x685E, 0x9742, + 0x685F, 0x9743, + 0x686A, 0x9744, + 0x686C, 0x9745, + 0x686D, 0x9746, + 0x686E, 0x9747, + 0x686F, 0x9748, + 0x6870, 0x9749, + 0x6871, 0x974A, + 0x6872, 0x974B, + 0x6873, 0x974C, + 0x6875, 0x974D, + 0x6878, 0x974E, + 0x6879, 0x974F, + 0x687A, 0x9750, + 0x687B, 0x9751, + 0x687C, 0x9752, + 0x687D, 0x9753, + 0x687E, 0x9754, + 0x687F, 0x9755, + 0x6880, 0x9756, + 0x6882, 0x9757, + 0x6884, 0x9758, + 0x6887, 0x9759, + 0x6888, 0x975A, + 0x6889, 0x975B, + 0x688A, 0x975C, + 0x688B, 0x975D, + 0x688C, 0x975E, + 0x688D, 0x975F, + 0x688E, 0x9760, + 0x6890, 0x9761, + 0x6891, 0x9762, + 0x6892, 0x9763, + 0x6894, 0x9764, + 0x6895, 0x9765, + 0x6896, 0x9766, + 0x6898, 0x9767, + 0x6899, 0x9768, + 0x689A, 0x9769, + 0x689B, 0x976A, + 0x689C, 0x976B, + 0x689D, 0x976C, + 0x689E, 0x976D, + 0x689F, 0x976E, + 0x68A0, 0x976F, + 0x68A1, 0x9770, + 0x68A3, 0x9771, + 0x68A4, 0x9772, + 0x68A5, 0x9773, + 0x68A9, 0x9774, + 0x68AA, 0x9775, + 0x68AB, 0x9776, + 0x68AC, 0x9777, + 0x68AE, 0x9778, + 0x68B1, 0x9779, + 0x68B2, 0x977A, + 0x68B4, 0x977B, + 0x68B6, 0x977C, + 0x68B7, 0x977D, + 0x68B8, 0x977E, + 0x68B9, 0x9780, + 0x68BA, 0x9781, + 0x68BB, 0x9782, + 0x68BC, 0x9783, + 0x68BD, 0x9784, + 0x68BE, 0x9785, + 0x68BF, 0x9786, + 0x68C1, 0x9787, + 0x68C3, 0x9788, + 0x68C4, 0x9789, + 0x68C5, 0x978A, + 0x68C6, 0x978B, + 0x68C7, 0x978C, + 0x68C8, 0x978D, + 0x68CA, 0x978E, + 0x68CC, 0x978F, + 0x68CE, 0x9790, + 0x68CF, 0x9791, + 0x68D0, 0x9792, + 0x68D1, 0x9793, + 0x68D3, 0x9794, + 0x68D4, 0x9795, + 0x68D6, 0x9796, + 0x68D7, 0x9797, + 0x68D9, 0x9798, + 0x68DB, 0x9799, + 0x68DC, 0x979A, + 0x68DD, 0x979B, + 0x68DE, 0x979C, + 0x68DF, 0x979D, + 0x68E1, 0x979E, + 0x68E2, 0x979F, + 0x68E4, 0x97A0, + 0x68E5, 0x97A1, + 0x68E6, 0x97A2, + 0x68E7, 0x97A3, + 0x68E8, 0x97A4, + 0x68E9, 0x97A5, + 0x68EA, 0x97A6, + 0x68EB, 0x97A7, + 0x68EC, 0x97A8, + 0x68ED, 0x97A9, + 0x68EF, 0x97AA, + 0x68F2, 0x97AB, + 0x68F3, 0x97AC, + 0x68F4, 0x97AD, + 0x68F6, 0x97AE, + 0x68F7, 0x97AF, + 0x68F8, 0x97B0, + 0x68FB, 0x97B1, + 0x68FD, 0x97B2, + 0x68FE, 0x97B3, + 0x68FF, 0x97B4, + 0x6900, 0x97B5, + 0x6902, 0x97B6, + 0x6903, 0x97B7, + 0x6904, 0x97B8, + 0x6906, 0x97B9, + 0x6907, 0x97BA, + 0x6908, 0x97BB, + 0x6909, 0x97BC, + 0x690A, 0x97BD, + 0x690C, 0x97BE, + 0x690F, 0x97BF, + 0x6911, 0x97C0, + 0x6913, 0x97C1, + 0x6914, 0x97C2, + 0x6915, 0x97C3, + 0x6916, 0x97C4, + 0x6917, 0x97C5, + 0x6918, 0x97C6, + 0x6919, 0x97C7, + 0x691A, 0x97C8, + 0x691B, 0x97C9, + 0x691C, 0x97CA, + 0x691D, 0x97CB, + 0x691E, 0x97CC, + 0x6921, 0x97CD, + 0x6922, 0x97CE, + 0x6923, 0x97CF, + 0x6925, 0x97D0, + 0x6926, 0x97D1, + 0x6927, 0x97D2, + 0x6928, 0x97D3, + 0x6929, 0x97D4, + 0x692A, 0x97D5, + 0x692B, 0x97D6, + 0x692C, 0x97D7, + 0x692E, 0x97D8, + 0x692F, 0x97D9, + 0x6931, 0x97DA, + 0x6932, 0x97DB, + 0x6933, 0x97DC, + 0x6935, 0x97DD, + 0x6936, 0x97DE, + 0x6937, 0x97DF, + 0x6938, 0x97E0, + 0x693A, 0x97E1, + 0x693B, 0x97E2, + 0x693C, 0x97E3, + 0x693E, 0x97E4, + 0x6940, 0x97E5, + 0x6941, 0x97E6, + 0x6943, 0x97E7, + 0x6944, 0x97E8, + 0x6945, 0x97E9, + 0x6946, 0x97EA, + 0x6947, 0x97EB, + 0x6948, 0x97EC, + 0x6949, 0x97ED, + 0x694A, 0x97EE, + 0x694B, 0x97EF, + 0x694C, 0x97F0, + 0x694D, 0x97F1, + 0x694E, 0x97F2, + 0x694F, 0x97F3, + 0x6950, 0x97F4, + 0x6951, 0x97F5, + 0x6952, 0x97F6, + 0x6953, 0x97F7, + 0x6955, 0x97F8, + 0x6956, 0x97F9, + 0x6958, 0x97FA, + 0x6959, 0x97FB, + 0x695B, 0x97FC, + 0x695C, 0x97FD, + 0x695F, 0x97FE, + 0x6961, 0x9840, + 0x6962, 0x9841, + 0x6964, 0x9842, + 0x6965, 0x9843, + 0x6967, 0x9844, + 0x6968, 0x9845, + 0x6969, 0x9846, + 0x696A, 0x9847, + 0x696C, 0x9848, + 0x696D, 0x9849, + 0x696F, 0x984A, + 0x6970, 0x984B, + 0x6972, 0x984C, + 0x6973, 0x984D, + 0x6974, 0x984E, + 0x6975, 0x984F, + 0x6976, 0x9850, + 0x697A, 0x9851, + 0x697B, 0x9852, + 0x697D, 0x9853, + 0x697E, 0x9854, + 0x697F, 0x9855, + 0x6981, 0x9856, + 0x6983, 0x9857, + 0x6985, 0x9858, + 0x698A, 0x9859, + 0x698B, 0x985A, + 0x698C, 0x985B, + 0x698E, 0x985C, + 0x698F, 0x985D, + 0x6990, 0x985E, + 0x6991, 0x985F, + 0x6992, 0x9860, + 0x6993, 0x9861, + 0x6996, 0x9862, + 0x6997, 0x9863, + 0x6999, 0x9864, + 0x699A, 0x9865, + 0x699D, 0x9866, + 0x699E, 0x9867, + 0x699F, 0x9868, + 0x69A0, 0x9869, + 0x69A1, 0x986A, + 0x69A2, 0x986B, + 0x69A3, 0x986C, + 0x69A4, 0x986D, + 0x69A5, 0x986E, + 0x69A6, 0x986F, + 0x69A9, 0x9870, + 0x69AA, 0x9871, + 0x69AC, 0x9872, + 0x69AE, 0x9873, + 0x69AF, 0x9874, + 0x69B0, 0x9875, + 0x69B2, 0x9876, + 0x69B3, 0x9877, + 0x69B5, 0x9878, + 0x69B6, 0x9879, + 0x69B8, 0x987A, + 0x69B9, 0x987B, + 0x69BA, 0x987C, + 0x69BC, 0x987D, + 0x69BD, 0x987E, + 0x69BE, 0x9880, + 0x69BF, 0x9881, + 0x69C0, 0x9882, + 0x69C2, 0x9883, + 0x69C3, 0x9884, + 0x69C4, 0x9885, + 0x69C5, 0x9886, + 0x69C6, 0x9887, + 0x69C7, 0x9888, + 0x69C8, 0x9889, + 0x69C9, 0x988A, + 0x69CB, 0x988B, + 0x69CD, 0x988C, + 0x69CF, 0x988D, + 0x69D1, 0x988E, + 0x69D2, 0x988F, + 0x69D3, 0x9890, + 0x69D5, 0x9891, + 0x69D6, 0x9892, + 0x69D7, 0x9893, + 0x69D8, 0x9894, + 0x69D9, 0x9895, + 0x69DA, 0x9896, + 0x69DC, 0x9897, + 0x69DD, 0x9898, + 0x69DE, 0x9899, + 0x69E1, 0x989A, + 0x69E2, 0x989B, + 0x69E3, 0x989C, + 0x69E4, 0x989D, + 0x69E5, 0x989E, + 0x69E6, 0x989F, + 0x69E7, 0x98A0, + 0x69E8, 0x98A1, + 0x69E9, 0x98A2, + 0x69EA, 0x98A3, + 0x69EB, 0x98A4, + 0x69EC, 0x98A5, + 0x69EE, 0x98A6, + 0x69EF, 0x98A7, + 0x69F0, 0x98A8, + 0x69F1, 0x98A9, + 0x69F3, 0x98AA, + 0x69F4, 0x98AB, + 0x69F5, 0x98AC, + 0x69F6, 0x98AD, + 0x69F7, 0x98AE, + 0x69F8, 0x98AF, + 0x69F9, 0x98B0, + 0x69FA, 0x98B1, + 0x69FB, 0x98B2, + 0x69FC, 0x98B3, + 0x69FE, 0x98B4, + 0x6A00, 0x98B5, + 0x6A01, 0x98B6, + 0x6A02, 0x98B7, + 0x6A03, 0x98B8, + 0x6A04, 0x98B9, + 0x6A05, 0x98BA, + 0x6A06, 0x98BB, + 0x6A07, 0x98BC, + 0x6A08, 0x98BD, + 0x6A09, 0x98BE, + 0x6A0B, 0x98BF, + 0x6A0C, 0x98C0, + 0x6A0D, 0x98C1, + 0x6A0E, 0x98C2, + 0x6A0F, 0x98C3, + 0x6A10, 0x98C4, + 0x6A11, 0x98C5, + 0x6A12, 0x98C6, + 0x6A13, 0x98C7, + 0x6A14, 0x98C8, + 0x6A15, 0x98C9, + 0x6A16, 0x98CA, + 0x6A19, 0x98CB, + 0x6A1A, 0x98CC, + 0x6A1B, 0x98CD, + 0x6A1C, 0x98CE, + 0x6A1D, 0x98CF, + 0x6A1E, 0x98D0, + 0x6A20, 0x98D1, + 0x6A22, 0x98D2, + 0x6A23, 0x98D3, + 0x6A24, 0x98D4, + 0x6A25, 0x98D5, + 0x6A26, 0x98D6, + 0x6A27, 0x98D7, + 0x6A29, 0x98D8, + 0x6A2B, 0x98D9, + 0x6A2C, 0x98DA, + 0x6A2D, 0x98DB, + 0x6A2E, 0x98DC, + 0x6A30, 0x98DD, + 0x6A32, 0x98DE, + 0x6A33, 0x98DF, + 0x6A34, 0x98E0, + 0x6A36, 0x98E1, + 0x6A37, 0x98E2, + 0x6A38, 0x98E3, + 0x6A39, 0x98E4, + 0x6A3A, 0x98E5, + 0x6A3B, 0x98E6, + 0x6A3C, 0x98E7, + 0x6A3F, 0x98E8, + 0x6A40, 0x98E9, + 0x6A41, 0x98EA, + 0x6A42, 0x98EB, + 0x6A43, 0x98EC, + 0x6A45, 0x98ED, + 0x6A46, 0x98EE, + 0x6A48, 0x98EF, + 0x6A49, 0x98F0, + 0x6A4A, 0x98F1, + 0x6A4B, 0x98F2, + 0x6A4C, 0x98F3, + 0x6A4D, 0x98F4, + 0x6A4E, 0x98F5, + 0x6A4F, 0x98F6, + 0x6A51, 0x98F7, + 0x6A52, 0x98F8, + 0x6A53, 0x98F9, + 0x6A54, 0x98FA, + 0x6A55, 0x98FB, + 0x6A56, 0x98FC, + 0x6A57, 0x98FD, + 0x6A5A, 0x98FE, + 0x6A5C, 0x9940, + 0x6A5D, 0x9941, + 0x6A5E, 0x9942, + 0x6A5F, 0x9943, + 0x6A60, 0x9944, + 0x6A62, 0x9945, + 0x6A63, 0x9946, + 0x6A64, 0x9947, + 0x6A66, 0x9948, + 0x6A67, 0x9949, + 0x6A68, 0x994A, + 0x6A69, 0x994B, + 0x6A6A, 0x994C, + 0x6A6B, 0x994D, + 0x6A6C, 0x994E, + 0x6A6D, 0x994F, + 0x6A6E, 0x9950, + 0x6A6F, 0x9951, + 0x6A70, 0x9952, + 0x6A72, 0x9953, + 0x6A73, 0x9954, + 0x6A74, 0x9955, + 0x6A75, 0x9956, + 0x6A76, 0x9957, + 0x6A77, 0x9958, + 0x6A78, 0x9959, + 0x6A7A, 0x995A, + 0x6A7B, 0x995B, + 0x6A7D, 0x995C, + 0x6A7E, 0x995D, + 0x6A7F, 0x995E, + 0x6A81, 0x995F, + 0x6A82, 0x9960, + 0x6A83, 0x9961, + 0x6A85, 0x9962, + 0x6A86, 0x9963, + 0x6A87, 0x9964, + 0x6A88, 0x9965, + 0x6A89, 0x9966, + 0x6A8A, 0x9967, + 0x6A8B, 0x9968, + 0x6A8C, 0x9969, + 0x6A8D, 0x996A, + 0x6A8F, 0x996B, + 0x6A92, 0x996C, + 0x6A93, 0x996D, + 0x6A94, 0x996E, + 0x6A95, 0x996F, + 0x6A96, 0x9970, + 0x6A98, 0x9971, + 0x6A99, 0x9972, + 0x6A9A, 0x9973, + 0x6A9B, 0x9974, + 0x6A9C, 0x9975, + 0x6A9D, 0x9976, + 0x6A9E, 0x9977, + 0x6A9F, 0x9978, + 0x6AA1, 0x9979, + 0x6AA2, 0x997A, + 0x6AA3, 0x997B, + 0x6AA4, 0x997C, + 0x6AA5, 0x997D, + 0x6AA6, 0x997E, + 0x6AA7, 0x9980, + 0x6AA8, 0x9981, + 0x6AAA, 0x9982, + 0x6AAD, 0x9983, + 0x6AAE, 0x9984, + 0x6AAF, 0x9985, + 0x6AB0, 0x9986, + 0x6AB1, 0x9987, + 0x6AB2, 0x9988, + 0x6AB3, 0x9989, + 0x6AB4, 0x998A, + 0x6AB5, 0x998B, + 0x6AB6, 0x998C, + 0x6AB7, 0x998D, + 0x6AB8, 0x998E, + 0x6AB9, 0x998F, + 0x6ABA, 0x9990, + 0x6ABB, 0x9991, + 0x6ABC, 0x9992, + 0x6ABD, 0x9993, + 0x6ABE, 0x9994, + 0x6ABF, 0x9995, + 0x6AC0, 0x9996, + 0x6AC1, 0x9997, + 0x6AC2, 0x9998, + 0x6AC3, 0x9999, + 0x6AC4, 0x999A, + 0x6AC5, 0x999B, + 0x6AC6, 0x999C, + 0x6AC7, 0x999D, + 0x6AC8, 0x999E, + 0x6AC9, 0x999F, + 0x6ACA, 0x99A0, + 0x6ACB, 0x99A1, + 0x6ACC, 0x99A2, + 0x6ACD, 0x99A3, + 0x6ACE, 0x99A4, + 0x6ACF, 0x99A5, + 0x6AD0, 0x99A6, + 0x6AD1, 0x99A7, + 0x6AD2, 0x99A8, + 0x6AD3, 0x99A9, + 0x6AD4, 0x99AA, + 0x6AD5, 0x99AB, + 0x6AD6, 0x99AC, + 0x6AD7, 0x99AD, + 0x6AD8, 0x99AE, + 0x6AD9, 0x99AF, + 0x6ADA, 0x99B0, + 0x6ADB, 0x99B1, + 0x6ADC, 0x99B2, + 0x6ADD, 0x99B3, + 0x6ADE, 0x99B4, + 0x6ADF, 0x99B5, + 0x6AE0, 0x99B6, + 0x6AE1, 0x99B7, + 0x6AE2, 0x99B8, + 0x6AE3, 0x99B9, + 0x6AE4, 0x99BA, + 0x6AE5, 0x99BB, + 0x6AE6, 0x99BC, + 0x6AE7, 0x99BD, + 0x6AE8, 0x99BE, + 0x6AE9, 0x99BF, + 0x6AEA, 0x99C0, + 0x6AEB, 0x99C1, + 0x6AEC, 0x99C2, + 0x6AED, 0x99C3, + 0x6AEE, 0x99C4, + 0x6AEF, 0x99C5, + 0x6AF0, 0x99C6, + 0x6AF1, 0x99C7, + 0x6AF2, 0x99C8, + 0x6AF3, 0x99C9, + 0x6AF4, 0x99CA, + 0x6AF5, 0x99CB, + 0x6AF6, 0x99CC, + 0x6AF7, 0x99CD, + 0x6AF8, 0x99CE, + 0x6AF9, 0x99CF, + 0x6AFA, 0x99D0, + 0x6AFB, 0x99D1, + 0x6AFC, 0x99D2, + 0x6AFD, 0x99D3, + 0x6AFE, 0x99D4, + 0x6AFF, 0x99D5, + 0x6B00, 0x99D6, + 0x6B01, 0x99D7, + 0x6B02, 0x99D8, + 0x6B03, 0x99D9, + 0x6B04, 0x99DA, + 0x6B05, 0x99DB, + 0x6B06, 0x99DC, + 0x6B07, 0x99DD, + 0x6B08, 0x99DE, + 0x6B09, 0x99DF, + 0x6B0A, 0x99E0, + 0x6B0B, 0x99E1, + 0x6B0C, 0x99E2, + 0x6B0D, 0x99E3, + 0x6B0E, 0x99E4, + 0x6B0F, 0x99E5, + 0x6B10, 0x99E6, + 0x6B11, 0x99E7, + 0x6B12, 0x99E8, + 0x6B13, 0x99E9, + 0x6B14, 0x99EA, + 0x6B15, 0x99EB, + 0x6B16, 0x99EC, + 0x6B17, 0x99ED, + 0x6B18, 0x99EE, + 0x6B19, 0x99EF, + 0x6B1A, 0x99F0, + 0x6B1B, 0x99F1, + 0x6B1C, 0x99F2, + 0x6B1D, 0x99F3, + 0x6B1E, 0x99F4, + 0x6B1F, 0x99F5, + 0x6B25, 0x99F6, + 0x6B26, 0x99F7, + 0x6B28, 0x99F8, + 0x6B29, 0x99F9, + 0x6B2A, 0x99FA, + 0x6B2B, 0x99FB, + 0x6B2C, 0x99FC, + 0x6B2D, 0x99FD, + 0x6B2E, 0x99FE, + 0x6B2F, 0x9A40, + 0x6B30, 0x9A41, + 0x6B31, 0x9A42, + 0x6B33, 0x9A43, + 0x6B34, 0x9A44, + 0x6B35, 0x9A45, + 0x6B36, 0x9A46, + 0x6B38, 0x9A47, + 0x6B3B, 0x9A48, + 0x6B3C, 0x9A49, + 0x6B3D, 0x9A4A, + 0x6B3F, 0x9A4B, + 0x6B40, 0x9A4C, + 0x6B41, 0x9A4D, + 0x6B42, 0x9A4E, + 0x6B44, 0x9A4F, + 0x6B45, 0x9A50, + 0x6B48, 0x9A51, + 0x6B4A, 0x9A52, + 0x6B4B, 0x9A53, + 0x6B4D, 0x9A54, + 0x6B4E, 0x9A55, + 0x6B4F, 0x9A56, + 0x6B50, 0x9A57, + 0x6B51, 0x9A58, + 0x6B52, 0x9A59, + 0x6B53, 0x9A5A, + 0x6B54, 0x9A5B, + 0x6B55, 0x9A5C, + 0x6B56, 0x9A5D, + 0x6B57, 0x9A5E, + 0x6B58, 0x9A5F, + 0x6B5A, 0x9A60, + 0x6B5B, 0x9A61, + 0x6B5C, 0x9A62, + 0x6B5D, 0x9A63, + 0x6B5E, 0x9A64, + 0x6B5F, 0x9A65, + 0x6B60, 0x9A66, + 0x6B61, 0x9A67, + 0x6B68, 0x9A68, + 0x6B69, 0x9A69, + 0x6B6B, 0x9A6A, + 0x6B6C, 0x9A6B, + 0x6B6D, 0x9A6C, + 0x6B6E, 0x9A6D, + 0x6B6F, 0x9A6E, + 0x6B70, 0x9A6F, + 0x6B71, 0x9A70, + 0x6B72, 0x9A71, + 0x6B73, 0x9A72, + 0x6B74, 0x9A73, + 0x6B75, 0x9A74, + 0x6B76, 0x9A75, + 0x6B77, 0x9A76, + 0x6B78, 0x9A77, + 0x6B7A, 0x9A78, + 0x6B7D, 0x9A79, + 0x6B7E, 0x9A7A, + 0x6B7F, 0x9A7B, + 0x6B80, 0x9A7C, + 0x6B85, 0x9A7D, + 0x6B88, 0x9A7E, + 0x6B8C, 0x9A80, + 0x6B8E, 0x9A81, + 0x6B8F, 0x9A82, + 0x6B90, 0x9A83, + 0x6B91, 0x9A84, + 0x6B94, 0x9A85, + 0x6B95, 0x9A86, + 0x6B97, 0x9A87, + 0x6B98, 0x9A88, + 0x6B99, 0x9A89, + 0x6B9C, 0x9A8A, + 0x6B9D, 0x9A8B, + 0x6B9E, 0x9A8C, + 0x6B9F, 0x9A8D, + 0x6BA0, 0x9A8E, + 0x6BA2, 0x9A8F, + 0x6BA3, 0x9A90, + 0x6BA4, 0x9A91, + 0x6BA5, 0x9A92, + 0x6BA6, 0x9A93, + 0x6BA7, 0x9A94, + 0x6BA8, 0x9A95, + 0x6BA9, 0x9A96, + 0x6BAB, 0x9A97, + 0x6BAC, 0x9A98, + 0x6BAD, 0x9A99, + 0x6BAE, 0x9A9A, + 0x6BAF, 0x9A9B, + 0x6BB0, 0x9A9C, + 0x6BB1, 0x9A9D, + 0x6BB2, 0x9A9E, + 0x6BB6, 0x9A9F, + 0x6BB8, 0x9AA0, + 0x6BB9, 0x9AA1, + 0x6BBA, 0x9AA2, + 0x6BBB, 0x9AA3, + 0x6BBC, 0x9AA4, + 0x6BBD, 0x9AA5, + 0x6BBE, 0x9AA6, + 0x6BC0, 0x9AA7, + 0x6BC3, 0x9AA8, + 0x6BC4, 0x9AA9, + 0x6BC6, 0x9AAA, + 0x6BC7, 0x9AAB, + 0x6BC8, 0x9AAC, + 0x6BC9, 0x9AAD, + 0x6BCA, 0x9AAE, + 0x6BCC, 0x9AAF, + 0x6BCE, 0x9AB0, + 0x6BD0, 0x9AB1, + 0x6BD1, 0x9AB2, + 0x6BD8, 0x9AB3, + 0x6BDA, 0x9AB4, + 0x6BDC, 0x9AB5, + 0x6BDD, 0x9AB6, + 0x6BDE, 0x9AB7, + 0x6BDF, 0x9AB8, + 0x6BE0, 0x9AB9, + 0x6BE2, 0x9ABA, + 0x6BE3, 0x9ABB, + 0x6BE4, 0x9ABC, + 0x6BE5, 0x9ABD, + 0x6BE6, 0x9ABE, + 0x6BE7, 0x9ABF, + 0x6BE8, 0x9AC0, + 0x6BE9, 0x9AC1, + 0x6BEC, 0x9AC2, + 0x6BED, 0x9AC3, + 0x6BEE, 0x9AC4, + 0x6BF0, 0x9AC5, + 0x6BF1, 0x9AC6, + 0x6BF2, 0x9AC7, + 0x6BF4, 0x9AC8, + 0x6BF6, 0x9AC9, + 0x6BF7, 0x9ACA, + 0x6BF8, 0x9ACB, + 0x6BFA, 0x9ACC, + 0x6BFB, 0x9ACD, + 0x6BFC, 0x9ACE, + 0x6BFE, 0x9ACF, + 0x6BFF, 0x9AD0, + 0x6C00, 0x9AD1, + 0x6C01, 0x9AD2, + 0x6C02, 0x9AD3, + 0x6C03, 0x9AD4, + 0x6C04, 0x9AD5, + 0x6C08, 0x9AD6, + 0x6C09, 0x9AD7, + 0x6C0A, 0x9AD8, + 0x6C0B, 0x9AD9, + 0x6C0C, 0x9ADA, + 0x6C0E, 0x9ADB, + 0x6C12, 0x9ADC, + 0x6C17, 0x9ADD, + 0x6C1C, 0x9ADE, + 0x6C1D, 0x9ADF, + 0x6C1E, 0x9AE0, + 0x6C20, 0x9AE1, + 0x6C23, 0x9AE2, + 0x6C25, 0x9AE3, + 0x6C2B, 0x9AE4, + 0x6C2C, 0x9AE5, + 0x6C2D, 0x9AE6, + 0x6C31, 0x9AE7, + 0x6C33, 0x9AE8, + 0x6C36, 0x9AE9, + 0x6C37, 0x9AEA, + 0x6C39, 0x9AEB, + 0x6C3A, 0x9AEC, + 0x6C3B, 0x9AED, + 0x6C3C, 0x9AEE, + 0x6C3E, 0x9AEF, + 0x6C3F, 0x9AF0, + 0x6C43, 0x9AF1, + 0x6C44, 0x9AF2, + 0x6C45, 0x9AF3, + 0x6C48, 0x9AF4, + 0x6C4B, 0x9AF5, + 0x6C4C, 0x9AF6, + 0x6C4D, 0x9AF7, + 0x6C4E, 0x9AF8, + 0x6C4F, 0x9AF9, + 0x6C51, 0x9AFA, + 0x6C52, 0x9AFB, + 0x6C53, 0x9AFC, + 0x6C56, 0x9AFD, + 0x6C58, 0x9AFE, + 0x6C59, 0x9B40, + 0x6C5A, 0x9B41, + 0x6C62, 0x9B42, + 0x6C63, 0x9B43, + 0x6C65, 0x9B44, + 0x6C66, 0x9B45, + 0x6C67, 0x9B46, + 0x6C6B, 0x9B47, + 0x6C6C, 0x9B48, + 0x6C6D, 0x9B49, + 0x6C6E, 0x9B4A, + 0x6C6F, 0x9B4B, + 0x6C71, 0x9B4C, + 0x6C73, 0x9B4D, + 0x6C75, 0x9B4E, + 0x6C77, 0x9B4F, + 0x6C78, 0x9B50, + 0x6C7A, 0x9B51, + 0x6C7B, 0x9B52, + 0x6C7C, 0x9B53, + 0x6C7F, 0x9B54, + 0x6C80, 0x9B55, + 0x6C84, 0x9B56, + 0x6C87, 0x9B57, + 0x6C8A, 0x9B58, + 0x6C8B, 0x9B59, + 0x6C8D, 0x9B5A, + 0x6C8E, 0x9B5B, + 0x6C91, 0x9B5C, + 0x6C92, 0x9B5D, + 0x6C95, 0x9B5E, + 0x6C96, 0x9B5F, + 0x6C97, 0x9B60, + 0x6C98, 0x9B61, + 0x6C9A, 0x9B62, + 0x6C9C, 0x9B63, + 0x6C9D, 0x9B64, + 0x6C9E, 0x9B65, + 0x6CA0, 0x9B66, + 0x6CA2, 0x9B67, + 0x6CA8, 0x9B68, + 0x6CAC, 0x9B69, + 0x6CAF, 0x9B6A, + 0x6CB0, 0x9B6B, + 0x6CB4, 0x9B6C, + 0x6CB5, 0x9B6D, + 0x6CB6, 0x9B6E, + 0x6CB7, 0x9B6F, + 0x6CBA, 0x9B70, + 0x6CC0, 0x9B71, + 0x6CC1, 0x9B72, + 0x6CC2, 0x9B73, + 0x6CC3, 0x9B74, + 0x6CC6, 0x9B75, + 0x6CC7, 0x9B76, + 0x6CC8, 0x9B77, + 0x6CCB, 0x9B78, + 0x6CCD, 0x9B79, + 0x6CCE, 0x9B7A, + 0x6CCF, 0x9B7B, + 0x6CD1, 0x9B7C, + 0x6CD2, 0x9B7D, + 0x6CD8, 0x9B7E, + 0x6CD9, 0x9B80, + 0x6CDA, 0x9B81, + 0x6CDC, 0x9B82, + 0x6CDD, 0x9B83, + 0x6CDF, 0x9B84, + 0x6CE4, 0x9B85, + 0x6CE6, 0x9B86, + 0x6CE7, 0x9B87, + 0x6CE9, 0x9B88, + 0x6CEC, 0x9B89, + 0x6CED, 0x9B8A, + 0x6CF2, 0x9B8B, + 0x6CF4, 0x9B8C, + 0x6CF9, 0x9B8D, + 0x6CFF, 0x9B8E, + 0x6D00, 0x9B8F, + 0x6D02, 0x9B90, + 0x6D03, 0x9B91, + 0x6D05, 0x9B92, + 0x6D06, 0x9B93, + 0x6D08, 0x9B94, + 0x6D09, 0x9B95, + 0x6D0A, 0x9B96, + 0x6D0D, 0x9B97, + 0x6D0F, 0x9B98, + 0x6D10, 0x9B99, + 0x6D11, 0x9B9A, + 0x6D13, 0x9B9B, + 0x6D14, 0x9B9C, + 0x6D15, 0x9B9D, + 0x6D16, 0x9B9E, + 0x6D18, 0x9B9F, + 0x6D1C, 0x9BA0, + 0x6D1D, 0x9BA1, + 0x6D1F, 0x9BA2, + 0x6D20, 0x9BA3, + 0x6D21, 0x9BA4, + 0x6D22, 0x9BA5, + 0x6D23, 0x9BA6, + 0x6D24, 0x9BA7, + 0x6D26, 0x9BA8, + 0x6D28, 0x9BA9, + 0x6D29, 0x9BAA, + 0x6D2C, 0x9BAB, + 0x6D2D, 0x9BAC, + 0x6D2F, 0x9BAD, + 0x6D30, 0x9BAE, + 0x6D34, 0x9BAF, + 0x6D36, 0x9BB0, + 0x6D37, 0x9BB1, + 0x6D38, 0x9BB2, + 0x6D3A, 0x9BB3, + 0x6D3F, 0x9BB4, + 0x6D40, 0x9BB5, + 0x6D42, 0x9BB6, + 0x6D44, 0x9BB7, + 0x6D49, 0x9BB8, + 0x6D4C, 0x9BB9, + 0x6D50, 0x9BBA, + 0x6D55, 0x9BBB, + 0x6D56, 0x9BBC, + 0x6D57, 0x9BBD, + 0x6D58, 0x9BBE, + 0x6D5B, 0x9BBF, + 0x6D5D, 0x9BC0, + 0x6D5F, 0x9BC1, + 0x6D61, 0x9BC2, + 0x6D62, 0x9BC3, + 0x6D64, 0x9BC4, + 0x6D65, 0x9BC5, + 0x6D67, 0x9BC6, + 0x6D68, 0x9BC7, + 0x6D6B, 0x9BC8, + 0x6D6C, 0x9BC9, + 0x6D6D, 0x9BCA, + 0x6D70, 0x9BCB, + 0x6D71, 0x9BCC, + 0x6D72, 0x9BCD, + 0x6D73, 0x9BCE, + 0x6D75, 0x9BCF, + 0x6D76, 0x9BD0, + 0x6D79, 0x9BD1, + 0x6D7A, 0x9BD2, + 0x6D7B, 0x9BD3, + 0x6D7D, 0x9BD4, + 0x6D7E, 0x9BD5, + 0x6D7F, 0x9BD6, + 0x6D80, 0x9BD7, + 0x6D81, 0x9BD8, + 0x6D83, 0x9BD9, + 0x6D84, 0x9BDA, + 0x6D86, 0x9BDB, + 0x6D87, 0x9BDC, + 0x6D8A, 0x9BDD, + 0x6D8B, 0x9BDE, + 0x6D8D, 0x9BDF, + 0x6D8F, 0x9BE0, + 0x6D90, 0x9BE1, + 0x6D92, 0x9BE2, + 0x6D96, 0x9BE3, + 0x6D97, 0x9BE4, + 0x6D98, 0x9BE5, + 0x6D99, 0x9BE6, + 0x6D9A, 0x9BE7, + 0x6D9C, 0x9BE8, + 0x6DA2, 0x9BE9, + 0x6DA5, 0x9BEA, + 0x6DAC, 0x9BEB, + 0x6DAD, 0x9BEC, + 0x6DB0, 0x9BED, + 0x6DB1, 0x9BEE, + 0x6DB3, 0x9BEF, + 0x6DB4, 0x9BF0, + 0x6DB6, 0x9BF1, + 0x6DB7, 0x9BF2, + 0x6DB9, 0x9BF3, + 0x6DBA, 0x9BF4, + 0x6DBB, 0x9BF5, + 0x6DBC, 0x9BF6, + 0x6DBD, 0x9BF7, + 0x6DBE, 0x9BF8, + 0x6DC1, 0x9BF9, + 0x6DC2, 0x9BFA, + 0x6DC3, 0x9BFB, + 0x6DC8, 0x9BFC, + 0x6DC9, 0x9BFD, + 0x6DCA, 0x9BFE, + 0x6DCD, 0x9C40, + 0x6DCE, 0x9C41, + 0x6DCF, 0x9C42, + 0x6DD0, 0x9C43, + 0x6DD2, 0x9C44, + 0x6DD3, 0x9C45, + 0x6DD4, 0x9C46, + 0x6DD5, 0x9C47, + 0x6DD7, 0x9C48, + 0x6DDA, 0x9C49, + 0x6DDB, 0x9C4A, + 0x6DDC, 0x9C4B, + 0x6DDF, 0x9C4C, + 0x6DE2, 0x9C4D, + 0x6DE3, 0x9C4E, + 0x6DE5, 0x9C4F, + 0x6DE7, 0x9C50, + 0x6DE8, 0x9C51, + 0x6DE9, 0x9C52, + 0x6DEA, 0x9C53, + 0x6DED, 0x9C54, + 0x6DEF, 0x9C55, + 0x6DF0, 0x9C56, + 0x6DF2, 0x9C57, + 0x6DF4, 0x9C58, + 0x6DF5, 0x9C59, + 0x6DF6, 0x9C5A, + 0x6DF8, 0x9C5B, + 0x6DFA, 0x9C5C, + 0x6DFD, 0x9C5D, + 0x6DFE, 0x9C5E, + 0x6DFF, 0x9C5F, + 0x6E00, 0x9C60, + 0x6E01, 0x9C61, + 0x6E02, 0x9C62, + 0x6E03, 0x9C63, + 0x6E04, 0x9C64, + 0x6E06, 0x9C65, + 0x6E07, 0x9C66, + 0x6E08, 0x9C67, + 0x6E09, 0x9C68, + 0x6E0B, 0x9C69, + 0x6E0F, 0x9C6A, + 0x6E12, 0x9C6B, + 0x6E13, 0x9C6C, + 0x6E15, 0x9C6D, + 0x6E18, 0x9C6E, + 0x6E19, 0x9C6F, + 0x6E1B, 0x9C70, + 0x6E1C, 0x9C71, + 0x6E1E, 0x9C72, + 0x6E1F, 0x9C73, + 0x6E22, 0x9C74, + 0x6E26, 0x9C75, + 0x6E27, 0x9C76, + 0x6E28, 0x9C77, + 0x6E2A, 0x9C78, + 0x6E2C, 0x9C79, + 0x6E2E, 0x9C7A, + 0x6E30, 0x9C7B, + 0x6E31, 0x9C7C, + 0x6E33, 0x9C7D, + 0x6E35, 0x9C7E, + 0x6E36, 0x9C80, + 0x6E37, 0x9C81, + 0x6E39, 0x9C82, + 0x6E3B, 0x9C83, + 0x6E3C, 0x9C84, + 0x6E3D, 0x9C85, + 0x6E3E, 0x9C86, + 0x6E3F, 0x9C87, + 0x6E40, 0x9C88, + 0x6E41, 0x9C89, + 0x6E42, 0x9C8A, + 0x6E45, 0x9C8B, + 0x6E46, 0x9C8C, + 0x6E47, 0x9C8D, + 0x6E48, 0x9C8E, + 0x6E49, 0x9C8F, + 0x6E4A, 0x9C90, + 0x6E4B, 0x9C91, + 0x6E4C, 0x9C92, + 0x6E4F, 0x9C93, + 0x6E50, 0x9C94, + 0x6E51, 0x9C95, + 0x6E52, 0x9C96, + 0x6E55, 0x9C97, + 0x6E57, 0x9C98, + 0x6E59, 0x9C99, + 0x6E5A, 0x9C9A, + 0x6E5C, 0x9C9B, + 0x6E5D, 0x9C9C, + 0x6E5E, 0x9C9D, + 0x6E60, 0x9C9E, + 0x6E61, 0x9C9F, + 0x6E62, 0x9CA0, + 0x6E63, 0x9CA1, + 0x6E64, 0x9CA2, + 0x6E65, 0x9CA3, + 0x6E66, 0x9CA4, + 0x6E67, 0x9CA5, + 0x6E68, 0x9CA6, + 0x6E69, 0x9CA7, + 0x6E6A, 0x9CA8, + 0x6E6C, 0x9CA9, + 0x6E6D, 0x9CAA, + 0x6E6F, 0x9CAB, + 0x6E70, 0x9CAC, + 0x6E71, 0x9CAD, + 0x6E72, 0x9CAE, + 0x6E73, 0x9CAF, + 0x6E74, 0x9CB0, + 0x6E75, 0x9CB1, + 0x6E76, 0x9CB2, + 0x6E77, 0x9CB3, + 0x6E78, 0x9CB4, + 0x6E79, 0x9CB5, + 0x6E7A, 0x9CB6, + 0x6E7B, 0x9CB7, + 0x6E7C, 0x9CB8, + 0x6E7D, 0x9CB9, + 0x6E80, 0x9CBA, + 0x6E81, 0x9CBB, + 0x6E82, 0x9CBC, + 0x6E84, 0x9CBD, + 0x6E87, 0x9CBE, + 0x6E88, 0x9CBF, + 0x6E8A, 0x9CC0, + 0x6E8B, 0x9CC1, + 0x6E8C, 0x9CC2, + 0x6E8D, 0x9CC3, + 0x6E8E, 0x9CC4, + 0x6E91, 0x9CC5, + 0x6E92, 0x9CC6, + 0x6E93, 0x9CC7, + 0x6E94, 0x9CC8, + 0x6E95, 0x9CC9, + 0x6E96, 0x9CCA, + 0x6E97, 0x9CCB, + 0x6E99, 0x9CCC, + 0x6E9A, 0x9CCD, + 0x6E9B, 0x9CCE, + 0x6E9D, 0x9CCF, + 0x6E9E, 0x9CD0, + 0x6EA0, 0x9CD1, + 0x6EA1, 0x9CD2, + 0x6EA3, 0x9CD3, + 0x6EA4, 0x9CD4, + 0x6EA6, 0x9CD5, + 0x6EA8, 0x9CD6, + 0x6EA9, 0x9CD7, + 0x6EAB, 0x9CD8, + 0x6EAC, 0x9CD9, + 0x6EAD, 0x9CDA, + 0x6EAE, 0x9CDB, + 0x6EB0, 0x9CDC, + 0x6EB3, 0x9CDD, + 0x6EB5, 0x9CDE, + 0x6EB8, 0x9CDF, + 0x6EB9, 0x9CE0, + 0x6EBC, 0x9CE1, + 0x6EBE, 0x9CE2, + 0x6EBF, 0x9CE3, + 0x6EC0, 0x9CE4, + 0x6EC3, 0x9CE5, + 0x6EC4, 0x9CE6, + 0x6EC5, 0x9CE7, + 0x6EC6, 0x9CE8, + 0x6EC8, 0x9CE9, + 0x6EC9, 0x9CEA, + 0x6ECA, 0x9CEB, + 0x6ECC, 0x9CEC, + 0x6ECD, 0x9CED, + 0x6ECE, 0x9CEE, + 0x6ED0, 0x9CEF, + 0x6ED2, 0x9CF0, + 0x6ED6, 0x9CF1, + 0x6ED8, 0x9CF2, + 0x6ED9, 0x9CF3, + 0x6EDB, 0x9CF4, + 0x6EDC, 0x9CF5, + 0x6EDD, 0x9CF6, + 0x6EE3, 0x9CF7, + 0x6EE7, 0x9CF8, + 0x6EEA, 0x9CF9, + 0x6EEB, 0x9CFA, + 0x6EEC, 0x9CFB, + 0x6EED, 0x9CFC, + 0x6EEE, 0x9CFD, + 0x6EEF, 0x9CFE, + 0x6EF0, 0x9D40, + 0x6EF1, 0x9D41, + 0x6EF2, 0x9D42, + 0x6EF3, 0x9D43, + 0x6EF5, 0x9D44, + 0x6EF6, 0x9D45, + 0x6EF7, 0x9D46, + 0x6EF8, 0x9D47, + 0x6EFA, 0x9D48, + 0x6EFB, 0x9D49, + 0x6EFC, 0x9D4A, + 0x6EFD, 0x9D4B, + 0x6EFE, 0x9D4C, + 0x6EFF, 0x9D4D, + 0x6F00, 0x9D4E, + 0x6F01, 0x9D4F, + 0x6F03, 0x9D50, + 0x6F04, 0x9D51, + 0x6F05, 0x9D52, + 0x6F07, 0x9D53, + 0x6F08, 0x9D54, + 0x6F0A, 0x9D55, + 0x6F0B, 0x9D56, + 0x6F0C, 0x9D57, + 0x6F0D, 0x9D58, + 0x6F0E, 0x9D59, + 0x6F10, 0x9D5A, + 0x6F11, 0x9D5B, + 0x6F12, 0x9D5C, + 0x6F16, 0x9D5D, + 0x6F17, 0x9D5E, + 0x6F18, 0x9D5F, + 0x6F19, 0x9D60, + 0x6F1A, 0x9D61, + 0x6F1B, 0x9D62, + 0x6F1C, 0x9D63, + 0x6F1D, 0x9D64, + 0x6F1E, 0x9D65, + 0x6F1F, 0x9D66, + 0x6F21, 0x9D67, + 0x6F22, 0x9D68, + 0x6F23, 0x9D69, + 0x6F25, 0x9D6A, + 0x6F26, 0x9D6B, + 0x6F27, 0x9D6C, + 0x6F28, 0x9D6D, + 0x6F2C, 0x9D6E, + 0x6F2E, 0x9D6F, + 0x6F30, 0x9D70, + 0x6F32, 0x9D71, + 0x6F34, 0x9D72, + 0x6F35, 0x9D73, + 0x6F37, 0x9D74, + 0x6F38, 0x9D75, + 0x6F39, 0x9D76, + 0x6F3A, 0x9D77, + 0x6F3B, 0x9D78, + 0x6F3C, 0x9D79, + 0x6F3D, 0x9D7A, + 0x6F3F, 0x9D7B, + 0x6F40, 0x9D7C, + 0x6F41, 0x9D7D, + 0x6F42, 0x9D7E, + 0x6F43, 0x9D80, + 0x6F44, 0x9D81, + 0x6F45, 0x9D82, + 0x6F48, 0x9D83, + 0x6F49, 0x9D84, + 0x6F4A, 0x9D85, + 0x6F4C, 0x9D86, + 0x6F4E, 0x9D87, + 0x6F4F, 0x9D88, + 0x6F50, 0x9D89, + 0x6F51, 0x9D8A, + 0x6F52, 0x9D8B, + 0x6F53, 0x9D8C, + 0x6F54, 0x9D8D, + 0x6F55, 0x9D8E, + 0x6F56, 0x9D8F, + 0x6F57, 0x9D90, + 0x6F59, 0x9D91, + 0x6F5A, 0x9D92, + 0x6F5B, 0x9D93, + 0x6F5D, 0x9D94, + 0x6F5F, 0x9D95, + 0x6F60, 0x9D96, + 0x6F61, 0x9D97, + 0x6F63, 0x9D98, + 0x6F64, 0x9D99, + 0x6F65, 0x9D9A, + 0x6F67, 0x9D9B, + 0x6F68, 0x9D9C, + 0x6F69, 0x9D9D, + 0x6F6A, 0x9D9E, + 0x6F6B, 0x9D9F, + 0x6F6C, 0x9DA0, + 0x6F6F, 0x9DA1, + 0x6F70, 0x9DA2, + 0x6F71, 0x9DA3, + 0x6F73, 0x9DA4, + 0x6F75, 0x9DA5, + 0x6F76, 0x9DA6, + 0x6F77, 0x9DA7, + 0x6F79, 0x9DA8, + 0x6F7B, 0x9DA9, + 0x6F7D, 0x9DAA, + 0x6F7E, 0x9DAB, + 0x6F7F, 0x9DAC, + 0x6F80, 0x9DAD, + 0x6F81, 0x9DAE, + 0x6F82, 0x9DAF, + 0x6F83, 0x9DB0, + 0x6F85, 0x9DB1, + 0x6F86, 0x9DB2, + 0x6F87, 0x9DB3, + 0x6F8A, 0x9DB4, + 0x6F8B, 0x9DB5, + 0x6F8F, 0x9DB6, + 0x6F90, 0x9DB7, + 0x6F91, 0x9DB8, + 0x6F92, 0x9DB9, + 0x6F93, 0x9DBA, + 0x6F94, 0x9DBB, + 0x6F95, 0x9DBC, + 0x6F96, 0x9DBD, + 0x6F97, 0x9DBE, + 0x6F98, 0x9DBF, + 0x6F99, 0x9DC0, + 0x6F9A, 0x9DC1, + 0x6F9B, 0x9DC2, + 0x6F9D, 0x9DC3, + 0x6F9E, 0x9DC4, + 0x6F9F, 0x9DC5, + 0x6FA0, 0x9DC6, + 0x6FA2, 0x9DC7, + 0x6FA3, 0x9DC8, + 0x6FA4, 0x9DC9, + 0x6FA5, 0x9DCA, + 0x6FA6, 0x9DCB, + 0x6FA8, 0x9DCC, + 0x6FA9, 0x9DCD, + 0x6FAA, 0x9DCE, + 0x6FAB, 0x9DCF, + 0x6FAC, 0x9DD0, + 0x6FAD, 0x9DD1, + 0x6FAE, 0x9DD2, + 0x6FAF, 0x9DD3, + 0x6FB0, 0x9DD4, + 0x6FB1, 0x9DD5, + 0x6FB2, 0x9DD6, + 0x6FB4, 0x9DD7, + 0x6FB5, 0x9DD8, + 0x6FB7, 0x9DD9, + 0x6FB8, 0x9DDA, + 0x6FBA, 0x9DDB, + 0x6FBB, 0x9DDC, + 0x6FBC, 0x9DDD, + 0x6FBD, 0x9DDE, + 0x6FBE, 0x9DDF, + 0x6FBF, 0x9DE0, + 0x6FC1, 0x9DE1, + 0x6FC3, 0x9DE2, + 0x6FC4, 0x9DE3, + 0x6FC5, 0x9DE4, + 0x6FC6, 0x9DE5, + 0x6FC7, 0x9DE6, + 0x6FC8, 0x9DE7, + 0x6FCA, 0x9DE8, + 0x6FCB, 0x9DE9, + 0x6FCC, 0x9DEA, + 0x6FCD, 0x9DEB, + 0x6FCE, 0x9DEC, + 0x6FCF, 0x9DED, + 0x6FD0, 0x9DEE, + 0x6FD3, 0x9DEF, + 0x6FD4, 0x9DF0, + 0x6FD5, 0x9DF1, + 0x6FD6, 0x9DF2, + 0x6FD7, 0x9DF3, + 0x6FD8, 0x9DF4, + 0x6FD9, 0x9DF5, + 0x6FDA, 0x9DF6, + 0x6FDB, 0x9DF7, + 0x6FDC, 0x9DF8, + 0x6FDD, 0x9DF9, + 0x6FDF, 0x9DFA, + 0x6FE2, 0x9DFB, + 0x6FE3, 0x9DFC, + 0x6FE4, 0x9DFD, + 0x6FE5, 0x9DFE, + 0x6FE6, 0x9E40, + 0x6FE7, 0x9E41, + 0x6FE8, 0x9E42, + 0x6FE9, 0x9E43, + 0x6FEA, 0x9E44, + 0x6FEB, 0x9E45, + 0x6FEC, 0x9E46, + 0x6FED, 0x9E47, + 0x6FF0, 0x9E48, + 0x6FF1, 0x9E49, + 0x6FF2, 0x9E4A, + 0x6FF3, 0x9E4B, + 0x6FF4, 0x9E4C, + 0x6FF5, 0x9E4D, + 0x6FF6, 0x9E4E, + 0x6FF7, 0x9E4F, + 0x6FF8, 0x9E50, + 0x6FF9, 0x9E51, + 0x6FFA, 0x9E52, + 0x6FFB, 0x9E53, + 0x6FFC, 0x9E54, + 0x6FFD, 0x9E55, + 0x6FFE, 0x9E56, + 0x6FFF, 0x9E57, + 0x7000, 0x9E58, + 0x7001, 0x9E59, + 0x7002, 0x9E5A, + 0x7003, 0x9E5B, + 0x7004, 0x9E5C, + 0x7005, 0x9E5D, + 0x7006, 0x9E5E, + 0x7007, 0x9E5F, + 0x7008, 0x9E60, + 0x7009, 0x9E61, + 0x700A, 0x9E62, + 0x700B, 0x9E63, + 0x700C, 0x9E64, + 0x700D, 0x9E65, + 0x700E, 0x9E66, + 0x700F, 0x9E67, + 0x7010, 0x9E68, + 0x7012, 0x9E69, + 0x7013, 0x9E6A, + 0x7014, 0x9E6B, + 0x7015, 0x9E6C, + 0x7016, 0x9E6D, + 0x7017, 0x9E6E, + 0x7018, 0x9E6F, + 0x7019, 0x9E70, + 0x701C, 0x9E71, + 0x701D, 0x9E72, + 0x701E, 0x9E73, + 0x701F, 0x9E74, + 0x7020, 0x9E75, + 0x7021, 0x9E76, + 0x7022, 0x9E77, + 0x7024, 0x9E78, + 0x7025, 0x9E79, + 0x7026, 0x9E7A, + 0x7027, 0x9E7B, + 0x7028, 0x9E7C, + 0x7029, 0x9E7D, + 0x702A, 0x9E7E, + 0x702B, 0x9E80, + 0x702C, 0x9E81, + 0x702D, 0x9E82, + 0x702E, 0x9E83, + 0x702F, 0x9E84, + 0x7030, 0x9E85, + 0x7031, 0x9E86, + 0x7032, 0x9E87, + 0x7033, 0x9E88, + 0x7034, 0x9E89, + 0x7036, 0x9E8A, + 0x7037, 0x9E8B, + 0x7038, 0x9E8C, + 0x703A, 0x9E8D, + 0x703B, 0x9E8E, + 0x703C, 0x9E8F, + 0x703D, 0x9E90, + 0x703E, 0x9E91, + 0x703F, 0x9E92, + 0x7040, 0x9E93, + 0x7041, 0x9E94, + 0x7042, 0x9E95, + 0x7043, 0x9E96, + 0x7044, 0x9E97, + 0x7045, 0x9E98, + 0x7046, 0x9E99, + 0x7047, 0x9E9A, + 0x7048, 0x9E9B, + 0x7049, 0x9E9C, + 0x704A, 0x9E9D, + 0x704B, 0x9E9E, + 0x704D, 0x9E9F, + 0x704E, 0x9EA0, + 0x7050, 0x9EA1, + 0x7051, 0x9EA2, + 0x7052, 0x9EA3, + 0x7053, 0x9EA4, + 0x7054, 0x9EA5, + 0x7055, 0x9EA6, + 0x7056, 0x9EA7, + 0x7057, 0x9EA8, + 0x7058, 0x9EA9, + 0x7059, 0x9EAA, + 0x705A, 0x9EAB, + 0x705B, 0x9EAC, + 0x705C, 0x9EAD, + 0x705D, 0x9EAE, + 0x705F, 0x9EAF, + 0x7060, 0x9EB0, + 0x7061, 0x9EB1, + 0x7062, 0x9EB2, + 0x7063, 0x9EB3, + 0x7064, 0x9EB4, + 0x7065, 0x9EB5, + 0x7066, 0x9EB6, + 0x7067, 0x9EB7, + 0x7068, 0x9EB8, + 0x7069, 0x9EB9, + 0x706A, 0x9EBA, + 0x706E, 0x9EBB, + 0x7071, 0x9EBC, + 0x7072, 0x9EBD, + 0x7073, 0x9EBE, + 0x7074, 0x9EBF, + 0x7077, 0x9EC0, + 0x7079, 0x9EC1, + 0x707A, 0x9EC2, + 0x707B, 0x9EC3, + 0x707D, 0x9EC4, + 0x7081, 0x9EC5, + 0x7082, 0x9EC6, + 0x7083, 0x9EC7, + 0x7084, 0x9EC8, + 0x7086, 0x9EC9, + 0x7087, 0x9ECA, + 0x7088, 0x9ECB, + 0x708B, 0x9ECC, + 0x708C, 0x9ECD, + 0x708D, 0x9ECE, + 0x708F, 0x9ECF, + 0x7090, 0x9ED0, + 0x7091, 0x9ED1, + 0x7093, 0x9ED2, + 0x7097, 0x9ED3, + 0x7098, 0x9ED4, + 0x709A, 0x9ED5, + 0x709B, 0x9ED6, + 0x709E, 0x9ED7, + 0x709F, 0x9ED8, + 0x70A0, 0x9ED9, + 0x70A1, 0x9EDA, + 0x70A2, 0x9EDB, + 0x70A3, 0x9EDC, + 0x70A4, 0x9EDD, + 0x70A5, 0x9EDE, + 0x70A6, 0x9EDF, + 0x70A7, 0x9EE0, + 0x70A8, 0x9EE1, + 0x70A9, 0x9EE2, + 0x70AA, 0x9EE3, + 0x70B0, 0x9EE4, + 0x70B2, 0x9EE5, + 0x70B4, 0x9EE6, + 0x70B5, 0x9EE7, + 0x70B6, 0x9EE8, + 0x70BA, 0x9EE9, + 0x70BE, 0x9EEA, + 0x70BF, 0x9EEB, + 0x70C4, 0x9EEC, + 0x70C5, 0x9EED, + 0x70C6, 0x9EEE, + 0x70C7, 0x9EEF, + 0x70C9, 0x9EF0, + 0x70CB, 0x9EF1, + 0x70CC, 0x9EF2, + 0x70CD, 0x9EF3, + 0x70CE, 0x9EF4, + 0x70CF, 0x9EF5, + 0x70D0, 0x9EF6, + 0x70D1, 0x9EF7, + 0x70D2, 0x9EF8, + 0x70D3, 0x9EF9, + 0x70D4, 0x9EFA, + 0x70D5, 0x9EFB, + 0x70D6, 0x9EFC, + 0x70D7, 0x9EFD, + 0x70DA, 0x9EFE, + 0x70DC, 0x9F40, + 0x70DD, 0x9F41, + 0x70DE, 0x9F42, + 0x70E0, 0x9F43, + 0x70E1, 0x9F44, + 0x70E2, 0x9F45, + 0x70E3, 0x9F46, + 0x70E5, 0x9F47, + 0x70EA, 0x9F48, + 0x70EE, 0x9F49, + 0x70F0, 0x9F4A, + 0x70F1, 0x9F4B, + 0x70F2, 0x9F4C, + 0x70F3, 0x9F4D, + 0x70F4, 0x9F4E, + 0x70F5, 0x9F4F, + 0x70F6, 0x9F50, + 0x70F8, 0x9F51, + 0x70FA, 0x9F52, + 0x70FB, 0x9F53, + 0x70FC, 0x9F54, + 0x70FE, 0x9F55, + 0x70FF, 0x9F56, + 0x7100, 0x9F57, + 0x7101, 0x9F58, + 0x7102, 0x9F59, + 0x7103, 0x9F5A, + 0x7104, 0x9F5B, + 0x7105, 0x9F5C, + 0x7106, 0x9F5D, + 0x7107, 0x9F5E, + 0x7108, 0x9F5F, + 0x710B, 0x9F60, + 0x710C, 0x9F61, + 0x710D, 0x9F62, + 0x710E, 0x9F63, + 0x710F, 0x9F64, + 0x7111, 0x9F65, + 0x7112, 0x9F66, + 0x7114, 0x9F67, + 0x7117, 0x9F68, + 0x711B, 0x9F69, + 0x711C, 0x9F6A, + 0x711D, 0x9F6B, + 0x711E, 0x9F6C, + 0x711F, 0x9F6D, + 0x7120, 0x9F6E, + 0x7121, 0x9F6F, + 0x7122, 0x9F70, + 0x7123, 0x9F71, + 0x7124, 0x9F72, + 0x7125, 0x9F73, + 0x7127, 0x9F74, + 0x7128, 0x9F75, + 0x7129, 0x9F76, + 0x712A, 0x9F77, + 0x712B, 0x9F78, + 0x712C, 0x9F79, + 0x712D, 0x9F7A, + 0x712E, 0x9F7B, + 0x7132, 0x9F7C, + 0x7133, 0x9F7D, + 0x7134, 0x9F7E, + 0x7135, 0x9F80, + 0x7137, 0x9F81, + 0x7138, 0x9F82, + 0x7139, 0x9F83, + 0x713A, 0x9F84, + 0x713B, 0x9F85, + 0x713C, 0x9F86, + 0x713D, 0x9F87, + 0x713E, 0x9F88, + 0x713F, 0x9F89, + 0x7140, 0x9F8A, + 0x7141, 0x9F8B, + 0x7142, 0x9F8C, + 0x7143, 0x9F8D, + 0x7144, 0x9F8E, + 0x7146, 0x9F8F, + 0x7147, 0x9F90, + 0x7148, 0x9F91, + 0x7149, 0x9F92, + 0x714B, 0x9F93, + 0x714D, 0x9F94, + 0x714F, 0x9F95, + 0x7150, 0x9F96, + 0x7151, 0x9F97, + 0x7152, 0x9F98, + 0x7153, 0x9F99, + 0x7154, 0x9F9A, + 0x7155, 0x9F9B, + 0x7156, 0x9F9C, + 0x7157, 0x9F9D, + 0x7158, 0x9F9E, + 0x7159, 0x9F9F, + 0x715A, 0x9FA0, + 0x715B, 0x9FA1, + 0x715D, 0x9FA2, + 0x715F, 0x9FA3, + 0x7160, 0x9FA4, + 0x7161, 0x9FA5, + 0x7162, 0x9FA6, + 0x7163, 0x9FA7, + 0x7165, 0x9FA8, + 0x7169, 0x9FA9, + 0x716A, 0x9FAA, + 0x716B, 0x9FAB, + 0x716C, 0x9FAC, + 0x716D, 0x9FAD, + 0x716F, 0x9FAE, + 0x7170, 0x9FAF, + 0x7171, 0x9FB0, + 0x7174, 0x9FB1, + 0x7175, 0x9FB2, + 0x7176, 0x9FB3, + 0x7177, 0x9FB4, + 0x7179, 0x9FB5, + 0x717B, 0x9FB6, + 0x717C, 0x9FB7, + 0x717E, 0x9FB8, + 0x717F, 0x9FB9, + 0x7180, 0x9FBA, + 0x7181, 0x9FBB, + 0x7182, 0x9FBC, + 0x7183, 0x9FBD, + 0x7185, 0x9FBE, + 0x7186, 0x9FBF, + 0x7187, 0x9FC0, + 0x7188, 0x9FC1, + 0x7189, 0x9FC2, + 0x718B, 0x9FC3, + 0x718C, 0x9FC4, + 0x718D, 0x9FC5, + 0x718E, 0x9FC6, + 0x7190, 0x9FC7, + 0x7191, 0x9FC8, + 0x7192, 0x9FC9, + 0x7193, 0x9FCA, + 0x7195, 0x9FCB, + 0x7196, 0x9FCC, + 0x7197, 0x9FCD, + 0x719A, 0x9FCE, + 0x719B, 0x9FCF, + 0x719C, 0x9FD0, + 0x719D, 0x9FD1, + 0x719E, 0x9FD2, + 0x71A1, 0x9FD3, + 0x71A2, 0x9FD4, + 0x71A3, 0x9FD5, + 0x71A4, 0x9FD6, + 0x71A5, 0x9FD7, + 0x71A6, 0x9FD8, + 0x71A7, 0x9FD9, + 0x71A9, 0x9FDA, + 0x71AA, 0x9FDB, + 0x71AB, 0x9FDC, + 0x71AD, 0x9FDD, + 0x71AE, 0x9FDE, + 0x71AF, 0x9FDF, + 0x71B0, 0x9FE0, + 0x71B1, 0x9FE1, + 0x71B2, 0x9FE2, + 0x71B4, 0x9FE3, + 0x71B6, 0x9FE4, + 0x71B7, 0x9FE5, + 0x71B8, 0x9FE6, + 0x71BA, 0x9FE7, + 0x71BB, 0x9FE8, + 0x71BC, 0x9FE9, + 0x71BD, 0x9FEA, + 0x71BE, 0x9FEB, + 0x71BF, 0x9FEC, + 0x71C0, 0x9FED, + 0x71C1, 0x9FEE, + 0x71C2, 0x9FEF, + 0x71C4, 0x9FF0, + 0x71C5, 0x9FF1, + 0x71C6, 0x9FF2, + 0x71C7, 0x9FF3, + 0x71C8, 0x9FF4, + 0x71C9, 0x9FF5, + 0x71CA, 0x9FF6, + 0x71CB, 0x9FF7, + 0x71CC, 0x9FF8, + 0x71CD, 0x9FF9, + 0x71CF, 0x9FFA, + 0x71D0, 0x9FFB, + 0x71D1, 0x9FFC, + 0x71D2, 0x9FFD, + 0x71D3, 0x9FFE, + 0x71D6, 0xA040, + 0x71D7, 0xA041, + 0x71D8, 0xA042, + 0x71D9, 0xA043, + 0x71DA, 0xA044, + 0x71DB, 0xA045, + 0x71DC, 0xA046, + 0x71DD, 0xA047, + 0x71DE, 0xA048, + 0x71DF, 0xA049, + 0x71E1, 0xA04A, + 0x71E2, 0xA04B, + 0x71E3, 0xA04C, + 0x71E4, 0xA04D, + 0x71E6, 0xA04E, + 0x71E8, 0xA04F, + 0x71E9, 0xA050, + 0x71EA, 0xA051, + 0x71EB, 0xA052, + 0x71EC, 0xA053, + 0x71ED, 0xA054, + 0x71EF, 0xA055, + 0x71F0, 0xA056, + 0x71F1, 0xA057, + 0x71F2, 0xA058, + 0x71F3, 0xA059, + 0x71F4, 0xA05A, + 0x71F5, 0xA05B, + 0x71F6, 0xA05C, + 0x71F7, 0xA05D, + 0x71F8, 0xA05E, + 0x71FA, 0xA05F, + 0x71FB, 0xA060, + 0x71FC, 0xA061, + 0x71FD, 0xA062, + 0x71FE, 0xA063, + 0x71FF, 0xA064, + 0x7200, 0xA065, + 0x7201, 0xA066, + 0x7202, 0xA067, + 0x7203, 0xA068, + 0x7204, 0xA069, + 0x7205, 0xA06A, + 0x7207, 0xA06B, + 0x7208, 0xA06C, + 0x7209, 0xA06D, + 0x720A, 0xA06E, + 0x720B, 0xA06F, + 0x720C, 0xA070, + 0x720D, 0xA071, + 0x720E, 0xA072, + 0x720F, 0xA073, + 0x7210, 0xA074, + 0x7211, 0xA075, + 0x7212, 0xA076, + 0x7213, 0xA077, + 0x7214, 0xA078, + 0x7215, 0xA079, + 0x7216, 0xA07A, + 0x7217, 0xA07B, + 0x7218, 0xA07C, + 0x7219, 0xA07D, + 0x721A, 0xA07E, + 0x721B, 0xA080, + 0x721C, 0xA081, + 0x721E, 0xA082, + 0x721F, 0xA083, + 0x7220, 0xA084, + 0x7221, 0xA085, + 0x7222, 0xA086, + 0x7223, 0xA087, + 0x7224, 0xA088, + 0x7225, 0xA089, + 0x7226, 0xA08A, + 0x7227, 0xA08B, + 0x7229, 0xA08C, + 0x722B, 0xA08D, + 0x722D, 0xA08E, + 0x722E, 0xA08F, + 0x722F, 0xA090, + 0x7232, 0xA091, + 0x7233, 0xA092, + 0x7234, 0xA093, + 0x723A, 0xA094, + 0x723C, 0xA095, + 0x723E, 0xA096, + 0x7240, 0xA097, + 0x7241, 0xA098, + 0x7242, 0xA099, + 0x7243, 0xA09A, + 0x7244, 0xA09B, + 0x7245, 0xA09C, + 0x7246, 0xA09D, + 0x7249, 0xA09E, + 0x724A, 0xA09F, + 0x724B, 0xA0A0, + 0x724E, 0xA0A1, + 0x724F, 0xA0A2, + 0x7250, 0xA0A3, + 0x7251, 0xA0A4, + 0x7253, 0xA0A5, + 0x7254, 0xA0A6, + 0x7255, 0xA0A7, + 0x7257, 0xA0A8, + 0x7258, 0xA0A9, + 0x725A, 0xA0AA, + 0x725C, 0xA0AB, + 0x725E, 0xA0AC, + 0x7260, 0xA0AD, + 0x7263, 0xA0AE, + 0x7264, 0xA0AF, + 0x7265, 0xA0B0, + 0x7268, 0xA0B1, + 0x726A, 0xA0B2, + 0x726B, 0xA0B3, + 0x726C, 0xA0B4, + 0x726D, 0xA0B5, + 0x7270, 0xA0B6, + 0x7271, 0xA0B7, + 0x7273, 0xA0B8, + 0x7274, 0xA0B9, + 0x7276, 0xA0BA, + 0x7277, 0xA0BB, + 0x7278, 0xA0BC, + 0x727B, 0xA0BD, + 0x727C, 0xA0BE, + 0x727D, 0xA0BF, + 0x7282, 0xA0C0, + 0x7283, 0xA0C1, + 0x7285, 0xA0C2, + 0x7286, 0xA0C3, + 0x7287, 0xA0C4, + 0x7288, 0xA0C5, + 0x7289, 0xA0C6, + 0x728C, 0xA0C7, + 0x728E, 0xA0C8, + 0x7290, 0xA0C9, + 0x7291, 0xA0CA, + 0x7293, 0xA0CB, + 0x7294, 0xA0CC, + 0x7295, 0xA0CD, + 0x7296, 0xA0CE, + 0x7297, 0xA0CF, + 0x7298, 0xA0D0, + 0x7299, 0xA0D1, + 0x729A, 0xA0D2, + 0x729B, 0xA0D3, + 0x729C, 0xA0D4, + 0x729D, 0xA0D5, + 0x729E, 0xA0D6, + 0x72A0, 0xA0D7, + 0x72A1, 0xA0D8, + 0x72A2, 0xA0D9, + 0x72A3, 0xA0DA, + 0x72A4, 0xA0DB, + 0x72A5, 0xA0DC, + 0x72A6, 0xA0DD, + 0x72A7, 0xA0DE, + 0x72A8, 0xA0DF, + 0x72A9, 0xA0E0, + 0x72AA, 0xA0E1, + 0x72AB, 0xA0E2, + 0x72AE, 0xA0E3, + 0x72B1, 0xA0E4, + 0x72B2, 0xA0E5, + 0x72B3, 0xA0E6, + 0x72B5, 0xA0E7, + 0x72BA, 0xA0E8, + 0x72BB, 0xA0E9, + 0x72BC, 0xA0EA, + 0x72BD, 0xA0EB, + 0x72BE, 0xA0EC, + 0x72BF, 0xA0ED, + 0x72C0, 0xA0EE, + 0x72C5, 0xA0EF, + 0x72C6, 0xA0F0, + 0x72C7, 0xA0F1, + 0x72C9, 0xA0F2, + 0x72CA, 0xA0F3, + 0x72CB, 0xA0F4, + 0x72CC, 0xA0F5, + 0x72CF, 0xA0F6, + 0x72D1, 0xA0F7, + 0x72D3, 0xA0F8, + 0x72D4, 0xA0F9, + 0x72D5, 0xA0FA, + 0x72D6, 0xA0FB, + 0x72D8, 0xA0FC, + 0x72DA, 0xA0FD, + 0x72DB, 0xA0FE, + 0x72DC, 0xAA40, + 0x72DD, 0xAA41, + 0x72DF, 0xAA42, + 0x72E2, 0xAA43, + 0x72E3, 0xAA44, + 0x72E4, 0xAA45, + 0x72E5, 0xAA46, + 0x72E6, 0xAA47, + 0x72E7, 0xAA48, + 0x72EA, 0xAA49, + 0x72EB, 0xAA4A, + 0x72F5, 0xAA4B, + 0x72F6, 0xAA4C, + 0x72F9, 0xAA4D, + 0x72FD, 0xAA4E, + 0x72FE, 0xAA4F, + 0x72FF, 0xAA50, + 0x7300, 0xAA51, + 0x7302, 0xAA52, + 0x7304, 0xAA53, + 0x7305, 0xAA54, + 0x7306, 0xAA55, + 0x7307, 0xAA56, + 0x7308, 0xAA57, + 0x7309, 0xAA58, + 0x730B, 0xAA59, + 0x730C, 0xAA5A, + 0x730D, 0xAA5B, + 0x730F, 0xAA5C, + 0x7310, 0xAA5D, + 0x7311, 0xAA5E, + 0x7312, 0xAA5F, + 0x7314, 0xAA60, + 0x7318, 0xAA61, + 0x7319, 0xAA62, + 0x731A, 0xAA63, + 0x731F, 0xAA64, + 0x7320, 0xAA65, + 0x7323, 0xAA66, + 0x7324, 0xAA67, + 0x7326, 0xAA68, + 0x7327, 0xAA69, + 0x7328, 0xAA6A, + 0x732D, 0xAA6B, + 0x732F, 0xAA6C, + 0x7330, 0xAA6D, + 0x7332, 0xAA6E, + 0x7333, 0xAA6F, + 0x7335, 0xAA70, + 0x7336, 0xAA71, + 0x733A, 0xAA72, + 0x733B, 0xAA73, + 0x733C, 0xAA74, + 0x733D, 0xAA75, + 0x7340, 0xAA76, + 0x7341, 0xAA77, + 0x7342, 0xAA78, + 0x7343, 0xAA79, + 0x7344, 0xAA7A, + 0x7345, 0xAA7B, + 0x7346, 0xAA7C, + 0x7347, 0xAA7D, + 0x7348, 0xAA7E, + 0x7349, 0xAA80, + 0x734A, 0xAA81, + 0x734B, 0xAA82, + 0x734C, 0xAA83, + 0x734E, 0xAA84, + 0x734F, 0xAA85, + 0x7351, 0xAA86, + 0x7353, 0xAA87, + 0x7354, 0xAA88, + 0x7355, 0xAA89, + 0x7356, 0xAA8A, + 0x7358, 0xAA8B, + 0x7359, 0xAA8C, + 0x735A, 0xAA8D, + 0x735B, 0xAA8E, + 0x735C, 0xAA8F, + 0x735D, 0xAA90, + 0x735E, 0xAA91, + 0x735F, 0xAA92, + 0x7361, 0xAA93, + 0x7362, 0xAA94, + 0x7363, 0xAA95, + 0x7364, 0xAA96, + 0x7365, 0xAA97, + 0x7366, 0xAA98, + 0x7367, 0xAA99, + 0x7368, 0xAA9A, + 0x7369, 0xAA9B, + 0x736A, 0xAA9C, + 0x736B, 0xAA9D, + 0x736E, 0xAA9E, + 0x7370, 0xAA9F, + 0x7371, 0xAAA0, + 0x7372, 0xAB40, + 0x7373, 0xAB41, + 0x7374, 0xAB42, + 0x7375, 0xAB43, + 0x7376, 0xAB44, + 0x7377, 0xAB45, + 0x7378, 0xAB46, + 0x7379, 0xAB47, + 0x737A, 0xAB48, + 0x737B, 0xAB49, + 0x737C, 0xAB4A, + 0x737D, 0xAB4B, + 0x737F, 0xAB4C, + 0x7380, 0xAB4D, + 0x7381, 0xAB4E, + 0x7382, 0xAB4F, + 0x7383, 0xAB50, + 0x7385, 0xAB51, + 0x7386, 0xAB52, + 0x7388, 0xAB53, + 0x738A, 0xAB54, + 0x738C, 0xAB55, + 0x738D, 0xAB56, + 0x738F, 0xAB57, + 0x7390, 0xAB58, + 0x7392, 0xAB59, + 0x7393, 0xAB5A, + 0x7394, 0xAB5B, + 0x7395, 0xAB5C, + 0x7397, 0xAB5D, + 0x7398, 0xAB5E, + 0x7399, 0xAB5F, + 0x739A, 0xAB60, + 0x739C, 0xAB61, + 0x739D, 0xAB62, + 0x739E, 0xAB63, + 0x73A0, 0xAB64, + 0x73A1, 0xAB65, + 0x73A3, 0xAB66, + 0x73A4, 0xAB67, + 0x73A5, 0xAB68, + 0x73A6, 0xAB69, + 0x73A7, 0xAB6A, + 0x73A8, 0xAB6B, + 0x73AA, 0xAB6C, + 0x73AC, 0xAB6D, + 0x73AD, 0xAB6E, + 0x73B1, 0xAB6F, + 0x73B4, 0xAB70, + 0x73B5, 0xAB71, + 0x73B6, 0xAB72, + 0x73B8, 0xAB73, + 0x73B9, 0xAB74, + 0x73BC, 0xAB75, + 0x73BD, 0xAB76, + 0x73BE, 0xAB77, + 0x73BF, 0xAB78, + 0x73C1, 0xAB79, + 0x73C3, 0xAB7A, + 0x73C4, 0xAB7B, + 0x73C5, 0xAB7C, + 0x73C6, 0xAB7D, + 0x73C7, 0xAB7E, + 0x73CB, 0xAB80, + 0x73CC, 0xAB81, + 0x73CE, 0xAB82, + 0x73D2, 0xAB83, + 0x73D3, 0xAB84, + 0x73D4, 0xAB85, + 0x73D5, 0xAB86, + 0x73D6, 0xAB87, + 0x73D7, 0xAB88, + 0x73D8, 0xAB89, + 0x73DA, 0xAB8A, + 0x73DB, 0xAB8B, + 0x73DC, 0xAB8C, + 0x73DD, 0xAB8D, + 0x73DF, 0xAB8E, + 0x73E1, 0xAB8F, + 0x73E2, 0xAB90, + 0x73E3, 0xAB91, + 0x73E4, 0xAB92, + 0x73E6, 0xAB93, + 0x73E8, 0xAB94, + 0x73EA, 0xAB95, + 0x73EB, 0xAB96, + 0x73EC, 0xAB97, + 0x73EE, 0xAB98, + 0x73EF, 0xAB99, + 0x73F0, 0xAB9A, + 0x73F1, 0xAB9B, + 0x73F3, 0xAB9C, + 0x73F4, 0xAB9D, + 0x73F5, 0xAB9E, + 0x73F6, 0xAB9F, + 0x73F7, 0xABA0, + 0x73F8, 0xAC40, + 0x73F9, 0xAC41, + 0x73FA, 0xAC42, + 0x73FB, 0xAC43, + 0x73FC, 0xAC44, + 0x73FD, 0xAC45, + 0x73FE, 0xAC46, + 0x73FF, 0xAC47, + 0x7400, 0xAC48, + 0x7401, 0xAC49, + 0x7402, 0xAC4A, + 0x7404, 0xAC4B, + 0x7407, 0xAC4C, + 0x7408, 0xAC4D, + 0x740B, 0xAC4E, + 0x740C, 0xAC4F, + 0x740D, 0xAC50, + 0x740E, 0xAC51, + 0x7411, 0xAC52, + 0x7412, 0xAC53, + 0x7413, 0xAC54, + 0x7414, 0xAC55, + 0x7415, 0xAC56, + 0x7416, 0xAC57, + 0x7417, 0xAC58, + 0x7418, 0xAC59, + 0x7419, 0xAC5A, + 0x741C, 0xAC5B, + 0x741D, 0xAC5C, + 0x741E, 0xAC5D, + 0x741F, 0xAC5E, + 0x7420, 0xAC5F, + 0x7421, 0xAC60, + 0x7423, 0xAC61, + 0x7424, 0xAC62, + 0x7427, 0xAC63, + 0x7429, 0xAC64, + 0x742B, 0xAC65, + 0x742D, 0xAC66, + 0x742F, 0xAC67, + 0x7431, 0xAC68, + 0x7432, 0xAC69, + 0x7437, 0xAC6A, + 0x7438, 0xAC6B, + 0x7439, 0xAC6C, + 0x743A, 0xAC6D, + 0x743B, 0xAC6E, + 0x743D, 0xAC6F, + 0x743E, 0xAC70, + 0x743F, 0xAC71, + 0x7440, 0xAC72, + 0x7442, 0xAC73, + 0x7443, 0xAC74, + 0x7444, 0xAC75, + 0x7445, 0xAC76, + 0x7446, 0xAC77, + 0x7447, 0xAC78, + 0x7448, 0xAC79, + 0x7449, 0xAC7A, + 0x744A, 0xAC7B, + 0x744B, 0xAC7C, + 0x744C, 0xAC7D, + 0x744D, 0xAC7E, + 0x744E, 0xAC80, + 0x744F, 0xAC81, + 0x7450, 0xAC82, + 0x7451, 0xAC83, + 0x7452, 0xAC84, + 0x7453, 0xAC85, + 0x7454, 0xAC86, + 0x7456, 0xAC87, + 0x7458, 0xAC88, + 0x745D, 0xAC89, + 0x7460, 0xAC8A, + 0x7461, 0xAC8B, + 0x7462, 0xAC8C, + 0x7463, 0xAC8D, + 0x7464, 0xAC8E, + 0x7465, 0xAC8F, + 0x7466, 0xAC90, + 0x7467, 0xAC91, + 0x7468, 0xAC92, + 0x7469, 0xAC93, + 0x746A, 0xAC94, + 0x746B, 0xAC95, + 0x746C, 0xAC96, + 0x746E, 0xAC97, + 0x746F, 0xAC98, + 0x7471, 0xAC99, + 0x7472, 0xAC9A, + 0x7473, 0xAC9B, + 0x7474, 0xAC9C, + 0x7475, 0xAC9D, + 0x7478, 0xAC9E, + 0x7479, 0xAC9F, + 0x747A, 0xACA0, + 0x747B, 0xAD40, + 0x747C, 0xAD41, + 0x747D, 0xAD42, + 0x747F, 0xAD43, + 0x7482, 0xAD44, + 0x7484, 0xAD45, + 0x7485, 0xAD46, + 0x7486, 0xAD47, + 0x7488, 0xAD48, + 0x7489, 0xAD49, + 0x748A, 0xAD4A, + 0x748C, 0xAD4B, + 0x748D, 0xAD4C, + 0x748F, 0xAD4D, + 0x7491, 0xAD4E, + 0x7492, 0xAD4F, + 0x7493, 0xAD50, + 0x7494, 0xAD51, + 0x7495, 0xAD52, + 0x7496, 0xAD53, + 0x7497, 0xAD54, + 0x7498, 0xAD55, + 0x7499, 0xAD56, + 0x749A, 0xAD57, + 0x749B, 0xAD58, + 0x749D, 0xAD59, + 0x749F, 0xAD5A, + 0x74A0, 0xAD5B, + 0x74A1, 0xAD5C, + 0x74A2, 0xAD5D, + 0x74A3, 0xAD5E, + 0x74A4, 0xAD5F, + 0x74A5, 0xAD60, + 0x74A6, 0xAD61, + 0x74AA, 0xAD62, + 0x74AB, 0xAD63, + 0x74AC, 0xAD64, + 0x74AD, 0xAD65, + 0x74AE, 0xAD66, + 0x74AF, 0xAD67, + 0x74B0, 0xAD68, + 0x74B1, 0xAD69, + 0x74B2, 0xAD6A, + 0x74B3, 0xAD6B, + 0x74B4, 0xAD6C, + 0x74B5, 0xAD6D, + 0x74B6, 0xAD6E, + 0x74B7, 0xAD6F, + 0x74B8, 0xAD70, + 0x74B9, 0xAD71, + 0x74BB, 0xAD72, + 0x74BC, 0xAD73, + 0x74BD, 0xAD74, + 0x74BE, 0xAD75, + 0x74BF, 0xAD76, + 0x74C0, 0xAD77, + 0x74C1, 0xAD78, + 0x74C2, 0xAD79, + 0x74C3, 0xAD7A, + 0x74C4, 0xAD7B, + 0x74C5, 0xAD7C, + 0x74C6, 0xAD7D, + 0x74C7, 0xAD7E, + 0x74C8, 0xAD80, + 0x74C9, 0xAD81, + 0x74CA, 0xAD82, + 0x74CB, 0xAD83, + 0x74CC, 0xAD84, + 0x74CD, 0xAD85, + 0x74CE, 0xAD86, + 0x74CF, 0xAD87, + 0x74D0, 0xAD88, + 0x74D1, 0xAD89, + 0x74D3, 0xAD8A, + 0x74D4, 0xAD8B, + 0x74D5, 0xAD8C, + 0x74D6, 0xAD8D, + 0x74D7, 0xAD8E, + 0x74D8, 0xAD8F, + 0x74D9, 0xAD90, + 0x74DA, 0xAD91, + 0x74DB, 0xAD92, + 0x74DD, 0xAD93, + 0x74DF, 0xAD94, + 0x74E1, 0xAD95, + 0x74E5, 0xAD96, + 0x74E7, 0xAD97, + 0x74E8, 0xAD98, + 0x74E9, 0xAD99, + 0x74EA, 0xAD9A, + 0x74EB, 0xAD9B, + 0x74EC, 0xAD9C, + 0x74ED, 0xAD9D, + 0x74F0, 0xAD9E, + 0x74F1, 0xAD9F, + 0x74F2, 0xADA0, + 0x74F3, 0xAE40, + 0x74F5, 0xAE41, + 0x74F8, 0xAE42, + 0x74F9, 0xAE43, + 0x74FA, 0xAE44, + 0x74FB, 0xAE45, + 0x74FC, 0xAE46, + 0x74FD, 0xAE47, + 0x74FE, 0xAE48, + 0x7500, 0xAE49, + 0x7501, 0xAE4A, + 0x7502, 0xAE4B, + 0x7503, 0xAE4C, + 0x7505, 0xAE4D, + 0x7506, 0xAE4E, + 0x7507, 0xAE4F, + 0x7508, 0xAE50, + 0x7509, 0xAE51, + 0x750A, 0xAE52, + 0x750B, 0xAE53, + 0x750C, 0xAE54, + 0x750E, 0xAE55, + 0x7510, 0xAE56, + 0x7512, 0xAE57, + 0x7514, 0xAE58, + 0x7515, 0xAE59, + 0x7516, 0xAE5A, + 0x7517, 0xAE5B, + 0x751B, 0xAE5C, + 0x751D, 0xAE5D, + 0x751E, 0xAE5E, + 0x7520, 0xAE5F, + 0x7521, 0xAE60, + 0x7522, 0xAE61, + 0x7523, 0xAE62, + 0x7524, 0xAE63, + 0x7526, 0xAE64, + 0x7527, 0xAE65, + 0x752A, 0xAE66, + 0x752E, 0xAE67, + 0x7534, 0xAE68, + 0x7536, 0xAE69, + 0x7539, 0xAE6A, + 0x753C, 0xAE6B, + 0x753D, 0xAE6C, + 0x753F, 0xAE6D, + 0x7541, 0xAE6E, + 0x7542, 0xAE6F, + 0x7543, 0xAE70, + 0x7544, 0xAE71, + 0x7546, 0xAE72, + 0x7547, 0xAE73, + 0x7549, 0xAE74, + 0x754A, 0xAE75, + 0x754D, 0xAE76, + 0x7550, 0xAE77, + 0x7551, 0xAE78, + 0x7552, 0xAE79, + 0x7553, 0xAE7A, + 0x7555, 0xAE7B, + 0x7556, 0xAE7C, + 0x7557, 0xAE7D, + 0x7558, 0xAE7E, + 0x755D, 0xAE80, + 0x755E, 0xAE81, + 0x755F, 0xAE82, + 0x7560, 0xAE83, + 0x7561, 0xAE84, + 0x7562, 0xAE85, + 0x7563, 0xAE86, + 0x7564, 0xAE87, + 0x7567, 0xAE88, + 0x7568, 0xAE89, + 0x7569, 0xAE8A, + 0x756B, 0xAE8B, + 0x756C, 0xAE8C, + 0x756D, 0xAE8D, + 0x756E, 0xAE8E, + 0x756F, 0xAE8F, + 0x7570, 0xAE90, + 0x7571, 0xAE91, + 0x7573, 0xAE92, + 0x7575, 0xAE93, + 0x7576, 0xAE94, + 0x7577, 0xAE95, + 0x757A, 0xAE96, + 0x757B, 0xAE97, + 0x757C, 0xAE98, + 0x757D, 0xAE99, + 0x757E, 0xAE9A, + 0x7580, 0xAE9B, + 0x7581, 0xAE9C, + 0x7582, 0xAE9D, + 0x7584, 0xAE9E, + 0x7585, 0xAE9F, + 0x7587, 0xAEA0, + 0x7588, 0xAF40, + 0x7589, 0xAF41, + 0x758A, 0xAF42, + 0x758C, 0xAF43, + 0x758D, 0xAF44, + 0x758E, 0xAF45, + 0x7590, 0xAF46, + 0x7593, 0xAF47, + 0x7595, 0xAF48, + 0x7598, 0xAF49, + 0x759B, 0xAF4A, + 0x759C, 0xAF4B, + 0x759E, 0xAF4C, + 0x75A2, 0xAF4D, + 0x75A6, 0xAF4E, + 0x75A7, 0xAF4F, + 0x75A8, 0xAF50, + 0x75A9, 0xAF51, + 0x75AA, 0xAF52, + 0x75AD, 0xAF53, + 0x75B6, 0xAF54, + 0x75B7, 0xAF55, + 0x75BA, 0xAF56, + 0x75BB, 0xAF57, + 0x75BF, 0xAF58, + 0x75C0, 0xAF59, + 0x75C1, 0xAF5A, + 0x75C6, 0xAF5B, + 0x75CB, 0xAF5C, + 0x75CC, 0xAF5D, + 0x75CE, 0xAF5E, + 0x75CF, 0xAF5F, + 0x75D0, 0xAF60, + 0x75D1, 0xAF61, + 0x75D3, 0xAF62, + 0x75D7, 0xAF63, + 0x75D9, 0xAF64, + 0x75DA, 0xAF65, + 0x75DC, 0xAF66, + 0x75DD, 0xAF67, + 0x75DF, 0xAF68, + 0x75E0, 0xAF69, + 0x75E1, 0xAF6A, + 0x75E5, 0xAF6B, + 0x75E9, 0xAF6C, + 0x75EC, 0xAF6D, + 0x75ED, 0xAF6E, + 0x75EE, 0xAF6F, + 0x75EF, 0xAF70, + 0x75F2, 0xAF71, + 0x75F3, 0xAF72, + 0x75F5, 0xAF73, + 0x75F6, 0xAF74, + 0x75F7, 0xAF75, + 0x75F8, 0xAF76, + 0x75FA, 0xAF77, + 0x75FB, 0xAF78, + 0x75FD, 0xAF79, + 0x75FE, 0xAF7A, + 0x7602, 0xAF7B, + 0x7604, 0xAF7C, + 0x7606, 0xAF7D, + 0x7607, 0xAF7E, + 0x7608, 0xAF80, + 0x7609, 0xAF81, + 0x760B, 0xAF82, + 0x760D, 0xAF83, + 0x760E, 0xAF84, + 0x760F, 0xAF85, + 0x7611, 0xAF86, + 0x7612, 0xAF87, + 0x7613, 0xAF88, + 0x7614, 0xAF89, + 0x7616, 0xAF8A, + 0x761A, 0xAF8B, + 0x761C, 0xAF8C, + 0x761D, 0xAF8D, + 0x761E, 0xAF8E, + 0x7621, 0xAF8F, + 0x7623, 0xAF90, + 0x7627, 0xAF91, + 0x7628, 0xAF92, + 0x762C, 0xAF93, + 0x762E, 0xAF94, + 0x762F, 0xAF95, + 0x7631, 0xAF96, + 0x7632, 0xAF97, + 0x7636, 0xAF98, + 0x7637, 0xAF99, + 0x7639, 0xAF9A, + 0x763A, 0xAF9B, + 0x763B, 0xAF9C, + 0x763D, 0xAF9D, + 0x7641, 0xAF9E, + 0x7642, 0xAF9F, + 0x7644, 0xAFA0, + 0x7645, 0xB040, + 0x7646, 0xB041, + 0x7647, 0xB042, + 0x7648, 0xB043, + 0x7649, 0xB044, + 0x764A, 0xB045, + 0x764B, 0xB046, + 0x764E, 0xB047, + 0x764F, 0xB048, + 0x7650, 0xB049, + 0x7651, 0xB04A, + 0x7652, 0xB04B, + 0x7653, 0xB04C, + 0x7655, 0xB04D, + 0x7657, 0xB04E, + 0x7658, 0xB04F, + 0x7659, 0xB050, + 0x765A, 0xB051, + 0x765B, 0xB052, + 0x765D, 0xB053, + 0x765F, 0xB054, + 0x7660, 0xB055, + 0x7661, 0xB056, + 0x7662, 0xB057, + 0x7664, 0xB058, + 0x7665, 0xB059, + 0x7666, 0xB05A, + 0x7667, 0xB05B, + 0x7668, 0xB05C, + 0x7669, 0xB05D, + 0x766A, 0xB05E, + 0x766C, 0xB05F, + 0x766D, 0xB060, + 0x766E, 0xB061, + 0x7670, 0xB062, + 0x7671, 0xB063, + 0x7672, 0xB064, + 0x7673, 0xB065, + 0x7674, 0xB066, + 0x7675, 0xB067, + 0x7676, 0xB068, + 0x7677, 0xB069, + 0x7679, 0xB06A, + 0x767A, 0xB06B, + 0x767C, 0xB06C, + 0x767F, 0xB06D, + 0x7680, 0xB06E, + 0x7681, 0xB06F, + 0x7683, 0xB070, + 0x7685, 0xB071, + 0x7689, 0xB072, + 0x768A, 0xB073, + 0x768C, 0xB074, + 0x768D, 0xB075, + 0x768F, 0xB076, + 0x7690, 0xB077, + 0x7692, 0xB078, + 0x7694, 0xB079, + 0x7695, 0xB07A, + 0x7697, 0xB07B, + 0x7698, 0xB07C, + 0x769A, 0xB07D, + 0x769B, 0xB07E, + 0x769C, 0xB080, + 0x769D, 0xB081, + 0x769E, 0xB082, + 0x769F, 0xB083, + 0x76A0, 0xB084, + 0x76A1, 0xB085, + 0x76A2, 0xB086, + 0x76A3, 0xB087, + 0x76A5, 0xB088, + 0x76A6, 0xB089, + 0x76A7, 0xB08A, + 0x76A8, 0xB08B, + 0x76A9, 0xB08C, + 0x76AA, 0xB08D, + 0x76AB, 0xB08E, + 0x76AC, 0xB08F, + 0x76AD, 0xB090, + 0x76AF, 0xB091, + 0x76B0, 0xB092, + 0x76B3, 0xB093, + 0x76B5, 0xB094, + 0x76B6, 0xB095, + 0x76B7, 0xB096, + 0x76B8, 0xB097, + 0x76B9, 0xB098, + 0x76BA, 0xB099, + 0x76BB, 0xB09A, + 0x76BC, 0xB09B, + 0x76BD, 0xB09C, + 0x76BE, 0xB09D, + 0x76C0, 0xB09E, + 0x76C1, 0xB09F, + 0x76C3, 0xB0A0, + 0x76C4, 0xB140, + 0x76C7, 0xB141, + 0x76C9, 0xB142, + 0x76CB, 0xB143, + 0x76CC, 0xB144, + 0x76D3, 0xB145, + 0x76D5, 0xB146, + 0x76D9, 0xB147, + 0x76DA, 0xB148, + 0x76DC, 0xB149, + 0x76DD, 0xB14A, + 0x76DE, 0xB14B, + 0x76E0, 0xB14C, + 0x76E1, 0xB14D, + 0x76E2, 0xB14E, + 0x76E3, 0xB14F, + 0x76E4, 0xB150, + 0x76E6, 0xB151, + 0x76E7, 0xB152, + 0x76E8, 0xB153, + 0x76E9, 0xB154, + 0x76EA, 0xB155, + 0x76EB, 0xB156, + 0x76EC, 0xB157, + 0x76ED, 0xB158, + 0x76F0, 0xB159, + 0x76F3, 0xB15A, + 0x76F5, 0xB15B, + 0x76F6, 0xB15C, + 0x76F7, 0xB15D, + 0x76FA, 0xB15E, + 0x76FB, 0xB15F, + 0x76FD, 0xB160, + 0x76FF, 0xB161, + 0x7700, 0xB162, + 0x7702, 0xB163, + 0x7703, 0xB164, + 0x7705, 0xB165, + 0x7706, 0xB166, + 0x770A, 0xB167, + 0x770C, 0xB168, + 0x770E, 0xB169, + 0x770F, 0xB16A, + 0x7710, 0xB16B, + 0x7711, 0xB16C, + 0x7712, 0xB16D, + 0x7713, 0xB16E, + 0x7714, 0xB16F, + 0x7715, 0xB170, + 0x7716, 0xB171, + 0x7717, 0xB172, + 0x7718, 0xB173, + 0x771B, 0xB174, + 0x771C, 0xB175, + 0x771D, 0xB176, + 0x771E, 0xB177, + 0x7721, 0xB178, + 0x7723, 0xB179, + 0x7724, 0xB17A, + 0x7725, 0xB17B, + 0x7727, 0xB17C, + 0x772A, 0xB17D, + 0x772B, 0xB17E, + 0x772C, 0xB180, + 0x772E, 0xB181, + 0x7730, 0xB182, + 0x7731, 0xB183, + 0x7732, 0xB184, + 0x7733, 0xB185, + 0x7734, 0xB186, + 0x7739, 0xB187, + 0x773B, 0xB188, + 0x773D, 0xB189, + 0x773E, 0xB18A, + 0x773F, 0xB18B, + 0x7742, 0xB18C, + 0x7744, 0xB18D, + 0x7745, 0xB18E, + 0x7746, 0xB18F, + 0x7748, 0xB190, + 0x7749, 0xB191, + 0x774A, 0xB192, + 0x774B, 0xB193, + 0x774C, 0xB194, + 0x774D, 0xB195, + 0x774E, 0xB196, + 0x774F, 0xB197, + 0x7752, 0xB198, + 0x7753, 0xB199, + 0x7754, 0xB19A, + 0x7755, 0xB19B, + 0x7756, 0xB19C, + 0x7757, 0xB19D, + 0x7758, 0xB19E, + 0x7759, 0xB19F, + 0x775C, 0xB1A0, + 0x775D, 0xB240, + 0x775E, 0xB241, + 0x775F, 0xB242, + 0x7760, 0xB243, + 0x7764, 0xB244, + 0x7767, 0xB245, + 0x7769, 0xB246, + 0x776A, 0xB247, + 0x776D, 0xB248, + 0x776E, 0xB249, + 0x776F, 0xB24A, + 0x7770, 0xB24B, + 0x7771, 0xB24C, + 0x7772, 0xB24D, + 0x7773, 0xB24E, + 0x7774, 0xB24F, + 0x7775, 0xB250, + 0x7776, 0xB251, + 0x7777, 0xB252, + 0x7778, 0xB253, + 0x777A, 0xB254, + 0x777B, 0xB255, + 0x777C, 0xB256, + 0x7781, 0xB257, + 0x7782, 0xB258, + 0x7783, 0xB259, + 0x7786, 0xB25A, + 0x7787, 0xB25B, + 0x7788, 0xB25C, + 0x7789, 0xB25D, + 0x778A, 0xB25E, + 0x778B, 0xB25F, + 0x778F, 0xB260, + 0x7790, 0xB261, + 0x7793, 0xB262, + 0x7794, 0xB263, + 0x7795, 0xB264, + 0x7796, 0xB265, + 0x7797, 0xB266, + 0x7798, 0xB267, + 0x7799, 0xB268, + 0x779A, 0xB269, + 0x779B, 0xB26A, + 0x779C, 0xB26B, + 0x779D, 0xB26C, + 0x779E, 0xB26D, + 0x77A1, 0xB26E, + 0x77A3, 0xB26F, + 0x77A4, 0xB270, + 0x77A6, 0xB271, + 0x77A8, 0xB272, + 0x77AB, 0xB273, + 0x77AD, 0xB274, + 0x77AE, 0xB275, + 0x77AF, 0xB276, + 0x77B1, 0xB277, + 0x77B2, 0xB278, + 0x77B4, 0xB279, + 0x77B6, 0xB27A, + 0x77B7, 0xB27B, + 0x77B8, 0xB27C, + 0x77B9, 0xB27D, + 0x77BA, 0xB27E, + 0x77BC, 0xB280, + 0x77BE, 0xB281, + 0x77C0, 0xB282, + 0x77C1, 0xB283, + 0x77C2, 0xB284, + 0x77C3, 0xB285, + 0x77C4, 0xB286, + 0x77C5, 0xB287, + 0x77C6, 0xB288, + 0x77C7, 0xB289, + 0x77C8, 0xB28A, + 0x77C9, 0xB28B, + 0x77CA, 0xB28C, + 0x77CB, 0xB28D, + 0x77CC, 0xB28E, + 0x77CE, 0xB28F, + 0x77CF, 0xB290, + 0x77D0, 0xB291, + 0x77D1, 0xB292, + 0x77D2, 0xB293, + 0x77D3, 0xB294, + 0x77D4, 0xB295, + 0x77D5, 0xB296, + 0x77D6, 0xB297, + 0x77D8, 0xB298, + 0x77D9, 0xB299, + 0x77DA, 0xB29A, + 0x77DD, 0xB29B, + 0x77DE, 0xB29C, + 0x77DF, 0xB29D, + 0x77E0, 0xB29E, + 0x77E1, 0xB29F, + 0x77E4, 0xB2A0, + 0x77E6, 0xB340, + 0x77E8, 0xB341, + 0x77EA, 0xB342, + 0x77EF, 0xB343, + 0x77F0, 0xB344, + 0x77F1, 0xB345, + 0x77F2, 0xB346, + 0x77F4, 0xB347, + 0x77F5, 0xB348, + 0x77F7, 0xB349, + 0x77F9, 0xB34A, + 0x77FA, 0xB34B, + 0x77FB, 0xB34C, + 0x77FC, 0xB34D, + 0x7803, 0xB34E, + 0x7804, 0xB34F, + 0x7805, 0xB350, + 0x7806, 0xB351, + 0x7807, 0xB352, + 0x7808, 0xB353, + 0x780A, 0xB354, + 0x780B, 0xB355, + 0x780E, 0xB356, + 0x780F, 0xB357, + 0x7810, 0xB358, + 0x7813, 0xB359, + 0x7815, 0xB35A, + 0x7819, 0xB35B, + 0x781B, 0xB35C, + 0x781E, 0xB35D, + 0x7820, 0xB35E, + 0x7821, 0xB35F, + 0x7822, 0xB360, + 0x7824, 0xB361, + 0x7828, 0xB362, + 0x782A, 0xB363, + 0x782B, 0xB364, + 0x782E, 0xB365, + 0x782F, 0xB366, + 0x7831, 0xB367, + 0x7832, 0xB368, + 0x7833, 0xB369, + 0x7835, 0xB36A, + 0x7836, 0xB36B, + 0x783D, 0xB36C, + 0x783F, 0xB36D, + 0x7841, 0xB36E, + 0x7842, 0xB36F, + 0x7843, 0xB370, + 0x7844, 0xB371, + 0x7846, 0xB372, + 0x7848, 0xB373, + 0x7849, 0xB374, + 0x784A, 0xB375, + 0x784B, 0xB376, + 0x784D, 0xB377, + 0x784F, 0xB378, + 0x7851, 0xB379, + 0x7853, 0xB37A, + 0x7854, 0xB37B, + 0x7858, 0xB37C, + 0x7859, 0xB37D, + 0x785A, 0xB37E, + 0x785B, 0xB380, + 0x785C, 0xB381, + 0x785E, 0xB382, + 0x785F, 0xB383, + 0x7860, 0xB384, + 0x7861, 0xB385, + 0x7862, 0xB386, + 0x7863, 0xB387, + 0x7864, 0xB388, + 0x7865, 0xB389, + 0x7866, 0xB38A, + 0x7867, 0xB38B, + 0x7868, 0xB38C, + 0x7869, 0xB38D, + 0x786F, 0xB38E, + 0x7870, 0xB38F, + 0x7871, 0xB390, + 0x7872, 0xB391, + 0x7873, 0xB392, + 0x7874, 0xB393, + 0x7875, 0xB394, + 0x7876, 0xB395, + 0x7878, 0xB396, + 0x7879, 0xB397, + 0x787A, 0xB398, + 0x787B, 0xB399, + 0x787D, 0xB39A, + 0x787E, 0xB39B, + 0x787F, 0xB39C, + 0x7880, 0xB39D, + 0x7881, 0xB39E, + 0x7882, 0xB39F, + 0x7883, 0xB3A0, + 0x7884, 0xB440, + 0x7885, 0xB441, + 0x7886, 0xB442, + 0x7888, 0xB443, + 0x788A, 0xB444, + 0x788B, 0xB445, + 0x788F, 0xB446, + 0x7890, 0xB447, + 0x7892, 0xB448, + 0x7894, 0xB449, + 0x7895, 0xB44A, + 0x7896, 0xB44B, + 0x7899, 0xB44C, + 0x789D, 0xB44D, + 0x789E, 0xB44E, + 0x78A0, 0xB44F, + 0x78A2, 0xB450, + 0x78A4, 0xB451, + 0x78A6, 0xB452, + 0x78A8, 0xB453, + 0x78A9, 0xB454, + 0x78AA, 0xB455, + 0x78AB, 0xB456, + 0x78AC, 0xB457, + 0x78AD, 0xB458, + 0x78AE, 0xB459, + 0x78AF, 0xB45A, + 0x78B5, 0xB45B, + 0x78B6, 0xB45C, + 0x78B7, 0xB45D, + 0x78B8, 0xB45E, + 0x78BA, 0xB45F, + 0x78BB, 0xB460, + 0x78BC, 0xB461, + 0x78BD, 0xB462, + 0x78BF, 0xB463, + 0x78C0, 0xB464, + 0x78C2, 0xB465, + 0x78C3, 0xB466, + 0x78C4, 0xB467, + 0x78C6, 0xB468, + 0x78C7, 0xB469, + 0x78C8, 0xB46A, + 0x78CC, 0xB46B, + 0x78CD, 0xB46C, + 0x78CE, 0xB46D, + 0x78CF, 0xB46E, + 0x78D1, 0xB46F, + 0x78D2, 0xB470, + 0x78D3, 0xB471, + 0x78D6, 0xB472, + 0x78D7, 0xB473, + 0x78D8, 0xB474, + 0x78DA, 0xB475, + 0x78DB, 0xB476, + 0x78DC, 0xB477, + 0x78DD, 0xB478, + 0x78DE, 0xB479, + 0x78DF, 0xB47A, + 0x78E0, 0xB47B, + 0x78E1, 0xB47C, + 0x78E2, 0xB47D, + 0x78E3, 0xB47E, + 0x78E4, 0xB480, + 0x78E5, 0xB481, + 0x78E6, 0xB482, + 0x78E7, 0xB483, + 0x78E9, 0xB484, + 0x78EA, 0xB485, + 0x78EB, 0xB486, + 0x78ED, 0xB487, + 0x78EE, 0xB488, + 0x78EF, 0xB489, + 0x78F0, 0xB48A, + 0x78F1, 0xB48B, + 0x78F3, 0xB48C, + 0x78F5, 0xB48D, + 0x78F6, 0xB48E, + 0x78F8, 0xB48F, + 0x78F9, 0xB490, + 0x78FB, 0xB491, + 0x78FC, 0xB492, + 0x78FD, 0xB493, + 0x78FE, 0xB494, + 0x78FF, 0xB495, + 0x7900, 0xB496, + 0x7902, 0xB497, + 0x7903, 0xB498, + 0x7904, 0xB499, + 0x7906, 0xB49A, + 0x7907, 0xB49B, + 0x7908, 0xB49C, + 0x7909, 0xB49D, + 0x790A, 0xB49E, + 0x790B, 0xB49F, + 0x790C, 0xB4A0, + 0x790D, 0xB540, + 0x790E, 0xB541, + 0x790F, 0xB542, + 0x7910, 0xB543, + 0x7911, 0xB544, + 0x7912, 0xB545, + 0x7914, 0xB546, + 0x7915, 0xB547, + 0x7916, 0xB548, + 0x7917, 0xB549, + 0x7918, 0xB54A, + 0x7919, 0xB54B, + 0x791A, 0xB54C, + 0x791B, 0xB54D, + 0x791C, 0xB54E, + 0x791D, 0xB54F, + 0x791F, 0xB550, + 0x7920, 0xB551, + 0x7921, 0xB552, + 0x7922, 0xB553, + 0x7923, 0xB554, + 0x7925, 0xB555, + 0x7926, 0xB556, + 0x7927, 0xB557, + 0x7928, 0xB558, + 0x7929, 0xB559, + 0x792A, 0xB55A, + 0x792B, 0xB55B, + 0x792C, 0xB55C, + 0x792D, 0xB55D, + 0x792E, 0xB55E, + 0x792F, 0xB55F, + 0x7930, 0xB560, + 0x7931, 0xB561, + 0x7932, 0xB562, + 0x7933, 0xB563, + 0x7935, 0xB564, + 0x7936, 0xB565, + 0x7937, 0xB566, + 0x7938, 0xB567, + 0x7939, 0xB568, + 0x793D, 0xB569, + 0x793F, 0xB56A, + 0x7942, 0xB56B, + 0x7943, 0xB56C, + 0x7944, 0xB56D, + 0x7945, 0xB56E, + 0x7947, 0xB56F, + 0x794A, 0xB570, + 0x794B, 0xB571, + 0x794C, 0xB572, + 0x794D, 0xB573, + 0x794E, 0xB574, + 0x794F, 0xB575, + 0x7950, 0xB576, + 0x7951, 0xB577, + 0x7952, 0xB578, + 0x7954, 0xB579, + 0x7955, 0xB57A, + 0x7958, 0xB57B, + 0x7959, 0xB57C, + 0x7961, 0xB57D, + 0x7963, 0xB57E, + 0x7964, 0xB580, + 0x7966, 0xB581, + 0x7969, 0xB582, + 0x796A, 0xB583, + 0x796B, 0xB584, + 0x796C, 0xB585, + 0x796E, 0xB586, + 0x7970, 0xB587, + 0x7971, 0xB588, + 0x7972, 0xB589, + 0x7973, 0xB58A, + 0x7974, 0xB58B, + 0x7975, 0xB58C, + 0x7976, 0xB58D, + 0x7979, 0xB58E, + 0x797B, 0xB58F, + 0x797C, 0xB590, + 0x797D, 0xB591, + 0x797E, 0xB592, + 0x797F, 0xB593, + 0x7982, 0xB594, + 0x7983, 0xB595, + 0x7986, 0xB596, + 0x7987, 0xB597, + 0x7988, 0xB598, + 0x7989, 0xB599, + 0x798B, 0xB59A, + 0x798C, 0xB59B, + 0x798D, 0xB59C, + 0x798E, 0xB59D, + 0x7990, 0xB59E, + 0x7991, 0xB59F, + 0x7992, 0xB5A0, + 0x7993, 0xB640, + 0x7994, 0xB641, + 0x7995, 0xB642, + 0x7996, 0xB643, + 0x7997, 0xB644, + 0x7998, 0xB645, + 0x7999, 0xB646, + 0x799B, 0xB647, + 0x799C, 0xB648, + 0x799D, 0xB649, + 0x799E, 0xB64A, + 0x799F, 0xB64B, + 0x79A0, 0xB64C, + 0x79A1, 0xB64D, + 0x79A2, 0xB64E, + 0x79A3, 0xB64F, + 0x79A4, 0xB650, + 0x79A5, 0xB651, + 0x79A6, 0xB652, + 0x79A8, 0xB653, + 0x79A9, 0xB654, + 0x79AA, 0xB655, + 0x79AB, 0xB656, + 0x79AC, 0xB657, + 0x79AD, 0xB658, + 0x79AE, 0xB659, + 0x79AF, 0xB65A, + 0x79B0, 0xB65B, + 0x79B1, 0xB65C, + 0x79B2, 0xB65D, + 0x79B4, 0xB65E, + 0x79B5, 0xB65F, + 0x79B6, 0xB660, + 0x79B7, 0xB661, + 0x79B8, 0xB662, + 0x79BC, 0xB663, + 0x79BF, 0xB664, + 0x79C2, 0xB665, + 0x79C4, 0xB666, + 0x79C5, 0xB667, + 0x79C7, 0xB668, + 0x79C8, 0xB669, + 0x79CA, 0xB66A, + 0x79CC, 0xB66B, + 0x79CE, 0xB66C, + 0x79CF, 0xB66D, + 0x79D0, 0xB66E, + 0x79D3, 0xB66F, + 0x79D4, 0xB670, + 0x79D6, 0xB671, + 0x79D7, 0xB672, + 0x79D9, 0xB673, + 0x79DA, 0xB674, + 0x79DB, 0xB675, + 0x79DC, 0xB676, + 0x79DD, 0xB677, + 0x79DE, 0xB678, + 0x79E0, 0xB679, + 0x79E1, 0xB67A, + 0x79E2, 0xB67B, + 0x79E5, 0xB67C, + 0x79E8, 0xB67D, + 0x79EA, 0xB67E, + 0x79EC, 0xB680, + 0x79EE, 0xB681, + 0x79F1, 0xB682, + 0x79F2, 0xB683, + 0x79F3, 0xB684, + 0x79F4, 0xB685, + 0x79F5, 0xB686, + 0x79F6, 0xB687, + 0x79F7, 0xB688, + 0x79F9, 0xB689, + 0x79FA, 0xB68A, + 0x79FC, 0xB68B, + 0x79FE, 0xB68C, + 0x79FF, 0xB68D, + 0x7A01, 0xB68E, + 0x7A04, 0xB68F, + 0x7A05, 0xB690, + 0x7A07, 0xB691, + 0x7A08, 0xB692, + 0x7A09, 0xB693, + 0x7A0A, 0xB694, + 0x7A0C, 0xB695, + 0x7A0F, 0xB696, + 0x7A10, 0xB697, + 0x7A11, 0xB698, + 0x7A12, 0xB699, + 0x7A13, 0xB69A, + 0x7A15, 0xB69B, + 0x7A16, 0xB69C, + 0x7A18, 0xB69D, + 0x7A19, 0xB69E, + 0x7A1B, 0xB69F, + 0x7A1C, 0xB6A0, + 0x7A1D, 0xB740, + 0x7A1F, 0xB741, + 0x7A21, 0xB742, + 0x7A22, 0xB743, + 0x7A24, 0xB744, + 0x7A25, 0xB745, + 0x7A26, 0xB746, + 0x7A27, 0xB747, + 0x7A28, 0xB748, + 0x7A29, 0xB749, + 0x7A2A, 0xB74A, + 0x7A2B, 0xB74B, + 0x7A2C, 0xB74C, + 0x7A2D, 0xB74D, + 0x7A2E, 0xB74E, + 0x7A2F, 0xB74F, + 0x7A30, 0xB750, + 0x7A31, 0xB751, + 0x7A32, 0xB752, + 0x7A34, 0xB753, + 0x7A35, 0xB754, + 0x7A36, 0xB755, + 0x7A38, 0xB756, + 0x7A3A, 0xB757, + 0x7A3E, 0xB758, + 0x7A40, 0xB759, + 0x7A41, 0xB75A, + 0x7A42, 0xB75B, + 0x7A43, 0xB75C, + 0x7A44, 0xB75D, + 0x7A45, 0xB75E, + 0x7A47, 0xB75F, + 0x7A48, 0xB760, + 0x7A49, 0xB761, + 0x7A4A, 0xB762, + 0x7A4B, 0xB763, + 0x7A4C, 0xB764, + 0x7A4D, 0xB765, + 0x7A4E, 0xB766, + 0x7A4F, 0xB767, + 0x7A50, 0xB768, + 0x7A52, 0xB769, + 0x7A53, 0xB76A, + 0x7A54, 0xB76B, + 0x7A55, 0xB76C, + 0x7A56, 0xB76D, + 0x7A58, 0xB76E, + 0x7A59, 0xB76F, + 0x7A5A, 0xB770, + 0x7A5B, 0xB771, + 0x7A5C, 0xB772, + 0x7A5D, 0xB773, + 0x7A5E, 0xB774, + 0x7A5F, 0xB775, + 0x7A60, 0xB776, + 0x7A61, 0xB777, + 0x7A62, 0xB778, + 0x7A63, 0xB779, + 0x7A64, 0xB77A, + 0x7A65, 0xB77B, + 0x7A66, 0xB77C, + 0x7A67, 0xB77D, + 0x7A68, 0xB77E, + 0x7A69, 0xB780, + 0x7A6A, 0xB781, + 0x7A6B, 0xB782, + 0x7A6C, 0xB783, + 0x7A6D, 0xB784, + 0x7A6E, 0xB785, + 0x7A6F, 0xB786, + 0x7A71, 0xB787, + 0x7A72, 0xB788, + 0x7A73, 0xB789, + 0x7A75, 0xB78A, + 0x7A7B, 0xB78B, + 0x7A7C, 0xB78C, + 0x7A7D, 0xB78D, + 0x7A7E, 0xB78E, + 0x7A82, 0xB78F, + 0x7A85, 0xB790, + 0x7A87, 0xB791, + 0x7A89, 0xB792, + 0x7A8A, 0xB793, + 0x7A8B, 0xB794, + 0x7A8C, 0xB795, + 0x7A8E, 0xB796, + 0x7A8F, 0xB797, + 0x7A90, 0xB798, + 0x7A93, 0xB799, + 0x7A94, 0xB79A, + 0x7A99, 0xB79B, + 0x7A9A, 0xB79C, + 0x7A9B, 0xB79D, + 0x7A9E, 0xB79E, + 0x7AA1, 0xB79F, + 0x7AA2, 0xB7A0, + 0x7AA3, 0xB840, + 0x7AA4, 0xB841, + 0x7AA7, 0xB842, + 0x7AA9, 0xB843, + 0x7AAA, 0xB844, + 0x7AAB, 0xB845, + 0x7AAE, 0xB846, + 0x7AAF, 0xB847, + 0x7AB0, 0xB848, + 0x7AB1, 0xB849, + 0x7AB2, 0xB84A, + 0x7AB4, 0xB84B, + 0x7AB5, 0xB84C, + 0x7AB6, 0xB84D, + 0x7AB7, 0xB84E, + 0x7AB8, 0xB84F, + 0x7AB9, 0xB850, + 0x7ABA, 0xB851, + 0x7ABB, 0xB852, + 0x7ABC, 0xB853, + 0x7ABD, 0xB854, + 0x7ABE, 0xB855, + 0x7AC0, 0xB856, + 0x7AC1, 0xB857, + 0x7AC2, 0xB858, + 0x7AC3, 0xB859, + 0x7AC4, 0xB85A, + 0x7AC5, 0xB85B, + 0x7AC6, 0xB85C, + 0x7AC7, 0xB85D, + 0x7AC8, 0xB85E, + 0x7AC9, 0xB85F, + 0x7ACA, 0xB860, + 0x7ACC, 0xB861, + 0x7ACD, 0xB862, + 0x7ACE, 0xB863, + 0x7ACF, 0xB864, + 0x7AD0, 0xB865, + 0x7AD1, 0xB866, + 0x7AD2, 0xB867, + 0x7AD3, 0xB868, + 0x7AD4, 0xB869, + 0x7AD5, 0xB86A, + 0x7AD7, 0xB86B, + 0x7AD8, 0xB86C, + 0x7ADA, 0xB86D, + 0x7ADB, 0xB86E, + 0x7ADC, 0xB86F, + 0x7ADD, 0xB870, + 0x7AE1, 0xB871, + 0x7AE2, 0xB872, + 0x7AE4, 0xB873, + 0x7AE7, 0xB874, + 0x7AE8, 0xB875, + 0x7AE9, 0xB876, + 0x7AEA, 0xB877, + 0x7AEB, 0xB878, + 0x7AEC, 0xB879, + 0x7AEE, 0xB87A, + 0x7AF0, 0xB87B, + 0x7AF1, 0xB87C, + 0x7AF2, 0xB87D, + 0x7AF3, 0xB87E, + 0x7AF4, 0xB880, + 0x7AF5, 0xB881, + 0x7AF6, 0xB882, + 0x7AF7, 0xB883, + 0x7AF8, 0xB884, + 0x7AFB, 0xB885, + 0x7AFC, 0xB886, + 0x7AFE, 0xB887, + 0x7B00, 0xB888, + 0x7B01, 0xB889, + 0x7B02, 0xB88A, + 0x7B05, 0xB88B, + 0x7B07, 0xB88C, + 0x7B09, 0xB88D, + 0x7B0C, 0xB88E, + 0x7B0D, 0xB88F, + 0x7B0E, 0xB890, + 0x7B10, 0xB891, + 0x7B12, 0xB892, + 0x7B13, 0xB893, + 0x7B16, 0xB894, + 0x7B17, 0xB895, + 0x7B18, 0xB896, + 0x7B1A, 0xB897, + 0x7B1C, 0xB898, + 0x7B1D, 0xB899, + 0x7B1F, 0xB89A, + 0x7B21, 0xB89B, + 0x7B22, 0xB89C, + 0x7B23, 0xB89D, + 0x7B27, 0xB89E, + 0x7B29, 0xB89F, + 0x7B2D, 0xB8A0, + 0x7B2F, 0xB940, + 0x7B30, 0xB941, + 0x7B32, 0xB942, + 0x7B34, 0xB943, + 0x7B35, 0xB944, + 0x7B36, 0xB945, + 0x7B37, 0xB946, + 0x7B39, 0xB947, + 0x7B3B, 0xB948, + 0x7B3D, 0xB949, + 0x7B3F, 0xB94A, + 0x7B40, 0xB94B, + 0x7B41, 0xB94C, + 0x7B42, 0xB94D, + 0x7B43, 0xB94E, + 0x7B44, 0xB94F, + 0x7B46, 0xB950, + 0x7B48, 0xB951, + 0x7B4A, 0xB952, + 0x7B4D, 0xB953, + 0x7B4E, 0xB954, + 0x7B53, 0xB955, + 0x7B55, 0xB956, + 0x7B57, 0xB957, + 0x7B59, 0xB958, + 0x7B5C, 0xB959, + 0x7B5E, 0xB95A, + 0x7B5F, 0xB95B, + 0x7B61, 0xB95C, + 0x7B63, 0xB95D, + 0x7B64, 0xB95E, + 0x7B65, 0xB95F, + 0x7B66, 0xB960, + 0x7B67, 0xB961, + 0x7B68, 0xB962, + 0x7B69, 0xB963, + 0x7B6A, 0xB964, + 0x7B6B, 0xB965, + 0x7B6C, 0xB966, + 0x7B6D, 0xB967, + 0x7B6F, 0xB968, + 0x7B70, 0xB969, + 0x7B73, 0xB96A, + 0x7B74, 0xB96B, + 0x7B76, 0xB96C, + 0x7B78, 0xB96D, + 0x7B7A, 0xB96E, + 0x7B7C, 0xB96F, + 0x7B7D, 0xB970, + 0x7B7F, 0xB971, + 0x7B81, 0xB972, + 0x7B82, 0xB973, + 0x7B83, 0xB974, + 0x7B84, 0xB975, + 0x7B86, 0xB976, + 0x7B87, 0xB977, + 0x7B88, 0xB978, + 0x7B89, 0xB979, + 0x7B8A, 0xB97A, + 0x7B8B, 0xB97B, + 0x7B8C, 0xB97C, + 0x7B8E, 0xB97D, + 0x7B8F, 0xB97E, + 0x7B91, 0xB980, + 0x7B92, 0xB981, + 0x7B93, 0xB982, + 0x7B96, 0xB983, + 0x7B98, 0xB984, + 0x7B99, 0xB985, + 0x7B9A, 0xB986, + 0x7B9B, 0xB987, + 0x7B9E, 0xB988, + 0x7B9F, 0xB989, + 0x7BA0, 0xB98A, + 0x7BA3, 0xB98B, + 0x7BA4, 0xB98C, + 0x7BA5, 0xB98D, + 0x7BAE, 0xB98E, + 0x7BAF, 0xB98F, + 0x7BB0, 0xB990, + 0x7BB2, 0xB991, + 0x7BB3, 0xB992, + 0x7BB5, 0xB993, + 0x7BB6, 0xB994, + 0x7BB7, 0xB995, + 0x7BB9, 0xB996, + 0x7BBA, 0xB997, + 0x7BBB, 0xB998, + 0x7BBC, 0xB999, + 0x7BBD, 0xB99A, + 0x7BBE, 0xB99B, + 0x7BBF, 0xB99C, + 0x7BC0, 0xB99D, + 0x7BC2, 0xB99E, + 0x7BC3, 0xB99F, + 0x7BC4, 0xB9A0, + 0x7BC5, 0xBA40, + 0x7BC8, 0xBA41, + 0x7BC9, 0xBA42, + 0x7BCA, 0xBA43, + 0x7BCB, 0xBA44, + 0x7BCD, 0xBA45, + 0x7BCE, 0xBA46, + 0x7BCF, 0xBA47, + 0x7BD0, 0xBA48, + 0x7BD2, 0xBA49, + 0x7BD4, 0xBA4A, + 0x7BD5, 0xBA4B, + 0x7BD6, 0xBA4C, + 0x7BD7, 0xBA4D, + 0x7BD8, 0xBA4E, + 0x7BDB, 0xBA4F, + 0x7BDC, 0xBA50, + 0x7BDE, 0xBA51, + 0x7BDF, 0xBA52, + 0x7BE0, 0xBA53, + 0x7BE2, 0xBA54, + 0x7BE3, 0xBA55, + 0x7BE4, 0xBA56, + 0x7BE7, 0xBA57, + 0x7BE8, 0xBA58, + 0x7BE9, 0xBA59, + 0x7BEB, 0xBA5A, + 0x7BEC, 0xBA5B, + 0x7BED, 0xBA5C, + 0x7BEF, 0xBA5D, + 0x7BF0, 0xBA5E, + 0x7BF2, 0xBA5F, + 0x7BF3, 0xBA60, + 0x7BF4, 0xBA61, + 0x7BF5, 0xBA62, + 0x7BF6, 0xBA63, + 0x7BF8, 0xBA64, + 0x7BF9, 0xBA65, + 0x7BFA, 0xBA66, + 0x7BFB, 0xBA67, + 0x7BFD, 0xBA68, + 0x7BFF, 0xBA69, + 0x7C00, 0xBA6A, + 0x7C01, 0xBA6B, + 0x7C02, 0xBA6C, + 0x7C03, 0xBA6D, + 0x7C04, 0xBA6E, + 0x7C05, 0xBA6F, + 0x7C06, 0xBA70, + 0x7C08, 0xBA71, + 0x7C09, 0xBA72, + 0x7C0A, 0xBA73, + 0x7C0D, 0xBA74, + 0x7C0E, 0xBA75, + 0x7C10, 0xBA76, + 0x7C11, 0xBA77, + 0x7C12, 0xBA78, + 0x7C13, 0xBA79, + 0x7C14, 0xBA7A, + 0x7C15, 0xBA7B, + 0x7C17, 0xBA7C, + 0x7C18, 0xBA7D, + 0x7C19, 0xBA7E, + 0x7C1A, 0xBA80, + 0x7C1B, 0xBA81, + 0x7C1C, 0xBA82, + 0x7C1D, 0xBA83, + 0x7C1E, 0xBA84, + 0x7C20, 0xBA85, + 0x7C21, 0xBA86, + 0x7C22, 0xBA87, + 0x7C23, 0xBA88, + 0x7C24, 0xBA89, + 0x7C25, 0xBA8A, + 0x7C28, 0xBA8B, + 0x7C29, 0xBA8C, + 0x7C2B, 0xBA8D, + 0x7C2C, 0xBA8E, + 0x7C2D, 0xBA8F, + 0x7C2E, 0xBA90, + 0x7C2F, 0xBA91, + 0x7C30, 0xBA92, + 0x7C31, 0xBA93, + 0x7C32, 0xBA94, + 0x7C33, 0xBA95, + 0x7C34, 0xBA96, + 0x7C35, 0xBA97, + 0x7C36, 0xBA98, + 0x7C37, 0xBA99, + 0x7C39, 0xBA9A, + 0x7C3A, 0xBA9B, + 0x7C3B, 0xBA9C, + 0x7C3C, 0xBA9D, + 0x7C3D, 0xBA9E, + 0x7C3E, 0xBA9F, + 0x7C42, 0xBAA0, + 0x7C43, 0xBB40, + 0x7C44, 0xBB41, + 0x7C45, 0xBB42, + 0x7C46, 0xBB43, + 0x7C47, 0xBB44, + 0x7C48, 0xBB45, + 0x7C49, 0xBB46, + 0x7C4A, 0xBB47, + 0x7C4B, 0xBB48, + 0x7C4C, 0xBB49, + 0x7C4E, 0xBB4A, + 0x7C4F, 0xBB4B, + 0x7C50, 0xBB4C, + 0x7C51, 0xBB4D, + 0x7C52, 0xBB4E, + 0x7C53, 0xBB4F, + 0x7C54, 0xBB50, + 0x7C55, 0xBB51, + 0x7C56, 0xBB52, + 0x7C57, 0xBB53, + 0x7C58, 0xBB54, + 0x7C59, 0xBB55, + 0x7C5A, 0xBB56, + 0x7C5B, 0xBB57, + 0x7C5C, 0xBB58, + 0x7C5D, 0xBB59, + 0x7C5E, 0xBB5A, + 0x7C5F, 0xBB5B, + 0x7C60, 0xBB5C, + 0x7C61, 0xBB5D, + 0x7C62, 0xBB5E, + 0x7C63, 0xBB5F, + 0x7C64, 0xBB60, + 0x7C65, 0xBB61, + 0x7C66, 0xBB62, + 0x7C67, 0xBB63, + 0x7C68, 0xBB64, + 0x7C69, 0xBB65, + 0x7C6A, 0xBB66, + 0x7C6B, 0xBB67, + 0x7C6C, 0xBB68, + 0x7C6D, 0xBB69, + 0x7C6E, 0xBB6A, + 0x7C6F, 0xBB6B, + 0x7C70, 0xBB6C, + 0x7C71, 0xBB6D, + 0x7C72, 0xBB6E, + 0x7C75, 0xBB6F, + 0x7C76, 0xBB70, + 0x7C77, 0xBB71, + 0x7C78, 0xBB72, + 0x7C79, 0xBB73, + 0x7C7A, 0xBB74, + 0x7C7E, 0xBB75, + 0x7C7F, 0xBB76, + 0x7C80, 0xBB77, + 0x7C81, 0xBB78, + 0x7C82, 0xBB79, + 0x7C83, 0xBB7A, + 0x7C84, 0xBB7B, + 0x7C85, 0xBB7C, + 0x7C86, 0xBB7D, + 0x7C87, 0xBB7E, + 0x7C88, 0xBB80, + 0x7C8A, 0xBB81, + 0x7C8B, 0xBB82, + 0x7C8C, 0xBB83, + 0x7C8D, 0xBB84, + 0x7C8E, 0xBB85, + 0x7C8F, 0xBB86, + 0x7C90, 0xBB87, + 0x7C93, 0xBB88, + 0x7C94, 0xBB89, + 0x7C96, 0xBB8A, + 0x7C99, 0xBB8B, + 0x7C9A, 0xBB8C, + 0x7C9B, 0xBB8D, + 0x7CA0, 0xBB8E, + 0x7CA1, 0xBB8F, + 0x7CA3, 0xBB90, + 0x7CA6, 0xBB91, + 0x7CA7, 0xBB92, + 0x7CA8, 0xBB93, + 0x7CA9, 0xBB94, + 0x7CAB, 0xBB95, + 0x7CAC, 0xBB96, + 0x7CAD, 0xBB97, + 0x7CAF, 0xBB98, + 0x7CB0, 0xBB99, + 0x7CB4, 0xBB9A, + 0x7CB5, 0xBB9B, + 0x7CB6, 0xBB9C, + 0x7CB7, 0xBB9D, + 0x7CB8, 0xBB9E, + 0x7CBA, 0xBB9F, + 0x7CBB, 0xBBA0, + 0x7CBF, 0xBC40, + 0x7CC0, 0xBC41, + 0x7CC2, 0xBC42, + 0x7CC3, 0xBC43, + 0x7CC4, 0xBC44, + 0x7CC6, 0xBC45, + 0x7CC9, 0xBC46, + 0x7CCB, 0xBC47, + 0x7CCE, 0xBC48, + 0x7CCF, 0xBC49, + 0x7CD0, 0xBC4A, + 0x7CD1, 0xBC4B, + 0x7CD2, 0xBC4C, + 0x7CD3, 0xBC4D, + 0x7CD4, 0xBC4E, + 0x7CD8, 0xBC4F, + 0x7CDA, 0xBC50, + 0x7CDB, 0xBC51, + 0x7CDD, 0xBC52, + 0x7CDE, 0xBC53, + 0x7CE1, 0xBC54, + 0x7CE2, 0xBC55, + 0x7CE3, 0xBC56, + 0x7CE4, 0xBC57, + 0x7CE5, 0xBC58, + 0x7CE6, 0xBC59, + 0x7CE7, 0xBC5A, + 0x7CE9, 0xBC5B, + 0x7CEA, 0xBC5C, + 0x7CEB, 0xBC5D, + 0x7CEC, 0xBC5E, + 0x7CED, 0xBC5F, + 0x7CEE, 0xBC60, + 0x7CF0, 0xBC61, + 0x7CF1, 0xBC62, + 0x7CF2, 0xBC63, + 0x7CF3, 0xBC64, + 0x7CF4, 0xBC65, + 0x7CF5, 0xBC66, + 0x7CF6, 0xBC67, + 0x7CF7, 0xBC68, + 0x7CF9, 0xBC69, + 0x7CFA, 0xBC6A, + 0x7CFC, 0xBC6B, + 0x7CFD, 0xBC6C, + 0x7CFE, 0xBC6D, + 0x7CFF, 0xBC6E, + 0x7D00, 0xBC6F, + 0x7D01, 0xBC70, + 0x7D02, 0xBC71, + 0x7D03, 0xBC72, + 0x7D04, 0xBC73, + 0x7D05, 0xBC74, + 0x7D06, 0xBC75, + 0x7D07, 0xBC76, + 0x7D08, 0xBC77, + 0x7D09, 0xBC78, + 0x7D0B, 0xBC79, + 0x7D0C, 0xBC7A, + 0x7D0D, 0xBC7B, + 0x7D0E, 0xBC7C, + 0x7D0F, 0xBC7D, + 0x7D10, 0xBC7E, + 0x7D11, 0xBC80, + 0x7D12, 0xBC81, + 0x7D13, 0xBC82, + 0x7D14, 0xBC83, + 0x7D15, 0xBC84, + 0x7D16, 0xBC85, + 0x7D17, 0xBC86, + 0x7D18, 0xBC87, + 0x7D19, 0xBC88, + 0x7D1A, 0xBC89, + 0x7D1B, 0xBC8A, + 0x7D1C, 0xBC8B, + 0x7D1D, 0xBC8C, + 0x7D1E, 0xBC8D, + 0x7D1F, 0xBC8E, + 0x7D21, 0xBC8F, + 0x7D23, 0xBC90, + 0x7D24, 0xBC91, + 0x7D25, 0xBC92, + 0x7D26, 0xBC93, + 0x7D28, 0xBC94, + 0x7D29, 0xBC95, + 0x7D2A, 0xBC96, + 0x7D2C, 0xBC97, + 0x7D2D, 0xBC98, + 0x7D2E, 0xBC99, + 0x7D30, 0xBC9A, + 0x7D31, 0xBC9B, + 0x7D32, 0xBC9C, + 0x7D33, 0xBC9D, + 0x7D34, 0xBC9E, + 0x7D35, 0xBC9F, + 0x7D36, 0xBCA0, + 0x7D37, 0xBD40, + 0x7D38, 0xBD41, + 0x7D39, 0xBD42, + 0x7D3A, 0xBD43, + 0x7D3B, 0xBD44, + 0x7D3C, 0xBD45, + 0x7D3D, 0xBD46, + 0x7D3E, 0xBD47, + 0x7D3F, 0xBD48, + 0x7D40, 0xBD49, + 0x7D41, 0xBD4A, + 0x7D42, 0xBD4B, + 0x7D43, 0xBD4C, + 0x7D44, 0xBD4D, + 0x7D45, 0xBD4E, + 0x7D46, 0xBD4F, + 0x7D47, 0xBD50, + 0x7D48, 0xBD51, + 0x7D49, 0xBD52, + 0x7D4A, 0xBD53, + 0x7D4B, 0xBD54, + 0x7D4C, 0xBD55, + 0x7D4D, 0xBD56, + 0x7D4E, 0xBD57, + 0x7D4F, 0xBD58, + 0x7D50, 0xBD59, + 0x7D51, 0xBD5A, + 0x7D52, 0xBD5B, + 0x7D53, 0xBD5C, + 0x7D54, 0xBD5D, + 0x7D55, 0xBD5E, + 0x7D56, 0xBD5F, + 0x7D57, 0xBD60, + 0x7D58, 0xBD61, + 0x7D59, 0xBD62, + 0x7D5A, 0xBD63, + 0x7D5B, 0xBD64, + 0x7D5C, 0xBD65, + 0x7D5D, 0xBD66, + 0x7D5E, 0xBD67, + 0x7D5F, 0xBD68, + 0x7D60, 0xBD69, + 0x7D61, 0xBD6A, + 0x7D62, 0xBD6B, + 0x7D63, 0xBD6C, + 0x7D64, 0xBD6D, + 0x7D65, 0xBD6E, + 0x7D66, 0xBD6F, + 0x7D67, 0xBD70, + 0x7D68, 0xBD71, + 0x7D69, 0xBD72, + 0x7D6A, 0xBD73, + 0x7D6B, 0xBD74, + 0x7D6C, 0xBD75, + 0x7D6D, 0xBD76, + 0x7D6F, 0xBD77, + 0x7D70, 0xBD78, + 0x7D71, 0xBD79, + 0x7D72, 0xBD7A, + 0x7D73, 0xBD7B, + 0x7D74, 0xBD7C, + 0x7D75, 0xBD7D, + 0x7D76, 0xBD7E, + 0x7D78, 0xBD80, + 0x7D79, 0xBD81, + 0x7D7A, 0xBD82, + 0x7D7B, 0xBD83, + 0x7D7C, 0xBD84, + 0x7D7D, 0xBD85, + 0x7D7E, 0xBD86, + 0x7D7F, 0xBD87, + 0x7D80, 0xBD88, + 0x7D81, 0xBD89, + 0x7D82, 0xBD8A, + 0x7D83, 0xBD8B, + 0x7D84, 0xBD8C, + 0x7D85, 0xBD8D, + 0x7D86, 0xBD8E, + 0x7D87, 0xBD8F, + 0x7D88, 0xBD90, + 0x7D89, 0xBD91, + 0x7D8A, 0xBD92, + 0x7D8B, 0xBD93, + 0x7D8C, 0xBD94, + 0x7D8D, 0xBD95, + 0x7D8E, 0xBD96, + 0x7D8F, 0xBD97, + 0x7D90, 0xBD98, + 0x7D91, 0xBD99, + 0x7D92, 0xBD9A, + 0x7D93, 0xBD9B, + 0x7D94, 0xBD9C, + 0x7D95, 0xBD9D, + 0x7D96, 0xBD9E, + 0x7D97, 0xBD9F, + 0x7D98, 0xBDA0, + 0x7D99, 0xBE40, + 0x7D9A, 0xBE41, + 0x7D9B, 0xBE42, + 0x7D9C, 0xBE43, + 0x7D9D, 0xBE44, + 0x7D9E, 0xBE45, + 0x7D9F, 0xBE46, + 0x7DA0, 0xBE47, + 0x7DA1, 0xBE48, + 0x7DA2, 0xBE49, + 0x7DA3, 0xBE4A, + 0x7DA4, 0xBE4B, + 0x7DA5, 0xBE4C, + 0x7DA7, 0xBE4D, + 0x7DA8, 0xBE4E, + 0x7DA9, 0xBE4F, + 0x7DAA, 0xBE50, + 0x7DAB, 0xBE51, + 0x7DAC, 0xBE52, + 0x7DAD, 0xBE53, + 0x7DAF, 0xBE54, + 0x7DB0, 0xBE55, + 0x7DB1, 0xBE56, + 0x7DB2, 0xBE57, + 0x7DB3, 0xBE58, + 0x7DB4, 0xBE59, + 0x7DB5, 0xBE5A, + 0x7DB6, 0xBE5B, + 0x7DB7, 0xBE5C, + 0x7DB8, 0xBE5D, + 0x7DB9, 0xBE5E, + 0x7DBA, 0xBE5F, + 0x7DBB, 0xBE60, + 0x7DBC, 0xBE61, + 0x7DBD, 0xBE62, + 0x7DBE, 0xBE63, + 0x7DBF, 0xBE64, + 0x7DC0, 0xBE65, + 0x7DC1, 0xBE66, + 0x7DC2, 0xBE67, + 0x7DC3, 0xBE68, + 0x7DC4, 0xBE69, + 0x7DC5, 0xBE6A, + 0x7DC6, 0xBE6B, + 0x7DC7, 0xBE6C, + 0x7DC8, 0xBE6D, + 0x7DC9, 0xBE6E, + 0x7DCA, 0xBE6F, + 0x7DCB, 0xBE70, + 0x7DCC, 0xBE71, + 0x7DCD, 0xBE72, + 0x7DCE, 0xBE73, + 0x7DCF, 0xBE74, + 0x7DD0, 0xBE75, + 0x7DD1, 0xBE76, + 0x7DD2, 0xBE77, + 0x7DD3, 0xBE78, + 0x7DD4, 0xBE79, + 0x7DD5, 0xBE7A, + 0x7DD6, 0xBE7B, + 0x7DD7, 0xBE7C, + 0x7DD8, 0xBE7D, + 0x7DD9, 0xBE7E, + 0x7DDA, 0xBE80, + 0x7DDB, 0xBE81, + 0x7DDC, 0xBE82, + 0x7DDD, 0xBE83, + 0x7DDE, 0xBE84, + 0x7DDF, 0xBE85, + 0x7DE0, 0xBE86, + 0x7DE1, 0xBE87, + 0x7DE2, 0xBE88, + 0x7DE3, 0xBE89, + 0x7DE4, 0xBE8A, + 0x7DE5, 0xBE8B, + 0x7DE6, 0xBE8C, + 0x7DE7, 0xBE8D, + 0x7DE8, 0xBE8E, + 0x7DE9, 0xBE8F, + 0x7DEA, 0xBE90, + 0x7DEB, 0xBE91, + 0x7DEC, 0xBE92, + 0x7DED, 0xBE93, + 0x7DEE, 0xBE94, + 0x7DEF, 0xBE95, + 0x7DF0, 0xBE96, + 0x7DF1, 0xBE97, + 0x7DF2, 0xBE98, + 0x7DF3, 0xBE99, + 0x7DF4, 0xBE9A, + 0x7DF5, 0xBE9B, + 0x7DF6, 0xBE9C, + 0x7DF7, 0xBE9D, + 0x7DF8, 0xBE9E, + 0x7DF9, 0xBE9F, + 0x7DFA, 0xBEA0, + 0x7DFB, 0xBF40, + 0x7DFC, 0xBF41, + 0x7DFD, 0xBF42, + 0x7DFE, 0xBF43, + 0x7DFF, 0xBF44, + 0x7E00, 0xBF45, + 0x7E01, 0xBF46, + 0x7E02, 0xBF47, + 0x7E03, 0xBF48, + 0x7E04, 0xBF49, + 0x7E05, 0xBF4A, + 0x7E06, 0xBF4B, + 0x7E07, 0xBF4C, + 0x7E08, 0xBF4D, + 0x7E09, 0xBF4E, + 0x7E0A, 0xBF4F, + 0x7E0B, 0xBF50, + 0x7E0C, 0xBF51, + 0x7E0D, 0xBF52, + 0x7E0E, 0xBF53, + 0x7E0F, 0xBF54, + 0x7E10, 0xBF55, + 0x7E11, 0xBF56, + 0x7E12, 0xBF57, + 0x7E13, 0xBF58, + 0x7E14, 0xBF59, + 0x7E15, 0xBF5A, + 0x7E16, 0xBF5B, + 0x7E17, 0xBF5C, + 0x7E18, 0xBF5D, + 0x7E19, 0xBF5E, + 0x7E1A, 0xBF5F, + 0x7E1B, 0xBF60, + 0x7E1C, 0xBF61, + 0x7E1D, 0xBF62, + 0x7E1E, 0xBF63, + 0x7E1F, 0xBF64, + 0x7E20, 0xBF65, + 0x7E21, 0xBF66, + 0x7E22, 0xBF67, + 0x7E23, 0xBF68, + 0x7E24, 0xBF69, + 0x7E25, 0xBF6A, + 0x7E26, 0xBF6B, + 0x7E27, 0xBF6C, + 0x7E28, 0xBF6D, + 0x7E29, 0xBF6E, + 0x7E2A, 0xBF6F, + 0x7E2B, 0xBF70, + 0x7E2C, 0xBF71, + 0x7E2D, 0xBF72, + 0x7E2E, 0xBF73, + 0x7E2F, 0xBF74, + 0x7E30, 0xBF75, + 0x7E31, 0xBF76, + 0x7E32, 0xBF77, + 0x7E33, 0xBF78, + 0x7E34, 0xBF79, + 0x7E35, 0xBF7A, + 0x7E36, 0xBF7B, + 0x7E37, 0xBF7C, + 0x7E38, 0xBF7D, + 0x7E39, 0xBF7E, + 0x7E3A, 0xBF80, + 0x7E3C, 0xBF81, + 0x7E3D, 0xBF82, + 0x7E3E, 0xBF83, + 0x7E3F, 0xBF84, + 0x7E40, 0xBF85, + 0x7E42, 0xBF86, + 0x7E43, 0xBF87, + 0x7E44, 0xBF88, + 0x7E45, 0xBF89, + 0x7E46, 0xBF8A, + 0x7E48, 0xBF8B, + 0x7E49, 0xBF8C, + 0x7E4A, 0xBF8D, + 0x7E4B, 0xBF8E, + 0x7E4C, 0xBF8F, + 0x7E4D, 0xBF90, + 0x7E4E, 0xBF91, + 0x7E4F, 0xBF92, + 0x7E50, 0xBF93, + 0x7E51, 0xBF94, + 0x7E52, 0xBF95, + 0x7E53, 0xBF96, + 0x7E54, 0xBF97, + 0x7E55, 0xBF98, + 0x7E56, 0xBF99, + 0x7E57, 0xBF9A, + 0x7E58, 0xBF9B, + 0x7E59, 0xBF9C, + 0x7E5A, 0xBF9D, + 0x7E5B, 0xBF9E, + 0x7E5C, 0xBF9F, + 0x7E5D, 0xBFA0, + 0x7E5E, 0xC040, + 0x7E5F, 0xC041, + 0x7E60, 0xC042, + 0x7E61, 0xC043, + 0x7E62, 0xC044, + 0x7E63, 0xC045, + 0x7E64, 0xC046, + 0x7E65, 0xC047, + 0x7E66, 0xC048, + 0x7E67, 0xC049, + 0x7E68, 0xC04A, + 0x7E69, 0xC04B, + 0x7E6A, 0xC04C, + 0x7E6B, 0xC04D, + 0x7E6C, 0xC04E, + 0x7E6D, 0xC04F, + 0x7E6E, 0xC050, + 0x7E6F, 0xC051, + 0x7E70, 0xC052, + 0x7E71, 0xC053, + 0x7E72, 0xC054, + 0x7E73, 0xC055, + 0x7E74, 0xC056, + 0x7E75, 0xC057, + 0x7E76, 0xC058, + 0x7E77, 0xC059, + 0x7E78, 0xC05A, + 0x7E79, 0xC05B, + 0x7E7A, 0xC05C, + 0x7E7B, 0xC05D, + 0x7E7C, 0xC05E, + 0x7E7D, 0xC05F, + 0x7E7E, 0xC060, + 0x7E7F, 0xC061, + 0x7E80, 0xC062, + 0x7E81, 0xC063, + 0x7E83, 0xC064, + 0x7E84, 0xC065, + 0x7E85, 0xC066, + 0x7E86, 0xC067, + 0x7E87, 0xC068, + 0x7E88, 0xC069, + 0x7E89, 0xC06A, + 0x7E8A, 0xC06B, + 0x7E8B, 0xC06C, + 0x7E8C, 0xC06D, + 0x7E8D, 0xC06E, + 0x7E8E, 0xC06F, + 0x7E8F, 0xC070, + 0x7E90, 0xC071, + 0x7E91, 0xC072, + 0x7E92, 0xC073, + 0x7E93, 0xC074, + 0x7E94, 0xC075, + 0x7E95, 0xC076, + 0x7E96, 0xC077, + 0x7E97, 0xC078, + 0x7E98, 0xC079, + 0x7E99, 0xC07A, + 0x7E9A, 0xC07B, + 0x7E9C, 0xC07C, + 0x7E9D, 0xC07D, + 0x7E9E, 0xC07E, + 0x7EAE, 0xC080, + 0x7EB4, 0xC081, + 0x7EBB, 0xC082, + 0x7EBC, 0xC083, + 0x7ED6, 0xC084, + 0x7EE4, 0xC085, + 0x7EEC, 0xC086, + 0x7EF9, 0xC087, + 0x7F0A, 0xC088, + 0x7F10, 0xC089, + 0x7F1E, 0xC08A, + 0x7F37, 0xC08B, + 0x7F39, 0xC08C, + 0x7F3B, 0xC08D, + 0x7F3C, 0xC08E, + 0x7F3D, 0xC08F, + 0x7F3E, 0xC090, + 0x7F3F, 0xC091, + 0x7F40, 0xC092, + 0x7F41, 0xC093, + 0x7F43, 0xC094, + 0x7F46, 0xC095, + 0x7F47, 0xC096, + 0x7F48, 0xC097, + 0x7F49, 0xC098, + 0x7F4A, 0xC099, + 0x7F4B, 0xC09A, + 0x7F4C, 0xC09B, + 0x7F4D, 0xC09C, + 0x7F4E, 0xC09D, + 0x7F4F, 0xC09E, + 0x7F52, 0xC09F, + 0x7F53, 0xC0A0, + 0x7F56, 0xC140, + 0x7F59, 0xC141, + 0x7F5B, 0xC142, + 0x7F5C, 0xC143, + 0x7F5D, 0xC144, + 0x7F5E, 0xC145, + 0x7F60, 0xC146, + 0x7F63, 0xC147, + 0x7F64, 0xC148, + 0x7F65, 0xC149, + 0x7F66, 0xC14A, + 0x7F67, 0xC14B, + 0x7F6B, 0xC14C, + 0x7F6C, 0xC14D, + 0x7F6D, 0xC14E, + 0x7F6F, 0xC14F, + 0x7F70, 0xC150, + 0x7F73, 0xC151, + 0x7F75, 0xC152, + 0x7F76, 0xC153, + 0x7F77, 0xC154, + 0x7F78, 0xC155, + 0x7F7A, 0xC156, + 0x7F7B, 0xC157, + 0x7F7C, 0xC158, + 0x7F7D, 0xC159, + 0x7F7F, 0xC15A, + 0x7F80, 0xC15B, + 0x7F82, 0xC15C, + 0x7F83, 0xC15D, + 0x7F84, 0xC15E, + 0x7F85, 0xC15F, + 0x7F86, 0xC160, + 0x7F87, 0xC161, + 0x7F88, 0xC162, + 0x7F89, 0xC163, + 0x7F8B, 0xC164, + 0x7F8D, 0xC165, + 0x7F8F, 0xC166, + 0x7F90, 0xC167, + 0x7F91, 0xC168, + 0x7F92, 0xC169, + 0x7F93, 0xC16A, + 0x7F95, 0xC16B, + 0x7F96, 0xC16C, + 0x7F97, 0xC16D, + 0x7F98, 0xC16E, + 0x7F99, 0xC16F, + 0x7F9B, 0xC170, + 0x7F9C, 0xC171, + 0x7FA0, 0xC172, + 0x7FA2, 0xC173, + 0x7FA3, 0xC174, + 0x7FA5, 0xC175, + 0x7FA6, 0xC176, + 0x7FA8, 0xC177, + 0x7FA9, 0xC178, + 0x7FAA, 0xC179, + 0x7FAB, 0xC17A, + 0x7FAC, 0xC17B, + 0x7FAD, 0xC17C, + 0x7FAE, 0xC17D, + 0x7FB1, 0xC17E, + 0x7FB3, 0xC180, + 0x7FB4, 0xC181, + 0x7FB5, 0xC182, + 0x7FB6, 0xC183, + 0x7FB7, 0xC184, + 0x7FBA, 0xC185, + 0x7FBB, 0xC186, + 0x7FBE, 0xC187, + 0x7FC0, 0xC188, + 0x7FC2, 0xC189, + 0x7FC3, 0xC18A, + 0x7FC4, 0xC18B, + 0x7FC6, 0xC18C, + 0x7FC7, 0xC18D, + 0x7FC8, 0xC18E, + 0x7FC9, 0xC18F, + 0x7FCB, 0xC190, + 0x7FCD, 0xC191, + 0x7FCF, 0xC192, + 0x7FD0, 0xC193, + 0x7FD1, 0xC194, + 0x7FD2, 0xC195, + 0x7FD3, 0xC196, + 0x7FD6, 0xC197, + 0x7FD7, 0xC198, + 0x7FD9, 0xC199, + 0x7FDA, 0xC19A, + 0x7FDB, 0xC19B, + 0x7FDC, 0xC19C, + 0x7FDD, 0xC19D, + 0x7FDE, 0xC19E, + 0x7FE2, 0xC19F, + 0x7FE3, 0xC1A0, + 0x7FE4, 0xC240, + 0x7FE7, 0xC241, + 0x7FE8, 0xC242, + 0x7FEA, 0xC243, + 0x7FEB, 0xC244, + 0x7FEC, 0xC245, + 0x7FED, 0xC246, + 0x7FEF, 0xC247, + 0x7FF2, 0xC248, + 0x7FF4, 0xC249, + 0x7FF5, 0xC24A, + 0x7FF6, 0xC24B, + 0x7FF7, 0xC24C, + 0x7FF8, 0xC24D, + 0x7FF9, 0xC24E, + 0x7FFA, 0xC24F, + 0x7FFD, 0xC250, + 0x7FFE, 0xC251, + 0x7FFF, 0xC252, + 0x8002, 0xC253, + 0x8007, 0xC254, + 0x8008, 0xC255, + 0x8009, 0xC256, + 0x800A, 0xC257, + 0x800E, 0xC258, + 0x800F, 0xC259, + 0x8011, 0xC25A, + 0x8013, 0xC25B, + 0x801A, 0xC25C, + 0x801B, 0xC25D, + 0x801D, 0xC25E, + 0x801E, 0xC25F, + 0x801F, 0xC260, + 0x8021, 0xC261, + 0x8023, 0xC262, + 0x8024, 0xC263, + 0x802B, 0xC264, + 0x802C, 0xC265, + 0x802D, 0xC266, + 0x802E, 0xC267, + 0x802F, 0xC268, + 0x8030, 0xC269, + 0x8032, 0xC26A, + 0x8034, 0xC26B, + 0x8039, 0xC26C, + 0x803A, 0xC26D, + 0x803C, 0xC26E, + 0x803E, 0xC26F, + 0x8040, 0xC270, + 0x8041, 0xC271, + 0x8044, 0xC272, + 0x8045, 0xC273, + 0x8047, 0xC274, + 0x8048, 0xC275, + 0x8049, 0xC276, + 0x804E, 0xC277, + 0x804F, 0xC278, + 0x8050, 0xC279, + 0x8051, 0xC27A, + 0x8053, 0xC27B, + 0x8055, 0xC27C, + 0x8056, 0xC27D, + 0x8057, 0xC27E, + 0x8059, 0xC280, + 0x805B, 0xC281, + 0x805C, 0xC282, + 0x805D, 0xC283, + 0x805E, 0xC284, + 0x805F, 0xC285, + 0x8060, 0xC286, + 0x8061, 0xC287, + 0x8062, 0xC288, + 0x8063, 0xC289, + 0x8064, 0xC28A, + 0x8065, 0xC28B, + 0x8066, 0xC28C, + 0x8067, 0xC28D, + 0x8068, 0xC28E, + 0x806B, 0xC28F, + 0x806C, 0xC290, + 0x806D, 0xC291, + 0x806E, 0xC292, + 0x806F, 0xC293, + 0x8070, 0xC294, + 0x8072, 0xC295, + 0x8073, 0xC296, + 0x8074, 0xC297, + 0x8075, 0xC298, + 0x8076, 0xC299, + 0x8077, 0xC29A, + 0x8078, 0xC29B, + 0x8079, 0xC29C, + 0x807A, 0xC29D, + 0x807B, 0xC29E, + 0x807C, 0xC29F, + 0x807D, 0xC2A0, + 0x807E, 0xC340, + 0x8081, 0xC341, + 0x8082, 0xC342, + 0x8085, 0xC343, + 0x8088, 0xC344, + 0x808A, 0xC345, + 0x808D, 0xC346, + 0x808E, 0xC347, + 0x808F, 0xC348, + 0x8090, 0xC349, + 0x8091, 0xC34A, + 0x8092, 0xC34B, + 0x8094, 0xC34C, + 0x8095, 0xC34D, + 0x8097, 0xC34E, + 0x8099, 0xC34F, + 0x809E, 0xC350, + 0x80A3, 0xC351, + 0x80A6, 0xC352, + 0x80A7, 0xC353, + 0x80A8, 0xC354, + 0x80AC, 0xC355, + 0x80B0, 0xC356, + 0x80B3, 0xC357, + 0x80B5, 0xC358, + 0x80B6, 0xC359, + 0x80B8, 0xC35A, + 0x80B9, 0xC35B, + 0x80BB, 0xC35C, + 0x80C5, 0xC35D, + 0x80C7, 0xC35E, + 0x80C8, 0xC35F, + 0x80C9, 0xC360, + 0x80CA, 0xC361, + 0x80CB, 0xC362, + 0x80CF, 0xC363, + 0x80D0, 0xC364, + 0x80D1, 0xC365, + 0x80D2, 0xC366, + 0x80D3, 0xC367, + 0x80D4, 0xC368, + 0x80D5, 0xC369, + 0x80D8, 0xC36A, + 0x80DF, 0xC36B, + 0x80E0, 0xC36C, + 0x80E2, 0xC36D, + 0x80E3, 0xC36E, + 0x80E6, 0xC36F, + 0x80EE, 0xC370, + 0x80F5, 0xC371, + 0x80F7, 0xC372, + 0x80F9, 0xC373, + 0x80FB, 0xC374, + 0x80FE, 0xC375, + 0x80FF, 0xC376, + 0x8100, 0xC377, + 0x8101, 0xC378, + 0x8103, 0xC379, + 0x8104, 0xC37A, + 0x8105, 0xC37B, + 0x8107, 0xC37C, + 0x8108, 0xC37D, + 0x810B, 0xC37E, + 0x810C, 0xC380, + 0x8115, 0xC381, + 0x8117, 0xC382, + 0x8119, 0xC383, + 0x811B, 0xC384, + 0x811C, 0xC385, + 0x811D, 0xC386, + 0x811F, 0xC387, + 0x8120, 0xC388, + 0x8121, 0xC389, + 0x8122, 0xC38A, + 0x8123, 0xC38B, + 0x8124, 0xC38C, + 0x8125, 0xC38D, + 0x8126, 0xC38E, + 0x8127, 0xC38F, + 0x8128, 0xC390, + 0x8129, 0xC391, + 0x812A, 0xC392, + 0x812B, 0xC393, + 0x812D, 0xC394, + 0x812E, 0xC395, + 0x8130, 0xC396, + 0x8133, 0xC397, + 0x8134, 0xC398, + 0x8135, 0xC399, + 0x8137, 0xC39A, + 0x8139, 0xC39B, + 0x813A, 0xC39C, + 0x813B, 0xC39D, + 0x813C, 0xC39E, + 0x813D, 0xC39F, + 0x813F, 0xC3A0, + 0x8140, 0xC440, + 0x8141, 0xC441, + 0x8142, 0xC442, + 0x8143, 0xC443, + 0x8144, 0xC444, + 0x8145, 0xC445, + 0x8147, 0xC446, + 0x8149, 0xC447, + 0x814D, 0xC448, + 0x814E, 0xC449, + 0x814F, 0xC44A, + 0x8152, 0xC44B, + 0x8156, 0xC44C, + 0x8157, 0xC44D, + 0x8158, 0xC44E, + 0x815B, 0xC44F, + 0x815C, 0xC450, + 0x815D, 0xC451, + 0x815E, 0xC452, + 0x815F, 0xC453, + 0x8161, 0xC454, + 0x8162, 0xC455, + 0x8163, 0xC456, + 0x8164, 0xC457, + 0x8166, 0xC458, + 0x8168, 0xC459, + 0x816A, 0xC45A, + 0x816B, 0xC45B, + 0x816C, 0xC45C, + 0x816F, 0xC45D, + 0x8172, 0xC45E, + 0x8173, 0xC45F, + 0x8175, 0xC460, + 0x8176, 0xC461, + 0x8177, 0xC462, + 0x8178, 0xC463, + 0x8181, 0xC464, + 0x8183, 0xC465, + 0x8184, 0xC466, + 0x8185, 0xC467, + 0x8186, 0xC468, + 0x8187, 0xC469, + 0x8189, 0xC46A, + 0x818B, 0xC46B, + 0x818C, 0xC46C, + 0x818D, 0xC46D, + 0x818E, 0xC46E, + 0x8190, 0xC46F, + 0x8192, 0xC470, + 0x8193, 0xC471, + 0x8194, 0xC472, + 0x8195, 0xC473, + 0x8196, 0xC474, + 0x8197, 0xC475, + 0x8199, 0xC476, + 0x819A, 0xC477, + 0x819E, 0xC478, + 0x819F, 0xC479, + 0x81A0, 0xC47A, + 0x81A1, 0xC47B, + 0x81A2, 0xC47C, + 0x81A4, 0xC47D, + 0x81A5, 0xC47E, + 0x81A7, 0xC480, + 0x81A9, 0xC481, + 0x81AB, 0xC482, + 0x81AC, 0xC483, + 0x81AD, 0xC484, + 0x81AE, 0xC485, + 0x81AF, 0xC486, + 0x81B0, 0xC487, + 0x81B1, 0xC488, + 0x81B2, 0xC489, + 0x81B4, 0xC48A, + 0x81B5, 0xC48B, + 0x81B6, 0xC48C, + 0x81B7, 0xC48D, + 0x81B8, 0xC48E, + 0x81B9, 0xC48F, + 0x81BC, 0xC490, + 0x81BD, 0xC491, + 0x81BE, 0xC492, + 0x81BF, 0xC493, + 0x81C4, 0xC494, + 0x81C5, 0xC495, + 0x81C7, 0xC496, + 0x81C8, 0xC497, + 0x81C9, 0xC498, + 0x81CB, 0xC499, + 0x81CD, 0xC49A, + 0x81CE, 0xC49B, + 0x81CF, 0xC49C, + 0x81D0, 0xC49D, + 0x81D1, 0xC49E, + 0x81D2, 0xC49F, + 0x81D3, 0xC4A0, + 0x81D4, 0xC540, + 0x81D5, 0xC541, + 0x81D6, 0xC542, + 0x81D7, 0xC543, + 0x81D8, 0xC544, + 0x81D9, 0xC545, + 0x81DA, 0xC546, + 0x81DB, 0xC547, + 0x81DC, 0xC548, + 0x81DD, 0xC549, + 0x81DE, 0xC54A, + 0x81DF, 0xC54B, + 0x81E0, 0xC54C, + 0x81E1, 0xC54D, + 0x81E2, 0xC54E, + 0x81E4, 0xC54F, + 0x81E5, 0xC550, + 0x81E6, 0xC551, + 0x81E8, 0xC552, + 0x81E9, 0xC553, + 0x81EB, 0xC554, + 0x81EE, 0xC555, + 0x81EF, 0xC556, + 0x81F0, 0xC557, + 0x81F1, 0xC558, + 0x81F2, 0xC559, + 0x81F5, 0xC55A, + 0x81F6, 0xC55B, + 0x81F7, 0xC55C, + 0x81F8, 0xC55D, + 0x81F9, 0xC55E, + 0x81FA, 0xC55F, + 0x81FD, 0xC560, + 0x81FF, 0xC561, + 0x8203, 0xC562, + 0x8207, 0xC563, + 0x8208, 0xC564, + 0x8209, 0xC565, + 0x820A, 0xC566, + 0x820B, 0xC567, + 0x820E, 0xC568, + 0x820F, 0xC569, + 0x8211, 0xC56A, + 0x8213, 0xC56B, + 0x8215, 0xC56C, + 0x8216, 0xC56D, + 0x8217, 0xC56E, + 0x8218, 0xC56F, + 0x8219, 0xC570, + 0x821A, 0xC571, + 0x821D, 0xC572, + 0x8220, 0xC573, + 0x8224, 0xC574, + 0x8225, 0xC575, + 0x8226, 0xC576, + 0x8227, 0xC577, + 0x8229, 0xC578, + 0x822E, 0xC579, + 0x8232, 0xC57A, + 0x823A, 0xC57B, + 0x823C, 0xC57C, + 0x823D, 0xC57D, + 0x823F, 0xC57E, + 0x8240, 0xC580, + 0x8241, 0xC581, + 0x8242, 0xC582, + 0x8243, 0xC583, + 0x8245, 0xC584, + 0x8246, 0xC585, + 0x8248, 0xC586, + 0x824A, 0xC587, + 0x824C, 0xC588, + 0x824D, 0xC589, + 0x824E, 0xC58A, + 0x8250, 0xC58B, + 0x8251, 0xC58C, + 0x8252, 0xC58D, + 0x8253, 0xC58E, + 0x8254, 0xC58F, + 0x8255, 0xC590, + 0x8256, 0xC591, + 0x8257, 0xC592, + 0x8259, 0xC593, + 0x825B, 0xC594, + 0x825C, 0xC595, + 0x825D, 0xC596, + 0x825E, 0xC597, + 0x8260, 0xC598, + 0x8261, 0xC599, + 0x8262, 0xC59A, + 0x8263, 0xC59B, + 0x8264, 0xC59C, + 0x8265, 0xC59D, + 0x8266, 0xC59E, + 0x8267, 0xC59F, + 0x8269, 0xC5A0, + 0x826A, 0xC640, + 0x826B, 0xC641, + 0x826C, 0xC642, + 0x826D, 0xC643, + 0x8271, 0xC644, + 0x8275, 0xC645, + 0x8276, 0xC646, + 0x8277, 0xC647, + 0x8278, 0xC648, + 0x827B, 0xC649, + 0x827C, 0xC64A, + 0x8280, 0xC64B, + 0x8281, 0xC64C, + 0x8283, 0xC64D, + 0x8285, 0xC64E, + 0x8286, 0xC64F, + 0x8287, 0xC650, + 0x8289, 0xC651, + 0x828C, 0xC652, + 0x8290, 0xC653, + 0x8293, 0xC654, + 0x8294, 0xC655, + 0x8295, 0xC656, + 0x8296, 0xC657, + 0x829A, 0xC658, + 0x829B, 0xC659, + 0x829E, 0xC65A, + 0x82A0, 0xC65B, + 0x82A2, 0xC65C, + 0x82A3, 0xC65D, + 0x82A7, 0xC65E, + 0x82B2, 0xC65F, + 0x82B5, 0xC660, + 0x82B6, 0xC661, + 0x82BA, 0xC662, + 0x82BB, 0xC663, + 0x82BC, 0xC664, + 0x82BF, 0xC665, + 0x82C0, 0xC666, + 0x82C2, 0xC667, + 0x82C3, 0xC668, + 0x82C5, 0xC669, + 0x82C6, 0xC66A, + 0x82C9, 0xC66B, + 0x82D0, 0xC66C, + 0x82D6, 0xC66D, + 0x82D9, 0xC66E, + 0x82DA, 0xC66F, + 0x82DD, 0xC670, + 0x82E2, 0xC671, + 0x82E7, 0xC672, + 0x82E8, 0xC673, + 0x82E9, 0xC674, + 0x82EA, 0xC675, + 0x82EC, 0xC676, + 0x82ED, 0xC677, + 0x82EE, 0xC678, + 0x82F0, 0xC679, + 0x82F2, 0xC67A, + 0x82F3, 0xC67B, + 0x82F5, 0xC67C, + 0x82F6, 0xC67D, + 0x82F8, 0xC67E, + 0x82FA, 0xC680, + 0x82FC, 0xC681, + 0x82FD, 0xC682, + 0x82FE, 0xC683, + 0x82FF, 0xC684, + 0x8300, 0xC685, + 0x830A, 0xC686, + 0x830B, 0xC687, + 0x830D, 0xC688, + 0x8310, 0xC689, + 0x8312, 0xC68A, + 0x8313, 0xC68B, + 0x8316, 0xC68C, + 0x8318, 0xC68D, + 0x8319, 0xC68E, + 0x831D, 0xC68F, + 0x831E, 0xC690, + 0x831F, 0xC691, + 0x8320, 0xC692, + 0x8321, 0xC693, + 0x8322, 0xC694, + 0x8323, 0xC695, + 0x8324, 0xC696, + 0x8325, 0xC697, + 0x8326, 0xC698, + 0x8329, 0xC699, + 0x832A, 0xC69A, + 0x832E, 0xC69B, + 0x8330, 0xC69C, + 0x8332, 0xC69D, + 0x8337, 0xC69E, + 0x833B, 0xC69F, + 0x833D, 0xC6A0, + 0x833E, 0xC740, + 0x833F, 0xC741, + 0x8341, 0xC742, + 0x8342, 0xC743, + 0x8344, 0xC744, + 0x8345, 0xC745, + 0x8348, 0xC746, + 0x834A, 0xC747, + 0x834B, 0xC748, + 0x834C, 0xC749, + 0x834D, 0xC74A, + 0x834E, 0xC74B, + 0x8353, 0xC74C, + 0x8355, 0xC74D, + 0x8356, 0xC74E, + 0x8357, 0xC74F, + 0x8358, 0xC750, + 0x8359, 0xC751, + 0x835D, 0xC752, + 0x8362, 0xC753, + 0x8370, 0xC754, + 0x8371, 0xC755, + 0x8372, 0xC756, + 0x8373, 0xC757, + 0x8374, 0xC758, + 0x8375, 0xC759, + 0x8376, 0xC75A, + 0x8379, 0xC75B, + 0x837A, 0xC75C, + 0x837E, 0xC75D, + 0x837F, 0xC75E, + 0x8380, 0xC75F, + 0x8381, 0xC760, + 0x8382, 0xC761, + 0x8383, 0xC762, + 0x8384, 0xC763, + 0x8387, 0xC764, + 0x8388, 0xC765, + 0x838A, 0xC766, + 0x838B, 0xC767, + 0x838C, 0xC768, + 0x838D, 0xC769, + 0x838F, 0xC76A, + 0x8390, 0xC76B, + 0x8391, 0xC76C, + 0x8394, 0xC76D, + 0x8395, 0xC76E, + 0x8396, 0xC76F, + 0x8397, 0xC770, + 0x8399, 0xC771, + 0x839A, 0xC772, + 0x839D, 0xC773, + 0x839F, 0xC774, + 0x83A1, 0xC775, + 0x83A2, 0xC776, + 0x83A3, 0xC777, + 0x83A4, 0xC778, + 0x83A5, 0xC779, + 0x83A6, 0xC77A, + 0x83A7, 0xC77B, + 0x83AC, 0xC77C, + 0x83AD, 0xC77D, + 0x83AE, 0xC77E, + 0x83AF, 0xC780, + 0x83B5, 0xC781, + 0x83BB, 0xC782, + 0x83BE, 0xC783, + 0x83BF, 0xC784, + 0x83C2, 0xC785, + 0x83C3, 0xC786, + 0x83C4, 0xC787, + 0x83C6, 0xC788, + 0x83C8, 0xC789, + 0x83C9, 0xC78A, + 0x83CB, 0xC78B, + 0x83CD, 0xC78C, + 0x83CE, 0xC78D, + 0x83D0, 0xC78E, + 0x83D1, 0xC78F, + 0x83D2, 0xC790, + 0x83D3, 0xC791, + 0x83D5, 0xC792, + 0x83D7, 0xC793, + 0x83D9, 0xC794, + 0x83DA, 0xC795, + 0x83DB, 0xC796, + 0x83DE, 0xC797, + 0x83E2, 0xC798, + 0x83E3, 0xC799, + 0x83E4, 0xC79A, + 0x83E6, 0xC79B, + 0x83E7, 0xC79C, + 0x83E8, 0xC79D, + 0x83EB, 0xC79E, + 0x83EC, 0xC79F, + 0x83ED, 0xC7A0, + 0x83EE, 0xC840, + 0x83EF, 0xC841, + 0x83F3, 0xC842, + 0x83F4, 0xC843, + 0x83F5, 0xC844, + 0x83F6, 0xC845, + 0x83F7, 0xC846, + 0x83FA, 0xC847, + 0x83FB, 0xC848, + 0x83FC, 0xC849, + 0x83FE, 0xC84A, + 0x83FF, 0xC84B, + 0x8400, 0xC84C, + 0x8402, 0xC84D, + 0x8405, 0xC84E, + 0x8407, 0xC84F, + 0x8408, 0xC850, + 0x8409, 0xC851, + 0x840A, 0xC852, + 0x8410, 0xC853, + 0x8412, 0xC854, + 0x8413, 0xC855, + 0x8414, 0xC856, + 0x8415, 0xC857, + 0x8416, 0xC858, + 0x8417, 0xC859, + 0x8419, 0xC85A, + 0x841A, 0xC85B, + 0x841B, 0xC85C, + 0x841E, 0xC85D, + 0x841F, 0xC85E, + 0x8420, 0xC85F, + 0x8421, 0xC860, + 0x8422, 0xC861, + 0x8423, 0xC862, + 0x8429, 0xC863, + 0x842A, 0xC864, + 0x842B, 0xC865, + 0x842C, 0xC866, + 0x842D, 0xC867, + 0x842E, 0xC868, + 0x842F, 0xC869, + 0x8430, 0xC86A, + 0x8432, 0xC86B, + 0x8433, 0xC86C, + 0x8434, 0xC86D, + 0x8435, 0xC86E, + 0x8436, 0xC86F, + 0x8437, 0xC870, + 0x8439, 0xC871, + 0x843A, 0xC872, + 0x843B, 0xC873, + 0x843E, 0xC874, + 0x843F, 0xC875, + 0x8440, 0xC876, + 0x8441, 0xC877, + 0x8442, 0xC878, + 0x8443, 0xC879, + 0x8444, 0xC87A, + 0x8445, 0xC87B, + 0x8447, 0xC87C, + 0x8448, 0xC87D, + 0x8449, 0xC87E, + 0x844A, 0xC880, + 0x844B, 0xC881, + 0x844C, 0xC882, + 0x844D, 0xC883, + 0x844E, 0xC884, + 0x844F, 0xC885, + 0x8450, 0xC886, + 0x8452, 0xC887, + 0x8453, 0xC888, + 0x8454, 0xC889, + 0x8455, 0xC88A, + 0x8456, 0xC88B, + 0x8458, 0xC88C, + 0x845D, 0xC88D, + 0x845E, 0xC88E, + 0x845F, 0xC88F, + 0x8460, 0xC890, + 0x8462, 0xC891, + 0x8464, 0xC892, + 0x8465, 0xC893, + 0x8466, 0xC894, + 0x8467, 0xC895, + 0x8468, 0xC896, + 0x846A, 0xC897, + 0x846E, 0xC898, + 0x846F, 0xC899, + 0x8470, 0xC89A, + 0x8472, 0xC89B, + 0x8474, 0xC89C, + 0x8477, 0xC89D, + 0x8479, 0xC89E, + 0x847B, 0xC89F, + 0x847C, 0xC8A0, + 0x847D, 0xC940, + 0x847E, 0xC941, + 0x847F, 0xC942, + 0x8480, 0xC943, + 0x8481, 0xC944, + 0x8483, 0xC945, + 0x8484, 0xC946, + 0x8485, 0xC947, + 0x8486, 0xC948, + 0x848A, 0xC949, + 0x848D, 0xC94A, + 0x848F, 0xC94B, + 0x8490, 0xC94C, + 0x8491, 0xC94D, + 0x8492, 0xC94E, + 0x8493, 0xC94F, + 0x8494, 0xC950, + 0x8495, 0xC951, + 0x8496, 0xC952, + 0x8498, 0xC953, + 0x849A, 0xC954, + 0x849B, 0xC955, + 0x849D, 0xC956, + 0x849E, 0xC957, + 0x849F, 0xC958, + 0x84A0, 0xC959, + 0x84A2, 0xC95A, + 0x84A3, 0xC95B, + 0x84A4, 0xC95C, + 0x84A5, 0xC95D, + 0x84A6, 0xC95E, + 0x84A7, 0xC95F, + 0x84A8, 0xC960, + 0x84A9, 0xC961, + 0x84AA, 0xC962, + 0x84AB, 0xC963, + 0x84AC, 0xC964, + 0x84AD, 0xC965, + 0x84AE, 0xC966, + 0x84B0, 0xC967, + 0x84B1, 0xC968, + 0x84B3, 0xC969, + 0x84B5, 0xC96A, + 0x84B6, 0xC96B, + 0x84B7, 0xC96C, + 0x84BB, 0xC96D, + 0x84BC, 0xC96E, + 0x84BE, 0xC96F, + 0x84C0, 0xC970, + 0x84C2, 0xC971, + 0x84C3, 0xC972, + 0x84C5, 0xC973, + 0x84C6, 0xC974, + 0x84C7, 0xC975, + 0x84C8, 0xC976, + 0x84CB, 0xC977, + 0x84CC, 0xC978, + 0x84CE, 0xC979, + 0x84CF, 0xC97A, + 0x84D2, 0xC97B, + 0x84D4, 0xC97C, + 0x84D5, 0xC97D, + 0x84D7, 0xC97E, + 0x84D8, 0xC980, + 0x84D9, 0xC981, + 0x84DA, 0xC982, + 0x84DB, 0xC983, + 0x84DC, 0xC984, + 0x84DE, 0xC985, + 0x84E1, 0xC986, + 0x84E2, 0xC987, + 0x84E4, 0xC988, + 0x84E7, 0xC989, + 0x84E8, 0xC98A, + 0x84E9, 0xC98B, + 0x84EA, 0xC98C, + 0x84EB, 0xC98D, + 0x84ED, 0xC98E, + 0x84EE, 0xC98F, + 0x84EF, 0xC990, + 0x84F1, 0xC991, + 0x84F2, 0xC992, + 0x84F3, 0xC993, + 0x84F4, 0xC994, + 0x84F5, 0xC995, + 0x84F6, 0xC996, + 0x84F7, 0xC997, + 0x84F8, 0xC998, + 0x84F9, 0xC999, + 0x84FA, 0xC99A, + 0x84FB, 0xC99B, + 0x84FD, 0xC99C, + 0x84FE, 0xC99D, + 0x8500, 0xC99E, + 0x8501, 0xC99F, + 0x8502, 0xC9A0, + 0x8503, 0xCA40, + 0x8504, 0xCA41, + 0x8505, 0xCA42, + 0x8506, 0xCA43, + 0x8507, 0xCA44, + 0x8508, 0xCA45, + 0x8509, 0xCA46, + 0x850A, 0xCA47, + 0x850B, 0xCA48, + 0x850D, 0xCA49, + 0x850E, 0xCA4A, + 0x850F, 0xCA4B, + 0x8510, 0xCA4C, + 0x8512, 0xCA4D, + 0x8514, 0xCA4E, + 0x8515, 0xCA4F, + 0x8516, 0xCA50, + 0x8518, 0xCA51, + 0x8519, 0xCA52, + 0x851B, 0xCA53, + 0x851C, 0xCA54, + 0x851D, 0xCA55, + 0x851E, 0xCA56, + 0x8520, 0xCA57, + 0x8522, 0xCA58, + 0x8523, 0xCA59, + 0x8524, 0xCA5A, + 0x8525, 0xCA5B, + 0x8526, 0xCA5C, + 0x8527, 0xCA5D, + 0x8528, 0xCA5E, + 0x8529, 0xCA5F, + 0x852A, 0xCA60, + 0x852D, 0xCA61, + 0x852E, 0xCA62, + 0x852F, 0xCA63, + 0x8530, 0xCA64, + 0x8531, 0xCA65, + 0x8532, 0xCA66, + 0x8533, 0xCA67, + 0x8534, 0xCA68, + 0x8535, 0xCA69, + 0x8536, 0xCA6A, + 0x853E, 0xCA6B, + 0x853F, 0xCA6C, + 0x8540, 0xCA6D, + 0x8541, 0xCA6E, + 0x8542, 0xCA6F, + 0x8544, 0xCA70, + 0x8545, 0xCA71, + 0x8546, 0xCA72, + 0x8547, 0xCA73, + 0x854B, 0xCA74, + 0x854C, 0xCA75, + 0x854D, 0xCA76, + 0x854E, 0xCA77, + 0x854F, 0xCA78, + 0x8550, 0xCA79, + 0x8551, 0xCA7A, + 0x8552, 0xCA7B, + 0x8553, 0xCA7C, + 0x8554, 0xCA7D, + 0x8555, 0xCA7E, + 0x8557, 0xCA80, + 0x8558, 0xCA81, + 0x855A, 0xCA82, + 0x855B, 0xCA83, + 0x855C, 0xCA84, + 0x855D, 0xCA85, + 0x855F, 0xCA86, + 0x8560, 0xCA87, + 0x8561, 0xCA88, + 0x8562, 0xCA89, + 0x8563, 0xCA8A, + 0x8565, 0xCA8B, + 0x8566, 0xCA8C, + 0x8567, 0xCA8D, + 0x8569, 0xCA8E, + 0x856A, 0xCA8F, + 0x856B, 0xCA90, + 0x856C, 0xCA91, + 0x856D, 0xCA92, + 0x856E, 0xCA93, + 0x856F, 0xCA94, + 0x8570, 0xCA95, + 0x8571, 0xCA96, + 0x8573, 0xCA97, + 0x8575, 0xCA98, + 0x8576, 0xCA99, + 0x8577, 0xCA9A, + 0x8578, 0xCA9B, + 0x857C, 0xCA9C, + 0x857D, 0xCA9D, + 0x857F, 0xCA9E, + 0x8580, 0xCA9F, + 0x8581, 0xCAA0, + 0x8582, 0xCB40, + 0x8583, 0xCB41, + 0x8586, 0xCB42, + 0x8588, 0xCB43, + 0x8589, 0xCB44, + 0x858A, 0xCB45, + 0x858B, 0xCB46, + 0x858C, 0xCB47, + 0x858D, 0xCB48, + 0x858E, 0xCB49, + 0x8590, 0xCB4A, + 0x8591, 0xCB4B, + 0x8592, 0xCB4C, + 0x8593, 0xCB4D, + 0x8594, 0xCB4E, + 0x8595, 0xCB4F, + 0x8596, 0xCB50, + 0x8597, 0xCB51, + 0x8598, 0xCB52, + 0x8599, 0xCB53, + 0x859A, 0xCB54, + 0x859D, 0xCB55, + 0x859E, 0xCB56, + 0x859F, 0xCB57, + 0x85A0, 0xCB58, + 0x85A1, 0xCB59, + 0x85A2, 0xCB5A, + 0x85A3, 0xCB5B, + 0x85A5, 0xCB5C, + 0x85A6, 0xCB5D, + 0x85A7, 0xCB5E, + 0x85A9, 0xCB5F, + 0x85AB, 0xCB60, + 0x85AC, 0xCB61, + 0x85AD, 0xCB62, + 0x85B1, 0xCB63, + 0x85B2, 0xCB64, + 0x85B3, 0xCB65, + 0x85B4, 0xCB66, + 0x85B5, 0xCB67, + 0x85B6, 0xCB68, + 0x85B8, 0xCB69, + 0x85BA, 0xCB6A, + 0x85BB, 0xCB6B, + 0x85BC, 0xCB6C, + 0x85BD, 0xCB6D, + 0x85BE, 0xCB6E, + 0x85BF, 0xCB6F, + 0x85C0, 0xCB70, + 0x85C2, 0xCB71, + 0x85C3, 0xCB72, + 0x85C4, 0xCB73, + 0x85C5, 0xCB74, + 0x85C6, 0xCB75, + 0x85C7, 0xCB76, + 0x85C8, 0xCB77, + 0x85CA, 0xCB78, + 0x85CB, 0xCB79, + 0x85CC, 0xCB7A, + 0x85CD, 0xCB7B, + 0x85CE, 0xCB7C, + 0x85D1, 0xCB7D, + 0x85D2, 0xCB7E, + 0x85D4, 0xCB80, + 0x85D6, 0xCB81, + 0x85D7, 0xCB82, + 0x85D8, 0xCB83, + 0x85D9, 0xCB84, + 0x85DA, 0xCB85, + 0x85DB, 0xCB86, + 0x85DD, 0xCB87, + 0x85DE, 0xCB88, + 0x85DF, 0xCB89, + 0x85E0, 0xCB8A, + 0x85E1, 0xCB8B, + 0x85E2, 0xCB8C, + 0x85E3, 0xCB8D, + 0x85E5, 0xCB8E, + 0x85E6, 0xCB8F, + 0x85E7, 0xCB90, + 0x85E8, 0xCB91, + 0x85EA, 0xCB92, + 0x85EB, 0xCB93, + 0x85EC, 0xCB94, + 0x85ED, 0xCB95, + 0x85EE, 0xCB96, + 0x85EF, 0xCB97, + 0x85F0, 0xCB98, + 0x85F1, 0xCB99, + 0x85F2, 0xCB9A, + 0x85F3, 0xCB9B, + 0x85F4, 0xCB9C, + 0x85F5, 0xCB9D, + 0x85F6, 0xCB9E, + 0x85F7, 0xCB9F, + 0x85F8, 0xCBA0, + 0x85F9, 0xCC40, + 0x85FA, 0xCC41, + 0x85FC, 0xCC42, + 0x85FD, 0xCC43, + 0x85FE, 0xCC44, + 0x8600, 0xCC45, + 0x8601, 0xCC46, + 0x8602, 0xCC47, + 0x8603, 0xCC48, + 0x8604, 0xCC49, + 0x8606, 0xCC4A, + 0x8607, 0xCC4B, + 0x8608, 0xCC4C, + 0x8609, 0xCC4D, + 0x860A, 0xCC4E, + 0x860B, 0xCC4F, + 0x860C, 0xCC50, + 0x860D, 0xCC51, + 0x860E, 0xCC52, + 0x860F, 0xCC53, + 0x8610, 0xCC54, + 0x8612, 0xCC55, + 0x8613, 0xCC56, + 0x8614, 0xCC57, + 0x8615, 0xCC58, + 0x8617, 0xCC59, + 0x8618, 0xCC5A, + 0x8619, 0xCC5B, + 0x861A, 0xCC5C, + 0x861B, 0xCC5D, + 0x861C, 0xCC5E, + 0x861D, 0xCC5F, + 0x861E, 0xCC60, + 0x861F, 0xCC61, + 0x8620, 0xCC62, + 0x8621, 0xCC63, + 0x8622, 0xCC64, + 0x8623, 0xCC65, + 0x8624, 0xCC66, + 0x8625, 0xCC67, + 0x8626, 0xCC68, + 0x8628, 0xCC69, + 0x862A, 0xCC6A, + 0x862B, 0xCC6B, + 0x862C, 0xCC6C, + 0x862D, 0xCC6D, + 0x862E, 0xCC6E, + 0x862F, 0xCC6F, + 0x8630, 0xCC70, + 0x8631, 0xCC71, + 0x8632, 0xCC72, + 0x8633, 0xCC73, + 0x8634, 0xCC74, + 0x8635, 0xCC75, + 0x8636, 0xCC76, + 0x8637, 0xCC77, + 0x8639, 0xCC78, + 0x863A, 0xCC79, + 0x863B, 0xCC7A, + 0x863D, 0xCC7B, + 0x863E, 0xCC7C, + 0x863F, 0xCC7D, + 0x8640, 0xCC7E, + 0x8641, 0xCC80, + 0x8642, 0xCC81, + 0x8643, 0xCC82, + 0x8644, 0xCC83, + 0x8645, 0xCC84, + 0x8646, 0xCC85, + 0x8647, 0xCC86, + 0x8648, 0xCC87, + 0x8649, 0xCC88, + 0x864A, 0xCC89, + 0x864B, 0xCC8A, + 0x864C, 0xCC8B, + 0x8652, 0xCC8C, + 0x8653, 0xCC8D, + 0x8655, 0xCC8E, + 0x8656, 0xCC8F, + 0x8657, 0xCC90, + 0x8658, 0xCC91, + 0x8659, 0xCC92, + 0x865B, 0xCC93, + 0x865C, 0xCC94, + 0x865D, 0xCC95, + 0x865F, 0xCC96, + 0x8660, 0xCC97, + 0x8661, 0xCC98, + 0x8663, 0xCC99, + 0x8664, 0xCC9A, + 0x8665, 0xCC9B, + 0x8666, 0xCC9C, + 0x8667, 0xCC9D, + 0x8668, 0xCC9E, + 0x8669, 0xCC9F, + 0x866A, 0xCCA0, + 0x866D, 0xCD40, + 0x866F, 0xCD41, + 0x8670, 0xCD42, + 0x8672, 0xCD43, + 0x8673, 0xCD44, + 0x8674, 0xCD45, + 0x8675, 0xCD46, + 0x8676, 0xCD47, + 0x8677, 0xCD48, + 0x8678, 0xCD49, + 0x8683, 0xCD4A, + 0x8684, 0xCD4B, + 0x8685, 0xCD4C, + 0x8686, 0xCD4D, + 0x8687, 0xCD4E, + 0x8688, 0xCD4F, + 0x8689, 0xCD50, + 0x868E, 0xCD51, + 0x868F, 0xCD52, + 0x8690, 0xCD53, + 0x8691, 0xCD54, + 0x8692, 0xCD55, + 0x8694, 0xCD56, + 0x8696, 0xCD57, + 0x8697, 0xCD58, + 0x8698, 0xCD59, + 0x8699, 0xCD5A, + 0x869A, 0xCD5B, + 0x869B, 0xCD5C, + 0x869E, 0xCD5D, + 0x869F, 0xCD5E, + 0x86A0, 0xCD5F, + 0x86A1, 0xCD60, + 0x86A2, 0xCD61, + 0x86A5, 0xCD62, + 0x86A6, 0xCD63, + 0x86AB, 0xCD64, + 0x86AD, 0xCD65, + 0x86AE, 0xCD66, + 0x86B2, 0xCD67, + 0x86B3, 0xCD68, + 0x86B7, 0xCD69, + 0x86B8, 0xCD6A, + 0x86B9, 0xCD6B, + 0x86BB, 0xCD6C, + 0x86BC, 0xCD6D, + 0x86BD, 0xCD6E, + 0x86BE, 0xCD6F, + 0x86BF, 0xCD70, + 0x86C1, 0xCD71, + 0x86C2, 0xCD72, + 0x86C3, 0xCD73, + 0x86C5, 0xCD74, + 0x86C8, 0xCD75, + 0x86CC, 0xCD76, + 0x86CD, 0xCD77, + 0x86D2, 0xCD78, + 0x86D3, 0xCD79, + 0x86D5, 0xCD7A, + 0x86D6, 0xCD7B, + 0x86D7, 0xCD7C, + 0x86DA, 0xCD7D, + 0x86DC, 0xCD7E, + 0x86DD, 0xCD80, + 0x86E0, 0xCD81, + 0x86E1, 0xCD82, + 0x86E2, 0xCD83, + 0x86E3, 0xCD84, + 0x86E5, 0xCD85, + 0x86E6, 0xCD86, + 0x86E7, 0xCD87, + 0x86E8, 0xCD88, + 0x86EA, 0xCD89, + 0x86EB, 0xCD8A, + 0x86EC, 0xCD8B, + 0x86EF, 0xCD8C, + 0x86F5, 0xCD8D, + 0x86F6, 0xCD8E, + 0x86F7, 0xCD8F, + 0x86FA, 0xCD90, + 0x86FB, 0xCD91, + 0x86FC, 0xCD92, + 0x86FD, 0xCD93, + 0x86FF, 0xCD94, + 0x8701, 0xCD95, + 0x8704, 0xCD96, + 0x8705, 0xCD97, + 0x8706, 0xCD98, + 0x870B, 0xCD99, + 0x870C, 0xCD9A, + 0x870E, 0xCD9B, + 0x870F, 0xCD9C, + 0x8710, 0xCD9D, + 0x8711, 0xCD9E, + 0x8714, 0xCD9F, + 0x8716, 0xCDA0, + 0x8719, 0xCE40, + 0x871B, 0xCE41, + 0x871D, 0xCE42, + 0x871F, 0xCE43, + 0x8720, 0xCE44, + 0x8724, 0xCE45, + 0x8726, 0xCE46, + 0x8727, 0xCE47, + 0x8728, 0xCE48, + 0x872A, 0xCE49, + 0x872B, 0xCE4A, + 0x872C, 0xCE4B, + 0x872D, 0xCE4C, + 0x872F, 0xCE4D, + 0x8730, 0xCE4E, + 0x8732, 0xCE4F, + 0x8733, 0xCE50, + 0x8735, 0xCE51, + 0x8736, 0xCE52, + 0x8738, 0xCE53, + 0x8739, 0xCE54, + 0x873A, 0xCE55, + 0x873C, 0xCE56, + 0x873D, 0xCE57, + 0x8740, 0xCE58, + 0x8741, 0xCE59, + 0x8742, 0xCE5A, + 0x8743, 0xCE5B, + 0x8744, 0xCE5C, + 0x8745, 0xCE5D, + 0x8746, 0xCE5E, + 0x874A, 0xCE5F, + 0x874B, 0xCE60, + 0x874D, 0xCE61, + 0x874F, 0xCE62, + 0x8750, 0xCE63, + 0x8751, 0xCE64, + 0x8752, 0xCE65, + 0x8754, 0xCE66, + 0x8755, 0xCE67, + 0x8756, 0xCE68, + 0x8758, 0xCE69, + 0x875A, 0xCE6A, + 0x875B, 0xCE6B, + 0x875C, 0xCE6C, + 0x875D, 0xCE6D, + 0x875E, 0xCE6E, + 0x875F, 0xCE6F, + 0x8761, 0xCE70, + 0x8762, 0xCE71, + 0x8766, 0xCE72, + 0x8767, 0xCE73, + 0x8768, 0xCE74, + 0x8769, 0xCE75, + 0x876A, 0xCE76, + 0x876B, 0xCE77, + 0x876C, 0xCE78, + 0x876D, 0xCE79, + 0x876F, 0xCE7A, + 0x8771, 0xCE7B, + 0x8772, 0xCE7C, + 0x8773, 0xCE7D, + 0x8775, 0xCE7E, + 0x8777, 0xCE80, + 0x8778, 0xCE81, + 0x8779, 0xCE82, + 0x877A, 0xCE83, + 0x877F, 0xCE84, + 0x8780, 0xCE85, + 0x8781, 0xCE86, + 0x8784, 0xCE87, + 0x8786, 0xCE88, + 0x8787, 0xCE89, + 0x8789, 0xCE8A, + 0x878A, 0xCE8B, + 0x878C, 0xCE8C, + 0x878E, 0xCE8D, + 0x878F, 0xCE8E, + 0x8790, 0xCE8F, + 0x8791, 0xCE90, + 0x8792, 0xCE91, + 0x8794, 0xCE92, + 0x8795, 0xCE93, + 0x8796, 0xCE94, + 0x8798, 0xCE95, + 0x8799, 0xCE96, + 0x879A, 0xCE97, + 0x879B, 0xCE98, + 0x879C, 0xCE99, + 0x879D, 0xCE9A, + 0x879E, 0xCE9B, + 0x87A0, 0xCE9C, + 0x87A1, 0xCE9D, + 0x87A2, 0xCE9E, + 0x87A3, 0xCE9F, + 0x87A4, 0xCEA0, + 0x87A5, 0xCF40, + 0x87A6, 0xCF41, + 0x87A7, 0xCF42, + 0x87A9, 0xCF43, + 0x87AA, 0xCF44, + 0x87AE, 0xCF45, + 0x87B0, 0xCF46, + 0x87B1, 0xCF47, + 0x87B2, 0xCF48, + 0x87B4, 0xCF49, + 0x87B6, 0xCF4A, + 0x87B7, 0xCF4B, + 0x87B8, 0xCF4C, + 0x87B9, 0xCF4D, + 0x87BB, 0xCF4E, + 0x87BC, 0xCF4F, + 0x87BE, 0xCF50, + 0x87BF, 0xCF51, + 0x87C1, 0xCF52, + 0x87C2, 0xCF53, + 0x87C3, 0xCF54, + 0x87C4, 0xCF55, + 0x87C5, 0xCF56, + 0x87C7, 0xCF57, + 0x87C8, 0xCF58, + 0x87C9, 0xCF59, + 0x87CC, 0xCF5A, + 0x87CD, 0xCF5B, + 0x87CE, 0xCF5C, + 0x87CF, 0xCF5D, + 0x87D0, 0xCF5E, + 0x87D4, 0xCF5F, + 0x87D5, 0xCF60, + 0x87D6, 0xCF61, + 0x87D7, 0xCF62, + 0x87D8, 0xCF63, + 0x87D9, 0xCF64, + 0x87DA, 0xCF65, + 0x87DC, 0xCF66, + 0x87DD, 0xCF67, + 0x87DE, 0xCF68, + 0x87DF, 0xCF69, + 0x87E1, 0xCF6A, + 0x87E2, 0xCF6B, + 0x87E3, 0xCF6C, + 0x87E4, 0xCF6D, + 0x87E6, 0xCF6E, + 0x87E7, 0xCF6F, + 0x87E8, 0xCF70, + 0x87E9, 0xCF71, + 0x87EB, 0xCF72, + 0x87EC, 0xCF73, + 0x87ED, 0xCF74, + 0x87EF, 0xCF75, + 0x87F0, 0xCF76, + 0x87F1, 0xCF77, + 0x87F2, 0xCF78, + 0x87F3, 0xCF79, + 0x87F4, 0xCF7A, + 0x87F5, 0xCF7B, + 0x87F6, 0xCF7C, + 0x87F7, 0xCF7D, + 0x87F8, 0xCF7E, + 0x87FA, 0xCF80, + 0x87FB, 0xCF81, + 0x87FC, 0xCF82, + 0x87FD, 0xCF83, + 0x87FF, 0xCF84, + 0x8800, 0xCF85, + 0x8801, 0xCF86, + 0x8802, 0xCF87, + 0x8804, 0xCF88, + 0x8805, 0xCF89, + 0x8806, 0xCF8A, + 0x8807, 0xCF8B, + 0x8808, 0xCF8C, + 0x8809, 0xCF8D, + 0x880B, 0xCF8E, + 0x880C, 0xCF8F, + 0x880D, 0xCF90, + 0x880E, 0xCF91, + 0x880F, 0xCF92, + 0x8810, 0xCF93, + 0x8811, 0xCF94, + 0x8812, 0xCF95, + 0x8814, 0xCF96, + 0x8817, 0xCF97, + 0x8818, 0xCF98, + 0x8819, 0xCF99, + 0x881A, 0xCF9A, + 0x881C, 0xCF9B, + 0x881D, 0xCF9C, + 0x881E, 0xCF9D, + 0x881F, 0xCF9E, + 0x8820, 0xCF9F, + 0x8823, 0xCFA0, + 0x8824, 0xD040, + 0x8825, 0xD041, + 0x8826, 0xD042, + 0x8827, 0xD043, + 0x8828, 0xD044, + 0x8829, 0xD045, + 0x882A, 0xD046, + 0x882B, 0xD047, + 0x882C, 0xD048, + 0x882D, 0xD049, + 0x882E, 0xD04A, + 0x882F, 0xD04B, + 0x8830, 0xD04C, + 0x8831, 0xD04D, + 0x8833, 0xD04E, + 0x8834, 0xD04F, + 0x8835, 0xD050, + 0x8836, 0xD051, + 0x8837, 0xD052, + 0x8838, 0xD053, + 0x883A, 0xD054, + 0x883B, 0xD055, + 0x883D, 0xD056, + 0x883E, 0xD057, + 0x883F, 0xD058, + 0x8841, 0xD059, + 0x8842, 0xD05A, + 0x8843, 0xD05B, + 0x8846, 0xD05C, + 0x8847, 0xD05D, + 0x8848, 0xD05E, + 0x8849, 0xD05F, + 0x884A, 0xD060, + 0x884B, 0xD061, + 0x884E, 0xD062, + 0x884F, 0xD063, + 0x8850, 0xD064, + 0x8851, 0xD065, + 0x8852, 0xD066, + 0x8853, 0xD067, + 0x8855, 0xD068, + 0x8856, 0xD069, + 0x8858, 0xD06A, + 0x885A, 0xD06B, + 0x885B, 0xD06C, + 0x885C, 0xD06D, + 0x885D, 0xD06E, + 0x885E, 0xD06F, + 0x885F, 0xD070, + 0x8860, 0xD071, + 0x8866, 0xD072, + 0x8867, 0xD073, + 0x886A, 0xD074, + 0x886D, 0xD075, + 0x886F, 0xD076, + 0x8871, 0xD077, + 0x8873, 0xD078, + 0x8874, 0xD079, + 0x8875, 0xD07A, + 0x8876, 0xD07B, + 0x8878, 0xD07C, + 0x8879, 0xD07D, + 0x887A, 0xD07E, + 0x887B, 0xD080, + 0x887C, 0xD081, + 0x8880, 0xD082, + 0x8883, 0xD083, + 0x8886, 0xD084, + 0x8887, 0xD085, + 0x8889, 0xD086, + 0x888A, 0xD087, + 0x888C, 0xD088, + 0x888E, 0xD089, + 0x888F, 0xD08A, + 0x8890, 0xD08B, + 0x8891, 0xD08C, + 0x8893, 0xD08D, + 0x8894, 0xD08E, + 0x8895, 0xD08F, + 0x8897, 0xD090, + 0x8898, 0xD091, + 0x8899, 0xD092, + 0x889A, 0xD093, + 0x889B, 0xD094, + 0x889D, 0xD095, + 0x889E, 0xD096, + 0x889F, 0xD097, + 0x88A0, 0xD098, + 0x88A1, 0xD099, + 0x88A3, 0xD09A, + 0x88A5, 0xD09B, + 0x88A6, 0xD09C, + 0x88A7, 0xD09D, + 0x88A8, 0xD09E, + 0x88A9, 0xD09F, + 0x88AA, 0xD0A0, + 0x88AC, 0xD140, + 0x88AE, 0xD141, + 0x88AF, 0xD142, + 0x88B0, 0xD143, + 0x88B2, 0xD144, + 0x88B3, 0xD145, + 0x88B4, 0xD146, + 0x88B5, 0xD147, + 0x88B6, 0xD148, + 0x88B8, 0xD149, + 0x88B9, 0xD14A, + 0x88BA, 0xD14B, + 0x88BB, 0xD14C, + 0x88BD, 0xD14D, + 0x88BE, 0xD14E, + 0x88BF, 0xD14F, + 0x88C0, 0xD150, + 0x88C3, 0xD151, + 0x88C4, 0xD152, + 0x88C7, 0xD153, + 0x88C8, 0xD154, + 0x88CA, 0xD155, + 0x88CB, 0xD156, + 0x88CC, 0xD157, + 0x88CD, 0xD158, + 0x88CF, 0xD159, + 0x88D0, 0xD15A, + 0x88D1, 0xD15B, + 0x88D3, 0xD15C, + 0x88D6, 0xD15D, + 0x88D7, 0xD15E, + 0x88DA, 0xD15F, + 0x88DB, 0xD160, + 0x88DC, 0xD161, + 0x88DD, 0xD162, + 0x88DE, 0xD163, + 0x88E0, 0xD164, + 0x88E1, 0xD165, + 0x88E6, 0xD166, + 0x88E7, 0xD167, + 0x88E9, 0xD168, + 0x88EA, 0xD169, + 0x88EB, 0xD16A, + 0x88EC, 0xD16B, + 0x88ED, 0xD16C, + 0x88EE, 0xD16D, + 0x88EF, 0xD16E, + 0x88F2, 0xD16F, + 0x88F5, 0xD170, + 0x88F6, 0xD171, + 0x88F7, 0xD172, + 0x88FA, 0xD173, + 0x88FB, 0xD174, + 0x88FD, 0xD175, + 0x88FF, 0xD176, + 0x8900, 0xD177, + 0x8901, 0xD178, + 0x8903, 0xD179, + 0x8904, 0xD17A, + 0x8905, 0xD17B, + 0x8906, 0xD17C, + 0x8907, 0xD17D, + 0x8908, 0xD17E, + 0x8909, 0xD180, + 0x890B, 0xD181, + 0x890C, 0xD182, + 0x890D, 0xD183, + 0x890E, 0xD184, + 0x890F, 0xD185, + 0x8911, 0xD186, + 0x8914, 0xD187, + 0x8915, 0xD188, + 0x8916, 0xD189, + 0x8917, 0xD18A, + 0x8918, 0xD18B, + 0x891C, 0xD18C, + 0x891D, 0xD18D, + 0x891E, 0xD18E, + 0x891F, 0xD18F, + 0x8920, 0xD190, + 0x8922, 0xD191, + 0x8923, 0xD192, + 0x8924, 0xD193, + 0x8926, 0xD194, + 0x8927, 0xD195, + 0x8928, 0xD196, + 0x8929, 0xD197, + 0x892C, 0xD198, + 0x892D, 0xD199, + 0x892E, 0xD19A, + 0x892F, 0xD19B, + 0x8931, 0xD19C, + 0x8932, 0xD19D, + 0x8933, 0xD19E, + 0x8935, 0xD19F, + 0x8937, 0xD1A0, + 0x8938, 0xD240, + 0x8939, 0xD241, + 0x893A, 0xD242, + 0x893B, 0xD243, + 0x893C, 0xD244, + 0x893D, 0xD245, + 0x893E, 0xD246, + 0x893F, 0xD247, + 0x8940, 0xD248, + 0x8942, 0xD249, + 0x8943, 0xD24A, + 0x8945, 0xD24B, + 0x8946, 0xD24C, + 0x8947, 0xD24D, + 0x8948, 0xD24E, + 0x8949, 0xD24F, + 0x894A, 0xD250, + 0x894B, 0xD251, + 0x894C, 0xD252, + 0x894D, 0xD253, + 0x894E, 0xD254, + 0x894F, 0xD255, + 0x8950, 0xD256, + 0x8951, 0xD257, + 0x8952, 0xD258, + 0x8953, 0xD259, + 0x8954, 0xD25A, + 0x8955, 0xD25B, + 0x8956, 0xD25C, + 0x8957, 0xD25D, + 0x8958, 0xD25E, + 0x8959, 0xD25F, + 0x895A, 0xD260, + 0x895B, 0xD261, + 0x895C, 0xD262, + 0x895D, 0xD263, + 0x8960, 0xD264, + 0x8961, 0xD265, + 0x8962, 0xD266, + 0x8963, 0xD267, + 0x8964, 0xD268, + 0x8965, 0xD269, + 0x8967, 0xD26A, + 0x8968, 0xD26B, + 0x8969, 0xD26C, + 0x896A, 0xD26D, + 0x896B, 0xD26E, + 0x896C, 0xD26F, + 0x896D, 0xD270, + 0x896E, 0xD271, + 0x896F, 0xD272, + 0x8970, 0xD273, + 0x8971, 0xD274, + 0x8972, 0xD275, + 0x8973, 0xD276, + 0x8974, 0xD277, + 0x8975, 0xD278, + 0x8976, 0xD279, + 0x8977, 0xD27A, + 0x8978, 0xD27B, + 0x8979, 0xD27C, + 0x897A, 0xD27D, + 0x897C, 0xD27E, + 0x897D, 0xD280, + 0x897E, 0xD281, + 0x8980, 0xD282, + 0x8982, 0xD283, + 0x8984, 0xD284, + 0x8985, 0xD285, + 0x8987, 0xD286, + 0x8988, 0xD287, + 0x8989, 0xD288, + 0x898A, 0xD289, + 0x898B, 0xD28A, + 0x898C, 0xD28B, + 0x898D, 0xD28C, + 0x898E, 0xD28D, + 0x898F, 0xD28E, + 0x8990, 0xD28F, + 0x8991, 0xD290, + 0x8992, 0xD291, + 0x8993, 0xD292, + 0x8994, 0xD293, + 0x8995, 0xD294, + 0x8996, 0xD295, + 0x8997, 0xD296, + 0x8998, 0xD297, + 0x8999, 0xD298, + 0x899A, 0xD299, + 0x899B, 0xD29A, + 0x899C, 0xD29B, + 0x899D, 0xD29C, + 0x899E, 0xD29D, + 0x899F, 0xD29E, + 0x89A0, 0xD29F, + 0x89A1, 0xD2A0, + 0x89A2, 0xD340, + 0x89A3, 0xD341, + 0x89A4, 0xD342, + 0x89A5, 0xD343, + 0x89A6, 0xD344, + 0x89A7, 0xD345, + 0x89A8, 0xD346, + 0x89A9, 0xD347, + 0x89AA, 0xD348, + 0x89AB, 0xD349, + 0x89AC, 0xD34A, + 0x89AD, 0xD34B, + 0x89AE, 0xD34C, + 0x89AF, 0xD34D, + 0x89B0, 0xD34E, + 0x89B1, 0xD34F, + 0x89B2, 0xD350, + 0x89B3, 0xD351, + 0x89B4, 0xD352, + 0x89B5, 0xD353, + 0x89B6, 0xD354, + 0x89B7, 0xD355, + 0x89B8, 0xD356, + 0x89B9, 0xD357, + 0x89BA, 0xD358, + 0x89BB, 0xD359, + 0x89BC, 0xD35A, + 0x89BD, 0xD35B, + 0x89BE, 0xD35C, + 0x89BF, 0xD35D, + 0x89C0, 0xD35E, + 0x89C3, 0xD35F, + 0x89CD, 0xD360, + 0x89D3, 0xD361, + 0x89D4, 0xD362, + 0x89D5, 0xD363, + 0x89D7, 0xD364, + 0x89D8, 0xD365, + 0x89D9, 0xD366, + 0x89DB, 0xD367, + 0x89DD, 0xD368, + 0x89DF, 0xD369, + 0x89E0, 0xD36A, + 0x89E1, 0xD36B, + 0x89E2, 0xD36C, + 0x89E4, 0xD36D, + 0x89E7, 0xD36E, + 0x89E8, 0xD36F, + 0x89E9, 0xD370, + 0x89EA, 0xD371, + 0x89EC, 0xD372, + 0x89ED, 0xD373, + 0x89EE, 0xD374, + 0x89F0, 0xD375, + 0x89F1, 0xD376, + 0x89F2, 0xD377, + 0x89F4, 0xD378, + 0x89F5, 0xD379, + 0x89F6, 0xD37A, + 0x89F7, 0xD37B, + 0x89F8, 0xD37C, + 0x89F9, 0xD37D, + 0x89FA, 0xD37E, + 0x89FB, 0xD380, + 0x89FC, 0xD381, + 0x89FD, 0xD382, + 0x89FE, 0xD383, + 0x89FF, 0xD384, + 0x8A01, 0xD385, + 0x8A02, 0xD386, + 0x8A03, 0xD387, + 0x8A04, 0xD388, + 0x8A05, 0xD389, + 0x8A06, 0xD38A, + 0x8A08, 0xD38B, + 0x8A09, 0xD38C, + 0x8A0A, 0xD38D, + 0x8A0B, 0xD38E, + 0x8A0C, 0xD38F, + 0x8A0D, 0xD390, + 0x8A0E, 0xD391, + 0x8A0F, 0xD392, + 0x8A10, 0xD393, + 0x8A11, 0xD394, + 0x8A12, 0xD395, + 0x8A13, 0xD396, + 0x8A14, 0xD397, + 0x8A15, 0xD398, + 0x8A16, 0xD399, + 0x8A17, 0xD39A, + 0x8A18, 0xD39B, + 0x8A19, 0xD39C, + 0x8A1A, 0xD39D, + 0x8A1B, 0xD39E, + 0x8A1C, 0xD39F, + 0x8A1D, 0xD3A0, + 0x8A1E, 0xD440, + 0x8A1F, 0xD441, + 0x8A20, 0xD442, + 0x8A21, 0xD443, + 0x8A22, 0xD444, + 0x8A23, 0xD445, + 0x8A24, 0xD446, + 0x8A25, 0xD447, + 0x8A26, 0xD448, + 0x8A27, 0xD449, + 0x8A28, 0xD44A, + 0x8A29, 0xD44B, + 0x8A2A, 0xD44C, + 0x8A2B, 0xD44D, + 0x8A2C, 0xD44E, + 0x8A2D, 0xD44F, + 0x8A2E, 0xD450, + 0x8A2F, 0xD451, + 0x8A30, 0xD452, + 0x8A31, 0xD453, + 0x8A32, 0xD454, + 0x8A33, 0xD455, + 0x8A34, 0xD456, + 0x8A35, 0xD457, + 0x8A36, 0xD458, + 0x8A37, 0xD459, + 0x8A38, 0xD45A, + 0x8A39, 0xD45B, + 0x8A3A, 0xD45C, + 0x8A3B, 0xD45D, + 0x8A3C, 0xD45E, + 0x8A3D, 0xD45F, + 0x8A3F, 0xD460, + 0x8A40, 0xD461, + 0x8A41, 0xD462, + 0x8A42, 0xD463, + 0x8A43, 0xD464, + 0x8A44, 0xD465, + 0x8A45, 0xD466, + 0x8A46, 0xD467, + 0x8A47, 0xD468, + 0x8A49, 0xD469, + 0x8A4A, 0xD46A, + 0x8A4B, 0xD46B, + 0x8A4C, 0xD46C, + 0x8A4D, 0xD46D, + 0x8A4E, 0xD46E, + 0x8A4F, 0xD46F, + 0x8A50, 0xD470, + 0x8A51, 0xD471, + 0x8A52, 0xD472, + 0x8A53, 0xD473, + 0x8A54, 0xD474, + 0x8A55, 0xD475, + 0x8A56, 0xD476, + 0x8A57, 0xD477, + 0x8A58, 0xD478, + 0x8A59, 0xD479, + 0x8A5A, 0xD47A, + 0x8A5B, 0xD47B, + 0x8A5C, 0xD47C, + 0x8A5D, 0xD47D, + 0x8A5E, 0xD47E, + 0x8A5F, 0xD480, + 0x8A60, 0xD481, + 0x8A61, 0xD482, + 0x8A62, 0xD483, + 0x8A63, 0xD484, + 0x8A64, 0xD485, + 0x8A65, 0xD486, + 0x8A66, 0xD487, + 0x8A67, 0xD488, + 0x8A68, 0xD489, + 0x8A69, 0xD48A, + 0x8A6A, 0xD48B, + 0x8A6B, 0xD48C, + 0x8A6C, 0xD48D, + 0x8A6D, 0xD48E, + 0x8A6E, 0xD48F, + 0x8A6F, 0xD490, + 0x8A70, 0xD491, + 0x8A71, 0xD492, + 0x8A72, 0xD493, + 0x8A73, 0xD494, + 0x8A74, 0xD495, + 0x8A75, 0xD496, + 0x8A76, 0xD497, + 0x8A77, 0xD498, + 0x8A78, 0xD499, + 0x8A7A, 0xD49A, + 0x8A7B, 0xD49B, + 0x8A7C, 0xD49C, + 0x8A7D, 0xD49D, + 0x8A7E, 0xD49E, + 0x8A7F, 0xD49F, + 0x8A80, 0xD4A0, + 0x8A81, 0xD540, + 0x8A82, 0xD541, + 0x8A83, 0xD542, + 0x8A84, 0xD543, + 0x8A85, 0xD544, + 0x8A86, 0xD545, + 0x8A87, 0xD546, + 0x8A88, 0xD547, + 0x8A8B, 0xD548, + 0x8A8C, 0xD549, + 0x8A8D, 0xD54A, + 0x8A8E, 0xD54B, + 0x8A8F, 0xD54C, + 0x8A90, 0xD54D, + 0x8A91, 0xD54E, + 0x8A92, 0xD54F, + 0x8A94, 0xD550, + 0x8A95, 0xD551, + 0x8A96, 0xD552, + 0x8A97, 0xD553, + 0x8A98, 0xD554, + 0x8A99, 0xD555, + 0x8A9A, 0xD556, + 0x8A9B, 0xD557, + 0x8A9C, 0xD558, + 0x8A9D, 0xD559, + 0x8A9E, 0xD55A, + 0x8A9F, 0xD55B, + 0x8AA0, 0xD55C, + 0x8AA1, 0xD55D, + 0x8AA2, 0xD55E, + 0x8AA3, 0xD55F, + 0x8AA4, 0xD560, + 0x8AA5, 0xD561, + 0x8AA6, 0xD562, + 0x8AA7, 0xD563, + 0x8AA8, 0xD564, + 0x8AA9, 0xD565, + 0x8AAA, 0xD566, + 0x8AAB, 0xD567, + 0x8AAC, 0xD568, + 0x8AAD, 0xD569, + 0x8AAE, 0xD56A, + 0x8AAF, 0xD56B, + 0x8AB0, 0xD56C, + 0x8AB1, 0xD56D, + 0x8AB2, 0xD56E, + 0x8AB3, 0xD56F, + 0x8AB4, 0xD570, + 0x8AB5, 0xD571, + 0x8AB6, 0xD572, + 0x8AB7, 0xD573, + 0x8AB8, 0xD574, + 0x8AB9, 0xD575, + 0x8ABA, 0xD576, + 0x8ABB, 0xD577, + 0x8ABC, 0xD578, + 0x8ABD, 0xD579, + 0x8ABE, 0xD57A, + 0x8ABF, 0xD57B, + 0x8AC0, 0xD57C, + 0x8AC1, 0xD57D, + 0x8AC2, 0xD57E, + 0x8AC3, 0xD580, + 0x8AC4, 0xD581, + 0x8AC5, 0xD582, + 0x8AC6, 0xD583, + 0x8AC7, 0xD584, + 0x8AC8, 0xD585, + 0x8AC9, 0xD586, + 0x8ACA, 0xD587, + 0x8ACB, 0xD588, + 0x8ACC, 0xD589, + 0x8ACD, 0xD58A, + 0x8ACE, 0xD58B, + 0x8ACF, 0xD58C, + 0x8AD0, 0xD58D, + 0x8AD1, 0xD58E, + 0x8AD2, 0xD58F, + 0x8AD3, 0xD590, + 0x8AD4, 0xD591, + 0x8AD5, 0xD592, + 0x8AD6, 0xD593, + 0x8AD7, 0xD594, + 0x8AD8, 0xD595, + 0x8AD9, 0xD596, + 0x8ADA, 0xD597, + 0x8ADB, 0xD598, + 0x8ADC, 0xD599, + 0x8ADD, 0xD59A, + 0x8ADE, 0xD59B, + 0x8ADF, 0xD59C, + 0x8AE0, 0xD59D, + 0x8AE1, 0xD59E, + 0x8AE2, 0xD59F, + 0x8AE3, 0xD5A0, + 0x8AE4, 0xD640, + 0x8AE5, 0xD641, + 0x8AE6, 0xD642, + 0x8AE7, 0xD643, + 0x8AE8, 0xD644, + 0x8AE9, 0xD645, + 0x8AEA, 0xD646, + 0x8AEB, 0xD647, + 0x8AEC, 0xD648, + 0x8AED, 0xD649, + 0x8AEE, 0xD64A, + 0x8AEF, 0xD64B, + 0x8AF0, 0xD64C, + 0x8AF1, 0xD64D, + 0x8AF2, 0xD64E, + 0x8AF3, 0xD64F, + 0x8AF4, 0xD650, + 0x8AF5, 0xD651, + 0x8AF6, 0xD652, + 0x8AF7, 0xD653, + 0x8AF8, 0xD654, + 0x8AF9, 0xD655, + 0x8AFA, 0xD656, + 0x8AFB, 0xD657, + 0x8AFC, 0xD658, + 0x8AFD, 0xD659, + 0x8AFE, 0xD65A, + 0x8AFF, 0xD65B, + 0x8B00, 0xD65C, + 0x8B01, 0xD65D, + 0x8B02, 0xD65E, + 0x8B03, 0xD65F, + 0x8B04, 0xD660, + 0x8B05, 0xD661, + 0x8B06, 0xD662, + 0x8B08, 0xD663, + 0x8B09, 0xD664, + 0x8B0A, 0xD665, + 0x8B0B, 0xD666, + 0x8B0C, 0xD667, + 0x8B0D, 0xD668, + 0x8B0E, 0xD669, + 0x8B0F, 0xD66A, + 0x8B10, 0xD66B, + 0x8B11, 0xD66C, + 0x8B12, 0xD66D, + 0x8B13, 0xD66E, + 0x8B14, 0xD66F, + 0x8B15, 0xD670, + 0x8B16, 0xD671, + 0x8B17, 0xD672, + 0x8B18, 0xD673, + 0x8B19, 0xD674, + 0x8B1A, 0xD675, + 0x8B1B, 0xD676, + 0x8B1C, 0xD677, + 0x8B1D, 0xD678, + 0x8B1E, 0xD679, + 0x8B1F, 0xD67A, + 0x8B20, 0xD67B, + 0x8B21, 0xD67C, + 0x8B22, 0xD67D, + 0x8B23, 0xD67E, + 0x8B24, 0xD680, + 0x8B25, 0xD681, + 0x8B27, 0xD682, + 0x8B28, 0xD683, + 0x8B29, 0xD684, + 0x8B2A, 0xD685, + 0x8B2B, 0xD686, + 0x8B2C, 0xD687, + 0x8B2D, 0xD688, + 0x8B2E, 0xD689, + 0x8B2F, 0xD68A, + 0x8B30, 0xD68B, + 0x8B31, 0xD68C, + 0x8B32, 0xD68D, + 0x8B33, 0xD68E, + 0x8B34, 0xD68F, + 0x8B35, 0xD690, + 0x8B36, 0xD691, + 0x8B37, 0xD692, + 0x8B38, 0xD693, + 0x8B39, 0xD694, + 0x8B3A, 0xD695, + 0x8B3B, 0xD696, + 0x8B3C, 0xD697, + 0x8B3D, 0xD698, + 0x8B3E, 0xD699, + 0x8B3F, 0xD69A, + 0x8B40, 0xD69B, + 0x8B41, 0xD69C, + 0x8B42, 0xD69D, + 0x8B43, 0xD69E, + 0x8B44, 0xD69F, + 0x8B45, 0xD6A0, + 0x8B46, 0xD740, + 0x8B47, 0xD741, + 0x8B48, 0xD742, + 0x8B49, 0xD743, + 0x8B4A, 0xD744, + 0x8B4B, 0xD745, + 0x8B4C, 0xD746, + 0x8B4D, 0xD747, + 0x8B4E, 0xD748, + 0x8B4F, 0xD749, + 0x8B50, 0xD74A, + 0x8B51, 0xD74B, + 0x8B52, 0xD74C, + 0x8B53, 0xD74D, + 0x8B54, 0xD74E, + 0x8B55, 0xD74F, + 0x8B56, 0xD750, + 0x8B57, 0xD751, + 0x8B58, 0xD752, + 0x8B59, 0xD753, + 0x8B5A, 0xD754, + 0x8B5B, 0xD755, + 0x8B5C, 0xD756, + 0x8B5D, 0xD757, + 0x8B5E, 0xD758, + 0x8B5F, 0xD759, + 0x8B60, 0xD75A, + 0x8B61, 0xD75B, + 0x8B62, 0xD75C, + 0x8B63, 0xD75D, + 0x8B64, 0xD75E, + 0x8B65, 0xD75F, + 0x8B67, 0xD760, + 0x8B68, 0xD761, + 0x8B69, 0xD762, + 0x8B6A, 0xD763, + 0x8B6B, 0xD764, + 0x8B6D, 0xD765, + 0x8B6E, 0xD766, + 0x8B6F, 0xD767, + 0x8B70, 0xD768, + 0x8B71, 0xD769, + 0x8B72, 0xD76A, + 0x8B73, 0xD76B, + 0x8B74, 0xD76C, + 0x8B75, 0xD76D, + 0x8B76, 0xD76E, + 0x8B77, 0xD76F, + 0x8B78, 0xD770, + 0x8B79, 0xD771, + 0x8B7A, 0xD772, + 0x8B7B, 0xD773, + 0x8B7C, 0xD774, + 0x8B7D, 0xD775, + 0x8B7E, 0xD776, + 0x8B7F, 0xD777, + 0x8B80, 0xD778, + 0x8B81, 0xD779, + 0x8B82, 0xD77A, + 0x8B83, 0xD77B, + 0x8B84, 0xD77C, + 0x8B85, 0xD77D, + 0x8B86, 0xD77E, + 0x8B87, 0xD780, + 0x8B88, 0xD781, + 0x8B89, 0xD782, + 0x8B8A, 0xD783, + 0x8B8B, 0xD784, + 0x8B8C, 0xD785, + 0x8B8D, 0xD786, + 0x8B8E, 0xD787, + 0x8B8F, 0xD788, + 0x8B90, 0xD789, + 0x8B91, 0xD78A, + 0x8B92, 0xD78B, + 0x8B93, 0xD78C, + 0x8B94, 0xD78D, + 0x8B95, 0xD78E, + 0x8B96, 0xD78F, + 0x8B97, 0xD790, + 0x8B98, 0xD791, + 0x8B99, 0xD792, + 0x8B9A, 0xD793, + 0x8B9B, 0xD794, + 0x8B9C, 0xD795, + 0x8B9D, 0xD796, + 0x8B9E, 0xD797, + 0x8B9F, 0xD798, + 0x8BAC, 0xD799, + 0x8BB1, 0xD79A, + 0x8BBB, 0xD79B, + 0x8BC7, 0xD79C, + 0x8BD0, 0xD79D, + 0x8BEA, 0xD79E, + 0x8C09, 0xD79F, + 0x8C1E, 0xD7A0, + 0x8C38, 0xD840, + 0x8C39, 0xD841, + 0x8C3A, 0xD842, + 0x8C3B, 0xD843, + 0x8C3C, 0xD844, + 0x8C3D, 0xD845, + 0x8C3E, 0xD846, + 0x8C3F, 0xD847, + 0x8C40, 0xD848, + 0x8C42, 0xD849, + 0x8C43, 0xD84A, + 0x8C44, 0xD84B, + 0x8C45, 0xD84C, + 0x8C48, 0xD84D, + 0x8C4A, 0xD84E, + 0x8C4B, 0xD84F, + 0x8C4D, 0xD850, + 0x8C4E, 0xD851, + 0x8C4F, 0xD852, + 0x8C50, 0xD853, + 0x8C51, 0xD854, + 0x8C52, 0xD855, + 0x8C53, 0xD856, + 0x8C54, 0xD857, + 0x8C56, 0xD858, + 0x8C57, 0xD859, + 0x8C58, 0xD85A, + 0x8C59, 0xD85B, + 0x8C5B, 0xD85C, + 0x8C5C, 0xD85D, + 0x8C5D, 0xD85E, + 0x8C5E, 0xD85F, + 0x8C5F, 0xD860, + 0x8C60, 0xD861, + 0x8C63, 0xD862, + 0x8C64, 0xD863, + 0x8C65, 0xD864, + 0x8C66, 0xD865, + 0x8C67, 0xD866, + 0x8C68, 0xD867, + 0x8C69, 0xD868, + 0x8C6C, 0xD869, + 0x8C6D, 0xD86A, + 0x8C6E, 0xD86B, + 0x8C6F, 0xD86C, + 0x8C70, 0xD86D, + 0x8C71, 0xD86E, + 0x8C72, 0xD86F, + 0x8C74, 0xD870, + 0x8C75, 0xD871, + 0x8C76, 0xD872, + 0x8C77, 0xD873, + 0x8C7B, 0xD874, + 0x8C7C, 0xD875, + 0x8C7D, 0xD876, + 0x8C7E, 0xD877, + 0x8C7F, 0xD878, + 0x8C80, 0xD879, + 0x8C81, 0xD87A, + 0x8C83, 0xD87B, + 0x8C84, 0xD87C, + 0x8C86, 0xD87D, + 0x8C87, 0xD87E, + 0x8C88, 0xD880, + 0x8C8B, 0xD881, + 0x8C8D, 0xD882, + 0x8C8E, 0xD883, + 0x8C8F, 0xD884, + 0x8C90, 0xD885, + 0x8C91, 0xD886, + 0x8C92, 0xD887, + 0x8C93, 0xD888, + 0x8C95, 0xD889, + 0x8C96, 0xD88A, + 0x8C97, 0xD88B, + 0x8C99, 0xD88C, + 0x8C9A, 0xD88D, + 0x8C9B, 0xD88E, + 0x8C9C, 0xD88F, + 0x8C9D, 0xD890, + 0x8C9E, 0xD891, + 0x8C9F, 0xD892, + 0x8CA0, 0xD893, + 0x8CA1, 0xD894, + 0x8CA2, 0xD895, + 0x8CA3, 0xD896, + 0x8CA4, 0xD897, + 0x8CA5, 0xD898, + 0x8CA6, 0xD899, + 0x8CA7, 0xD89A, + 0x8CA8, 0xD89B, + 0x8CA9, 0xD89C, + 0x8CAA, 0xD89D, + 0x8CAB, 0xD89E, + 0x8CAC, 0xD89F, + 0x8CAD, 0xD8A0, + 0x8CAE, 0xD940, + 0x8CAF, 0xD941, + 0x8CB0, 0xD942, + 0x8CB1, 0xD943, + 0x8CB2, 0xD944, + 0x8CB3, 0xD945, + 0x8CB4, 0xD946, + 0x8CB5, 0xD947, + 0x8CB6, 0xD948, + 0x8CB7, 0xD949, + 0x8CB8, 0xD94A, + 0x8CB9, 0xD94B, + 0x8CBA, 0xD94C, + 0x8CBB, 0xD94D, + 0x8CBC, 0xD94E, + 0x8CBD, 0xD94F, + 0x8CBE, 0xD950, + 0x8CBF, 0xD951, + 0x8CC0, 0xD952, + 0x8CC1, 0xD953, + 0x8CC2, 0xD954, + 0x8CC3, 0xD955, + 0x8CC4, 0xD956, + 0x8CC5, 0xD957, + 0x8CC6, 0xD958, + 0x8CC7, 0xD959, + 0x8CC8, 0xD95A, + 0x8CC9, 0xD95B, + 0x8CCA, 0xD95C, + 0x8CCB, 0xD95D, + 0x8CCC, 0xD95E, + 0x8CCD, 0xD95F, + 0x8CCE, 0xD960, + 0x8CCF, 0xD961, + 0x8CD0, 0xD962, + 0x8CD1, 0xD963, + 0x8CD2, 0xD964, + 0x8CD3, 0xD965, + 0x8CD4, 0xD966, + 0x8CD5, 0xD967, + 0x8CD6, 0xD968, + 0x8CD7, 0xD969, + 0x8CD8, 0xD96A, + 0x8CD9, 0xD96B, + 0x8CDA, 0xD96C, + 0x8CDB, 0xD96D, + 0x8CDC, 0xD96E, + 0x8CDD, 0xD96F, + 0x8CDE, 0xD970, + 0x8CDF, 0xD971, + 0x8CE0, 0xD972, + 0x8CE1, 0xD973, + 0x8CE2, 0xD974, + 0x8CE3, 0xD975, + 0x8CE4, 0xD976, + 0x8CE5, 0xD977, + 0x8CE6, 0xD978, + 0x8CE7, 0xD979, + 0x8CE8, 0xD97A, + 0x8CE9, 0xD97B, + 0x8CEA, 0xD97C, + 0x8CEB, 0xD97D, + 0x8CEC, 0xD97E, + 0x8CED, 0xD980, + 0x8CEE, 0xD981, + 0x8CEF, 0xD982, + 0x8CF0, 0xD983, + 0x8CF1, 0xD984, + 0x8CF2, 0xD985, + 0x8CF3, 0xD986, + 0x8CF4, 0xD987, + 0x8CF5, 0xD988, + 0x8CF6, 0xD989, + 0x8CF7, 0xD98A, + 0x8CF8, 0xD98B, + 0x8CF9, 0xD98C, + 0x8CFA, 0xD98D, + 0x8CFB, 0xD98E, + 0x8CFC, 0xD98F, + 0x8CFD, 0xD990, + 0x8CFE, 0xD991, + 0x8CFF, 0xD992, + 0x8D00, 0xD993, + 0x8D01, 0xD994, + 0x8D02, 0xD995, + 0x8D03, 0xD996, + 0x8D04, 0xD997, + 0x8D05, 0xD998, + 0x8D06, 0xD999, + 0x8D07, 0xD99A, + 0x8D08, 0xD99B, + 0x8D09, 0xD99C, + 0x8D0A, 0xD99D, + 0x8D0B, 0xD99E, + 0x8D0C, 0xD99F, + 0x8D0D, 0xD9A0, + 0x8D0E, 0xDA40, + 0x8D0F, 0xDA41, + 0x8D10, 0xDA42, + 0x8D11, 0xDA43, + 0x8D12, 0xDA44, + 0x8D13, 0xDA45, + 0x8D14, 0xDA46, + 0x8D15, 0xDA47, + 0x8D16, 0xDA48, + 0x8D17, 0xDA49, + 0x8D18, 0xDA4A, + 0x8D19, 0xDA4B, + 0x8D1A, 0xDA4C, + 0x8D1B, 0xDA4D, + 0x8D1C, 0xDA4E, + 0x8D20, 0xDA4F, + 0x8D51, 0xDA50, + 0x8D52, 0xDA51, + 0x8D57, 0xDA52, + 0x8D5F, 0xDA53, + 0x8D65, 0xDA54, + 0x8D68, 0xDA55, + 0x8D69, 0xDA56, + 0x8D6A, 0xDA57, + 0x8D6C, 0xDA58, + 0x8D6E, 0xDA59, + 0x8D6F, 0xDA5A, + 0x8D71, 0xDA5B, + 0x8D72, 0xDA5C, + 0x8D78, 0xDA5D, + 0x8D79, 0xDA5E, + 0x8D7A, 0xDA5F, + 0x8D7B, 0xDA60, + 0x8D7C, 0xDA61, + 0x8D7D, 0xDA62, + 0x8D7E, 0xDA63, + 0x8D7F, 0xDA64, + 0x8D80, 0xDA65, + 0x8D82, 0xDA66, + 0x8D83, 0xDA67, + 0x8D86, 0xDA68, + 0x8D87, 0xDA69, + 0x8D88, 0xDA6A, + 0x8D89, 0xDA6B, + 0x8D8C, 0xDA6C, + 0x8D8D, 0xDA6D, + 0x8D8E, 0xDA6E, + 0x8D8F, 0xDA6F, + 0x8D90, 0xDA70, + 0x8D92, 0xDA71, + 0x8D93, 0xDA72, + 0x8D95, 0xDA73, + 0x8D96, 0xDA74, + 0x8D97, 0xDA75, + 0x8D98, 0xDA76, + 0x8D99, 0xDA77, + 0x8D9A, 0xDA78, + 0x8D9B, 0xDA79, + 0x8D9C, 0xDA7A, + 0x8D9D, 0xDA7B, + 0x8D9E, 0xDA7C, + 0x8DA0, 0xDA7D, + 0x8DA1, 0xDA7E, + 0x8DA2, 0xDA80, + 0x8DA4, 0xDA81, + 0x8DA5, 0xDA82, + 0x8DA6, 0xDA83, + 0x8DA7, 0xDA84, + 0x8DA8, 0xDA85, + 0x8DA9, 0xDA86, + 0x8DAA, 0xDA87, + 0x8DAB, 0xDA88, + 0x8DAC, 0xDA89, + 0x8DAD, 0xDA8A, + 0x8DAE, 0xDA8B, + 0x8DAF, 0xDA8C, + 0x8DB0, 0xDA8D, + 0x8DB2, 0xDA8E, + 0x8DB6, 0xDA8F, + 0x8DB7, 0xDA90, + 0x8DB9, 0xDA91, + 0x8DBB, 0xDA92, + 0x8DBD, 0xDA93, + 0x8DC0, 0xDA94, + 0x8DC1, 0xDA95, + 0x8DC2, 0xDA96, + 0x8DC5, 0xDA97, + 0x8DC7, 0xDA98, + 0x8DC8, 0xDA99, + 0x8DC9, 0xDA9A, + 0x8DCA, 0xDA9B, + 0x8DCD, 0xDA9C, + 0x8DD0, 0xDA9D, + 0x8DD2, 0xDA9E, + 0x8DD3, 0xDA9F, + 0x8DD4, 0xDAA0, + 0x8DD5, 0xDB40, + 0x8DD8, 0xDB41, + 0x8DD9, 0xDB42, + 0x8DDC, 0xDB43, + 0x8DE0, 0xDB44, + 0x8DE1, 0xDB45, + 0x8DE2, 0xDB46, + 0x8DE5, 0xDB47, + 0x8DE6, 0xDB48, + 0x8DE7, 0xDB49, + 0x8DE9, 0xDB4A, + 0x8DED, 0xDB4B, + 0x8DEE, 0xDB4C, + 0x8DF0, 0xDB4D, + 0x8DF1, 0xDB4E, + 0x8DF2, 0xDB4F, + 0x8DF4, 0xDB50, + 0x8DF6, 0xDB51, + 0x8DFC, 0xDB52, + 0x8DFE, 0xDB53, + 0x8DFF, 0xDB54, + 0x8E00, 0xDB55, + 0x8E01, 0xDB56, + 0x8E02, 0xDB57, + 0x8E03, 0xDB58, + 0x8E04, 0xDB59, + 0x8E06, 0xDB5A, + 0x8E07, 0xDB5B, + 0x8E08, 0xDB5C, + 0x8E0B, 0xDB5D, + 0x8E0D, 0xDB5E, + 0x8E0E, 0xDB5F, + 0x8E10, 0xDB60, + 0x8E11, 0xDB61, + 0x8E12, 0xDB62, + 0x8E13, 0xDB63, + 0x8E15, 0xDB64, + 0x8E16, 0xDB65, + 0x8E17, 0xDB66, + 0x8E18, 0xDB67, + 0x8E19, 0xDB68, + 0x8E1A, 0xDB69, + 0x8E1B, 0xDB6A, + 0x8E1C, 0xDB6B, + 0x8E20, 0xDB6C, + 0x8E21, 0xDB6D, + 0x8E24, 0xDB6E, + 0x8E25, 0xDB6F, + 0x8E26, 0xDB70, + 0x8E27, 0xDB71, + 0x8E28, 0xDB72, + 0x8E2B, 0xDB73, + 0x8E2D, 0xDB74, + 0x8E30, 0xDB75, + 0x8E32, 0xDB76, + 0x8E33, 0xDB77, + 0x8E34, 0xDB78, + 0x8E36, 0xDB79, + 0x8E37, 0xDB7A, + 0x8E38, 0xDB7B, + 0x8E3B, 0xDB7C, + 0x8E3C, 0xDB7D, + 0x8E3E, 0xDB7E, + 0x8E3F, 0xDB80, + 0x8E43, 0xDB81, + 0x8E45, 0xDB82, + 0x8E46, 0xDB83, + 0x8E4C, 0xDB84, + 0x8E4D, 0xDB85, + 0x8E4E, 0xDB86, + 0x8E4F, 0xDB87, + 0x8E50, 0xDB88, + 0x8E53, 0xDB89, + 0x8E54, 0xDB8A, + 0x8E55, 0xDB8B, + 0x8E56, 0xDB8C, + 0x8E57, 0xDB8D, + 0x8E58, 0xDB8E, + 0x8E5A, 0xDB8F, + 0x8E5B, 0xDB90, + 0x8E5C, 0xDB91, + 0x8E5D, 0xDB92, + 0x8E5E, 0xDB93, + 0x8E5F, 0xDB94, + 0x8E60, 0xDB95, + 0x8E61, 0xDB96, + 0x8E62, 0xDB97, + 0x8E63, 0xDB98, + 0x8E64, 0xDB99, + 0x8E65, 0xDB9A, + 0x8E67, 0xDB9B, + 0x8E68, 0xDB9C, + 0x8E6A, 0xDB9D, + 0x8E6B, 0xDB9E, + 0x8E6E, 0xDB9F, + 0x8E71, 0xDBA0, + 0x8E73, 0xDC40, + 0x8E75, 0xDC41, + 0x8E77, 0xDC42, + 0x8E78, 0xDC43, + 0x8E79, 0xDC44, + 0x8E7A, 0xDC45, + 0x8E7B, 0xDC46, + 0x8E7D, 0xDC47, + 0x8E7E, 0xDC48, + 0x8E80, 0xDC49, + 0x8E82, 0xDC4A, + 0x8E83, 0xDC4B, + 0x8E84, 0xDC4C, + 0x8E86, 0xDC4D, + 0x8E88, 0xDC4E, + 0x8E89, 0xDC4F, + 0x8E8A, 0xDC50, + 0x8E8B, 0xDC51, + 0x8E8C, 0xDC52, + 0x8E8D, 0xDC53, + 0x8E8E, 0xDC54, + 0x8E91, 0xDC55, + 0x8E92, 0xDC56, + 0x8E93, 0xDC57, + 0x8E95, 0xDC58, + 0x8E96, 0xDC59, + 0x8E97, 0xDC5A, + 0x8E98, 0xDC5B, + 0x8E99, 0xDC5C, + 0x8E9A, 0xDC5D, + 0x8E9B, 0xDC5E, + 0x8E9D, 0xDC5F, + 0x8E9F, 0xDC60, + 0x8EA0, 0xDC61, + 0x8EA1, 0xDC62, + 0x8EA2, 0xDC63, + 0x8EA3, 0xDC64, + 0x8EA4, 0xDC65, + 0x8EA5, 0xDC66, + 0x8EA6, 0xDC67, + 0x8EA7, 0xDC68, + 0x8EA8, 0xDC69, + 0x8EA9, 0xDC6A, + 0x8EAA, 0xDC6B, + 0x8EAD, 0xDC6C, + 0x8EAE, 0xDC6D, + 0x8EB0, 0xDC6E, + 0x8EB1, 0xDC6F, + 0x8EB3, 0xDC70, + 0x8EB4, 0xDC71, + 0x8EB5, 0xDC72, + 0x8EB6, 0xDC73, + 0x8EB7, 0xDC74, + 0x8EB8, 0xDC75, + 0x8EB9, 0xDC76, + 0x8EBB, 0xDC77, + 0x8EBC, 0xDC78, + 0x8EBD, 0xDC79, + 0x8EBE, 0xDC7A, + 0x8EBF, 0xDC7B, + 0x8EC0, 0xDC7C, + 0x8EC1, 0xDC7D, + 0x8EC2, 0xDC7E, + 0x8EC3, 0xDC80, + 0x8EC4, 0xDC81, + 0x8EC5, 0xDC82, + 0x8EC6, 0xDC83, + 0x8EC7, 0xDC84, + 0x8EC8, 0xDC85, + 0x8EC9, 0xDC86, + 0x8ECA, 0xDC87, + 0x8ECB, 0xDC88, + 0x8ECC, 0xDC89, + 0x8ECD, 0xDC8A, + 0x8ECF, 0xDC8B, + 0x8ED0, 0xDC8C, + 0x8ED1, 0xDC8D, + 0x8ED2, 0xDC8E, + 0x8ED3, 0xDC8F, + 0x8ED4, 0xDC90, + 0x8ED5, 0xDC91, + 0x8ED6, 0xDC92, + 0x8ED7, 0xDC93, + 0x8ED8, 0xDC94, + 0x8ED9, 0xDC95, + 0x8EDA, 0xDC96, + 0x8EDB, 0xDC97, + 0x8EDC, 0xDC98, + 0x8EDD, 0xDC99, + 0x8EDE, 0xDC9A, + 0x8EDF, 0xDC9B, + 0x8EE0, 0xDC9C, + 0x8EE1, 0xDC9D, + 0x8EE2, 0xDC9E, + 0x8EE3, 0xDC9F, + 0x8EE4, 0xDCA0, + 0x8EE5, 0xDD40, + 0x8EE6, 0xDD41, + 0x8EE7, 0xDD42, + 0x8EE8, 0xDD43, + 0x8EE9, 0xDD44, + 0x8EEA, 0xDD45, + 0x8EEB, 0xDD46, + 0x8EEC, 0xDD47, + 0x8EED, 0xDD48, + 0x8EEE, 0xDD49, + 0x8EEF, 0xDD4A, + 0x8EF0, 0xDD4B, + 0x8EF1, 0xDD4C, + 0x8EF2, 0xDD4D, + 0x8EF3, 0xDD4E, + 0x8EF4, 0xDD4F, + 0x8EF5, 0xDD50, + 0x8EF6, 0xDD51, + 0x8EF7, 0xDD52, + 0x8EF8, 0xDD53, + 0x8EF9, 0xDD54, + 0x8EFA, 0xDD55, + 0x8EFB, 0xDD56, + 0x8EFC, 0xDD57, + 0x8EFD, 0xDD58, + 0x8EFE, 0xDD59, + 0x8EFF, 0xDD5A, + 0x8F00, 0xDD5B, + 0x8F01, 0xDD5C, + 0x8F02, 0xDD5D, + 0x8F03, 0xDD5E, + 0x8F04, 0xDD5F, + 0x8F05, 0xDD60, + 0x8F06, 0xDD61, + 0x8F07, 0xDD62, + 0x8F08, 0xDD63, + 0x8F09, 0xDD64, + 0x8F0A, 0xDD65, + 0x8F0B, 0xDD66, + 0x8F0C, 0xDD67, + 0x8F0D, 0xDD68, + 0x8F0E, 0xDD69, + 0x8F0F, 0xDD6A, + 0x8F10, 0xDD6B, + 0x8F11, 0xDD6C, + 0x8F12, 0xDD6D, + 0x8F13, 0xDD6E, + 0x8F14, 0xDD6F, + 0x8F15, 0xDD70, + 0x8F16, 0xDD71, + 0x8F17, 0xDD72, + 0x8F18, 0xDD73, + 0x8F19, 0xDD74, + 0x8F1A, 0xDD75, + 0x8F1B, 0xDD76, + 0x8F1C, 0xDD77, + 0x8F1D, 0xDD78, + 0x8F1E, 0xDD79, + 0x8F1F, 0xDD7A, + 0x8F20, 0xDD7B, + 0x8F21, 0xDD7C, + 0x8F22, 0xDD7D, + 0x8F23, 0xDD7E, + 0x8F24, 0xDD80, + 0x8F25, 0xDD81, + 0x8F26, 0xDD82, + 0x8F27, 0xDD83, + 0x8F28, 0xDD84, + 0x8F29, 0xDD85, + 0x8F2A, 0xDD86, + 0x8F2B, 0xDD87, + 0x8F2C, 0xDD88, + 0x8F2D, 0xDD89, + 0x8F2E, 0xDD8A, + 0x8F2F, 0xDD8B, + 0x8F30, 0xDD8C, + 0x8F31, 0xDD8D, + 0x8F32, 0xDD8E, + 0x8F33, 0xDD8F, + 0x8F34, 0xDD90, + 0x8F35, 0xDD91, + 0x8F36, 0xDD92, + 0x8F37, 0xDD93, + 0x8F38, 0xDD94, + 0x8F39, 0xDD95, + 0x8F3A, 0xDD96, + 0x8F3B, 0xDD97, + 0x8F3C, 0xDD98, + 0x8F3D, 0xDD99, + 0x8F3E, 0xDD9A, + 0x8F3F, 0xDD9B, + 0x8F40, 0xDD9C, + 0x8F41, 0xDD9D, + 0x8F42, 0xDD9E, + 0x8F43, 0xDD9F, + 0x8F44, 0xDDA0, + 0x8F45, 0xDE40, + 0x8F46, 0xDE41, + 0x8F47, 0xDE42, + 0x8F48, 0xDE43, + 0x8F49, 0xDE44, + 0x8F4A, 0xDE45, + 0x8F4B, 0xDE46, + 0x8F4C, 0xDE47, + 0x8F4D, 0xDE48, + 0x8F4E, 0xDE49, + 0x8F4F, 0xDE4A, + 0x8F50, 0xDE4B, + 0x8F51, 0xDE4C, + 0x8F52, 0xDE4D, + 0x8F53, 0xDE4E, + 0x8F54, 0xDE4F, + 0x8F55, 0xDE50, + 0x8F56, 0xDE51, + 0x8F57, 0xDE52, + 0x8F58, 0xDE53, + 0x8F59, 0xDE54, + 0x8F5A, 0xDE55, + 0x8F5B, 0xDE56, + 0x8F5C, 0xDE57, + 0x8F5D, 0xDE58, + 0x8F5E, 0xDE59, + 0x8F5F, 0xDE5A, + 0x8F60, 0xDE5B, + 0x8F61, 0xDE5C, + 0x8F62, 0xDE5D, + 0x8F63, 0xDE5E, + 0x8F64, 0xDE5F, + 0x8F65, 0xDE60, + 0x8F6A, 0xDE61, + 0x8F80, 0xDE62, + 0x8F8C, 0xDE63, + 0x8F92, 0xDE64, + 0x8F9D, 0xDE65, + 0x8FA0, 0xDE66, + 0x8FA1, 0xDE67, + 0x8FA2, 0xDE68, + 0x8FA4, 0xDE69, + 0x8FA5, 0xDE6A, + 0x8FA6, 0xDE6B, + 0x8FA7, 0xDE6C, + 0x8FAA, 0xDE6D, + 0x8FAC, 0xDE6E, + 0x8FAD, 0xDE6F, + 0x8FAE, 0xDE70, + 0x8FAF, 0xDE71, + 0x8FB2, 0xDE72, + 0x8FB3, 0xDE73, + 0x8FB4, 0xDE74, + 0x8FB5, 0xDE75, + 0x8FB7, 0xDE76, + 0x8FB8, 0xDE77, + 0x8FBA, 0xDE78, + 0x8FBB, 0xDE79, + 0x8FBC, 0xDE7A, + 0x8FBF, 0xDE7B, + 0x8FC0, 0xDE7C, + 0x8FC3, 0xDE7D, + 0x8FC6, 0xDE7E, + 0x8FC9, 0xDE80, + 0x8FCA, 0xDE81, + 0x8FCB, 0xDE82, + 0x8FCC, 0xDE83, + 0x8FCD, 0xDE84, + 0x8FCF, 0xDE85, + 0x8FD2, 0xDE86, + 0x8FD6, 0xDE87, + 0x8FD7, 0xDE88, + 0x8FDA, 0xDE89, + 0x8FE0, 0xDE8A, + 0x8FE1, 0xDE8B, + 0x8FE3, 0xDE8C, + 0x8FE7, 0xDE8D, + 0x8FEC, 0xDE8E, + 0x8FEF, 0xDE8F, + 0x8FF1, 0xDE90, + 0x8FF2, 0xDE91, + 0x8FF4, 0xDE92, + 0x8FF5, 0xDE93, + 0x8FF6, 0xDE94, + 0x8FFA, 0xDE95, + 0x8FFB, 0xDE96, + 0x8FFC, 0xDE97, + 0x8FFE, 0xDE98, + 0x8FFF, 0xDE99, + 0x9007, 0xDE9A, + 0x9008, 0xDE9B, + 0x900C, 0xDE9C, + 0x900E, 0xDE9D, + 0x9013, 0xDE9E, + 0x9015, 0xDE9F, + 0x9018, 0xDEA0, + 0x9019, 0xDF40, + 0x901C, 0xDF41, + 0x9023, 0xDF42, + 0x9024, 0xDF43, + 0x9025, 0xDF44, + 0x9027, 0xDF45, + 0x9028, 0xDF46, + 0x9029, 0xDF47, + 0x902A, 0xDF48, + 0x902B, 0xDF49, + 0x902C, 0xDF4A, + 0x9030, 0xDF4B, + 0x9031, 0xDF4C, + 0x9032, 0xDF4D, + 0x9033, 0xDF4E, + 0x9034, 0xDF4F, + 0x9037, 0xDF50, + 0x9039, 0xDF51, + 0x903A, 0xDF52, + 0x903D, 0xDF53, + 0x903F, 0xDF54, + 0x9040, 0xDF55, + 0x9043, 0xDF56, + 0x9045, 0xDF57, + 0x9046, 0xDF58, + 0x9048, 0xDF59, + 0x9049, 0xDF5A, + 0x904A, 0xDF5B, + 0x904B, 0xDF5C, + 0x904C, 0xDF5D, + 0x904E, 0xDF5E, + 0x9054, 0xDF5F, + 0x9055, 0xDF60, + 0x9056, 0xDF61, + 0x9059, 0xDF62, + 0x905A, 0xDF63, + 0x905C, 0xDF64, + 0x905D, 0xDF65, + 0x905E, 0xDF66, + 0x905F, 0xDF67, + 0x9060, 0xDF68, + 0x9061, 0xDF69, + 0x9064, 0xDF6A, + 0x9066, 0xDF6B, + 0x9067, 0xDF6C, + 0x9069, 0xDF6D, + 0x906A, 0xDF6E, + 0x906B, 0xDF6F, + 0x906C, 0xDF70, + 0x906F, 0xDF71, + 0x9070, 0xDF72, + 0x9071, 0xDF73, + 0x9072, 0xDF74, + 0x9073, 0xDF75, + 0x9076, 0xDF76, + 0x9077, 0xDF77, + 0x9078, 0xDF78, + 0x9079, 0xDF79, + 0x907A, 0xDF7A, + 0x907B, 0xDF7B, + 0x907C, 0xDF7C, + 0x907E, 0xDF7D, + 0x9081, 0xDF7E, + 0x9084, 0xDF80, + 0x9085, 0xDF81, + 0x9086, 0xDF82, + 0x9087, 0xDF83, + 0x9089, 0xDF84, + 0x908A, 0xDF85, + 0x908C, 0xDF86, + 0x908D, 0xDF87, + 0x908E, 0xDF88, + 0x908F, 0xDF89, + 0x9090, 0xDF8A, + 0x9092, 0xDF8B, + 0x9094, 0xDF8C, + 0x9096, 0xDF8D, + 0x9098, 0xDF8E, + 0x909A, 0xDF8F, + 0x909C, 0xDF90, + 0x909E, 0xDF91, + 0x909F, 0xDF92, + 0x90A0, 0xDF93, + 0x90A4, 0xDF94, + 0x90A5, 0xDF95, + 0x90A7, 0xDF96, + 0x90A8, 0xDF97, + 0x90A9, 0xDF98, + 0x90AB, 0xDF99, + 0x90AD, 0xDF9A, + 0x90B2, 0xDF9B, + 0x90B7, 0xDF9C, + 0x90BC, 0xDF9D, + 0x90BD, 0xDF9E, + 0x90BF, 0xDF9F, + 0x90C0, 0xDFA0, + 0x90C2, 0xE040, + 0x90C3, 0xE041, + 0x90C6, 0xE042, + 0x90C8, 0xE043, + 0x90C9, 0xE044, + 0x90CB, 0xE045, + 0x90CC, 0xE046, + 0x90CD, 0xE047, + 0x90D2, 0xE048, + 0x90D4, 0xE049, + 0x90D5, 0xE04A, + 0x90D6, 0xE04B, + 0x90D8, 0xE04C, + 0x90D9, 0xE04D, + 0x90DA, 0xE04E, + 0x90DE, 0xE04F, + 0x90DF, 0xE050, + 0x90E0, 0xE051, + 0x90E3, 0xE052, + 0x90E4, 0xE053, + 0x90E5, 0xE054, + 0x90E9, 0xE055, + 0x90EA, 0xE056, + 0x90EC, 0xE057, + 0x90EE, 0xE058, + 0x90F0, 0xE059, + 0x90F1, 0xE05A, + 0x90F2, 0xE05B, + 0x90F3, 0xE05C, + 0x90F5, 0xE05D, + 0x90F6, 0xE05E, + 0x90F7, 0xE05F, + 0x90F9, 0xE060, + 0x90FA, 0xE061, + 0x90FB, 0xE062, + 0x90FC, 0xE063, + 0x90FF, 0xE064, + 0x9100, 0xE065, + 0x9101, 0xE066, + 0x9103, 0xE067, + 0x9105, 0xE068, + 0x9106, 0xE069, + 0x9107, 0xE06A, + 0x9108, 0xE06B, + 0x9109, 0xE06C, + 0x910A, 0xE06D, + 0x910B, 0xE06E, + 0x910C, 0xE06F, + 0x910D, 0xE070, + 0x910E, 0xE071, + 0x910F, 0xE072, + 0x9110, 0xE073, + 0x9111, 0xE074, + 0x9112, 0xE075, + 0x9113, 0xE076, + 0x9114, 0xE077, + 0x9115, 0xE078, + 0x9116, 0xE079, + 0x9117, 0xE07A, + 0x9118, 0xE07B, + 0x911A, 0xE07C, + 0x911B, 0xE07D, + 0x911C, 0xE07E, + 0x911D, 0xE080, + 0x911F, 0xE081, + 0x9120, 0xE082, + 0x9121, 0xE083, + 0x9124, 0xE084, + 0x9125, 0xE085, + 0x9126, 0xE086, + 0x9127, 0xE087, + 0x9128, 0xE088, + 0x9129, 0xE089, + 0x912A, 0xE08A, + 0x912B, 0xE08B, + 0x912C, 0xE08C, + 0x912D, 0xE08D, + 0x912E, 0xE08E, + 0x9130, 0xE08F, + 0x9132, 0xE090, + 0x9133, 0xE091, + 0x9134, 0xE092, + 0x9135, 0xE093, + 0x9136, 0xE094, + 0x9137, 0xE095, + 0x9138, 0xE096, + 0x913A, 0xE097, + 0x913B, 0xE098, + 0x913C, 0xE099, + 0x913D, 0xE09A, + 0x913E, 0xE09B, + 0x913F, 0xE09C, + 0x9140, 0xE09D, + 0x9141, 0xE09E, + 0x9142, 0xE09F, + 0x9144, 0xE0A0, + 0x9145, 0xE140, + 0x9147, 0xE141, + 0x9148, 0xE142, + 0x9151, 0xE143, + 0x9153, 0xE144, + 0x9154, 0xE145, + 0x9155, 0xE146, + 0x9156, 0xE147, + 0x9158, 0xE148, + 0x9159, 0xE149, + 0x915B, 0xE14A, + 0x915C, 0xE14B, + 0x915F, 0xE14C, + 0x9160, 0xE14D, + 0x9166, 0xE14E, + 0x9167, 0xE14F, + 0x9168, 0xE150, + 0x916B, 0xE151, + 0x916D, 0xE152, + 0x9173, 0xE153, + 0x917A, 0xE154, + 0x917B, 0xE155, + 0x917C, 0xE156, + 0x9180, 0xE157, + 0x9181, 0xE158, + 0x9182, 0xE159, + 0x9183, 0xE15A, + 0x9184, 0xE15B, + 0x9186, 0xE15C, + 0x9188, 0xE15D, + 0x918A, 0xE15E, + 0x918E, 0xE15F, + 0x918F, 0xE160, + 0x9193, 0xE161, + 0x9194, 0xE162, + 0x9195, 0xE163, + 0x9196, 0xE164, + 0x9197, 0xE165, + 0x9198, 0xE166, + 0x9199, 0xE167, + 0x919C, 0xE168, + 0x919D, 0xE169, + 0x919E, 0xE16A, + 0x919F, 0xE16B, + 0x91A0, 0xE16C, + 0x91A1, 0xE16D, + 0x91A4, 0xE16E, + 0x91A5, 0xE16F, + 0x91A6, 0xE170, + 0x91A7, 0xE171, + 0x91A8, 0xE172, + 0x91A9, 0xE173, + 0x91AB, 0xE174, + 0x91AC, 0xE175, + 0x91B0, 0xE176, + 0x91B1, 0xE177, + 0x91B2, 0xE178, + 0x91B3, 0xE179, + 0x91B6, 0xE17A, + 0x91B7, 0xE17B, + 0x91B8, 0xE17C, + 0x91B9, 0xE17D, + 0x91BB, 0xE17E, + 0x91BC, 0xE180, + 0x91BD, 0xE181, + 0x91BE, 0xE182, + 0x91BF, 0xE183, + 0x91C0, 0xE184, + 0x91C1, 0xE185, + 0x91C2, 0xE186, + 0x91C3, 0xE187, + 0x91C4, 0xE188, + 0x91C5, 0xE189, + 0x91C6, 0xE18A, + 0x91C8, 0xE18B, + 0x91CB, 0xE18C, + 0x91D0, 0xE18D, + 0x91D2, 0xE18E, + 0x91D3, 0xE18F, + 0x91D4, 0xE190, + 0x91D5, 0xE191, + 0x91D6, 0xE192, + 0x91D7, 0xE193, + 0x91D8, 0xE194, + 0x91D9, 0xE195, + 0x91DA, 0xE196, + 0x91DB, 0xE197, + 0x91DD, 0xE198, + 0x91DE, 0xE199, + 0x91DF, 0xE19A, + 0x91E0, 0xE19B, + 0x91E1, 0xE19C, + 0x91E2, 0xE19D, + 0x91E3, 0xE19E, + 0x91E4, 0xE19F, + 0x91E5, 0xE1A0, + 0x91E6, 0xE240, + 0x91E7, 0xE241, + 0x91E8, 0xE242, + 0x91E9, 0xE243, + 0x91EA, 0xE244, + 0x91EB, 0xE245, + 0x91EC, 0xE246, + 0x91ED, 0xE247, + 0x91EE, 0xE248, + 0x91EF, 0xE249, + 0x91F0, 0xE24A, + 0x91F1, 0xE24B, + 0x91F2, 0xE24C, + 0x91F3, 0xE24D, + 0x91F4, 0xE24E, + 0x91F5, 0xE24F, + 0x91F6, 0xE250, + 0x91F7, 0xE251, + 0x91F8, 0xE252, + 0x91F9, 0xE253, + 0x91FA, 0xE254, + 0x91FB, 0xE255, + 0x91FC, 0xE256, + 0x91FD, 0xE257, + 0x91FE, 0xE258, + 0x91FF, 0xE259, + 0x9200, 0xE25A, + 0x9201, 0xE25B, + 0x9202, 0xE25C, + 0x9203, 0xE25D, + 0x9204, 0xE25E, + 0x9205, 0xE25F, + 0x9206, 0xE260, + 0x9207, 0xE261, + 0x9208, 0xE262, + 0x9209, 0xE263, + 0x920A, 0xE264, + 0x920B, 0xE265, + 0x920C, 0xE266, + 0x920D, 0xE267, + 0x920E, 0xE268, + 0x920F, 0xE269, + 0x9210, 0xE26A, + 0x9211, 0xE26B, + 0x9212, 0xE26C, + 0x9213, 0xE26D, + 0x9214, 0xE26E, + 0x9215, 0xE26F, + 0x9216, 0xE270, + 0x9217, 0xE271, + 0x9218, 0xE272, + 0x9219, 0xE273, + 0x921A, 0xE274, + 0x921B, 0xE275, + 0x921C, 0xE276, + 0x921D, 0xE277, + 0x921E, 0xE278, + 0x921F, 0xE279, + 0x9220, 0xE27A, + 0x9221, 0xE27B, + 0x9222, 0xE27C, + 0x9223, 0xE27D, + 0x9224, 0xE27E, + 0x9225, 0xE280, + 0x9226, 0xE281, + 0x9227, 0xE282, + 0x9228, 0xE283, + 0x9229, 0xE284, + 0x922A, 0xE285, + 0x922B, 0xE286, + 0x922C, 0xE287, + 0x922D, 0xE288, + 0x922E, 0xE289, + 0x922F, 0xE28A, + 0x9230, 0xE28B, + 0x9231, 0xE28C, + 0x9232, 0xE28D, + 0x9233, 0xE28E, + 0x9234, 0xE28F, + 0x9235, 0xE290, + 0x9236, 0xE291, + 0x9237, 0xE292, + 0x9238, 0xE293, + 0x9239, 0xE294, + 0x923A, 0xE295, + 0x923B, 0xE296, + 0x923C, 0xE297, + 0x923D, 0xE298, + 0x923E, 0xE299, + 0x923F, 0xE29A, + 0x9240, 0xE29B, + 0x9241, 0xE29C, + 0x9242, 0xE29D, + 0x9243, 0xE29E, + 0x9244, 0xE29F, + 0x9245, 0xE2A0, + 0x9246, 0xE340, + 0x9247, 0xE341, + 0x9248, 0xE342, + 0x9249, 0xE343, + 0x924A, 0xE344, + 0x924B, 0xE345, + 0x924C, 0xE346, + 0x924D, 0xE347, + 0x924E, 0xE348, + 0x924F, 0xE349, + 0x9250, 0xE34A, + 0x9251, 0xE34B, + 0x9252, 0xE34C, + 0x9253, 0xE34D, + 0x9254, 0xE34E, + 0x9255, 0xE34F, + 0x9256, 0xE350, + 0x9257, 0xE351, + 0x9258, 0xE352, + 0x9259, 0xE353, + 0x925A, 0xE354, + 0x925B, 0xE355, + 0x925C, 0xE356, + 0x925D, 0xE357, + 0x925E, 0xE358, + 0x925F, 0xE359, + 0x9260, 0xE35A, + 0x9261, 0xE35B, + 0x9262, 0xE35C, + 0x9263, 0xE35D, + 0x9264, 0xE35E, + 0x9265, 0xE35F, + 0x9266, 0xE360, + 0x9267, 0xE361, + 0x9268, 0xE362, + 0x9269, 0xE363, + 0x926A, 0xE364, + 0x926B, 0xE365, + 0x926C, 0xE366, + 0x926D, 0xE367, + 0x926E, 0xE368, + 0x926F, 0xE369, + 0x9270, 0xE36A, + 0x9271, 0xE36B, + 0x9272, 0xE36C, + 0x9273, 0xE36D, + 0x9275, 0xE36E, + 0x9276, 0xE36F, + 0x9277, 0xE370, + 0x9278, 0xE371, + 0x9279, 0xE372, + 0x927A, 0xE373, + 0x927B, 0xE374, + 0x927C, 0xE375, + 0x927D, 0xE376, + 0x927E, 0xE377, + 0x927F, 0xE378, + 0x9280, 0xE379, + 0x9281, 0xE37A, + 0x9282, 0xE37B, + 0x9283, 0xE37C, + 0x9284, 0xE37D, + 0x9285, 0xE37E, + 0x9286, 0xE380, + 0x9287, 0xE381, + 0x9288, 0xE382, + 0x9289, 0xE383, + 0x928A, 0xE384, + 0x928B, 0xE385, + 0x928C, 0xE386, + 0x928D, 0xE387, + 0x928F, 0xE388, + 0x9290, 0xE389, + 0x9291, 0xE38A, + 0x9292, 0xE38B, + 0x9293, 0xE38C, + 0x9294, 0xE38D, + 0x9295, 0xE38E, + 0x9296, 0xE38F, + 0x9297, 0xE390, + 0x9298, 0xE391, + 0x9299, 0xE392, + 0x929A, 0xE393, + 0x929B, 0xE394, + 0x929C, 0xE395, + 0x929D, 0xE396, + 0x929E, 0xE397, + 0x929F, 0xE398, + 0x92A0, 0xE399, + 0x92A1, 0xE39A, + 0x92A2, 0xE39B, + 0x92A3, 0xE39C, + 0x92A4, 0xE39D, + 0x92A5, 0xE39E, + 0x92A6, 0xE39F, + 0x92A7, 0xE3A0, + 0x92A8, 0xE440, + 0x92A9, 0xE441, + 0x92AA, 0xE442, + 0x92AB, 0xE443, + 0x92AC, 0xE444, + 0x92AD, 0xE445, + 0x92AF, 0xE446, + 0x92B0, 0xE447, + 0x92B1, 0xE448, + 0x92B2, 0xE449, + 0x92B3, 0xE44A, + 0x92B4, 0xE44B, + 0x92B5, 0xE44C, + 0x92B6, 0xE44D, + 0x92B7, 0xE44E, + 0x92B8, 0xE44F, + 0x92B9, 0xE450, + 0x92BA, 0xE451, + 0x92BB, 0xE452, + 0x92BC, 0xE453, + 0x92BD, 0xE454, + 0x92BE, 0xE455, + 0x92BF, 0xE456, + 0x92C0, 0xE457, + 0x92C1, 0xE458, + 0x92C2, 0xE459, + 0x92C3, 0xE45A, + 0x92C4, 0xE45B, + 0x92C5, 0xE45C, + 0x92C6, 0xE45D, + 0x92C7, 0xE45E, + 0x92C9, 0xE45F, + 0x92CA, 0xE460, + 0x92CB, 0xE461, + 0x92CC, 0xE462, + 0x92CD, 0xE463, + 0x92CE, 0xE464, + 0x92CF, 0xE465, + 0x92D0, 0xE466, + 0x92D1, 0xE467, + 0x92D2, 0xE468, + 0x92D3, 0xE469, + 0x92D4, 0xE46A, + 0x92D5, 0xE46B, + 0x92D6, 0xE46C, + 0x92D7, 0xE46D, + 0x92D8, 0xE46E, + 0x92D9, 0xE46F, + 0x92DA, 0xE470, + 0x92DB, 0xE471, + 0x92DC, 0xE472, + 0x92DD, 0xE473, + 0x92DE, 0xE474, + 0x92DF, 0xE475, + 0x92E0, 0xE476, + 0x92E1, 0xE477, + 0x92E2, 0xE478, + 0x92E3, 0xE479, + 0x92E4, 0xE47A, + 0x92E5, 0xE47B, + 0x92E6, 0xE47C, + 0x92E7, 0xE47D, + 0x92E8, 0xE47E, + 0x92E9, 0xE480, + 0x92EA, 0xE481, + 0x92EB, 0xE482, + 0x92EC, 0xE483, + 0x92ED, 0xE484, + 0x92EE, 0xE485, + 0x92EF, 0xE486, + 0x92F0, 0xE487, + 0x92F1, 0xE488, + 0x92F2, 0xE489, + 0x92F3, 0xE48A, + 0x92F4, 0xE48B, + 0x92F5, 0xE48C, + 0x92F6, 0xE48D, + 0x92F7, 0xE48E, + 0x92F8, 0xE48F, + 0x92F9, 0xE490, + 0x92FA, 0xE491, + 0x92FB, 0xE492, + 0x92FC, 0xE493, + 0x92FD, 0xE494, + 0x92FE, 0xE495, + 0x92FF, 0xE496, + 0x9300, 0xE497, + 0x9301, 0xE498, + 0x9302, 0xE499, + 0x9303, 0xE49A, + 0x9304, 0xE49B, + 0x9305, 0xE49C, + 0x9306, 0xE49D, + 0x9307, 0xE49E, + 0x9308, 0xE49F, + 0x9309, 0xE4A0, + 0x930A, 0xE540, + 0x930B, 0xE541, + 0x930C, 0xE542, + 0x930D, 0xE543, + 0x930E, 0xE544, + 0x930F, 0xE545, + 0x9310, 0xE546, + 0x9311, 0xE547, + 0x9312, 0xE548, + 0x9313, 0xE549, + 0x9314, 0xE54A, + 0x9315, 0xE54B, + 0x9316, 0xE54C, + 0x9317, 0xE54D, + 0x9318, 0xE54E, + 0x9319, 0xE54F, + 0x931A, 0xE550, + 0x931B, 0xE551, + 0x931C, 0xE552, + 0x931D, 0xE553, + 0x931E, 0xE554, + 0x931F, 0xE555, + 0x9320, 0xE556, + 0x9321, 0xE557, + 0x9322, 0xE558, + 0x9323, 0xE559, + 0x9324, 0xE55A, + 0x9325, 0xE55B, + 0x9326, 0xE55C, + 0x9327, 0xE55D, + 0x9328, 0xE55E, + 0x9329, 0xE55F, + 0x932A, 0xE560, + 0x932B, 0xE561, + 0x932C, 0xE562, + 0x932D, 0xE563, + 0x932E, 0xE564, + 0x932F, 0xE565, + 0x9330, 0xE566, + 0x9331, 0xE567, + 0x9332, 0xE568, + 0x9333, 0xE569, + 0x9334, 0xE56A, + 0x9335, 0xE56B, + 0x9336, 0xE56C, + 0x9337, 0xE56D, + 0x9338, 0xE56E, + 0x9339, 0xE56F, + 0x933A, 0xE570, + 0x933B, 0xE571, + 0x933C, 0xE572, + 0x933D, 0xE573, + 0x933F, 0xE574, + 0x9340, 0xE575, + 0x9341, 0xE576, + 0x9342, 0xE577, + 0x9343, 0xE578, + 0x9344, 0xE579, + 0x9345, 0xE57A, + 0x9346, 0xE57B, + 0x9347, 0xE57C, + 0x9348, 0xE57D, + 0x9349, 0xE57E, + 0x934A, 0xE580, + 0x934B, 0xE581, + 0x934C, 0xE582, + 0x934D, 0xE583, + 0x934E, 0xE584, + 0x934F, 0xE585, + 0x9350, 0xE586, + 0x9351, 0xE587, + 0x9352, 0xE588, + 0x9353, 0xE589, + 0x9354, 0xE58A, + 0x9355, 0xE58B, + 0x9356, 0xE58C, + 0x9357, 0xE58D, + 0x9358, 0xE58E, + 0x9359, 0xE58F, + 0x935A, 0xE590, + 0x935B, 0xE591, + 0x935C, 0xE592, + 0x935D, 0xE593, + 0x935E, 0xE594, + 0x935F, 0xE595, + 0x9360, 0xE596, + 0x9361, 0xE597, + 0x9362, 0xE598, + 0x9363, 0xE599, + 0x9364, 0xE59A, + 0x9365, 0xE59B, + 0x9366, 0xE59C, + 0x9367, 0xE59D, + 0x9368, 0xE59E, + 0x9369, 0xE59F, + 0x936B, 0xE5A0, + 0x936C, 0xE640, + 0x936D, 0xE641, + 0x936E, 0xE642, + 0x936F, 0xE643, + 0x9370, 0xE644, + 0x9371, 0xE645, + 0x9372, 0xE646, + 0x9373, 0xE647, + 0x9374, 0xE648, + 0x9375, 0xE649, + 0x9376, 0xE64A, + 0x9377, 0xE64B, + 0x9378, 0xE64C, + 0x9379, 0xE64D, + 0x937A, 0xE64E, + 0x937B, 0xE64F, + 0x937C, 0xE650, + 0x937D, 0xE651, + 0x937E, 0xE652, + 0x937F, 0xE653, + 0x9380, 0xE654, + 0x9381, 0xE655, + 0x9382, 0xE656, + 0x9383, 0xE657, + 0x9384, 0xE658, + 0x9385, 0xE659, + 0x9386, 0xE65A, + 0x9387, 0xE65B, + 0x9388, 0xE65C, + 0x9389, 0xE65D, + 0x938A, 0xE65E, + 0x938B, 0xE65F, + 0x938C, 0xE660, + 0x938D, 0xE661, + 0x938E, 0xE662, + 0x9390, 0xE663, + 0x9391, 0xE664, + 0x9392, 0xE665, + 0x9393, 0xE666, + 0x9394, 0xE667, + 0x9395, 0xE668, + 0x9396, 0xE669, + 0x9397, 0xE66A, + 0x9398, 0xE66B, + 0x9399, 0xE66C, + 0x939A, 0xE66D, + 0x939B, 0xE66E, + 0x939C, 0xE66F, + 0x939D, 0xE670, + 0x939E, 0xE671, + 0x939F, 0xE672, + 0x93A0, 0xE673, + 0x93A1, 0xE674, + 0x93A2, 0xE675, + 0x93A3, 0xE676, + 0x93A4, 0xE677, + 0x93A5, 0xE678, + 0x93A6, 0xE679, + 0x93A7, 0xE67A, + 0x93A8, 0xE67B, + 0x93A9, 0xE67C, + 0x93AA, 0xE67D, + 0x93AB, 0xE67E, + 0x93AC, 0xE680, + 0x93AD, 0xE681, + 0x93AE, 0xE682, + 0x93AF, 0xE683, + 0x93B0, 0xE684, + 0x93B1, 0xE685, + 0x93B2, 0xE686, + 0x93B3, 0xE687, + 0x93B4, 0xE688, + 0x93B5, 0xE689, + 0x93B6, 0xE68A, + 0x93B7, 0xE68B, + 0x93B8, 0xE68C, + 0x93B9, 0xE68D, + 0x93BA, 0xE68E, + 0x93BB, 0xE68F, + 0x93BC, 0xE690, + 0x93BD, 0xE691, + 0x93BE, 0xE692, + 0x93BF, 0xE693, + 0x93C0, 0xE694, + 0x93C1, 0xE695, + 0x93C2, 0xE696, + 0x93C3, 0xE697, + 0x93C4, 0xE698, + 0x93C5, 0xE699, + 0x93C6, 0xE69A, + 0x93C7, 0xE69B, + 0x93C8, 0xE69C, + 0x93C9, 0xE69D, + 0x93CB, 0xE69E, + 0x93CC, 0xE69F, + 0x93CD, 0xE6A0, + 0x93CE, 0xE740, + 0x93CF, 0xE741, + 0x93D0, 0xE742, + 0x93D1, 0xE743, + 0x93D2, 0xE744, + 0x93D3, 0xE745, + 0x93D4, 0xE746, + 0x93D5, 0xE747, + 0x93D7, 0xE748, + 0x93D8, 0xE749, + 0x93D9, 0xE74A, + 0x93DA, 0xE74B, + 0x93DB, 0xE74C, + 0x93DC, 0xE74D, + 0x93DD, 0xE74E, + 0x93DE, 0xE74F, + 0x93DF, 0xE750, + 0x93E0, 0xE751, + 0x93E1, 0xE752, + 0x93E2, 0xE753, + 0x93E3, 0xE754, + 0x93E4, 0xE755, + 0x93E5, 0xE756, + 0x93E6, 0xE757, + 0x93E7, 0xE758, + 0x93E8, 0xE759, + 0x93E9, 0xE75A, + 0x93EA, 0xE75B, + 0x93EB, 0xE75C, + 0x93EC, 0xE75D, + 0x93ED, 0xE75E, + 0x93EE, 0xE75F, + 0x93EF, 0xE760, + 0x93F0, 0xE761, + 0x93F1, 0xE762, + 0x93F2, 0xE763, + 0x93F3, 0xE764, + 0x93F4, 0xE765, + 0x93F5, 0xE766, + 0x93F6, 0xE767, + 0x93F7, 0xE768, + 0x93F8, 0xE769, + 0x93F9, 0xE76A, + 0x93FA, 0xE76B, + 0x93FB, 0xE76C, + 0x93FC, 0xE76D, + 0x93FD, 0xE76E, + 0x93FE, 0xE76F, + 0x93FF, 0xE770, + 0x9400, 0xE771, + 0x9401, 0xE772, + 0x9402, 0xE773, + 0x9403, 0xE774, + 0x9404, 0xE775, + 0x9405, 0xE776, + 0x9406, 0xE777, + 0x9407, 0xE778, + 0x9408, 0xE779, + 0x9409, 0xE77A, + 0x940A, 0xE77B, + 0x940B, 0xE77C, + 0x940C, 0xE77D, + 0x940D, 0xE77E, + 0x940E, 0xE780, + 0x940F, 0xE781, + 0x9410, 0xE782, + 0x9411, 0xE783, + 0x9412, 0xE784, + 0x9413, 0xE785, + 0x9414, 0xE786, + 0x9415, 0xE787, + 0x9416, 0xE788, + 0x9417, 0xE789, + 0x9418, 0xE78A, + 0x9419, 0xE78B, + 0x941A, 0xE78C, + 0x941B, 0xE78D, + 0x941C, 0xE78E, + 0x941D, 0xE78F, + 0x941E, 0xE790, + 0x941F, 0xE791, + 0x9420, 0xE792, + 0x9421, 0xE793, + 0x9422, 0xE794, + 0x9423, 0xE795, + 0x9424, 0xE796, + 0x9425, 0xE797, + 0x9426, 0xE798, + 0x9427, 0xE799, + 0x9428, 0xE79A, + 0x9429, 0xE79B, + 0x942A, 0xE79C, + 0x942B, 0xE79D, + 0x942C, 0xE79E, + 0x942D, 0xE79F, + 0x942E, 0xE7A0, + 0x942F, 0xE840, + 0x9430, 0xE841, + 0x9431, 0xE842, + 0x9432, 0xE843, + 0x9433, 0xE844, + 0x9434, 0xE845, + 0x9435, 0xE846, + 0x9436, 0xE847, + 0x9437, 0xE848, + 0x9438, 0xE849, + 0x9439, 0xE84A, + 0x943A, 0xE84B, + 0x943B, 0xE84C, + 0x943C, 0xE84D, + 0x943D, 0xE84E, + 0x943F, 0xE84F, + 0x9440, 0xE850, + 0x9441, 0xE851, + 0x9442, 0xE852, + 0x9443, 0xE853, + 0x9444, 0xE854, + 0x9445, 0xE855, + 0x9446, 0xE856, + 0x9447, 0xE857, + 0x9448, 0xE858, + 0x9449, 0xE859, + 0x944A, 0xE85A, + 0x944B, 0xE85B, + 0x944C, 0xE85C, + 0x944D, 0xE85D, + 0x944E, 0xE85E, + 0x944F, 0xE85F, + 0x9450, 0xE860, + 0x9451, 0xE861, + 0x9452, 0xE862, + 0x9453, 0xE863, + 0x9454, 0xE864, + 0x9455, 0xE865, + 0x9456, 0xE866, + 0x9457, 0xE867, + 0x9458, 0xE868, + 0x9459, 0xE869, + 0x945A, 0xE86A, + 0x945B, 0xE86B, + 0x945C, 0xE86C, + 0x945D, 0xE86D, + 0x945E, 0xE86E, + 0x945F, 0xE86F, + 0x9460, 0xE870, + 0x9461, 0xE871, + 0x9462, 0xE872, + 0x9463, 0xE873, + 0x9464, 0xE874, + 0x9465, 0xE875, + 0x9466, 0xE876, + 0x9467, 0xE877, + 0x9468, 0xE878, + 0x9469, 0xE879, + 0x946A, 0xE87A, + 0x946C, 0xE87B, + 0x946D, 0xE87C, + 0x946E, 0xE87D, + 0x946F, 0xE87E, + 0x9470, 0xE880, + 0x9471, 0xE881, + 0x9472, 0xE882, + 0x9473, 0xE883, + 0x9474, 0xE884, + 0x9475, 0xE885, + 0x9476, 0xE886, + 0x9477, 0xE887, + 0x9478, 0xE888, + 0x9479, 0xE889, + 0x947A, 0xE88A, + 0x947B, 0xE88B, + 0x947C, 0xE88C, + 0x947D, 0xE88D, + 0x947E, 0xE88E, + 0x947F, 0xE88F, + 0x9480, 0xE890, + 0x9481, 0xE891, + 0x9482, 0xE892, + 0x9483, 0xE893, + 0x9484, 0xE894, + 0x9491, 0xE895, + 0x9496, 0xE896, + 0x9498, 0xE897, + 0x94C7, 0xE898, + 0x94CF, 0xE899, + 0x94D3, 0xE89A, + 0x94D4, 0xE89B, + 0x94DA, 0xE89C, + 0x94E6, 0xE89D, + 0x94FB, 0xE89E, + 0x951C, 0xE89F, + 0x9520, 0xE8A0, + 0x9527, 0xE940, + 0x9533, 0xE941, + 0x953D, 0xE942, + 0x9543, 0xE943, + 0x9548, 0xE944, + 0x954B, 0xE945, + 0x9555, 0xE946, + 0x955A, 0xE947, + 0x9560, 0xE948, + 0x956E, 0xE949, + 0x9574, 0xE94A, + 0x9575, 0xE94B, + 0x9577, 0xE94C, + 0x9578, 0xE94D, + 0x9579, 0xE94E, + 0x957A, 0xE94F, + 0x957B, 0xE950, + 0x957C, 0xE951, + 0x957D, 0xE952, + 0x957E, 0xE953, + 0x9580, 0xE954, + 0x9581, 0xE955, + 0x9582, 0xE956, + 0x9583, 0xE957, + 0x9584, 0xE958, + 0x9585, 0xE959, + 0x9586, 0xE95A, + 0x9587, 0xE95B, + 0x9588, 0xE95C, + 0x9589, 0xE95D, + 0x958A, 0xE95E, + 0x958B, 0xE95F, + 0x958C, 0xE960, + 0x958D, 0xE961, + 0x958E, 0xE962, + 0x958F, 0xE963, + 0x9590, 0xE964, + 0x9591, 0xE965, + 0x9592, 0xE966, + 0x9593, 0xE967, + 0x9594, 0xE968, + 0x9595, 0xE969, + 0x9596, 0xE96A, + 0x9597, 0xE96B, + 0x9598, 0xE96C, + 0x9599, 0xE96D, + 0x959A, 0xE96E, + 0x959B, 0xE96F, + 0x959C, 0xE970, + 0x959D, 0xE971, + 0x959E, 0xE972, + 0x959F, 0xE973, + 0x95A0, 0xE974, + 0x95A1, 0xE975, + 0x95A2, 0xE976, + 0x95A3, 0xE977, + 0x95A4, 0xE978, + 0x95A5, 0xE979, + 0x95A6, 0xE97A, + 0x95A7, 0xE97B, + 0x95A8, 0xE97C, + 0x95A9, 0xE97D, + 0x95AA, 0xE97E, + 0x95AB, 0xE980, + 0x95AC, 0xE981, + 0x95AD, 0xE982, + 0x95AE, 0xE983, + 0x95AF, 0xE984, + 0x95B0, 0xE985, + 0x95B1, 0xE986, + 0x95B2, 0xE987, + 0x95B3, 0xE988, + 0x95B4, 0xE989, + 0x95B5, 0xE98A, + 0x95B6, 0xE98B, + 0x95B7, 0xE98C, + 0x95B8, 0xE98D, + 0x95B9, 0xE98E, + 0x95BA, 0xE98F, + 0x95BB, 0xE990, + 0x95BC, 0xE991, + 0x95BD, 0xE992, + 0x95BE, 0xE993, + 0x95BF, 0xE994, + 0x95C0, 0xE995, + 0x95C1, 0xE996, + 0x95C2, 0xE997, + 0x95C3, 0xE998, + 0x95C4, 0xE999, + 0x95C5, 0xE99A, + 0x95C6, 0xE99B, + 0x95C7, 0xE99C, + 0x95C8, 0xE99D, + 0x95C9, 0xE99E, + 0x95CA, 0xE99F, + 0x95CB, 0xE9A0, + 0x95CC, 0xEA40, + 0x95CD, 0xEA41, + 0x95CE, 0xEA42, + 0x95CF, 0xEA43, + 0x95D0, 0xEA44, + 0x95D1, 0xEA45, + 0x95D2, 0xEA46, + 0x95D3, 0xEA47, + 0x95D4, 0xEA48, + 0x95D5, 0xEA49, + 0x95D6, 0xEA4A, + 0x95D7, 0xEA4B, + 0x95D8, 0xEA4C, + 0x95D9, 0xEA4D, + 0x95DA, 0xEA4E, + 0x95DB, 0xEA4F, + 0x95DC, 0xEA50, + 0x95DD, 0xEA51, + 0x95DE, 0xEA52, + 0x95DF, 0xEA53, + 0x95E0, 0xEA54, + 0x95E1, 0xEA55, + 0x95E2, 0xEA56, + 0x95E3, 0xEA57, + 0x95E4, 0xEA58, + 0x95E5, 0xEA59, + 0x95E6, 0xEA5A, + 0x95E7, 0xEA5B, + 0x95EC, 0xEA5C, + 0x95FF, 0xEA5D, + 0x9607, 0xEA5E, + 0x9613, 0xEA5F, + 0x9618, 0xEA60, + 0x961B, 0xEA61, + 0x961E, 0xEA62, + 0x9620, 0xEA63, + 0x9623, 0xEA64, + 0x9624, 0xEA65, + 0x9625, 0xEA66, + 0x9626, 0xEA67, + 0x9627, 0xEA68, + 0x9628, 0xEA69, + 0x9629, 0xEA6A, + 0x962B, 0xEA6B, + 0x962C, 0xEA6C, + 0x962D, 0xEA6D, + 0x962F, 0xEA6E, + 0x9630, 0xEA6F, + 0x9637, 0xEA70, + 0x9638, 0xEA71, + 0x9639, 0xEA72, + 0x963A, 0xEA73, + 0x963E, 0xEA74, + 0x9641, 0xEA75, + 0x9643, 0xEA76, + 0x964A, 0xEA77, + 0x964E, 0xEA78, + 0x964F, 0xEA79, + 0x9651, 0xEA7A, + 0x9652, 0xEA7B, + 0x9653, 0xEA7C, + 0x9656, 0xEA7D, + 0x9657, 0xEA7E, + 0x9658, 0xEA80, + 0x9659, 0xEA81, + 0x965A, 0xEA82, + 0x965C, 0xEA83, + 0x965D, 0xEA84, + 0x965E, 0xEA85, + 0x9660, 0xEA86, + 0x9663, 0xEA87, + 0x9665, 0xEA88, + 0x9666, 0xEA89, + 0x966B, 0xEA8A, + 0x966D, 0xEA8B, + 0x966E, 0xEA8C, + 0x966F, 0xEA8D, + 0x9670, 0xEA8E, + 0x9671, 0xEA8F, + 0x9673, 0xEA90, + 0x9678, 0xEA91, + 0x9679, 0xEA92, + 0x967A, 0xEA93, + 0x967B, 0xEA94, + 0x967C, 0xEA95, + 0x967D, 0xEA96, + 0x967E, 0xEA97, + 0x967F, 0xEA98, + 0x9680, 0xEA99, + 0x9681, 0xEA9A, + 0x9682, 0xEA9B, + 0x9683, 0xEA9C, + 0x9684, 0xEA9D, + 0x9687, 0xEA9E, + 0x9689, 0xEA9F, + 0x968A, 0xEAA0, + 0x968C, 0xEB40, + 0x968E, 0xEB41, + 0x9691, 0xEB42, + 0x9692, 0xEB43, + 0x9693, 0xEB44, + 0x9695, 0xEB45, + 0x9696, 0xEB46, + 0x969A, 0xEB47, + 0x969B, 0xEB48, + 0x969D, 0xEB49, + 0x969E, 0xEB4A, + 0x969F, 0xEB4B, + 0x96A0, 0xEB4C, + 0x96A1, 0xEB4D, + 0x96A2, 0xEB4E, + 0x96A3, 0xEB4F, + 0x96A4, 0xEB50, + 0x96A5, 0xEB51, + 0x96A6, 0xEB52, + 0x96A8, 0xEB53, + 0x96A9, 0xEB54, + 0x96AA, 0xEB55, + 0x96AB, 0xEB56, + 0x96AC, 0xEB57, + 0x96AD, 0xEB58, + 0x96AE, 0xEB59, + 0x96AF, 0xEB5A, + 0x96B1, 0xEB5B, + 0x96B2, 0xEB5C, + 0x96B4, 0xEB5D, + 0x96B5, 0xEB5E, + 0x96B7, 0xEB5F, + 0x96B8, 0xEB60, + 0x96BA, 0xEB61, + 0x96BB, 0xEB62, + 0x96BF, 0xEB63, + 0x96C2, 0xEB64, + 0x96C3, 0xEB65, + 0x96C8, 0xEB66, + 0x96CA, 0xEB67, + 0x96CB, 0xEB68, + 0x96D0, 0xEB69, + 0x96D1, 0xEB6A, + 0x96D3, 0xEB6B, + 0x96D4, 0xEB6C, + 0x96D6, 0xEB6D, + 0x96D7, 0xEB6E, + 0x96D8, 0xEB6F, + 0x96D9, 0xEB70, + 0x96DA, 0xEB71, + 0x96DB, 0xEB72, + 0x96DC, 0xEB73, + 0x96DD, 0xEB74, + 0x96DE, 0xEB75, + 0x96DF, 0xEB76, + 0x96E1, 0xEB77, + 0x96E2, 0xEB78, + 0x96E3, 0xEB79, + 0x96E4, 0xEB7A, + 0x96E5, 0xEB7B, + 0x96E6, 0xEB7C, + 0x96E7, 0xEB7D, + 0x96EB, 0xEB7E, + 0x96EC, 0xEB80, + 0x96ED, 0xEB81, + 0x96EE, 0xEB82, + 0x96F0, 0xEB83, + 0x96F1, 0xEB84, + 0x96F2, 0xEB85, + 0x96F4, 0xEB86, + 0x96F5, 0xEB87, + 0x96F8, 0xEB88, + 0x96FA, 0xEB89, + 0x96FB, 0xEB8A, + 0x96FC, 0xEB8B, + 0x96FD, 0xEB8C, + 0x96FF, 0xEB8D, + 0x9702, 0xEB8E, + 0x9703, 0xEB8F, + 0x9705, 0xEB90, + 0x970A, 0xEB91, + 0x970B, 0xEB92, + 0x970C, 0xEB93, + 0x9710, 0xEB94, + 0x9711, 0xEB95, + 0x9712, 0xEB96, + 0x9714, 0xEB97, + 0x9715, 0xEB98, + 0x9717, 0xEB99, + 0x9718, 0xEB9A, + 0x9719, 0xEB9B, + 0x971A, 0xEB9C, + 0x971B, 0xEB9D, + 0x971D, 0xEB9E, + 0x971F, 0xEB9F, + 0x9720, 0xEBA0, + 0x9721, 0xEC40, + 0x9722, 0xEC41, + 0x9723, 0xEC42, + 0x9724, 0xEC43, + 0x9725, 0xEC44, + 0x9726, 0xEC45, + 0x9727, 0xEC46, + 0x9728, 0xEC47, + 0x9729, 0xEC48, + 0x972B, 0xEC49, + 0x972C, 0xEC4A, + 0x972E, 0xEC4B, + 0x972F, 0xEC4C, + 0x9731, 0xEC4D, + 0x9733, 0xEC4E, + 0x9734, 0xEC4F, + 0x9735, 0xEC50, + 0x9736, 0xEC51, + 0x9737, 0xEC52, + 0x973A, 0xEC53, + 0x973B, 0xEC54, + 0x973C, 0xEC55, + 0x973D, 0xEC56, + 0x973F, 0xEC57, + 0x9740, 0xEC58, + 0x9741, 0xEC59, + 0x9742, 0xEC5A, + 0x9743, 0xEC5B, + 0x9744, 0xEC5C, + 0x9745, 0xEC5D, + 0x9746, 0xEC5E, + 0x9747, 0xEC5F, + 0x9748, 0xEC60, + 0x9749, 0xEC61, + 0x974A, 0xEC62, + 0x974B, 0xEC63, + 0x974C, 0xEC64, + 0x974D, 0xEC65, + 0x974E, 0xEC66, + 0x974F, 0xEC67, + 0x9750, 0xEC68, + 0x9751, 0xEC69, + 0x9754, 0xEC6A, + 0x9755, 0xEC6B, + 0x9757, 0xEC6C, + 0x9758, 0xEC6D, + 0x975A, 0xEC6E, + 0x975C, 0xEC6F, + 0x975D, 0xEC70, + 0x975F, 0xEC71, + 0x9763, 0xEC72, + 0x9764, 0xEC73, + 0x9766, 0xEC74, + 0x9767, 0xEC75, + 0x9768, 0xEC76, + 0x976A, 0xEC77, + 0x976B, 0xEC78, + 0x976C, 0xEC79, + 0x976D, 0xEC7A, + 0x976E, 0xEC7B, + 0x976F, 0xEC7C, + 0x9770, 0xEC7D, + 0x9771, 0xEC7E, + 0x9772, 0xEC80, + 0x9775, 0xEC81, + 0x9777, 0xEC82, + 0x9778, 0xEC83, + 0x9779, 0xEC84, + 0x977A, 0xEC85, + 0x977B, 0xEC86, + 0x977D, 0xEC87, + 0x977E, 0xEC88, + 0x977F, 0xEC89, + 0x9780, 0xEC8A, + 0x9781, 0xEC8B, + 0x9782, 0xEC8C, + 0x9783, 0xEC8D, + 0x9784, 0xEC8E, + 0x9786, 0xEC8F, + 0x9787, 0xEC90, + 0x9788, 0xEC91, + 0x9789, 0xEC92, + 0x978A, 0xEC93, + 0x978C, 0xEC94, + 0x978E, 0xEC95, + 0x978F, 0xEC96, + 0x9790, 0xEC97, + 0x9793, 0xEC98, + 0x9795, 0xEC99, + 0x9796, 0xEC9A, + 0x9797, 0xEC9B, + 0x9799, 0xEC9C, + 0x979A, 0xEC9D, + 0x979B, 0xEC9E, + 0x979C, 0xEC9F, + 0x979D, 0xECA0, + 0x979E, 0xED40, + 0x979F, 0xED41, + 0x97A1, 0xED42, + 0x97A2, 0xED43, + 0x97A4, 0xED44, + 0x97A5, 0xED45, + 0x97A6, 0xED46, + 0x97A7, 0xED47, + 0x97A8, 0xED48, + 0x97A9, 0xED49, + 0x97AA, 0xED4A, + 0x97AC, 0xED4B, + 0x97AE, 0xED4C, + 0x97B0, 0xED4D, + 0x97B1, 0xED4E, + 0x97B3, 0xED4F, + 0x97B5, 0xED50, + 0x97B6, 0xED51, + 0x97B7, 0xED52, + 0x97B8, 0xED53, + 0x97B9, 0xED54, + 0x97BA, 0xED55, + 0x97BB, 0xED56, + 0x97BC, 0xED57, + 0x97BD, 0xED58, + 0x97BE, 0xED59, + 0x97BF, 0xED5A, + 0x97C0, 0xED5B, + 0x97C1, 0xED5C, + 0x97C2, 0xED5D, + 0x97C3, 0xED5E, + 0x97C4, 0xED5F, + 0x97C5, 0xED60, + 0x97C6, 0xED61, + 0x97C7, 0xED62, + 0x97C8, 0xED63, + 0x97C9, 0xED64, + 0x97CA, 0xED65, + 0x97CB, 0xED66, + 0x97CC, 0xED67, + 0x97CD, 0xED68, + 0x97CE, 0xED69, + 0x97CF, 0xED6A, + 0x97D0, 0xED6B, + 0x97D1, 0xED6C, + 0x97D2, 0xED6D, + 0x97D3, 0xED6E, + 0x97D4, 0xED6F, + 0x97D5, 0xED70, + 0x97D6, 0xED71, + 0x97D7, 0xED72, + 0x97D8, 0xED73, + 0x97D9, 0xED74, + 0x97DA, 0xED75, + 0x97DB, 0xED76, + 0x97DC, 0xED77, + 0x97DD, 0xED78, + 0x97DE, 0xED79, + 0x97DF, 0xED7A, + 0x97E0, 0xED7B, + 0x97E1, 0xED7C, + 0x97E2, 0xED7D, + 0x97E3, 0xED7E, + 0x97E4, 0xED80, + 0x97E5, 0xED81, + 0x97E8, 0xED82, + 0x97EE, 0xED83, + 0x97EF, 0xED84, + 0x97F0, 0xED85, + 0x97F1, 0xED86, + 0x97F2, 0xED87, + 0x97F4, 0xED88, + 0x97F7, 0xED89, + 0x97F8, 0xED8A, + 0x97F9, 0xED8B, + 0x97FA, 0xED8C, + 0x97FB, 0xED8D, + 0x97FC, 0xED8E, + 0x97FD, 0xED8F, + 0x97FE, 0xED90, + 0x97FF, 0xED91, + 0x9800, 0xED92, + 0x9801, 0xED93, + 0x9802, 0xED94, + 0x9803, 0xED95, + 0x9804, 0xED96, + 0x9805, 0xED97, + 0x9806, 0xED98, + 0x9807, 0xED99, + 0x9808, 0xED9A, + 0x9809, 0xED9B, + 0x980A, 0xED9C, + 0x980B, 0xED9D, + 0x980C, 0xED9E, + 0x980D, 0xED9F, + 0x980E, 0xEDA0, + 0x980F, 0xEE40, + 0x9810, 0xEE41, + 0x9811, 0xEE42, + 0x9812, 0xEE43, + 0x9813, 0xEE44, + 0x9814, 0xEE45, + 0x9815, 0xEE46, + 0x9816, 0xEE47, + 0x9817, 0xEE48, + 0x9818, 0xEE49, + 0x9819, 0xEE4A, + 0x981A, 0xEE4B, + 0x981B, 0xEE4C, + 0x981C, 0xEE4D, + 0x981D, 0xEE4E, + 0x981E, 0xEE4F, + 0x981F, 0xEE50, + 0x9820, 0xEE51, + 0x9821, 0xEE52, + 0x9822, 0xEE53, + 0x9823, 0xEE54, + 0x9824, 0xEE55, + 0x9825, 0xEE56, + 0x9826, 0xEE57, + 0x9827, 0xEE58, + 0x9828, 0xEE59, + 0x9829, 0xEE5A, + 0x982A, 0xEE5B, + 0x982B, 0xEE5C, + 0x982C, 0xEE5D, + 0x982D, 0xEE5E, + 0x982E, 0xEE5F, + 0x982F, 0xEE60, + 0x9830, 0xEE61, + 0x9831, 0xEE62, + 0x9832, 0xEE63, + 0x9833, 0xEE64, + 0x9834, 0xEE65, + 0x9835, 0xEE66, + 0x9836, 0xEE67, + 0x9837, 0xEE68, + 0x9838, 0xEE69, + 0x9839, 0xEE6A, + 0x983A, 0xEE6B, + 0x983B, 0xEE6C, + 0x983C, 0xEE6D, + 0x983D, 0xEE6E, + 0x983E, 0xEE6F, + 0x983F, 0xEE70, + 0x9840, 0xEE71, + 0x9841, 0xEE72, + 0x9842, 0xEE73, + 0x9843, 0xEE74, + 0x9844, 0xEE75, + 0x9845, 0xEE76, + 0x9846, 0xEE77, + 0x9847, 0xEE78, + 0x9848, 0xEE79, + 0x9849, 0xEE7A, + 0x984A, 0xEE7B, + 0x984B, 0xEE7C, + 0x984C, 0xEE7D, + 0x984D, 0xEE7E, + 0x984E, 0xEE80, + 0x984F, 0xEE81, + 0x9850, 0xEE82, + 0x9851, 0xEE83, + 0x9852, 0xEE84, + 0x9853, 0xEE85, + 0x9854, 0xEE86, + 0x9855, 0xEE87, + 0x9856, 0xEE88, + 0x9857, 0xEE89, + 0x9858, 0xEE8A, + 0x9859, 0xEE8B, + 0x985A, 0xEE8C, + 0x985B, 0xEE8D, + 0x985C, 0xEE8E, + 0x985D, 0xEE8F, + 0x985E, 0xEE90, + 0x985F, 0xEE91, + 0x9860, 0xEE92, + 0x9861, 0xEE93, + 0x9862, 0xEE94, + 0x9863, 0xEE95, + 0x9864, 0xEE96, + 0x9865, 0xEE97, + 0x9866, 0xEE98, + 0x9867, 0xEE99, + 0x9868, 0xEE9A, + 0x9869, 0xEE9B, + 0x986A, 0xEE9C, + 0x986B, 0xEE9D, + 0x986C, 0xEE9E, + 0x986D, 0xEE9F, + 0x986E, 0xEEA0, + 0x986F, 0xEF40, + 0x9870, 0xEF41, + 0x9871, 0xEF42, + 0x9872, 0xEF43, + 0x9873, 0xEF44, + 0x9874, 0xEF45, + 0x988B, 0xEF46, + 0x988E, 0xEF47, + 0x9892, 0xEF48, + 0x9895, 0xEF49, + 0x9899, 0xEF4A, + 0x98A3, 0xEF4B, + 0x98A8, 0xEF4C, + 0x98A9, 0xEF4D, + 0x98AA, 0xEF4E, + 0x98AB, 0xEF4F, + 0x98AC, 0xEF50, + 0x98AD, 0xEF51, + 0x98AE, 0xEF52, + 0x98AF, 0xEF53, + 0x98B0, 0xEF54, + 0x98B1, 0xEF55, + 0x98B2, 0xEF56, + 0x98B3, 0xEF57, + 0x98B4, 0xEF58, + 0x98B5, 0xEF59, + 0x98B6, 0xEF5A, + 0x98B7, 0xEF5B, + 0x98B8, 0xEF5C, + 0x98B9, 0xEF5D, + 0x98BA, 0xEF5E, + 0x98BB, 0xEF5F, + 0x98BC, 0xEF60, + 0x98BD, 0xEF61, + 0x98BE, 0xEF62, + 0x98BF, 0xEF63, + 0x98C0, 0xEF64, + 0x98C1, 0xEF65, + 0x98C2, 0xEF66, + 0x98C3, 0xEF67, + 0x98C4, 0xEF68, + 0x98C5, 0xEF69, + 0x98C6, 0xEF6A, + 0x98C7, 0xEF6B, + 0x98C8, 0xEF6C, + 0x98C9, 0xEF6D, + 0x98CA, 0xEF6E, + 0x98CB, 0xEF6F, + 0x98CC, 0xEF70, + 0x98CD, 0xEF71, + 0x98CF, 0xEF72, + 0x98D0, 0xEF73, + 0x98D4, 0xEF74, + 0x98D6, 0xEF75, + 0x98D7, 0xEF76, + 0x98DB, 0xEF77, + 0x98DC, 0xEF78, + 0x98DD, 0xEF79, + 0x98E0, 0xEF7A, + 0x98E1, 0xEF7B, + 0x98E2, 0xEF7C, + 0x98E3, 0xEF7D, + 0x98E4, 0xEF7E, + 0x98E5, 0xEF80, + 0x98E6, 0xEF81, + 0x98E9, 0xEF82, + 0x98EA, 0xEF83, + 0x98EB, 0xEF84, + 0x98EC, 0xEF85, + 0x98ED, 0xEF86, + 0x98EE, 0xEF87, + 0x98EF, 0xEF88, + 0x98F0, 0xEF89, + 0x98F1, 0xEF8A, + 0x98F2, 0xEF8B, + 0x98F3, 0xEF8C, + 0x98F4, 0xEF8D, + 0x98F5, 0xEF8E, + 0x98F6, 0xEF8F, + 0x98F7, 0xEF90, + 0x98F8, 0xEF91, + 0x98F9, 0xEF92, + 0x98FA, 0xEF93, + 0x98FB, 0xEF94, + 0x98FC, 0xEF95, + 0x98FD, 0xEF96, + 0x98FE, 0xEF97, + 0x98FF, 0xEF98, + 0x9900, 0xEF99, + 0x9901, 0xEF9A, + 0x9902, 0xEF9B, + 0x9903, 0xEF9C, + 0x9904, 0xEF9D, + 0x9905, 0xEF9E, + 0x9906, 0xEF9F, + 0x9907, 0xEFA0, + 0x9908, 0xF040, + 0x9909, 0xF041, + 0x990A, 0xF042, + 0x990B, 0xF043, + 0x990C, 0xF044, + 0x990E, 0xF045, + 0x990F, 0xF046, + 0x9911, 0xF047, + 0x9912, 0xF048, + 0x9913, 0xF049, + 0x9914, 0xF04A, + 0x9915, 0xF04B, + 0x9916, 0xF04C, + 0x9917, 0xF04D, + 0x9918, 0xF04E, + 0x9919, 0xF04F, + 0x991A, 0xF050, + 0x991B, 0xF051, + 0x991C, 0xF052, + 0x991D, 0xF053, + 0x991E, 0xF054, + 0x991F, 0xF055, + 0x9920, 0xF056, + 0x9921, 0xF057, + 0x9922, 0xF058, + 0x9923, 0xF059, + 0x9924, 0xF05A, + 0x9925, 0xF05B, + 0x9926, 0xF05C, + 0x9927, 0xF05D, + 0x9928, 0xF05E, + 0x9929, 0xF05F, + 0x992A, 0xF060, + 0x992B, 0xF061, + 0x992C, 0xF062, + 0x992D, 0xF063, + 0x992F, 0xF064, + 0x9930, 0xF065, + 0x9931, 0xF066, + 0x9932, 0xF067, + 0x9933, 0xF068, + 0x9934, 0xF069, + 0x9935, 0xF06A, + 0x9936, 0xF06B, + 0x9937, 0xF06C, + 0x9938, 0xF06D, + 0x9939, 0xF06E, + 0x993A, 0xF06F, + 0x993B, 0xF070, + 0x993C, 0xF071, + 0x993D, 0xF072, + 0x993E, 0xF073, + 0x993F, 0xF074, + 0x9940, 0xF075, + 0x9941, 0xF076, + 0x9942, 0xF077, + 0x9943, 0xF078, + 0x9944, 0xF079, + 0x9945, 0xF07A, + 0x9946, 0xF07B, + 0x9947, 0xF07C, + 0x9948, 0xF07D, + 0x9949, 0xF07E, + 0x994A, 0xF080, + 0x994B, 0xF081, + 0x994C, 0xF082, + 0x994D, 0xF083, + 0x994E, 0xF084, + 0x994F, 0xF085, + 0x9950, 0xF086, + 0x9951, 0xF087, + 0x9952, 0xF088, + 0x9953, 0xF089, + 0x9956, 0xF08A, + 0x9957, 0xF08B, + 0x9958, 0xF08C, + 0x9959, 0xF08D, + 0x995A, 0xF08E, + 0x995B, 0xF08F, + 0x995C, 0xF090, + 0x995D, 0xF091, + 0x995E, 0xF092, + 0x995F, 0xF093, + 0x9960, 0xF094, + 0x9961, 0xF095, + 0x9962, 0xF096, + 0x9964, 0xF097, + 0x9966, 0xF098, + 0x9973, 0xF099, + 0x9978, 0xF09A, + 0x9979, 0xF09B, + 0x997B, 0xF09C, + 0x997E, 0xF09D, + 0x9982, 0xF09E, + 0x9983, 0xF09F, + 0x9989, 0xF0A0, + 0x998C, 0xF140, + 0x998E, 0xF141, + 0x999A, 0xF142, + 0x999B, 0xF143, + 0x999C, 0xF144, + 0x999D, 0xF145, + 0x999E, 0xF146, + 0x999F, 0xF147, + 0x99A0, 0xF148, + 0x99A1, 0xF149, + 0x99A2, 0xF14A, + 0x99A3, 0xF14B, + 0x99A4, 0xF14C, + 0x99A6, 0xF14D, + 0x99A7, 0xF14E, + 0x99A9, 0xF14F, + 0x99AA, 0xF150, + 0x99AB, 0xF151, + 0x99AC, 0xF152, + 0x99AD, 0xF153, + 0x99AE, 0xF154, + 0x99AF, 0xF155, + 0x99B0, 0xF156, + 0x99B1, 0xF157, + 0x99B2, 0xF158, + 0x99B3, 0xF159, + 0x99B4, 0xF15A, + 0x99B5, 0xF15B, + 0x99B6, 0xF15C, + 0x99B7, 0xF15D, + 0x99B8, 0xF15E, + 0x99B9, 0xF15F, + 0x99BA, 0xF160, + 0x99BB, 0xF161, + 0x99BC, 0xF162, + 0x99BD, 0xF163, + 0x99BE, 0xF164, + 0x99BF, 0xF165, + 0x99C0, 0xF166, + 0x99C1, 0xF167, + 0x99C2, 0xF168, + 0x99C3, 0xF169, + 0x99C4, 0xF16A, + 0x99C5, 0xF16B, + 0x99C6, 0xF16C, + 0x99C7, 0xF16D, + 0x99C8, 0xF16E, + 0x99C9, 0xF16F, + 0x99CA, 0xF170, + 0x99CB, 0xF171, + 0x99CC, 0xF172, + 0x99CD, 0xF173, + 0x99CE, 0xF174, + 0x99CF, 0xF175, + 0x99D0, 0xF176, + 0x99D1, 0xF177, + 0x99D2, 0xF178, + 0x99D3, 0xF179, + 0x99D4, 0xF17A, + 0x99D5, 0xF17B, + 0x99D6, 0xF17C, + 0x99D7, 0xF17D, + 0x99D8, 0xF17E, + 0x99D9, 0xF180, + 0x99DA, 0xF181, + 0x99DB, 0xF182, + 0x99DC, 0xF183, + 0x99DD, 0xF184, + 0x99DE, 0xF185, + 0x99DF, 0xF186, + 0x99E0, 0xF187, + 0x99E1, 0xF188, + 0x99E2, 0xF189, + 0x99E3, 0xF18A, + 0x99E4, 0xF18B, + 0x99E5, 0xF18C, + 0x99E6, 0xF18D, + 0x99E7, 0xF18E, + 0x99E8, 0xF18F, + 0x99E9, 0xF190, + 0x99EA, 0xF191, + 0x99EB, 0xF192, + 0x99EC, 0xF193, + 0x99ED, 0xF194, + 0x99EE, 0xF195, + 0x99EF, 0xF196, + 0x99F0, 0xF197, + 0x99F1, 0xF198, + 0x99F2, 0xF199, + 0x99F3, 0xF19A, + 0x99F4, 0xF19B, + 0x99F5, 0xF19C, + 0x99F6, 0xF19D, + 0x99F7, 0xF19E, + 0x99F8, 0xF19F, + 0x99F9, 0xF1A0, + 0x99FA, 0xF240, + 0x99FB, 0xF241, + 0x99FC, 0xF242, + 0x99FD, 0xF243, + 0x99FE, 0xF244, + 0x99FF, 0xF245, + 0x9A00, 0xF246, + 0x9A01, 0xF247, + 0x9A02, 0xF248, + 0x9A03, 0xF249, + 0x9A04, 0xF24A, + 0x9A05, 0xF24B, + 0x9A06, 0xF24C, + 0x9A07, 0xF24D, + 0x9A08, 0xF24E, + 0x9A09, 0xF24F, + 0x9A0A, 0xF250, + 0x9A0B, 0xF251, + 0x9A0C, 0xF252, + 0x9A0D, 0xF253, + 0x9A0E, 0xF254, + 0x9A0F, 0xF255, + 0x9A10, 0xF256, + 0x9A11, 0xF257, + 0x9A12, 0xF258, + 0x9A13, 0xF259, + 0x9A14, 0xF25A, + 0x9A15, 0xF25B, + 0x9A16, 0xF25C, + 0x9A17, 0xF25D, + 0x9A18, 0xF25E, + 0x9A19, 0xF25F, + 0x9A1A, 0xF260, + 0x9A1B, 0xF261, + 0x9A1C, 0xF262, + 0x9A1D, 0xF263, + 0x9A1E, 0xF264, + 0x9A1F, 0xF265, + 0x9A20, 0xF266, + 0x9A21, 0xF267, + 0x9A22, 0xF268, + 0x9A23, 0xF269, + 0x9A24, 0xF26A, + 0x9A25, 0xF26B, + 0x9A26, 0xF26C, + 0x9A27, 0xF26D, + 0x9A28, 0xF26E, + 0x9A29, 0xF26F, + 0x9A2A, 0xF270, + 0x9A2B, 0xF271, + 0x9A2C, 0xF272, + 0x9A2D, 0xF273, + 0x9A2E, 0xF274, + 0x9A2F, 0xF275, + 0x9A30, 0xF276, + 0x9A31, 0xF277, + 0x9A32, 0xF278, + 0x9A33, 0xF279, + 0x9A34, 0xF27A, + 0x9A35, 0xF27B, + 0x9A36, 0xF27C, + 0x9A37, 0xF27D, + 0x9A38, 0xF27E, + 0x9A39, 0xF280, + 0x9A3A, 0xF281, + 0x9A3B, 0xF282, + 0x9A3C, 0xF283, + 0x9A3D, 0xF284, + 0x9A3E, 0xF285, + 0x9A3F, 0xF286, + 0x9A40, 0xF287, + 0x9A41, 0xF288, + 0x9A42, 0xF289, + 0x9A43, 0xF28A, + 0x9A44, 0xF28B, + 0x9A45, 0xF28C, + 0x9A46, 0xF28D, + 0x9A47, 0xF28E, + 0x9A48, 0xF28F, + 0x9A49, 0xF290, + 0x9A4A, 0xF291, + 0x9A4B, 0xF292, + 0x9A4C, 0xF293, + 0x9A4D, 0xF294, + 0x9A4E, 0xF295, + 0x9A4F, 0xF296, + 0x9A50, 0xF297, + 0x9A51, 0xF298, + 0x9A52, 0xF299, + 0x9A53, 0xF29A, + 0x9A54, 0xF29B, + 0x9A55, 0xF29C, + 0x9A56, 0xF29D, + 0x9A57, 0xF29E, + 0x9A58, 0xF29F, + 0x9A59, 0xF2A0, + 0x9A5A, 0xF340, + 0x9A5B, 0xF341, + 0x9A5C, 0xF342, + 0x9A5D, 0xF343, + 0x9A5E, 0xF344, + 0x9A5F, 0xF345, + 0x9A60, 0xF346, + 0x9A61, 0xF347, + 0x9A62, 0xF348, + 0x9A63, 0xF349, + 0x9A64, 0xF34A, + 0x9A65, 0xF34B, + 0x9A66, 0xF34C, + 0x9A67, 0xF34D, + 0x9A68, 0xF34E, + 0x9A69, 0xF34F, + 0x9A6A, 0xF350, + 0x9A6B, 0xF351, + 0x9A72, 0xF352, + 0x9A83, 0xF353, + 0x9A89, 0xF354, + 0x9A8D, 0xF355, + 0x9A8E, 0xF356, + 0x9A94, 0xF357, + 0x9A95, 0xF358, + 0x9A99, 0xF359, + 0x9AA6, 0xF35A, + 0x9AA9, 0xF35B, + 0x9AAA, 0xF35C, + 0x9AAB, 0xF35D, + 0x9AAC, 0xF35E, + 0x9AAD, 0xF35F, + 0x9AAE, 0xF360, + 0x9AAF, 0xF361, + 0x9AB2, 0xF362, + 0x9AB3, 0xF363, + 0x9AB4, 0xF364, + 0x9AB5, 0xF365, + 0x9AB9, 0xF366, + 0x9ABB, 0xF367, + 0x9ABD, 0xF368, + 0x9ABE, 0xF369, + 0x9ABF, 0xF36A, + 0x9AC3, 0xF36B, + 0x9AC4, 0xF36C, + 0x9AC6, 0xF36D, + 0x9AC7, 0xF36E, + 0x9AC8, 0xF36F, + 0x9AC9, 0xF370, + 0x9ACA, 0xF371, + 0x9ACD, 0xF372, + 0x9ACE, 0xF373, + 0x9ACF, 0xF374, + 0x9AD0, 0xF375, + 0x9AD2, 0xF376, + 0x9AD4, 0xF377, + 0x9AD5, 0xF378, + 0x9AD6, 0xF379, + 0x9AD7, 0xF37A, + 0x9AD9, 0xF37B, + 0x9ADA, 0xF37C, + 0x9ADB, 0xF37D, + 0x9ADC, 0xF37E, + 0x9ADD, 0xF380, + 0x9ADE, 0xF381, + 0x9AE0, 0xF382, + 0x9AE2, 0xF383, + 0x9AE3, 0xF384, + 0x9AE4, 0xF385, + 0x9AE5, 0xF386, + 0x9AE7, 0xF387, + 0x9AE8, 0xF388, + 0x9AE9, 0xF389, + 0x9AEA, 0xF38A, + 0x9AEC, 0xF38B, + 0x9AEE, 0xF38C, + 0x9AF0, 0xF38D, + 0x9AF1, 0xF38E, + 0x9AF2, 0xF38F, + 0x9AF3, 0xF390, + 0x9AF4, 0xF391, + 0x9AF5, 0xF392, + 0x9AF6, 0xF393, + 0x9AF7, 0xF394, + 0x9AF8, 0xF395, + 0x9AFA, 0xF396, + 0x9AFC, 0xF397, + 0x9AFD, 0xF398, + 0x9AFE, 0xF399, + 0x9AFF, 0xF39A, + 0x9B00, 0xF39B, + 0x9B01, 0xF39C, + 0x9B02, 0xF39D, + 0x9B04, 0xF39E, + 0x9B05, 0xF39F, + 0x9B06, 0xF3A0, + 0x9B07, 0xF440, + 0x9B09, 0xF441, + 0x9B0A, 0xF442, + 0x9B0B, 0xF443, + 0x9B0C, 0xF444, + 0x9B0D, 0xF445, + 0x9B0E, 0xF446, + 0x9B10, 0xF447, + 0x9B11, 0xF448, + 0x9B12, 0xF449, + 0x9B14, 0xF44A, + 0x9B15, 0xF44B, + 0x9B16, 0xF44C, + 0x9B17, 0xF44D, + 0x9B18, 0xF44E, + 0x9B19, 0xF44F, + 0x9B1A, 0xF450, + 0x9B1B, 0xF451, + 0x9B1C, 0xF452, + 0x9B1D, 0xF453, + 0x9B1E, 0xF454, + 0x9B20, 0xF455, + 0x9B21, 0xF456, + 0x9B22, 0xF457, + 0x9B24, 0xF458, + 0x9B25, 0xF459, + 0x9B26, 0xF45A, + 0x9B27, 0xF45B, + 0x9B28, 0xF45C, + 0x9B29, 0xF45D, + 0x9B2A, 0xF45E, + 0x9B2B, 0xF45F, + 0x9B2C, 0xF460, + 0x9B2D, 0xF461, + 0x9B2E, 0xF462, + 0x9B30, 0xF463, + 0x9B31, 0xF464, + 0x9B33, 0xF465, + 0x9B34, 0xF466, + 0x9B35, 0xF467, + 0x9B36, 0xF468, + 0x9B37, 0xF469, + 0x9B38, 0xF46A, + 0x9B39, 0xF46B, + 0x9B3A, 0xF46C, + 0x9B3D, 0xF46D, + 0x9B3E, 0xF46E, + 0x9B3F, 0xF46F, + 0x9B40, 0xF470, + 0x9B46, 0xF471, + 0x9B4A, 0xF472, + 0x9B4B, 0xF473, + 0x9B4C, 0xF474, + 0x9B4E, 0xF475, + 0x9B50, 0xF476, + 0x9B52, 0xF477, + 0x9B53, 0xF478, + 0x9B55, 0xF479, + 0x9B56, 0xF47A, + 0x9B57, 0xF47B, + 0x9B58, 0xF47C, + 0x9B59, 0xF47D, + 0x9B5A, 0xF47E, + 0x9B5B, 0xF480, + 0x9B5C, 0xF481, + 0x9B5D, 0xF482, + 0x9B5E, 0xF483, + 0x9B5F, 0xF484, + 0x9B60, 0xF485, + 0x9B61, 0xF486, + 0x9B62, 0xF487, + 0x9B63, 0xF488, + 0x9B64, 0xF489, + 0x9B65, 0xF48A, + 0x9B66, 0xF48B, + 0x9B67, 0xF48C, + 0x9B68, 0xF48D, + 0x9B69, 0xF48E, + 0x9B6A, 0xF48F, + 0x9B6B, 0xF490, + 0x9B6C, 0xF491, + 0x9B6D, 0xF492, + 0x9B6E, 0xF493, + 0x9B6F, 0xF494, + 0x9B70, 0xF495, + 0x9B71, 0xF496, + 0x9B72, 0xF497, + 0x9B73, 0xF498, + 0x9B74, 0xF499, + 0x9B75, 0xF49A, + 0x9B76, 0xF49B, + 0x9B77, 0xF49C, + 0x9B78, 0xF49D, + 0x9B79, 0xF49E, + 0x9B7A, 0xF49F, + 0x9B7B, 0xF4A0, + 0x9B7C, 0xF540, + 0x9B7D, 0xF541, + 0x9B7E, 0xF542, + 0x9B7F, 0xF543, + 0x9B80, 0xF544, + 0x9B81, 0xF545, + 0x9B82, 0xF546, + 0x9B83, 0xF547, + 0x9B84, 0xF548, + 0x9B85, 0xF549, + 0x9B86, 0xF54A, + 0x9B87, 0xF54B, + 0x9B88, 0xF54C, + 0x9B89, 0xF54D, + 0x9B8A, 0xF54E, + 0x9B8B, 0xF54F, + 0x9B8C, 0xF550, + 0x9B8D, 0xF551, + 0x9B8E, 0xF552, + 0x9B8F, 0xF553, + 0x9B90, 0xF554, + 0x9B91, 0xF555, + 0x9B92, 0xF556, + 0x9B93, 0xF557, + 0x9B94, 0xF558, + 0x9B95, 0xF559, + 0x9B96, 0xF55A, + 0x9B97, 0xF55B, + 0x9B98, 0xF55C, + 0x9B99, 0xF55D, + 0x9B9A, 0xF55E, + 0x9B9B, 0xF55F, + 0x9B9C, 0xF560, + 0x9B9D, 0xF561, + 0x9B9E, 0xF562, + 0x9B9F, 0xF563, + 0x9BA0, 0xF564, + 0x9BA1, 0xF565, + 0x9BA2, 0xF566, + 0x9BA3, 0xF567, + 0x9BA4, 0xF568, + 0x9BA5, 0xF569, + 0x9BA6, 0xF56A, + 0x9BA7, 0xF56B, + 0x9BA8, 0xF56C, + 0x9BA9, 0xF56D, + 0x9BAA, 0xF56E, + 0x9BAB, 0xF56F, + 0x9BAC, 0xF570, + 0x9BAD, 0xF571, + 0x9BAE, 0xF572, + 0x9BAF, 0xF573, + 0x9BB0, 0xF574, + 0x9BB1, 0xF575, + 0x9BB2, 0xF576, + 0x9BB3, 0xF577, + 0x9BB4, 0xF578, + 0x9BB5, 0xF579, + 0x9BB6, 0xF57A, + 0x9BB7, 0xF57B, + 0x9BB8, 0xF57C, + 0x9BB9, 0xF57D, + 0x9BBA, 0xF57E, + 0x9BBB, 0xF580, + 0x9BBC, 0xF581, + 0x9BBD, 0xF582, + 0x9BBE, 0xF583, + 0x9BBF, 0xF584, + 0x9BC0, 0xF585, + 0x9BC1, 0xF586, + 0x9BC2, 0xF587, + 0x9BC3, 0xF588, + 0x9BC4, 0xF589, + 0x9BC5, 0xF58A, + 0x9BC6, 0xF58B, + 0x9BC7, 0xF58C, + 0x9BC8, 0xF58D, + 0x9BC9, 0xF58E, + 0x9BCA, 0xF58F, + 0x9BCB, 0xF590, + 0x9BCC, 0xF591, + 0x9BCD, 0xF592, + 0x9BCE, 0xF593, + 0x9BCF, 0xF594, + 0x9BD0, 0xF595, + 0x9BD1, 0xF596, + 0x9BD2, 0xF597, + 0x9BD3, 0xF598, + 0x9BD4, 0xF599, + 0x9BD5, 0xF59A, + 0x9BD6, 0xF59B, + 0x9BD7, 0xF59C, + 0x9BD8, 0xF59D, + 0x9BD9, 0xF59E, + 0x9BDA, 0xF59F, + 0x9BDB, 0xF5A0, + 0x9BDC, 0xF640, + 0x9BDD, 0xF641, + 0x9BDE, 0xF642, + 0x9BDF, 0xF643, + 0x9BE0, 0xF644, + 0x9BE1, 0xF645, + 0x9BE2, 0xF646, + 0x9BE3, 0xF647, + 0x9BE4, 0xF648, + 0x9BE5, 0xF649, + 0x9BE6, 0xF64A, + 0x9BE7, 0xF64B, + 0x9BE8, 0xF64C, + 0x9BE9, 0xF64D, + 0x9BEA, 0xF64E, + 0x9BEB, 0xF64F, + 0x9BEC, 0xF650, + 0x9BED, 0xF651, + 0x9BEE, 0xF652, + 0x9BEF, 0xF653, + 0x9BF0, 0xF654, + 0x9BF1, 0xF655, + 0x9BF2, 0xF656, + 0x9BF3, 0xF657, + 0x9BF4, 0xF658, + 0x9BF5, 0xF659, + 0x9BF6, 0xF65A, + 0x9BF7, 0xF65B, + 0x9BF8, 0xF65C, + 0x9BF9, 0xF65D, + 0x9BFA, 0xF65E, + 0x9BFB, 0xF65F, + 0x9BFC, 0xF660, + 0x9BFD, 0xF661, + 0x9BFE, 0xF662, + 0x9BFF, 0xF663, + 0x9C00, 0xF664, + 0x9C01, 0xF665, + 0x9C02, 0xF666, + 0x9C03, 0xF667, + 0x9C04, 0xF668, + 0x9C05, 0xF669, + 0x9C06, 0xF66A, + 0x9C07, 0xF66B, + 0x9C08, 0xF66C, + 0x9C09, 0xF66D, + 0x9C0A, 0xF66E, + 0x9C0B, 0xF66F, + 0x9C0C, 0xF670, + 0x9C0D, 0xF671, + 0x9C0E, 0xF672, + 0x9C0F, 0xF673, + 0x9C10, 0xF674, + 0x9C11, 0xF675, + 0x9C12, 0xF676, + 0x9C13, 0xF677, + 0x9C14, 0xF678, + 0x9C15, 0xF679, + 0x9C16, 0xF67A, + 0x9C17, 0xF67B, + 0x9C18, 0xF67C, + 0x9C19, 0xF67D, + 0x9C1A, 0xF67E, + 0x9C1B, 0xF680, + 0x9C1C, 0xF681, + 0x9C1D, 0xF682, + 0x9C1E, 0xF683, + 0x9C1F, 0xF684, + 0x9C20, 0xF685, + 0x9C21, 0xF686, + 0x9C22, 0xF687, + 0x9C23, 0xF688, + 0x9C24, 0xF689, + 0x9C25, 0xF68A, + 0x9C26, 0xF68B, + 0x9C27, 0xF68C, + 0x9C28, 0xF68D, + 0x9C29, 0xF68E, + 0x9C2A, 0xF68F, + 0x9C2B, 0xF690, + 0x9C2C, 0xF691, + 0x9C2D, 0xF692, + 0x9C2E, 0xF693, + 0x9C2F, 0xF694, + 0x9C30, 0xF695, + 0x9C31, 0xF696, + 0x9C32, 0xF697, + 0x9C33, 0xF698, + 0x9C34, 0xF699, + 0x9C35, 0xF69A, + 0x9C36, 0xF69B, + 0x9C37, 0xF69C, + 0x9C38, 0xF69D, + 0x9C39, 0xF69E, + 0x9C3A, 0xF69F, + 0x9C3B, 0xF6A0, + 0x9C3C, 0xF740, + 0x9C3D, 0xF741, + 0x9C3E, 0xF742, + 0x9C3F, 0xF743, + 0x9C40, 0xF744, + 0x9C41, 0xF745, + 0x9C42, 0xF746, + 0x9C43, 0xF747, + 0x9C44, 0xF748, + 0x9C45, 0xF749, + 0x9C46, 0xF74A, + 0x9C47, 0xF74B, + 0x9C48, 0xF74C, + 0x9C49, 0xF74D, + 0x9C4A, 0xF74E, + 0x9C4B, 0xF74F, + 0x9C4C, 0xF750, + 0x9C4D, 0xF751, + 0x9C4E, 0xF752, + 0x9C4F, 0xF753, + 0x9C50, 0xF754, + 0x9C51, 0xF755, + 0x9C52, 0xF756, + 0x9C53, 0xF757, + 0x9C54, 0xF758, + 0x9C55, 0xF759, + 0x9C56, 0xF75A, + 0x9C57, 0xF75B, + 0x9C58, 0xF75C, + 0x9C59, 0xF75D, + 0x9C5A, 0xF75E, + 0x9C5B, 0xF75F, + 0x9C5C, 0xF760, + 0x9C5D, 0xF761, + 0x9C5E, 0xF762, + 0x9C5F, 0xF763, + 0x9C60, 0xF764, + 0x9C61, 0xF765, + 0x9C62, 0xF766, + 0x9C63, 0xF767, + 0x9C64, 0xF768, + 0x9C65, 0xF769, + 0x9C66, 0xF76A, + 0x9C67, 0xF76B, + 0x9C68, 0xF76C, + 0x9C69, 0xF76D, + 0x9C6A, 0xF76E, + 0x9C6B, 0xF76F, + 0x9C6C, 0xF770, + 0x9C6D, 0xF771, + 0x9C6E, 0xF772, + 0x9C6F, 0xF773, + 0x9C70, 0xF774, + 0x9C71, 0xF775, + 0x9C72, 0xF776, + 0x9C73, 0xF777, + 0x9C74, 0xF778, + 0x9C75, 0xF779, + 0x9C76, 0xF77A, + 0x9C77, 0xF77B, + 0x9C78, 0xF77C, + 0x9C79, 0xF77D, + 0x9C7A, 0xF77E, + 0x9C7B, 0xF780, + 0x9C7D, 0xF781, + 0x9C7E, 0xF782, + 0x9C80, 0xF783, + 0x9C83, 0xF784, + 0x9C84, 0xF785, + 0x9C89, 0xF786, + 0x9C8A, 0xF787, + 0x9C8C, 0xF788, + 0x9C8F, 0xF789, + 0x9C93, 0xF78A, + 0x9C96, 0xF78B, + 0x9C97, 0xF78C, + 0x9C98, 0xF78D, + 0x9C99, 0xF78E, + 0x9C9D, 0xF78F, + 0x9CAA, 0xF790, + 0x9CAC, 0xF791, + 0x9CAF, 0xF792, + 0x9CB9, 0xF793, + 0x9CBE, 0xF794, + 0x9CBF, 0xF795, + 0x9CC0, 0xF796, + 0x9CC1, 0xF797, + 0x9CC2, 0xF798, + 0x9CC8, 0xF799, + 0x9CC9, 0xF79A, + 0x9CD1, 0xF79B, + 0x9CD2, 0xF79C, + 0x9CDA, 0xF79D, + 0x9CDB, 0xF79E, + 0x9CE0, 0xF79F, + 0x9CE1, 0xF7A0, + 0x9CE3, 0xF840, + 0x9CE4, 0xF841, + 0x9CE5, 0xF842, + 0x9CE6, 0xF843, + 0x9CE7, 0xF844, + 0x9CE8, 0xF845, + 0x9CE9, 0xF846, + 0x9CEA, 0xF847, + 0x9CEB, 0xF848, + 0x9CEC, 0xF849, + 0x9CED, 0xF84A, + 0x9CEE, 0xF84B, + 0x9CEF, 0xF84C, + 0x9CF0, 0xF84D, + 0x9CF1, 0xF84E, + 0x9CF2, 0xF84F, + 0x9CF3, 0xF850, + 0x9CF4, 0xF851, + 0x9CF5, 0xF852, + 0x9CF6, 0xF853, + 0x9CF7, 0xF854, + 0x9CF8, 0xF855, + 0x9CF9, 0xF856, + 0x9CFA, 0xF857, + 0x9CFB, 0xF858, + 0x9CFC, 0xF859, + 0x9CFD, 0xF85A, + 0x9CFE, 0xF85B, + 0x9CFF, 0xF85C, + 0x9D00, 0xF85D, + 0x9D01, 0xF85E, + 0x9D02, 0xF85F, + 0x9D03, 0xF860, + 0x9D04, 0xF861, + 0x9D05, 0xF862, + 0x9D06, 0xF863, + 0x9D07, 0xF864, + 0x9D08, 0xF865, + 0x9D09, 0xF866, + 0x9D0A, 0xF867, + 0x9D0B, 0xF868, + 0x9D0C, 0xF869, + 0x9D0D, 0xF86A, + 0x9D0E, 0xF86B, + 0x9D0F, 0xF86C, + 0x9D10, 0xF86D, + 0x9D11, 0xF86E, + 0x9D12, 0xF86F, + 0x9D13, 0xF870, + 0x9D14, 0xF871, + 0x9D15, 0xF872, + 0x9D16, 0xF873, + 0x9D17, 0xF874, + 0x9D18, 0xF875, + 0x9D19, 0xF876, + 0x9D1A, 0xF877, + 0x9D1B, 0xF878, + 0x9D1C, 0xF879, + 0x9D1D, 0xF87A, + 0x9D1E, 0xF87B, + 0x9D1F, 0xF87C, + 0x9D20, 0xF87D, + 0x9D21, 0xF87E, + 0x9D22, 0xF880, + 0x9D23, 0xF881, + 0x9D24, 0xF882, + 0x9D25, 0xF883, + 0x9D26, 0xF884, + 0x9D27, 0xF885, + 0x9D28, 0xF886, + 0x9D29, 0xF887, + 0x9D2A, 0xF888, + 0x9D2B, 0xF889, + 0x9D2C, 0xF88A, + 0x9D2D, 0xF88B, + 0x9D2E, 0xF88C, + 0x9D2F, 0xF88D, + 0x9D30, 0xF88E, + 0x9D31, 0xF88F, + 0x9D32, 0xF890, + 0x9D33, 0xF891, + 0x9D34, 0xF892, + 0x9D35, 0xF893, + 0x9D36, 0xF894, + 0x9D37, 0xF895, + 0x9D38, 0xF896, + 0x9D39, 0xF897, + 0x9D3A, 0xF898, + 0x9D3B, 0xF899, + 0x9D3C, 0xF89A, + 0x9D3D, 0xF89B, + 0x9D3E, 0xF89C, + 0x9D3F, 0xF89D, + 0x9D40, 0xF89E, + 0x9D41, 0xF89F, + 0x9D42, 0xF8A0, + 0x9D43, 0xF940, + 0x9D44, 0xF941, + 0x9D45, 0xF942, + 0x9D46, 0xF943, + 0x9D47, 0xF944, + 0x9D48, 0xF945, + 0x9D49, 0xF946, + 0x9D4A, 0xF947, + 0x9D4B, 0xF948, + 0x9D4C, 0xF949, + 0x9D4D, 0xF94A, + 0x9D4E, 0xF94B, + 0x9D4F, 0xF94C, + 0x9D50, 0xF94D, + 0x9D51, 0xF94E, + 0x9D52, 0xF94F, + 0x9D53, 0xF950, + 0x9D54, 0xF951, + 0x9D55, 0xF952, + 0x9D56, 0xF953, + 0x9D57, 0xF954, + 0x9D58, 0xF955, + 0x9D59, 0xF956, + 0x9D5A, 0xF957, + 0x9D5B, 0xF958, + 0x9D5C, 0xF959, + 0x9D5D, 0xF95A, + 0x9D5E, 0xF95B, + 0x9D5F, 0xF95C, + 0x9D60, 0xF95D, + 0x9D61, 0xF95E, + 0x9D62, 0xF95F, + 0x9D63, 0xF960, + 0x9D64, 0xF961, + 0x9D65, 0xF962, + 0x9D66, 0xF963, + 0x9D67, 0xF964, + 0x9D68, 0xF965, + 0x9D69, 0xF966, + 0x9D6A, 0xF967, + 0x9D6B, 0xF968, + 0x9D6C, 0xF969, + 0x9D6D, 0xF96A, + 0x9D6E, 0xF96B, + 0x9D6F, 0xF96C, + 0x9D70, 0xF96D, + 0x9D71, 0xF96E, + 0x9D72, 0xF96F, + 0x9D73, 0xF970, + 0x9D74, 0xF971, + 0x9D75, 0xF972, + 0x9D76, 0xF973, + 0x9D77, 0xF974, + 0x9D78, 0xF975, + 0x9D79, 0xF976, + 0x9D7A, 0xF977, + 0x9D7B, 0xF978, + 0x9D7C, 0xF979, + 0x9D7D, 0xF97A, + 0x9D7E, 0xF97B, + 0x9D7F, 0xF97C, + 0x9D80, 0xF97D, + 0x9D81, 0xF97E, + 0x9D82, 0xF980, + 0x9D83, 0xF981, + 0x9D84, 0xF982, + 0x9D85, 0xF983, + 0x9D86, 0xF984, + 0x9D87, 0xF985, + 0x9D88, 0xF986, + 0x9D89, 0xF987, + 0x9D8A, 0xF988, + 0x9D8B, 0xF989, + 0x9D8C, 0xF98A, + 0x9D8D, 0xF98B, + 0x9D8E, 0xF98C, + 0x9D8F, 0xF98D, + 0x9D90, 0xF98E, + 0x9D91, 0xF98F, + 0x9D92, 0xF990, + 0x9D93, 0xF991, + 0x9D94, 0xF992, + 0x9D95, 0xF993, + 0x9D96, 0xF994, + 0x9D97, 0xF995, + 0x9D98, 0xF996, + 0x9D99, 0xF997, + 0x9D9A, 0xF998, + 0x9D9B, 0xF999, + 0x9D9C, 0xF99A, + 0x9D9D, 0xF99B, + 0x9D9E, 0xF99C, + 0x9D9F, 0xF99D, + 0x9DA0, 0xF99E, + 0x9DA1, 0xF99F, + 0x9DA2, 0xF9A0, + 0x9DA3, 0xFA40, + 0x9DA4, 0xFA41, + 0x9DA5, 0xFA42, + 0x9DA6, 0xFA43, + 0x9DA7, 0xFA44, + 0x9DA8, 0xFA45, + 0x9DA9, 0xFA46, + 0x9DAA, 0xFA47, + 0x9DAB, 0xFA48, + 0x9DAC, 0xFA49, + 0x9DAD, 0xFA4A, + 0x9DAE, 0xFA4B, + 0x9DAF, 0xFA4C, + 0x9DB0, 0xFA4D, + 0x9DB1, 0xFA4E, + 0x9DB2, 0xFA4F, + 0x9DB3, 0xFA50, + 0x9DB4, 0xFA51, + 0x9DB5, 0xFA52, + 0x9DB6, 0xFA53, + 0x9DB7, 0xFA54, + 0x9DB8, 0xFA55, + 0x9DB9, 0xFA56, + 0x9DBA, 0xFA57, + 0x9DBB, 0xFA58, + 0x9DBC, 0xFA59, + 0x9DBD, 0xFA5A, + 0x9DBE, 0xFA5B, + 0x9DBF, 0xFA5C, + 0x9DC0, 0xFA5D, + 0x9DC1, 0xFA5E, + 0x9DC2, 0xFA5F, + 0x9DC3, 0xFA60, + 0x9DC4, 0xFA61, + 0x9DC5, 0xFA62, + 0x9DC6, 0xFA63, + 0x9DC7, 0xFA64, + 0x9DC8, 0xFA65, + 0x9DC9, 0xFA66, + 0x9DCA, 0xFA67, + 0x9DCB, 0xFA68, + 0x9DCC, 0xFA69, + 0x9DCD, 0xFA6A, + 0x9DCE, 0xFA6B, + 0x9DCF, 0xFA6C, + 0x9DD0, 0xFA6D, + 0x9DD1, 0xFA6E, + 0x9DD2, 0xFA6F, + 0x9DD3, 0xFA70, + 0x9DD4, 0xFA71, + 0x9DD5, 0xFA72, + 0x9DD6, 0xFA73, + 0x9DD7, 0xFA74, + 0x9DD8, 0xFA75, + 0x9DD9, 0xFA76, + 0x9DDA, 0xFA77, + 0x9DDB, 0xFA78, + 0x9DDC, 0xFA79, + 0x9DDD, 0xFA7A, + 0x9DDE, 0xFA7B, + 0x9DDF, 0xFA7C, + 0x9DE0, 0xFA7D, + 0x9DE1, 0xFA7E, + 0x9DE2, 0xFA80, + 0x9DE3, 0xFA81, + 0x9DE4, 0xFA82, + 0x9DE5, 0xFA83, + 0x9DE6, 0xFA84, + 0x9DE7, 0xFA85, + 0x9DE8, 0xFA86, + 0x9DE9, 0xFA87, + 0x9DEA, 0xFA88, + 0x9DEB, 0xFA89, + 0x9DEC, 0xFA8A, + 0x9DED, 0xFA8B, + 0x9DEE, 0xFA8C, + 0x9DEF, 0xFA8D, + 0x9DF0, 0xFA8E, + 0x9DF1, 0xFA8F, + 0x9DF2, 0xFA90, + 0x9DF3, 0xFA91, + 0x9DF4, 0xFA92, + 0x9DF5, 0xFA93, + 0x9DF6, 0xFA94, + 0x9DF7, 0xFA95, + 0x9DF8, 0xFA96, + 0x9DF9, 0xFA97, + 0x9DFA, 0xFA98, + 0x9DFB, 0xFA99, + 0x9DFC, 0xFA9A, + 0x9DFD, 0xFA9B, + 0x9DFE, 0xFA9C, + 0x9DFF, 0xFA9D, + 0x9E00, 0xFA9E, + 0x9E01, 0xFA9F, + 0x9E02, 0xFAA0, + 0x9E03, 0xFB40, + 0x9E04, 0xFB41, + 0x9E05, 0xFB42, + 0x9E06, 0xFB43, + 0x9E07, 0xFB44, + 0x9E08, 0xFB45, + 0x9E09, 0xFB46, + 0x9E0A, 0xFB47, + 0x9E0B, 0xFB48, + 0x9E0C, 0xFB49, + 0x9E0D, 0xFB4A, + 0x9E0E, 0xFB4B, + 0x9E0F, 0xFB4C, + 0x9E10, 0xFB4D, + 0x9E11, 0xFB4E, + 0x9E12, 0xFB4F, + 0x9E13, 0xFB50, + 0x9E14, 0xFB51, + 0x9E15, 0xFB52, + 0x9E16, 0xFB53, + 0x9E17, 0xFB54, + 0x9E18, 0xFB55, + 0x9E19, 0xFB56, + 0x9E1A, 0xFB57, + 0x9E1B, 0xFB58, + 0x9E1C, 0xFB59, + 0x9E1D, 0xFB5A, + 0x9E1E, 0xFB5B, + 0x9E24, 0xFB5C, + 0x9E27, 0xFB5D, + 0x9E2E, 0xFB5E, + 0x9E30, 0xFB5F, + 0x9E34, 0xFB60, + 0x9E3B, 0xFB61, + 0x9E3C, 0xFB62, + 0x9E40, 0xFB63, + 0x9E4D, 0xFB64, + 0x9E50, 0xFB65, + 0x9E52, 0xFB66, + 0x9E53, 0xFB67, + 0x9E54, 0xFB68, + 0x9E56, 0xFB69, + 0x9E59, 0xFB6A, + 0x9E5D, 0xFB6B, + 0x9E5F, 0xFB6C, + 0x9E60, 0xFB6D, + 0x9E61, 0xFB6E, + 0x9E62, 0xFB6F, + 0x9E65, 0xFB70, + 0x9E6E, 0xFB71, + 0x9E6F, 0xFB72, + 0x9E72, 0xFB73, + 0x9E74, 0xFB74, + 0x9E75, 0xFB75, + 0x9E76, 0xFB76, + 0x9E77, 0xFB77, + 0x9E78, 0xFB78, + 0x9E79, 0xFB79, + 0x9E7A, 0xFB7A, + 0x9E7B, 0xFB7B, + 0x9E7C, 0xFB7C, + 0x9E7D, 0xFB7D, + 0x9E80, 0xFB7E, + 0x9E81, 0xFB80, + 0x9E83, 0xFB81, + 0x9E84, 0xFB82, + 0x9E85, 0xFB83, + 0x9E86, 0xFB84, + 0x9E89, 0xFB85, + 0x9E8A, 0xFB86, + 0x9E8C, 0xFB87, + 0x9E8D, 0xFB88, + 0x9E8E, 0xFB89, + 0x9E8F, 0xFB8A, + 0x9E90, 0xFB8B, + 0x9E91, 0xFB8C, + 0x9E94, 0xFB8D, + 0x9E95, 0xFB8E, + 0x9E96, 0xFB8F, + 0x9E97, 0xFB90, + 0x9E98, 0xFB91, + 0x9E99, 0xFB92, + 0x9E9A, 0xFB93, + 0x9E9B, 0xFB94, + 0x9E9C, 0xFB95, + 0x9E9E, 0xFB96, + 0x9EA0, 0xFB97, + 0x9EA1, 0xFB98, + 0x9EA2, 0xFB99, + 0x9EA3, 0xFB9A, + 0x9EA4, 0xFB9B, + 0x9EA5, 0xFB9C, + 0x9EA7, 0xFB9D, + 0x9EA8, 0xFB9E, + 0x9EA9, 0xFB9F, + 0x9EAA, 0xFBA0, + 0x9EAB, 0xFC40, + 0x9EAC, 0xFC41, + 0x9EAD, 0xFC42, + 0x9EAE, 0xFC43, + 0x9EAF, 0xFC44, + 0x9EB0, 0xFC45, + 0x9EB1, 0xFC46, + 0x9EB2, 0xFC47, + 0x9EB3, 0xFC48, + 0x9EB5, 0xFC49, + 0x9EB6, 0xFC4A, + 0x9EB7, 0xFC4B, + 0x9EB9, 0xFC4C, + 0x9EBA, 0xFC4D, + 0x9EBC, 0xFC4E, + 0x9EBF, 0xFC4F, + 0x9EC0, 0xFC50, + 0x9EC1, 0xFC51, + 0x9EC2, 0xFC52, + 0x9EC3, 0xFC53, + 0x9EC5, 0xFC54, + 0x9EC6, 0xFC55, + 0x9EC7, 0xFC56, + 0x9EC8, 0xFC57, + 0x9ECA, 0xFC58, + 0x9ECB, 0xFC59, + 0x9ECC, 0xFC5A, + 0x9ED0, 0xFC5B, + 0x9ED2, 0xFC5C, + 0x9ED3, 0xFC5D, + 0x9ED5, 0xFC5E, + 0x9ED6, 0xFC5F, + 0x9ED7, 0xFC60, + 0x9ED9, 0xFC61, + 0x9EDA, 0xFC62, + 0x9EDE, 0xFC63, + 0x9EE1, 0xFC64, + 0x9EE3, 0xFC65, + 0x9EE4, 0xFC66, + 0x9EE6, 0xFC67, + 0x9EE8, 0xFC68, + 0x9EEB, 0xFC69, + 0x9EEC, 0xFC6A, + 0x9EED, 0xFC6B, + 0x9EEE, 0xFC6C, + 0x9EF0, 0xFC6D, + 0x9EF1, 0xFC6E, + 0x9EF2, 0xFC6F, + 0x9EF3, 0xFC70, + 0x9EF4, 0xFC71, + 0x9EF5, 0xFC72, + 0x9EF6, 0xFC73, + 0x9EF7, 0xFC74, + 0x9EF8, 0xFC75, + 0x9EFA, 0xFC76, + 0x9EFD, 0xFC77, + 0x9EFF, 0xFC78, + 0x9F00, 0xFC79, + 0x9F01, 0xFC7A, + 0x9F02, 0xFC7B, + 0x9F03, 0xFC7C, + 0x9F04, 0xFC7D, + 0x9F05, 0xFC7E, + 0x9F06, 0xFC80, + 0x9F07, 0xFC81, + 0x9F08, 0xFC82, + 0x9F09, 0xFC83, + 0x9F0A, 0xFC84, + 0x9F0C, 0xFC85, + 0x9F0F, 0xFC86, + 0x9F11, 0xFC87, + 0x9F12, 0xFC88, + 0x9F14, 0xFC89, + 0x9F15, 0xFC8A, + 0x9F16, 0xFC8B, + 0x9F18, 0xFC8C, + 0x9F1A, 0xFC8D, + 0x9F1B, 0xFC8E, + 0x9F1C, 0xFC8F, + 0x9F1D, 0xFC90, + 0x9F1E, 0xFC91, + 0x9F1F, 0xFC92, + 0x9F21, 0xFC93, + 0x9F23, 0xFC94, + 0x9F24, 0xFC95, + 0x9F25, 0xFC96, + 0x9F26, 0xFC97, + 0x9F27, 0xFC98, + 0x9F28, 0xFC99, + 0x9F29, 0xFC9A, + 0x9F2A, 0xFC9B, + 0x9F2B, 0xFC9C, + 0x9F2D, 0xFC9D, + 0x9F2E, 0xFC9E, + 0x9F30, 0xFC9F, + 0x9F31, 0xFCA0, + 0x9F32, 0xFD40, + 0x9F33, 0xFD41, + 0x9F34, 0xFD42, + 0x9F35, 0xFD43, + 0x9F36, 0xFD44, + 0x9F38, 0xFD45, + 0x9F3A, 0xFD46, + 0x9F3C, 0xFD47, + 0x9F3F, 0xFD48, + 0x9F40, 0xFD49, + 0x9F41, 0xFD4A, + 0x9F42, 0xFD4B, + 0x9F43, 0xFD4C, + 0x9F45, 0xFD4D, + 0x9F46, 0xFD4E, + 0x9F47, 0xFD4F, + 0x9F48, 0xFD50, + 0x9F49, 0xFD51, + 0x9F4A, 0xFD52, + 0x9F4B, 0xFD53, + 0x9F4C, 0xFD54, + 0x9F4D, 0xFD55, + 0x9F4E, 0xFD56, + 0x9F4F, 0xFD57, + 0x9F52, 0xFD58, + 0x9F53, 0xFD59, + 0x9F54, 0xFD5A, + 0x9F55, 0xFD5B, + 0x9F56, 0xFD5C, + 0x9F57, 0xFD5D, + 0x9F58, 0xFD5E, + 0x9F59, 0xFD5F, + 0x9F5A, 0xFD60, + 0x9F5B, 0xFD61, + 0x9F5C, 0xFD62, + 0x9F5D, 0xFD63, + 0x9F5E, 0xFD64, + 0x9F5F, 0xFD65, + 0x9F60, 0xFD66, + 0x9F61, 0xFD67, + 0x9F62, 0xFD68, + 0x9F63, 0xFD69, + 0x9F64, 0xFD6A, + 0x9F65, 0xFD6B, + 0x9F66, 0xFD6C, + 0x9F67, 0xFD6D, + 0x9F68, 0xFD6E, + 0x9F69, 0xFD6F, + 0x9F6A, 0xFD70, + 0x9F6B, 0xFD71, + 0x9F6C, 0xFD72, + 0x9F6D, 0xFD73, + 0x9F6E, 0xFD74, + 0x9F6F, 0xFD75, + 0x9F70, 0xFD76, + 0x9F71, 0xFD77, + 0x9F72, 0xFD78, + 0x9F73, 0xFD79, + 0x9F74, 0xFD7A, + 0x9F75, 0xFD7B, + 0x9F76, 0xFD7C, + 0x9F77, 0xFD7D, + 0x9F78, 0xFD7E, + 0x9F79, 0xFD80, + 0x9F7A, 0xFD81, + 0x9F7B, 0xFD82, + 0x9F7C, 0xFD83, + 0x9F7D, 0xFD84, + 0x9F7E, 0xFD85, + 0x9F81, 0xFD86, + 0x9F82, 0xFD87, + 0x9F8D, 0xFD88, + 0x9F8E, 0xFD89, + 0x9F8F, 0xFD8A, + 0x9F90, 0xFD8B, + 0x9F91, 0xFD8C, + 0x9F92, 0xFD8D, + 0x9F93, 0xFD8E, + 0x9F94, 0xFD8F, + 0x9F95, 0xFD90, + 0x9F96, 0xFD91, + 0x9F97, 0xFD92, + 0x9F98, 0xFD93, + 0x9F9C, 0xFD94, + 0x9F9D, 0xFD95, + 0x9F9E, 0xFD96, + 0x9FA1, 0xFD97, + 0x9FA2, 0xFD98, + 0x9FA3, 0xFD99, + 0x9FA4, 0xFD9A, + 0x9FA5, 0xFD9B, + 0xE000, 0xAAA1, + 0xE001, 0xAAA2, + 0xE002, 0xAAA3, + 0xE003, 0xAAA4, + 0xE004, 0xAAA5, + 0xE005, 0xAAA6, + 0xE006, 0xAAA7, + 0xE007, 0xAAA8, + 0xE008, 0xAAA9, + 0xE009, 0xAAAA, + 0xE00A, 0xAAAB, + 0xE00B, 0xAAAC, + 0xE00C, 0xAAAD, + 0xE00D, 0xAAAE, + 0xE00E, 0xAAAF, + 0xE00F, 0xAAB0, + 0xE010, 0xAAB1, + 0xE011, 0xAAB2, + 0xE012, 0xAAB3, + 0xE013, 0xAAB4, + 0xE014, 0xAAB5, + 0xE015, 0xAAB6, + 0xE016, 0xAAB7, + 0xE017, 0xAAB8, + 0xE018, 0xAAB9, + 0xE019, 0xAABA, + 0xE01A, 0xAABB, + 0xE01B, 0xAABC, + 0xE01C, 0xAABD, + 0xE01D, 0xAABE, + 0xE01E, 0xAABF, + 0xE01F, 0xAAC0, + 0xE020, 0xAAC1, + 0xE021, 0xAAC2, + 0xE022, 0xAAC3, + 0xE023, 0xAAC4, + 0xE024, 0xAAC5, + 0xE025, 0xAAC6, + 0xE026, 0xAAC7, + 0xE027, 0xAAC8, + 0xE028, 0xAAC9, + 0xE029, 0xAACA, + 0xE02A, 0xAACB, + 0xE02B, 0xAACC, + 0xE02C, 0xAACD, + 0xE02D, 0xAACE, + 0xE02E, 0xAACF, + 0xE02F, 0xAAD0, + 0xE030, 0xAAD1, + 0xE031, 0xAAD2, + 0xE032, 0xAAD3, + 0xE033, 0xAAD4, + 0xE034, 0xAAD5, + 0xE035, 0xAAD6, + 0xE036, 0xAAD7, + 0xE037, 0xAAD8, + 0xE038, 0xAAD9, + 0xE039, 0xAADA, + 0xE03A, 0xAADB, + 0xE03B, 0xAADC, + 0xE03C, 0xAADD, + 0xE03D, 0xAADE, + 0xE03E, 0xAADF, + 0xE03F, 0xAAE0, + 0xE040, 0xAAE1, + 0xE041, 0xAAE2, + 0xE042, 0xAAE3, + 0xE043, 0xAAE4, + 0xE044, 0xAAE5, + 0xE045, 0xAAE6, + 0xE046, 0xAAE7, + 0xE047, 0xAAE8, + 0xE048, 0xAAE9, + 0xE049, 0xAAEA, + 0xE04A, 0xAAEB, + 0xE04B, 0xAAEC, + 0xE04C, 0xAAED, + 0xE04D, 0xAAEE, + 0xE04E, 0xAAEF, + 0xE04F, 0xAAF0, + 0xE050, 0xAAF1, + 0xE051, 0xAAF2, + 0xE052, 0xAAF3, + 0xE053, 0xAAF4, + 0xE054, 0xAAF5, + 0xE055, 0xAAF6, + 0xE056, 0xAAF7, + 0xE057, 0xAAF8, + 0xE058, 0xAAF9, + 0xE059, 0xAAFA, + 0xE05A, 0xAAFB, + 0xE05B, 0xAAFC, + 0xE05C, 0xAAFD, + 0xE05D, 0xAAFE, + 0xE05E, 0xABA1, + 0xE05F, 0xABA2, + 0xE060, 0xABA3, + 0xE061, 0xABA4, + 0xE062, 0xABA5, + 0xE063, 0xABA6, + 0xE064, 0xABA7, + 0xE065, 0xABA8, + 0xE066, 0xABA9, + 0xE067, 0xABAA, + 0xE068, 0xABAB, + 0xE069, 0xABAC, + 0xE06A, 0xABAD, + 0xE06B, 0xABAE, + 0xE06C, 0xABAF, + 0xE06D, 0xABB0, + 0xE06E, 0xABB1, + 0xE06F, 0xABB2, + 0xE070, 0xABB3, + 0xE071, 0xABB4, + 0xE072, 0xABB5, + 0xE073, 0xABB6, + 0xE074, 0xABB7, + 0xE075, 0xABB8, + 0xE076, 0xABB9, + 0xE077, 0xABBA, + 0xE078, 0xABBB, + 0xE079, 0xABBC, + 0xE07A, 0xABBD, + 0xE07B, 0xABBE, + 0xE07C, 0xABBF, + 0xE07D, 0xABC0, + 0xE07E, 0xABC1, + 0xE07F, 0xABC2, + 0xE080, 0xABC3, + 0xE081, 0xABC4, + 0xE082, 0xABC5, + 0xE083, 0xABC6, + 0xE084, 0xABC7, + 0xE085, 0xABC8, + 0xE086, 0xABC9, + 0xE087, 0xABCA, + 0xE088, 0xABCB, + 0xE089, 0xABCC, + 0xE08A, 0xABCD, + 0xE08B, 0xABCE, + 0xE08C, 0xABCF, + 0xE08D, 0xABD0, + 0xE08E, 0xABD1, + 0xE08F, 0xABD2, + 0xE090, 0xABD3, + 0xE091, 0xABD4, + 0xE092, 0xABD5, + 0xE093, 0xABD6, + 0xE094, 0xABD7, + 0xE095, 0xABD8, + 0xE096, 0xABD9, + 0xE097, 0xABDA, + 0xE098, 0xABDB, + 0xE099, 0xABDC, + 0xE09A, 0xABDD, + 0xE09B, 0xABDE, + 0xE09C, 0xABDF, + 0xE09D, 0xABE0, + 0xE09E, 0xABE1, + 0xE09F, 0xABE2, + 0xE0A0, 0xABE3, + 0xE0A1, 0xABE4, + 0xE0A2, 0xABE5, + 0xE0A3, 0xABE6, + 0xE0A4, 0xABE7, + 0xE0A5, 0xABE8, + 0xE0A6, 0xABE9, + 0xE0A7, 0xABEA, + 0xE0A8, 0xABEB, + 0xE0A9, 0xABEC, + 0xE0AA, 0xABED, + 0xE0AB, 0xABEE, + 0xE0AC, 0xABEF, + 0xE0AD, 0xABF0, + 0xE0AE, 0xABF1, + 0xE0AF, 0xABF2, + 0xE0B0, 0xABF3, + 0xE0B1, 0xABF4, + 0xE0B2, 0xABF5, + 0xE0B3, 0xABF6, + 0xE0B4, 0xABF7, + 0xE0B5, 0xABF8, + 0xE0B6, 0xABF9, + 0xE0B7, 0xABFA, + 0xE0B8, 0xABFB, + 0xE0B9, 0xABFC, + 0xE0BA, 0xABFD, + 0xE0BB, 0xABFE, + 0xE0BC, 0xACA1, + 0xE0BD, 0xACA2, + 0xE0BE, 0xACA3, + 0xE0BF, 0xACA4, + 0xE0C0, 0xACA5, + 0xE0C1, 0xACA6, + 0xE0C2, 0xACA7, + 0xE0C3, 0xACA8, + 0xE0C4, 0xACA9, + 0xE0C5, 0xACAA, + 0xE0C6, 0xACAB, + 0xE0C7, 0xACAC, + 0xE0C8, 0xACAD, + 0xE0C9, 0xACAE, + 0xE0CA, 0xACAF, + 0xE0CB, 0xACB0, + 0xE0CC, 0xACB1, + 0xE0CD, 0xACB2, + 0xE0CE, 0xACB3, + 0xE0CF, 0xACB4, + 0xE0D0, 0xACB5, + 0xE0D1, 0xACB6, + 0xE0D2, 0xACB7, + 0xE0D3, 0xACB8, + 0xE0D4, 0xACB9, + 0xE0D5, 0xACBA, + 0xE0D6, 0xACBB, + 0xE0D7, 0xACBC, + 0xE0D8, 0xACBD, + 0xE0D9, 0xACBE, + 0xE0DA, 0xACBF, + 0xE0DB, 0xACC0, + 0xE0DC, 0xACC1, + 0xE0DD, 0xACC2, + 0xE0DE, 0xACC3, + 0xE0DF, 0xACC4, + 0xE0E0, 0xACC5, + 0xE0E1, 0xACC6, + 0xE0E2, 0xACC7, + 0xE0E3, 0xACC8, + 0xE0E4, 0xACC9, + 0xE0E5, 0xACCA, + 0xE0E6, 0xACCB, + 0xE0E7, 0xACCC, + 0xE0E8, 0xACCD, + 0xE0E9, 0xACCE, + 0xE0EA, 0xACCF, + 0xE0EB, 0xACD0, + 0xE0EC, 0xACD1, + 0xE0ED, 0xACD2, + 0xE0EE, 0xACD3, + 0xE0EF, 0xACD4, + 0xE0F0, 0xACD5, + 0xE0F1, 0xACD6, + 0xE0F2, 0xACD7, + 0xE0F3, 0xACD8, + 0xE0F4, 0xACD9, + 0xE0F5, 0xACDA, + 0xE0F6, 0xACDB, + 0xE0F7, 0xACDC, + 0xE0F8, 0xACDD, + 0xE0F9, 0xACDE, + 0xE0FA, 0xACDF, + 0xE0FB, 0xACE0, + 0xE0FC, 0xACE1, + 0xE0FD, 0xACE2, + 0xE0FE, 0xACE3, + 0xE0FF, 0xACE4, + 0xE100, 0xACE5, + 0xE101, 0xACE6, + 0xE102, 0xACE7, + 0xE103, 0xACE8, + 0xE104, 0xACE9, + 0xE105, 0xACEA, + 0xE106, 0xACEB, + 0xE107, 0xACEC, + 0xE108, 0xACED, + 0xE109, 0xACEE, + 0xE10A, 0xACEF, + 0xE10B, 0xACF0, + 0xE10C, 0xACF1, + 0xE10D, 0xACF2, + 0xE10E, 0xACF3, + 0xE10F, 0xACF4, + 0xE110, 0xACF5, + 0xE111, 0xACF6, + 0xE112, 0xACF7, + 0xE113, 0xACF8, + 0xE114, 0xACF9, + 0xE115, 0xACFA, + 0xE116, 0xACFB, + 0xE117, 0xACFC, + 0xE118, 0xACFD, + 0xE119, 0xACFE, + 0xE11A, 0xADA1, + 0xE11B, 0xADA2, + 0xE11C, 0xADA3, + 0xE11D, 0xADA4, + 0xE11E, 0xADA5, + 0xE11F, 0xADA6, + 0xE120, 0xADA7, + 0xE121, 0xADA8, + 0xE122, 0xADA9, + 0xE123, 0xADAA, + 0xE124, 0xADAB, + 0xE125, 0xADAC, + 0xE126, 0xADAD, + 0xE127, 0xADAE, + 0xE128, 0xADAF, + 0xE129, 0xADB0, + 0xE12A, 0xADB1, + 0xE12B, 0xADB2, + 0xE12C, 0xADB3, + 0xE12D, 0xADB4, + 0xE12E, 0xADB5, + 0xE12F, 0xADB6, + 0xE130, 0xADB7, + 0xE131, 0xADB8, + 0xE132, 0xADB9, + 0xE133, 0xADBA, + 0xE134, 0xADBB, + 0xE135, 0xADBC, + 0xE136, 0xADBD, + 0xE137, 0xADBE, + 0xE138, 0xADBF, + 0xE139, 0xADC0, + 0xE13A, 0xADC1, + 0xE13B, 0xADC2, + 0xE13C, 0xADC3, + 0xE13D, 0xADC4, + 0xE13E, 0xADC5, + 0xE13F, 0xADC6, + 0xE140, 0xADC7, + 0xE141, 0xADC8, + 0xE142, 0xADC9, + 0xE143, 0xADCA, + 0xE144, 0xADCB, + 0xE145, 0xADCC, + 0xE146, 0xADCD, + 0xE147, 0xADCE, + 0xE148, 0xADCF, + 0xE149, 0xADD0, + 0xE14A, 0xADD1, + 0xE14B, 0xADD2, + 0xE14C, 0xADD3, + 0xE14D, 0xADD4, + 0xE14E, 0xADD5, + 0xE14F, 0xADD6, + 0xE150, 0xADD7, + 0xE151, 0xADD8, + 0xE152, 0xADD9, + 0xE153, 0xADDA, + 0xE154, 0xADDB, + 0xE155, 0xADDC, + 0xE156, 0xADDD, + 0xE157, 0xADDE, + 0xE158, 0xADDF, + 0xE159, 0xADE0, + 0xE15A, 0xADE1, + 0xE15B, 0xADE2, + 0xE15C, 0xADE3, + 0xE15D, 0xADE4, + 0xE15E, 0xADE5, + 0xE15F, 0xADE6, + 0xE160, 0xADE7, + 0xE161, 0xADE8, + 0xE162, 0xADE9, + 0xE163, 0xADEA, + 0xE164, 0xADEB, + 0xE165, 0xADEC, + 0xE166, 0xADED, + 0xE167, 0xADEE, + 0xE168, 0xADEF, + 0xE169, 0xADF0, + 0xE16A, 0xADF1, + 0xE16B, 0xADF2, + 0xE16C, 0xADF3, + 0xE16D, 0xADF4, + 0xE16E, 0xADF5, + 0xE16F, 0xADF6, + 0xE170, 0xADF7, + 0xE171, 0xADF8, + 0xE172, 0xADF9, + 0xE173, 0xADFA, + 0xE174, 0xADFB, + 0xE175, 0xADFC, + 0xE176, 0xADFD, + 0xE177, 0xADFE, + 0xE178, 0xAEA1, + 0xE179, 0xAEA2, + 0xE17A, 0xAEA3, + 0xE17B, 0xAEA4, + 0xE17C, 0xAEA5, + 0xE17D, 0xAEA6, + 0xE17E, 0xAEA7, + 0xE17F, 0xAEA8, + 0xE180, 0xAEA9, + 0xE181, 0xAEAA, + 0xE182, 0xAEAB, + 0xE183, 0xAEAC, + 0xE184, 0xAEAD, + 0xE185, 0xAEAE, + 0xE186, 0xAEAF, + 0xE187, 0xAEB0, + 0xE188, 0xAEB1, + 0xE189, 0xAEB2, + 0xE18A, 0xAEB3, + 0xE18B, 0xAEB4, + 0xE18C, 0xAEB5, + 0xE18D, 0xAEB6, + 0xE18E, 0xAEB7, + 0xE18F, 0xAEB8, + 0xE190, 0xAEB9, + 0xE191, 0xAEBA, + 0xE192, 0xAEBB, + 0xE193, 0xAEBC, + 0xE194, 0xAEBD, + 0xE195, 0xAEBE, + 0xE196, 0xAEBF, + 0xE197, 0xAEC0, + 0xE198, 0xAEC1, + 0xE199, 0xAEC2, + 0xE19A, 0xAEC3, + 0xE19B, 0xAEC4, + 0xE19C, 0xAEC5, + 0xE19D, 0xAEC6, + 0xE19E, 0xAEC7, + 0xE19F, 0xAEC8, + 0xE1A0, 0xAEC9, + 0xE1A1, 0xAECA, + 0xE1A2, 0xAECB, + 0xE1A3, 0xAECC, + 0xE1A4, 0xAECD, + 0xE1A5, 0xAECE, + 0xE1A6, 0xAECF, + 0xE1A7, 0xAED0, + 0xE1A8, 0xAED1, + 0xE1A9, 0xAED2, + 0xE1AA, 0xAED3, + 0xE1AB, 0xAED4, + 0xE1AC, 0xAED5, + 0xE1AD, 0xAED6, + 0xE1AE, 0xAED7, + 0xE1AF, 0xAED8, + 0xE1B0, 0xAED9, + 0xE1B1, 0xAEDA, + 0xE1B2, 0xAEDB, + 0xE1B3, 0xAEDC, + 0xE1B4, 0xAEDD, + 0xE1B5, 0xAEDE, + 0xE1B6, 0xAEDF, + 0xE1B7, 0xAEE0, + 0xE1B8, 0xAEE1, + 0xE1B9, 0xAEE2, + 0xE1BA, 0xAEE3, + 0xE1BB, 0xAEE4, + 0xE1BC, 0xAEE5, + 0xE1BD, 0xAEE6, + 0xE1BE, 0xAEE7, + 0xE1BF, 0xAEE8, + 0xE1C0, 0xAEE9, + 0xE1C1, 0xAEEA, + 0xE1C2, 0xAEEB, + 0xE1C3, 0xAEEC, + 0xE1C4, 0xAEED, + 0xE1C5, 0xAEEE, + 0xE1C6, 0xAEEF, + 0xE1C7, 0xAEF0, + 0xE1C8, 0xAEF1, + 0xE1C9, 0xAEF2, + 0xE1CA, 0xAEF3, + 0xE1CB, 0xAEF4, + 0xE1CC, 0xAEF5, + 0xE1CD, 0xAEF6, + 0xE1CE, 0xAEF7, + 0xE1CF, 0xAEF8, + 0xE1D0, 0xAEF9, + 0xE1D1, 0xAEFA, + 0xE1D2, 0xAEFB, + 0xE1D3, 0xAEFC, + 0xE1D4, 0xAEFD, + 0xE1D5, 0xAEFE, + 0xE1D6, 0xAFA1, + 0xE1D7, 0xAFA2, + 0xE1D8, 0xAFA3, + 0xE1D9, 0xAFA4, + 0xE1DA, 0xAFA5, + 0xE1DB, 0xAFA6, + 0xE1DC, 0xAFA7, + 0xE1DD, 0xAFA8, + 0xE1DE, 0xAFA9, + 0xE1DF, 0xAFAA, + 0xE1E0, 0xAFAB, + 0xE1E1, 0xAFAC, + 0xE1E2, 0xAFAD, + 0xE1E3, 0xAFAE, + 0xE1E4, 0xAFAF, + 0xE1E5, 0xAFB0, + 0xE1E6, 0xAFB1, + 0xE1E7, 0xAFB2, + 0xE1E8, 0xAFB3, + 0xE1E9, 0xAFB4, + 0xE1EA, 0xAFB5, + 0xE1EB, 0xAFB6, + 0xE1EC, 0xAFB7, + 0xE1ED, 0xAFB8, + 0xE1EE, 0xAFB9, + 0xE1EF, 0xAFBA, + 0xE1F0, 0xAFBB, + 0xE1F1, 0xAFBC, + 0xE1F2, 0xAFBD, + 0xE1F3, 0xAFBE, + 0xE1F4, 0xAFBF, + 0xE1F5, 0xAFC0, + 0xE1F6, 0xAFC1, + 0xE1F7, 0xAFC2, + 0xE1F8, 0xAFC3, + 0xE1F9, 0xAFC4, + 0xE1FA, 0xAFC5, + 0xE1FB, 0xAFC6, + 0xE1FC, 0xAFC7, + 0xE1FD, 0xAFC8, + 0xE1FE, 0xAFC9, + 0xE1FF, 0xAFCA, + 0xE200, 0xAFCB, + 0xE201, 0xAFCC, + 0xE202, 0xAFCD, + 0xE203, 0xAFCE, + 0xE204, 0xAFCF, + 0xE205, 0xAFD0, + 0xE206, 0xAFD1, + 0xE207, 0xAFD2, + 0xE208, 0xAFD3, + 0xE209, 0xAFD4, + 0xE20A, 0xAFD5, + 0xE20B, 0xAFD6, + 0xE20C, 0xAFD7, + 0xE20D, 0xAFD8, + 0xE20E, 0xAFD9, + 0xE20F, 0xAFDA, + 0xE210, 0xAFDB, + 0xE211, 0xAFDC, + 0xE212, 0xAFDD, + 0xE213, 0xAFDE, + 0xE214, 0xAFDF, + 0xE215, 0xAFE0, + 0xE216, 0xAFE1, + 0xE217, 0xAFE2, + 0xE218, 0xAFE3, + 0xE219, 0xAFE4, + 0xE21A, 0xAFE5, + 0xE21B, 0xAFE6, + 0xE21C, 0xAFE7, + 0xE21D, 0xAFE8, + 0xE21E, 0xAFE9, + 0xE21F, 0xAFEA, + 0xE220, 0xAFEB, + 0xE221, 0xAFEC, + 0xE222, 0xAFED, + 0xE223, 0xAFEE, + 0xE224, 0xAFEF, + 0xE225, 0xAFF0, + 0xE226, 0xAFF1, + 0xE227, 0xAFF2, + 0xE228, 0xAFF3, + 0xE229, 0xAFF4, + 0xE22A, 0xAFF5, + 0xE22B, 0xAFF6, + 0xE22C, 0xAFF7, + 0xE22D, 0xAFF8, + 0xE22E, 0xAFF9, + 0xE22F, 0xAFFA, + 0xE230, 0xAFFB, + 0xE231, 0xAFFC, + 0xE232, 0xAFFD, + 0xE233, 0xAFFE, + 0xE234, 0xF8A1, + 0xE235, 0xF8A2, + 0xE236, 0xF8A3, + 0xE237, 0xF8A4, + 0xE238, 0xF8A5, + 0xE239, 0xF8A6, + 0xE23A, 0xF8A7, + 0xE23B, 0xF8A8, + 0xE23C, 0xF8A9, + 0xE23D, 0xF8AA, + 0xE23E, 0xF8AB, + 0xE23F, 0xF8AC, + 0xE240, 0xF8AD, + 0xE241, 0xF8AE, + 0xE242, 0xF8AF, + 0xE243, 0xF8B0, + 0xE244, 0xF8B1, + 0xE245, 0xF8B2, + 0xE246, 0xF8B3, + 0xE247, 0xF8B4, + 0xE248, 0xF8B5, + 0xE249, 0xF8B6, + 0xE24A, 0xF8B7, + 0xE24B, 0xF8B8, + 0xE24C, 0xF8B9, + 0xE24D, 0xF8BA, + 0xE24E, 0xF8BB, + 0xE24F, 0xF8BC, + 0xE250, 0xF8BD, + 0xE251, 0xF8BE, + 0xE252, 0xF8BF, + 0xE253, 0xF8C0, + 0xE254, 0xF8C1, + 0xE255, 0xF8C2, + 0xE256, 0xF8C3, + 0xE257, 0xF8C4, + 0xE258, 0xF8C5, + 0xE259, 0xF8C6, + 0xE25A, 0xF8C7, + 0xE25B, 0xF8C8, + 0xE25C, 0xF8C9, + 0xE25D, 0xF8CA, + 0xE25E, 0xF8CB, + 0xE25F, 0xF8CC, + 0xE260, 0xF8CD, + 0xE261, 0xF8CE, + 0xE262, 0xF8CF, + 0xE263, 0xF8D0, + 0xE264, 0xF8D1, + 0xE265, 0xF8D2, + 0xE266, 0xF8D3, + 0xE267, 0xF8D4, + 0xE268, 0xF8D5, + 0xE269, 0xF8D6, + 0xE26A, 0xF8D7, + 0xE26B, 0xF8D8, + 0xE26C, 0xF8D9, + 0xE26D, 0xF8DA, + 0xE26E, 0xF8DB, + 0xE26F, 0xF8DC, + 0xE270, 0xF8DD, + 0xE271, 0xF8DE, + 0xE272, 0xF8DF, + 0xE273, 0xF8E0, + 0xE274, 0xF8E1, + 0xE275, 0xF8E2, + 0xE276, 0xF8E3, + 0xE277, 0xF8E4, + 0xE278, 0xF8E5, + 0xE279, 0xF8E6, + 0xE27A, 0xF8E7, + 0xE27B, 0xF8E8, + 0xE27C, 0xF8E9, + 0xE27D, 0xF8EA, + 0xE27E, 0xF8EB, + 0xE27F, 0xF8EC, + 0xE280, 0xF8ED, + 0xE281, 0xF8EE, + 0xE282, 0xF8EF, + 0xE283, 0xF8F0, + 0xE284, 0xF8F1, + 0xE285, 0xF8F2, + 0xE286, 0xF8F3, + 0xE287, 0xF8F4, + 0xE288, 0xF8F5, + 0xE289, 0xF8F6, + 0xE28A, 0xF8F7, + 0xE28B, 0xF8F8, + 0xE28C, 0xF8F9, + 0xE28D, 0xF8FA, + 0xE28E, 0xF8FB, + 0xE28F, 0xF8FC, + 0xE290, 0xF8FD, + 0xE291, 0xF8FE, + 0xE292, 0xF9A1, + 0xE293, 0xF9A2, + 0xE294, 0xF9A3, + 0xE295, 0xF9A4, + 0xE296, 0xF9A5, + 0xE297, 0xF9A6, + 0xE298, 0xF9A7, + 0xE299, 0xF9A8, + 0xE29A, 0xF9A9, + 0xE29B, 0xF9AA, + 0xE29C, 0xF9AB, + 0xE29D, 0xF9AC, + 0xE29E, 0xF9AD, + 0xE29F, 0xF9AE, + 0xE2A0, 0xF9AF, + 0xE2A1, 0xF9B0, + 0xE2A2, 0xF9B1, + 0xE2A3, 0xF9B2, + 0xE2A4, 0xF9B3, + 0xE2A5, 0xF9B4, + 0xE2A6, 0xF9B5, + 0xE2A7, 0xF9B6, + 0xE2A8, 0xF9B7, + 0xE2A9, 0xF9B8, + 0xE2AA, 0xF9B9, + 0xE2AB, 0xF9BA, + 0xE2AC, 0xF9BB, + 0xE2AD, 0xF9BC, + 0xE2AE, 0xF9BD, + 0xE2AF, 0xF9BE, + 0xE2B0, 0xF9BF, + 0xE2B1, 0xF9C0, + 0xE2B2, 0xF9C1, + 0xE2B3, 0xF9C2, + 0xE2B4, 0xF9C3, + 0xE2B5, 0xF9C4, + 0xE2B6, 0xF9C5, + 0xE2B7, 0xF9C6, + 0xE2B8, 0xF9C7, + 0xE2B9, 0xF9C8, + 0xE2BA, 0xF9C9, + 0xE2BB, 0xF9CA, + 0xE2BC, 0xF9CB, + 0xE2BD, 0xF9CC, + 0xE2BE, 0xF9CD, + 0xE2BF, 0xF9CE, + 0xE2C0, 0xF9CF, + 0xE2C1, 0xF9D0, + 0xE2C2, 0xF9D1, + 0xE2C3, 0xF9D2, + 0xE2C4, 0xF9D3, + 0xE2C5, 0xF9D4, + 0xE2C6, 0xF9D5, + 0xE2C7, 0xF9D6, + 0xE2C8, 0xF9D7, + 0xE2C9, 0xF9D8, + 0xE2CA, 0xF9D9, + 0xE2CB, 0xF9DA, + 0xE2CC, 0xF9DB, + 0xE2CD, 0xF9DC, + 0xE2CE, 0xF9DD, + 0xE2CF, 0xF9DE, + 0xE2D0, 0xF9DF, + 0xE2D1, 0xF9E0, + 0xE2D2, 0xF9E1, + 0xE2D3, 0xF9E2, + 0xE2D4, 0xF9E3, + 0xE2D5, 0xF9E4, + 0xE2D6, 0xF9E5, + 0xE2D7, 0xF9E6, + 0xE2D8, 0xF9E7, + 0xE2D9, 0xF9E8, + 0xE2DA, 0xF9E9, + 0xE2DB, 0xF9EA, + 0xE2DC, 0xF9EB, + 0xE2DD, 0xF9EC, + 0xE2DE, 0xF9ED, + 0xE2DF, 0xF9EE, + 0xE2E0, 0xF9EF, + 0xE2E1, 0xF9F0, + 0xE2E2, 0xF9F1, + 0xE2E3, 0xF9F2, + 0xE2E4, 0xF9F3, + 0xE2E5, 0xF9F4, + 0xE2E6, 0xF9F5, + 0xE2E7, 0xF9F6, + 0xE2E8, 0xF9F7, + 0xE2E9, 0xF9F8, + 0xE2EA, 0xF9F9, + 0xE2EB, 0xF9FA, + 0xE2EC, 0xF9FB, + 0xE2ED, 0xF9FC, + 0xE2EE, 0xF9FD, + 0xE2EF, 0xF9FE, + 0xE2F0, 0xFAA1, + 0xE2F1, 0xFAA2, + 0xE2F2, 0xFAA3, + 0xE2F3, 0xFAA4, + 0xE2F4, 0xFAA5, + 0xE2F5, 0xFAA6, + 0xE2F6, 0xFAA7, + 0xE2F7, 0xFAA8, + 0xE2F8, 0xFAA9, + 0xE2F9, 0xFAAA, + 0xE2FA, 0xFAAB, + 0xE2FB, 0xFAAC, + 0xE2FC, 0xFAAD, + 0xE2FD, 0xFAAE, + 0xE2FE, 0xFAAF, + 0xE2FF, 0xFAB0, + 0xE300, 0xFAB1, + 0xE301, 0xFAB2, + 0xE302, 0xFAB3, + 0xE303, 0xFAB4, + 0xE304, 0xFAB5, + 0xE305, 0xFAB6, + 0xE306, 0xFAB7, + 0xE307, 0xFAB8, + 0xE308, 0xFAB9, + 0xE309, 0xFABA, + 0xE30A, 0xFABB, + 0xE30B, 0xFABC, + 0xE30C, 0xFABD, + 0xE30D, 0xFABE, + 0xE30E, 0xFABF, + 0xE30F, 0xFAC0, + 0xE310, 0xFAC1, + 0xE311, 0xFAC2, + 0xE312, 0xFAC3, + 0xE313, 0xFAC4, + 0xE314, 0xFAC5, + 0xE315, 0xFAC6, + 0xE316, 0xFAC7, + 0xE317, 0xFAC8, + 0xE318, 0xFAC9, + 0xE319, 0xFACA, + 0xE31A, 0xFACB, + 0xE31B, 0xFACC, + 0xE31C, 0xFACD, + 0xE31D, 0xFACE, + 0xE31E, 0xFACF, + 0xE31F, 0xFAD0, + 0xE320, 0xFAD1, + 0xE321, 0xFAD2, + 0xE322, 0xFAD3, + 0xE323, 0xFAD4, + 0xE324, 0xFAD5, + 0xE325, 0xFAD6, + 0xE326, 0xFAD7, + 0xE327, 0xFAD8, + 0xE328, 0xFAD9, + 0xE329, 0xFADA, + 0xE32A, 0xFADB, + 0xE32B, 0xFADC, + 0xE32C, 0xFADD, + 0xE32D, 0xFADE, + 0xE32E, 0xFADF, + 0xE32F, 0xFAE0, + 0xE330, 0xFAE1, + 0xE331, 0xFAE2, + 0xE332, 0xFAE3, + 0xE333, 0xFAE4, + 0xE334, 0xFAE5, + 0xE335, 0xFAE6, + 0xE336, 0xFAE7, + 0xE337, 0xFAE8, + 0xE338, 0xFAE9, + 0xE339, 0xFAEA, + 0xE33A, 0xFAEB, + 0xE33B, 0xFAEC, + 0xE33C, 0xFAED, + 0xE33D, 0xFAEE, + 0xE33E, 0xFAEF, + 0xE33F, 0xFAF0, + 0xE340, 0xFAF1, + 0xE341, 0xFAF2, + 0xE342, 0xFAF3, + 0xE343, 0xFAF4, + 0xE344, 0xFAF5, + 0xE345, 0xFAF6, + 0xE346, 0xFAF7, + 0xE347, 0xFAF8, + 0xE348, 0xFAF9, + 0xE349, 0xFAFA, + 0xE34A, 0xFAFB, + 0xE34B, 0xFAFC, + 0xE34C, 0xFAFD, + 0xE34D, 0xFAFE, + 0xE34E, 0xFBA1, + 0xE34F, 0xFBA2, + 0xE350, 0xFBA3, + 0xE351, 0xFBA4, + 0xE352, 0xFBA5, + 0xE353, 0xFBA6, + 0xE354, 0xFBA7, + 0xE355, 0xFBA8, + 0xE356, 0xFBA9, + 0xE357, 0xFBAA, + 0xE358, 0xFBAB, + 0xE359, 0xFBAC, + 0xE35A, 0xFBAD, + 0xE35B, 0xFBAE, + 0xE35C, 0xFBAF, + 0xE35D, 0xFBB0, + 0xE35E, 0xFBB1, + 0xE35F, 0xFBB2, + 0xE360, 0xFBB3, + 0xE361, 0xFBB4, + 0xE362, 0xFBB5, + 0xE363, 0xFBB6, + 0xE364, 0xFBB7, + 0xE365, 0xFBB8, + 0xE366, 0xFBB9, + 0xE367, 0xFBBA, + 0xE368, 0xFBBB, + 0xE369, 0xFBBC, + 0xE36A, 0xFBBD, + 0xE36B, 0xFBBE, + 0xE36C, 0xFBBF, + 0xE36D, 0xFBC0, + 0xE36E, 0xFBC1, + 0xE36F, 0xFBC2, + 0xE370, 0xFBC3, + 0xE371, 0xFBC4, + 0xE372, 0xFBC5, + 0xE373, 0xFBC6, + 0xE374, 0xFBC7, + 0xE375, 0xFBC8, + 0xE376, 0xFBC9, + 0xE377, 0xFBCA, + 0xE378, 0xFBCB, + 0xE379, 0xFBCC, + 0xE37A, 0xFBCD, + 0xE37B, 0xFBCE, + 0xE37C, 0xFBCF, + 0xE37D, 0xFBD0, + 0xE37E, 0xFBD1, + 0xE37F, 0xFBD2, + 0xE380, 0xFBD3, + 0xE381, 0xFBD4, + 0xE382, 0xFBD5, + 0xE383, 0xFBD6, + 0xE384, 0xFBD7, + 0xE385, 0xFBD8, + 0xE386, 0xFBD9, + 0xE387, 0xFBDA, + 0xE388, 0xFBDB, + 0xE389, 0xFBDC, + 0xE38A, 0xFBDD, + 0xE38B, 0xFBDE, + 0xE38C, 0xFBDF, + 0xE38D, 0xFBE0, + 0xE38E, 0xFBE1, + 0xE38F, 0xFBE2, + 0xE390, 0xFBE3, + 0xE391, 0xFBE4, + 0xE392, 0xFBE5, + 0xE393, 0xFBE6, + 0xE394, 0xFBE7, + 0xE395, 0xFBE8, + 0xE396, 0xFBE9, + 0xE397, 0xFBEA, + 0xE398, 0xFBEB, + 0xE399, 0xFBEC, + 0xE39A, 0xFBED, + 0xE39B, 0xFBEE, + 0xE39C, 0xFBEF, + 0xE39D, 0xFBF0, + 0xE39E, 0xFBF1, + 0xE39F, 0xFBF2, + 0xE3A0, 0xFBF3, + 0xE3A1, 0xFBF4, + 0xE3A2, 0xFBF5, + 0xE3A3, 0xFBF6, + 0xE3A4, 0xFBF7, + 0xE3A5, 0xFBF8, + 0xE3A6, 0xFBF9, + 0xE3A7, 0xFBFA, + 0xE3A8, 0xFBFB, + 0xE3A9, 0xFBFC, + 0xE3AA, 0xFBFD, + 0xE3AB, 0xFBFE, + 0xE3AC, 0xFCA1, + 0xE3AD, 0xFCA2, + 0xE3AE, 0xFCA3, + 0xE3AF, 0xFCA4, + 0xE3B0, 0xFCA5, + 0xE3B1, 0xFCA6, + 0xE3B2, 0xFCA7, + 0xE3B3, 0xFCA8, + 0xE3B4, 0xFCA9, + 0xE3B5, 0xFCAA, + 0xE3B6, 0xFCAB, + 0xE3B7, 0xFCAC, + 0xE3B8, 0xFCAD, + 0xE3B9, 0xFCAE, + 0xE3BA, 0xFCAF, + 0xE3BB, 0xFCB0, + 0xE3BC, 0xFCB1, + 0xE3BD, 0xFCB2, + 0xE3BE, 0xFCB3, + 0xE3BF, 0xFCB4, + 0xE3C0, 0xFCB5, + 0xE3C1, 0xFCB6, + 0xE3C2, 0xFCB7, + 0xE3C3, 0xFCB8, + 0xE3C4, 0xFCB9, + 0xE3C5, 0xFCBA, + 0xE3C6, 0xFCBB, + 0xE3C7, 0xFCBC, + 0xE3C8, 0xFCBD, + 0xE3C9, 0xFCBE, + 0xE3CA, 0xFCBF, + 0xE3CB, 0xFCC0, + 0xE3CC, 0xFCC1, + 0xE3CD, 0xFCC2, + 0xE3CE, 0xFCC3, + 0xE3CF, 0xFCC4, + 0xE3D0, 0xFCC5, + 0xE3D1, 0xFCC6, + 0xE3D2, 0xFCC7, + 0xE3D3, 0xFCC8, + 0xE3D4, 0xFCC9, + 0xE3D5, 0xFCCA, + 0xE3D6, 0xFCCB, + 0xE3D7, 0xFCCC, + 0xE3D8, 0xFCCD, + 0xE3D9, 0xFCCE, + 0xE3DA, 0xFCCF, + 0xE3DB, 0xFCD0, + 0xE3DC, 0xFCD1, + 0xE3DD, 0xFCD2, + 0xE3DE, 0xFCD3, + 0xE3DF, 0xFCD4, + 0xE3E0, 0xFCD5, + 0xE3E1, 0xFCD6, + 0xE3E2, 0xFCD7, + 0xE3E3, 0xFCD8, + 0xE3E4, 0xFCD9, + 0xE3E5, 0xFCDA, + 0xE3E6, 0xFCDB, + 0xE3E7, 0xFCDC, + 0xE3E8, 0xFCDD, + 0xE3E9, 0xFCDE, + 0xE3EA, 0xFCDF, + 0xE3EB, 0xFCE0, + 0xE3EC, 0xFCE1, + 0xE3ED, 0xFCE2, + 0xE3EE, 0xFCE3, + 0xE3EF, 0xFCE4, + 0xE3F0, 0xFCE5, + 0xE3F1, 0xFCE6, + 0xE3F2, 0xFCE7, + 0xE3F3, 0xFCE8, + 0xE3F4, 0xFCE9, + 0xE3F5, 0xFCEA, + 0xE3F6, 0xFCEB, + 0xE3F7, 0xFCEC, + 0xE3F8, 0xFCED, + 0xE3F9, 0xFCEE, + 0xE3FA, 0xFCEF, + 0xE3FB, 0xFCF0, + 0xE3FC, 0xFCF1, + 0xE3FD, 0xFCF2, + 0xE3FE, 0xFCF3, + 0xE3FF, 0xFCF4, + 0xE400, 0xFCF5, + 0xE401, 0xFCF6, + 0xE402, 0xFCF7, + 0xE403, 0xFCF8, + 0xE404, 0xFCF9, + 0xE405, 0xFCFA, + 0xE406, 0xFCFB, + 0xE407, 0xFCFC, + 0xE408, 0xFCFD, + 0xE409, 0xFCFE, + 0xE40A, 0xFDA1, + 0xE40B, 0xFDA2, + 0xE40C, 0xFDA3, + 0xE40D, 0xFDA4, + 0xE40E, 0xFDA5, + 0xE40F, 0xFDA6, + 0xE410, 0xFDA7, + 0xE411, 0xFDA8, + 0xE412, 0xFDA9, + 0xE413, 0xFDAA, + 0xE414, 0xFDAB, + 0xE415, 0xFDAC, + 0xE416, 0xFDAD, + 0xE417, 0xFDAE, + 0xE418, 0xFDAF, + 0xE419, 0xFDB0, + 0xE41A, 0xFDB1, + 0xE41B, 0xFDB2, + 0xE41C, 0xFDB3, + 0xE41D, 0xFDB4, + 0xE41E, 0xFDB5, + 0xE41F, 0xFDB6, + 0xE420, 0xFDB7, + 0xE421, 0xFDB8, + 0xE422, 0xFDB9, + 0xE423, 0xFDBA, + 0xE424, 0xFDBB, + 0xE425, 0xFDBC, + 0xE426, 0xFDBD, + 0xE427, 0xFDBE, + 0xE428, 0xFDBF, + 0xE429, 0xFDC0, + 0xE42A, 0xFDC1, + 0xE42B, 0xFDC2, + 0xE42C, 0xFDC3, + 0xE42D, 0xFDC4, + 0xE42E, 0xFDC5, + 0xE42F, 0xFDC6, + 0xE430, 0xFDC7, + 0xE431, 0xFDC8, + 0xE432, 0xFDC9, + 0xE433, 0xFDCA, + 0xE434, 0xFDCB, + 0xE435, 0xFDCC, + 0xE436, 0xFDCD, + 0xE437, 0xFDCE, + 0xE438, 0xFDCF, + 0xE439, 0xFDD0, + 0xE43A, 0xFDD1, + 0xE43B, 0xFDD2, + 0xE43C, 0xFDD3, + 0xE43D, 0xFDD4, + 0xE43E, 0xFDD5, + 0xE43F, 0xFDD6, + 0xE440, 0xFDD7, + 0xE441, 0xFDD8, + 0xE442, 0xFDD9, + 0xE443, 0xFDDA, + 0xE444, 0xFDDB, + 0xE445, 0xFDDC, + 0xE446, 0xFDDD, + 0xE447, 0xFDDE, + 0xE448, 0xFDDF, + 0xE449, 0xFDE0, + 0xE44A, 0xFDE1, + 0xE44B, 0xFDE2, + 0xE44C, 0xFDE3, + 0xE44D, 0xFDE4, + 0xE44E, 0xFDE5, + 0xE44F, 0xFDE6, + 0xE450, 0xFDE7, + 0xE451, 0xFDE8, + 0xE452, 0xFDE9, + 0xE453, 0xFDEA, + 0xE454, 0xFDEB, + 0xE455, 0xFDEC, + 0xE456, 0xFDED, + 0xE457, 0xFDEE, + 0xE458, 0xFDEF, + 0xE459, 0xFDF0, + 0xE45A, 0xFDF1, + 0xE45B, 0xFDF2, + 0xE45C, 0xFDF3, + 0xE45D, 0xFDF4, + 0xE45E, 0xFDF5, + 0xE45F, 0xFDF6, + 0xE460, 0xFDF7, + 0xE461, 0xFDF8, + 0xE462, 0xFDF9, + 0xE463, 0xFDFA, + 0xE464, 0xFDFB, + 0xE465, 0xFDFC, + 0xE466, 0xFDFD, + 0xE467, 0xFDFE, + 0xE468, 0xFEA1, + 0xE469, 0xFEA2, + 0xE46A, 0xFEA3, + 0xE46B, 0xFEA4, + 0xE46C, 0xFEA5, + 0xE46D, 0xFEA6, + 0xE46E, 0xFEA7, + 0xE46F, 0xFEA8, + 0xE470, 0xFEA9, + 0xE471, 0xFEAA, + 0xE472, 0xFEAB, + 0xE473, 0xFEAC, + 0xE474, 0xFEAD, + 0xE475, 0xFEAE, + 0xE476, 0xFEAF, + 0xE477, 0xFEB0, + 0xE478, 0xFEB1, + 0xE479, 0xFEB2, + 0xE47A, 0xFEB3, + 0xE47B, 0xFEB4, + 0xE47C, 0xFEB5, + 0xE47D, 0xFEB6, + 0xE47E, 0xFEB7, + 0xE47F, 0xFEB8, + 0xE480, 0xFEB9, + 0xE481, 0xFEBA, + 0xE482, 0xFEBB, + 0xE483, 0xFEBC, + 0xE484, 0xFEBD, + 0xE485, 0xFEBE, + 0xE486, 0xFEBF, + 0xE487, 0xFEC0, + 0xE488, 0xFEC1, + 0xE489, 0xFEC2, + 0xE48A, 0xFEC3, + 0xE48B, 0xFEC4, + 0xE48C, 0xFEC5, + 0xE48D, 0xFEC6, + 0xE48E, 0xFEC7, + 0xE48F, 0xFEC8, + 0xE490, 0xFEC9, + 0xE491, 0xFECA, + 0xE492, 0xFECB, + 0xE493, 0xFECC, + 0xE494, 0xFECD, + 0xE495, 0xFECE, + 0xE496, 0xFECF, + 0xE497, 0xFED0, + 0xE498, 0xFED1, + 0xE499, 0xFED2, + 0xE49A, 0xFED3, + 0xE49B, 0xFED4, + 0xE49C, 0xFED5, + 0xE49D, 0xFED6, + 0xE49E, 0xFED7, + 0xE49F, 0xFED8, + 0xE4A0, 0xFED9, + 0xE4A1, 0xFEDA, + 0xE4A2, 0xFEDB, + 0xE4A3, 0xFEDC, + 0xE4A4, 0xFEDD, + 0xE4A5, 0xFEDE, + 0xE4A6, 0xFEDF, + 0xE4A7, 0xFEE0, + 0xE4A8, 0xFEE1, + 0xE4A9, 0xFEE2, + 0xE4AA, 0xFEE3, + 0xE4AB, 0xFEE4, + 0xE4AC, 0xFEE5, + 0xE4AD, 0xFEE6, + 0xE4AE, 0xFEE7, + 0xE4AF, 0xFEE8, + 0xE4B0, 0xFEE9, + 0xE4B1, 0xFEEA, + 0xE4B2, 0xFEEB, + 0xE4B3, 0xFEEC, + 0xE4B4, 0xFEED, + 0xE4B5, 0xFEEE, + 0xE4B6, 0xFEEF, + 0xE4B7, 0xFEF0, + 0xE4B8, 0xFEF1, + 0xE4B9, 0xFEF2, + 0xE4BA, 0xFEF3, + 0xE4BB, 0xFEF4, + 0xE4BC, 0xFEF5, + 0xE4BD, 0xFEF6, + 0xE4BE, 0xFEF7, + 0xE4BF, 0xFEF8, + 0xE4C0, 0xFEF9, + 0xE4C1, 0xFEFA, + 0xE4C2, 0xFEFB, + 0xE4C3, 0xFEFC, + 0xE4C4, 0xFEFD, + 0xE4C5, 0xFEFE, + 0xE4C6, 0xA140, + 0xE4C7, 0xA141, + 0xE4C8, 0xA142, + 0xE4C9, 0xA143, + 0xE4CA, 0xA144, + 0xE4CB, 0xA145, + 0xE4CC, 0xA146, + 0xE4CD, 0xA147, + 0xE4CE, 0xA148, + 0xE4CF, 0xA149, + 0xE4D0, 0xA14A, + 0xE4D1, 0xA14B, + 0xE4D2, 0xA14C, + 0xE4D3, 0xA14D, + 0xE4D4, 0xA14E, + 0xE4D5, 0xA14F, + 0xE4D6, 0xA150, + 0xE4D7, 0xA151, + 0xE4D8, 0xA152, + 0xE4D9, 0xA153, + 0xE4DA, 0xA154, + 0xE4DB, 0xA155, + 0xE4DC, 0xA156, + 0xE4DD, 0xA157, + 0xE4DE, 0xA158, + 0xE4DF, 0xA159, + 0xE4E0, 0xA15A, + 0xE4E1, 0xA15B, + 0xE4E2, 0xA15C, + 0xE4E3, 0xA15D, + 0xE4E4, 0xA15E, + 0xE4E5, 0xA15F, + 0xE4E6, 0xA160, + 0xE4E7, 0xA161, + 0xE4E8, 0xA162, + 0xE4E9, 0xA163, + 0xE4EA, 0xA164, + 0xE4EB, 0xA165, + 0xE4EC, 0xA166, + 0xE4ED, 0xA167, + 0xE4EE, 0xA168, + 0xE4EF, 0xA169, + 0xE4F0, 0xA16A, + 0xE4F1, 0xA16B, + 0xE4F2, 0xA16C, + 0xE4F3, 0xA16D, + 0xE4F4, 0xA16E, + 0xE4F5, 0xA16F, + 0xE4F6, 0xA170, + 0xE4F7, 0xA171, + 0xE4F8, 0xA172, + 0xE4F9, 0xA173, + 0xE4FA, 0xA174, + 0xE4FB, 0xA175, + 0xE4FC, 0xA176, + 0xE4FD, 0xA177, + 0xE4FE, 0xA178, + 0xE4FF, 0xA179, + 0xE500, 0xA17A, + 0xE501, 0xA17B, + 0xE502, 0xA17C, + 0xE503, 0xA17D, + 0xE504, 0xA17E, + 0xE505, 0xA180, + 0xE506, 0xA181, + 0xE507, 0xA182, + 0xE508, 0xA183, + 0xE509, 0xA184, + 0xE50A, 0xA185, + 0xE50B, 0xA186, + 0xE50C, 0xA187, + 0xE50D, 0xA188, + 0xE50E, 0xA189, + 0xE50F, 0xA18A, + 0xE510, 0xA18B, + 0xE511, 0xA18C, + 0xE512, 0xA18D, + 0xE513, 0xA18E, + 0xE514, 0xA18F, + 0xE515, 0xA190, + 0xE516, 0xA191, + 0xE517, 0xA192, + 0xE518, 0xA193, + 0xE519, 0xA194, + 0xE51A, 0xA195, + 0xE51B, 0xA196, + 0xE51C, 0xA197, + 0xE51D, 0xA198, + 0xE51E, 0xA199, + 0xE51F, 0xA19A, + 0xE520, 0xA19B, + 0xE521, 0xA19C, + 0xE522, 0xA19D, + 0xE523, 0xA19E, + 0xE524, 0xA19F, + 0xE525, 0xA1A0, + 0xE526, 0xA240, + 0xE527, 0xA241, + 0xE528, 0xA242, + 0xE529, 0xA243, + 0xE52A, 0xA244, + 0xE52B, 0xA245, + 0xE52C, 0xA246, + 0xE52D, 0xA247, + 0xE52E, 0xA248, + 0xE52F, 0xA249, + 0xE530, 0xA24A, + 0xE531, 0xA24B, + 0xE532, 0xA24C, + 0xE533, 0xA24D, + 0xE534, 0xA24E, + 0xE535, 0xA24F, + 0xE536, 0xA250, + 0xE537, 0xA251, + 0xE538, 0xA252, + 0xE539, 0xA253, + 0xE53A, 0xA254, + 0xE53B, 0xA255, + 0xE53C, 0xA256, + 0xE53D, 0xA257, + 0xE53E, 0xA258, + 0xE53F, 0xA259, + 0xE540, 0xA25A, + 0xE541, 0xA25B, + 0xE542, 0xA25C, + 0xE543, 0xA25D, + 0xE544, 0xA25E, + 0xE545, 0xA25F, + 0xE546, 0xA260, + 0xE547, 0xA261, + 0xE548, 0xA262, + 0xE549, 0xA263, + 0xE54A, 0xA264, + 0xE54B, 0xA265, + 0xE54C, 0xA266, + 0xE54D, 0xA267, + 0xE54E, 0xA268, + 0xE54F, 0xA269, + 0xE550, 0xA26A, + 0xE551, 0xA26B, + 0xE552, 0xA26C, + 0xE553, 0xA26D, + 0xE554, 0xA26E, + 0xE555, 0xA26F, + 0xE556, 0xA270, + 0xE557, 0xA271, + 0xE558, 0xA272, + 0xE559, 0xA273, + 0xE55A, 0xA274, + 0xE55B, 0xA275, + 0xE55C, 0xA276, + 0xE55D, 0xA277, + 0xE55E, 0xA278, + 0xE55F, 0xA279, + 0xE560, 0xA27A, + 0xE561, 0xA27B, + 0xE562, 0xA27C, + 0xE563, 0xA27D, + 0xE564, 0xA27E, + 0xE565, 0xA280, + 0xE566, 0xA281, + 0xE567, 0xA282, + 0xE568, 0xA283, + 0xE569, 0xA284, + 0xE56A, 0xA285, + 0xE56B, 0xA286, + 0xE56C, 0xA287, + 0xE56D, 0xA288, + 0xE56E, 0xA289, + 0xE56F, 0xA28A, + 0xE570, 0xA28B, + 0xE571, 0xA28C, + 0xE572, 0xA28D, + 0xE573, 0xA28E, + 0xE574, 0xA28F, + 0xE575, 0xA290, + 0xE576, 0xA291, + 0xE577, 0xA292, + 0xE578, 0xA293, + 0xE579, 0xA294, + 0xE57A, 0xA295, + 0xE57B, 0xA296, + 0xE57C, 0xA297, + 0xE57D, 0xA298, + 0xE57E, 0xA299, + 0xE57F, 0xA29A, + 0xE580, 0xA29B, + 0xE581, 0xA29C, + 0xE582, 0xA29D, + 0xE583, 0xA29E, + 0xE584, 0xA29F, + 0xE585, 0xA2A0, + 0xE586, 0xA340, + 0xE587, 0xA341, + 0xE588, 0xA342, + 0xE589, 0xA343, + 0xE58A, 0xA344, + 0xE58B, 0xA345, + 0xE58C, 0xA346, + 0xE58D, 0xA347, + 0xE58E, 0xA348, + 0xE58F, 0xA349, + 0xE590, 0xA34A, + 0xE591, 0xA34B, + 0xE592, 0xA34C, + 0xE593, 0xA34D, + 0xE594, 0xA34E, + 0xE595, 0xA34F, + 0xE596, 0xA350, + 0xE597, 0xA351, + 0xE598, 0xA352, + 0xE599, 0xA353, + 0xE59A, 0xA354, + 0xE59B, 0xA355, + 0xE59C, 0xA356, + 0xE59D, 0xA357, + 0xE59E, 0xA358, + 0xE59F, 0xA359, + 0xE5A0, 0xA35A, + 0xE5A1, 0xA35B, + 0xE5A2, 0xA35C, + 0xE5A3, 0xA35D, + 0xE5A4, 0xA35E, + 0xE5A5, 0xA35F, + 0xE5A6, 0xA360, + 0xE5A7, 0xA361, + 0xE5A8, 0xA362, + 0xE5A9, 0xA363, + 0xE5AA, 0xA364, + 0xE5AB, 0xA365, + 0xE5AC, 0xA366, + 0xE5AD, 0xA367, + 0xE5AE, 0xA368, + 0xE5AF, 0xA369, + 0xE5B0, 0xA36A, + 0xE5B1, 0xA36B, + 0xE5B2, 0xA36C, + 0xE5B3, 0xA36D, + 0xE5B4, 0xA36E, + 0xE5B5, 0xA36F, + 0xE5B6, 0xA370, + 0xE5B7, 0xA371, + 0xE5B8, 0xA372, + 0xE5B9, 0xA373, + 0xE5BA, 0xA374, + 0xE5BB, 0xA375, + 0xE5BC, 0xA376, + 0xE5BD, 0xA377, + 0xE5BE, 0xA378, + 0xE5BF, 0xA379, + 0xE5C0, 0xA37A, + 0xE5C1, 0xA37B, + 0xE5C2, 0xA37C, + 0xE5C3, 0xA37D, + 0xE5C4, 0xA37E, + 0xE5C5, 0xA380, + 0xE5C6, 0xA381, + 0xE5C7, 0xA382, + 0xE5C8, 0xA383, + 0xE5C9, 0xA384, + 0xE5CA, 0xA385, + 0xE5CB, 0xA386, + 0xE5CC, 0xA387, + 0xE5CD, 0xA388, + 0xE5CE, 0xA389, + 0xE5CF, 0xA38A, + 0xE5D0, 0xA38B, + 0xE5D1, 0xA38C, + 0xE5D2, 0xA38D, + 0xE5D3, 0xA38E, + 0xE5D4, 0xA38F, + 0xE5D5, 0xA390, + 0xE5D6, 0xA391, + 0xE5D7, 0xA392, + 0xE5D8, 0xA393, + 0xE5D9, 0xA394, + 0xE5DA, 0xA395, + 0xE5DB, 0xA396, + 0xE5DC, 0xA397, + 0xE5DD, 0xA398, + 0xE5DE, 0xA399, + 0xE5DF, 0xA39A, + 0xE5E0, 0xA39B, + 0xE5E1, 0xA39C, + 0xE5E2, 0xA39D, + 0xE5E3, 0xA39E, + 0xE5E4, 0xA39F, + 0xE5E5, 0xA3A0, + 0xE5E6, 0xA440, + 0xE5E7, 0xA441, + 0xE5E8, 0xA442, + 0xE5E9, 0xA443, + 0xE5EA, 0xA444, + 0xE5EB, 0xA445, + 0xE5EC, 0xA446, + 0xE5ED, 0xA447, + 0xE5EE, 0xA448, + 0xE5EF, 0xA449, + 0xE5F0, 0xA44A, + 0xE5F1, 0xA44B, + 0xE5F2, 0xA44C, + 0xE5F3, 0xA44D, + 0xE5F4, 0xA44E, + 0xE5F5, 0xA44F, + 0xE5F6, 0xA450, + 0xE5F7, 0xA451, + 0xE5F8, 0xA452, + 0xE5F9, 0xA453, + 0xE5FA, 0xA454, + 0xE5FB, 0xA455, + 0xE5FC, 0xA456, + 0xE5FD, 0xA457, + 0xE5FE, 0xA458, + 0xE5FF, 0xA459, + 0xE600, 0xA45A, + 0xE601, 0xA45B, + 0xE602, 0xA45C, + 0xE603, 0xA45D, + 0xE604, 0xA45E, + 0xE605, 0xA45F, + 0xE606, 0xA460, + 0xE607, 0xA461, + 0xE608, 0xA462, + 0xE609, 0xA463, + 0xE60A, 0xA464, + 0xE60B, 0xA465, + 0xE60C, 0xA466, + 0xE60D, 0xA467, + 0xE60E, 0xA468, + 0xE60F, 0xA469, + 0xE610, 0xA46A, + 0xE611, 0xA46B, + 0xE612, 0xA46C, + 0xE613, 0xA46D, + 0xE614, 0xA46E, + 0xE615, 0xA46F, + 0xE616, 0xA470, + 0xE617, 0xA471, + 0xE618, 0xA472, + 0xE619, 0xA473, + 0xE61A, 0xA474, + 0xE61B, 0xA475, + 0xE61C, 0xA476, + 0xE61D, 0xA477, + 0xE61E, 0xA478, + 0xE61F, 0xA479, + 0xE620, 0xA47A, + 0xE621, 0xA47B, + 0xE622, 0xA47C, + 0xE623, 0xA47D, + 0xE624, 0xA47E, + 0xE625, 0xA480, + 0xE626, 0xA481, + 0xE627, 0xA482, + 0xE628, 0xA483, + 0xE629, 0xA484, + 0xE62A, 0xA485, + 0xE62B, 0xA486, + 0xE62C, 0xA487, + 0xE62D, 0xA488, + 0xE62E, 0xA489, + 0xE62F, 0xA48A, + 0xE630, 0xA48B, + 0xE631, 0xA48C, + 0xE632, 0xA48D, + 0xE633, 0xA48E, + 0xE634, 0xA48F, + 0xE635, 0xA490, + 0xE636, 0xA491, + 0xE637, 0xA492, + 0xE638, 0xA493, + 0xE639, 0xA494, + 0xE63A, 0xA495, + 0xE63B, 0xA496, + 0xE63C, 0xA497, + 0xE63D, 0xA498, + 0xE63E, 0xA499, + 0xE63F, 0xA49A, + 0xE640, 0xA49B, + 0xE641, 0xA49C, + 0xE642, 0xA49D, + 0xE643, 0xA49E, + 0xE644, 0xA49F, + 0xE645, 0xA4A0, + 0xE646, 0xA540, + 0xE647, 0xA541, + 0xE648, 0xA542, + 0xE649, 0xA543, + 0xE64A, 0xA544, + 0xE64B, 0xA545, + 0xE64C, 0xA546, + 0xE64D, 0xA547, + 0xE64E, 0xA548, + 0xE64F, 0xA549, + 0xE650, 0xA54A, + 0xE651, 0xA54B, + 0xE652, 0xA54C, + 0xE653, 0xA54D, + 0xE654, 0xA54E, + 0xE655, 0xA54F, + 0xE656, 0xA550, + 0xE657, 0xA551, + 0xE658, 0xA552, + 0xE659, 0xA553, + 0xE65A, 0xA554, + 0xE65B, 0xA555, + 0xE65C, 0xA556, + 0xE65D, 0xA557, + 0xE65E, 0xA558, + 0xE65F, 0xA559, + 0xE660, 0xA55A, + 0xE661, 0xA55B, + 0xE662, 0xA55C, + 0xE663, 0xA55D, + 0xE664, 0xA55E, + 0xE665, 0xA55F, + 0xE666, 0xA560, + 0xE667, 0xA561, + 0xE668, 0xA562, + 0xE669, 0xA563, + 0xE66A, 0xA564, + 0xE66B, 0xA565, + 0xE66C, 0xA566, + 0xE66D, 0xA567, + 0xE66E, 0xA568, + 0xE66F, 0xA569, + 0xE670, 0xA56A, + 0xE671, 0xA56B, + 0xE672, 0xA56C, + 0xE673, 0xA56D, + 0xE674, 0xA56E, + 0xE675, 0xA56F, + 0xE676, 0xA570, + 0xE677, 0xA571, + 0xE678, 0xA572, + 0xE679, 0xA573, + 0xE67A, 0xA574, + 0xE67B, 0xA575, + 0xE67C, 0xA576, + 0xE67D, 0xA577, + 0xE67E, 0xA578, + 0xE67F, 0xA579, + 0xE680, 0xA57A, + 0xE681, 0xA57B, + 0xE682, 0xA57C, + 0xE683, 0xA57D, + 0xE684, 0xA57E, + 0xE685, 0xA580, + 0xE686, 0xA581, + 0xE687, 0xA582, + 0xE688, 0xA583, + 0xE689, 0xA584, + 0xE68A, 0xA585, + 0xE68B, 0xA586, + 0xE68C, 0xA587, + 0xE68D, 0xA588, + 0xE68E, 0xA589, + 0xE68F, 0xA58A, + 0xE690, 0xA58B, + 0xE691, 0xA58C, + 0xE692, 0xA58D, + 0xE693, 0xA58E, + 0xE694, 0xA58F, + 0xE695, 0xA590, + 0xE696, 0xA591, + 0xE697, 0xA592, + 0xE698, 0xA593, + 0xE699, 0xA594, + 0xE69A, 0xA595, + 0xE69B, 0xA596, + 0xE69C, 0xA597, + 0xE69D, 0xA598, + 0xE69E, 0xA599, + 0xE69F, 0xA59A, + 0xE6A0, 0xA59B, + 0xE6A1, 0xA59C, + 0xE6A2, 0xA59D, + 0xE6A3, 0xA59E, + 0xE6A4, 0xA59F, + 0xE6A5, 0xA5A0, + 0xE6A6, 0xA640, + 0xE6A7, 0xA641, + 0xE6A8, 0xA642, + 0xE6A9, 0xA643, + 0xE6AA, 0xA644, + 0xE6AB, 0xA645, + 0xE6AC, 0xA646, + 0xE6AD, 0xA647, + 0xE6AE, 0xA648, + 0xE6AF, 0xA649, + 0xE6B0, 0xA64A, + 0xE6B1, 0xA64B, + 0xE6B2, 0xA64C, + 0xE6B3, 0xA64D, + 0xE6B4, 0xA64E, + 0xE6B5, 0xA64F, + 0xE6B6, 0xA650, + 0xE6B7, 0xA651, + 0xE6B8, 0xA652, + 0xE6B9, 0xA653, + 0xE6BA, 0xA654, + 0xE6BB, 0xA655, + 0xE6BC, 0xA656, + 0xE6BD, 0xA657, + 0xE6BE, 0xA658, + 0xE6BF, 0xA659, + 0xE6C0, 0xA65A, + 0xE6C1, 0xA65B, + 0xE6C2, 0xA65C, + 0xE6C3, 0xA65D, + 0xE6C4, 0xA65E, + 0xE6C5, 0xA65F, + 0xE6C6, 0xA660, + 0xE6C7, 0xA661, + 0xE6C8, 0xA662, + 0xE6C9, 0xA663, + 0xE6CA, 0xA664, + 0xE6CB, 0xA665, + 0xE6CC, 0xA666, + 0xE6CD, 0xA667, + 0xE6CE, 0xA668, + 0xE6CF, 0xA669, + 0xE6D0, 0xA66A, + 0xE6D1, 0xA66B, + 0xE6D2, 0xA66C, + 0xE6D3, 0xA66D, + 0xE6D4, 0xA66E, + 0xE6D5, 0xA66F, + 0xE6D6, 0xA670, + 0xE6D7, 0xA671, + 0xE6D8, 0xA672, + 0xE6D9, 0xA673, + 0xE6DA, 0xA674, + 0xE6DB, 0xA675, + 0xE6DC, 0xA676, + 0xE6DD, 0xA677, + 0xE6DE, 0xA678, + 0xE6DF, 0xA679, + 0xE6E0, 0xA67A, + 0xE6E1, 0xA67B, + 0xE6E2, 0xA67C, + 0xE6E3, 0xA67D, + 0xE6E4, 0xA67E, + 0xE6E5, 0xA680, + 0xE6E6, 0xA681, + 0xE6E7, 0xA682, + 0xE6E8, 0xA683, + 0xE6E9, 0xA684, + 0xE6EA, 0xA685, + 0xE6EB, 0xA686, + 0xE6EC, 0xA687, + 0xE6ED, 0xA688, + 0xE6EE, 0xA689, + 0xE6EF, 0xA68A, + 0xE6F0, 0xA68B, + 0xE6F1, 0xA68C, + 0xE6F2, 0xA68D, + 0xE6F3, 0xA68E, + 0xE6F4, 0xA68F, + 0xE6F5, 0xA690, + 0xE6F6, 0xA691, + 0xE6F7, 0xA692, + 0xE6F8, 0xA693, + 0xE6F9, 0xA694, + 0xE6FA, 0xA695, + 0xE6FB, 0xA696, + 0xE6FC, 0xA697, + 0xE6FD, 0xA698, + 0xE6FE, 0xA699, + 0xE6FF, 0xA69A, + 0xE700, 0xA69B, + 0xE701, 0xA69C, + 0xE702, 0xA69D, + 0xE703, 0xA69E, + 0xE704, 0xA69F, + 0xE705, 0xA6A0, + 0xE706, 0xA740, + 0xE707, 0xA741, + 0xE708, 0xA742, + 0xE709, 0xA743, + 0xE70A, 0xA744, + 0xE70B, 0xA745, + 0xE70C, 0xA746, + 0xE70D, 0xA747, + 0xE70E, 0xA748, + 0xE70F, 0xA749, + 0xE710, 0xA74A, + 0xE711, 0xA74B, + 0xE712, 0xA74C, + 0xE713, 0xA74D, + 0xE714, 0xA74E, + 0xE715, 0xA74F, + 0xE716, 0xA750, + 0xE717, 0xA751, + 0xE718, 0xA752, + 0xE719, 0xA753, + 0xE71A, 0xA754, + 0xE71B, 0xA755, + 0xE71C, 0xA756, + 0xE71D, 0xA757, + 0xE71E, 0xA758, + 0xE71F, 0xA759, + 0xE720, 0xA75A, + 0xE721, 0xA75B, + 0xE722, 0xA75C, + 0xE723, 0xA75D, + 0xE724, 0xA75E, + 0xE725, 0xA75F, + 0xE726, 0xA760, + 0xE727, 0xA761, + 0xE728, 0xA762, + 0xE729, 0xA763, + 0xE72A, 0xA764, + 0xE72B, 0xA765, + 0xE72C, 0xA766, + 0xE72D, 0xA767, + 0xE72E, 0xA768, + 0xE72F, 0xA769, + 0xE730, 0xA76A, + 0xE731, 0xA76B, + 0xE732, 0xA76C, + 0xE733, 0xA76D, + 0xE734, 0xA76E, + 0xE735, 0xA76F, + 0xE736, 0xA770, + 0xE737, 0xA771, + 0xE738, 0xA772, + 0xE739, 0xA773, + 0xE73A, 0xA774, + 0xE73B, 0xA775, + 0xE73C, 0xA776, + 0xE73D, 0xA777, + 0xE73E, 0xA778, + 0xE73F, 0xA779, + 0xE740, 0xA77A, + 0xE741, 0xA77B, + 0xE742, 0xA77C, + 0xE743, 0xA77D, + 0xE744, 0xA77E, + 0xE745, 0xA780, + 0xE746, 0xA781, + 0xE747, 0xA782, + 0xE748, 0xA783, + 0xE749, 0xA784, + 0xE74A, 0xA785, + 0xE74B, 0xA786, + 0xE74C, 0xA787, + 0xE74D, 0xA788, + 0xE74E, 0xA789, + 0xE74F, 0xA78A, + 0xE750, 0xA78B, + 0xE751, 0xA78C, + 0xE752, 0xA78D, + 0xE753, 0xA78E, + 0xE754, 0xA78F, + 0xE755, 0xA790, + 0xE756, 0xA791, + 0xE757, 0xA792, + 0xE758, 0xA793, + 0xE759, 0xA794, + 0xE75A, 0xA795, + 0xE75B, 0xA796, + 0xE75C, 0xA797, + 0xE75D, 0xA798, + 0xE75E, 0xA799, + 0xE75F, 0xA79A, + 0xE760, 0xA79B, + 0xE761, 0xA79C, + 0xE762, 0xA79D, + 0xE763, 0xA79E, + 0xE764, 0xA79F, + 0xE765, 0xA7A0, + 0xE766, 0xA2AB, + 0xE767, 0xA2AC, + 0xE768, 0xA2AD, + 0xE769, 0xA2AE, + 0xE76A, 0xA2AF, + 0xE76B, 0xA2B0, + 0xE76D, 0xA2E4, + 0xE76E, 0xA2EF, + 0xE76F, 0xA2F0, + 0xE770, 0xA2FD, + 0xE771, 0xA2FE, + 0xE772, 0xA4F4, + 0xE773, 0xA4F5, + 0xE774, 0xA4F6, + 0xE775, 0xA4F7, + 0xE776, 0xA4F8, + 0xE777, 0xA4F9, + 0xE778, 0xA4FA, + 0xE779, 0xA4FB, + 0xE77A, 0xA4FC, + 0xE77B, 0xA4FD, + 0xE77C, 0xA4FE, + 0xE77D, 0xA5F7, + 0xE77E, 0xA5F8, + 0xE77F, 0xA5F9, + 0xE780, 0xA5FA, + 0xE781, 0xA5FB, + 0xE782, 0xA5FC, + 0xE783, 0xA5FD, + 0xE784, 0xA5FE, + 0xE785, 0xA6B9, + 0xE786, 0xA6BA, + 0xE787, 0xA6BB, + 0xE788, 0xA6BC, + 0xE789, 0xA6BD, + 0xE78A, 0xA6BE, + 0xE78B, 0xA6BF, + 0xE78C, 0xA6C0, + 0xE78D, 0xA6D9, + 0xE78E, 0xA6DA, + 0xE78F, 0xA6DB, + 0xE790, 0xA6DC, + 0xE791, 0xA6DD, + 0xE792, 0xA6DE, + 0xE793, 0xA6DF, + 0xE794, 0xA6EC, + 0xE795, 0xA6ED, + 0xE796, 0xA6F3, + 0xE797, 0xA6F6, + 0xE798, 0xA6F7, + 0xE799, 0xA6F8, + 0xE79A, 0xA6F9, + 0xE79B, 0xA6FA, + 0xE79C, 0xA6FB, + 0xE79D, 0xA6FC, + 0xE79E, 0xA6FD, + 0xE79F, 0xA6FE, + 0xE7A0, 0xA7C2, + 0xE7A1, 0xA7C3, + 0xE7A2, 0xA7C4, + 0xE7A3, 0xA7C5, + 0xE7A4, 0xA7C6, + 0xE7A5, 0xA7C7, + 0xE7A6, 0xA7C8, + 0xE7A7, 0xA7C9, + 0xE7A8, 0xA7CA, + 0xE7A9, 0xA7CB, + 0xE7AA, 0xA7CC, + 0xE7AB, 0xA7CD, + 0xE7AC, 0xA7CE, + 0xE7AD, 0xA7CF, + 0xE7AE, 0xA7D0, + 0xE7AF, 0xA7F2, + 0xE7B0, 0xA7F3, + 0xE7B1, 0xA7F4, + 0xE7B2, 0xA7F5, + 0xE7B3, 0xA7F6, + 0xE7B4, 0xA7F7, + 0xE7B5, 0xA7F8, + 0xE7B6, 0xA7F9, + 0xE7B7, 0xA7FA, + 0xE7B8, 0xA7FB, + 0xE7B9, 0xA7FC, + 0xE7BA, 0xA7FD, + 0xE7BB, 0xA7FE, + 0xE7BC, 0xA896, + 0xE7BD, 0xA897, + 0xE7BE, 0xA898, + 0xE7BF, 0xA899, + 0xE7C0, 0xA89A, + 0xE7C1, 0xA89B, + 0xE7C2, 0xA89C, + 0xE7C3, 0xA89D, + 0xE7C4, 0xA89E, + 0xE7C5, 0xA89F, + 0xE7C6, 0xA8A0, + 0xE7C7, 0xA8BC, + 0xE7C9, 0xA8C1, + 0xE7CA, 0xA8C2, + 0xE7CB, 0xA8C3, + 0xE7CC, 0xA8C4, + 0xE7CD, 0xA8EA, + 0xE7CE, 0xA8EB, + 0xE7CF, 0xA8EC, + 0xE7D0, 0xA8ED, + 0xE7D1, 0xA8EE, + 0xE7D2, 0xA8EF, + 0xE7D3, 0xA8F0, + 0xE7D4, 0xA8F1, + 0xE7D5, 0xA8F2, + 0xE7D6, 0xA8F3, + 0xE7D7, 0xA8F4, + 0xE7D8, 0xA8F5, + 0xE7D9, 0xA8F6, + 0xE7DA, 0xA8F7, + 0xE7DB, 0xA8F8, + 0xE7DC, 0xA8F9, + 0xE7DD, 0xA8FA, + 0xE7DE, 0xA8FB, + 0xE7DF, 0xA8FC, + 0xE7E0, 0xA8FD, + 0xE7E1, 0xA8FE, + 0xE7E2, 0xA958, + 0xE7E3, 0xA95B, + 0xE7E4, 0xA95D, + 0xE7E5, 0xA95E, + 0xE7E6, 0xA95F, + 0xE7F4, 0xA997, + 0xE7F5, 0xA998, + 0xE7F6, 0xA999, + 0xE7F7, 0xA99A, + 0xE7F8, 0xA99B, + 0xE7F9, 0xA99C, + 0xE7FA, 0xA99D, + 0xE7FB, 0xA99E, + 0xE7FC, 0xA99F, + 0xE7FD, 0xA9A0, + 0xE7FE, 0xA9A1, + 0xE7FF, 0xA9A2, + 0xE800, 0xA9A3, + 0xE801, 0xA9F0, + 0xE802, 0xA9F1, + 0xE803, 0xA9F2, + 0xE804, 0xA9F3, + 0xE805, 0xA9F4, + 0xE806, 0xA9F5, + 0xE807, 0xA9F6, + 0xE808, 0xA9F7, + 0xE809, 0xA9F8, + 0xE80A, 0xA9F9, + 0xE80B, 0xA9FA, + 0xE80C, 0xA9FB, + 0xE80D, 0xA9FC, + 0xE80E, 0xA9FD, + 0xE80F, 0xA9FE, + 0xE810, 0xD7FA, + 0xE811, 0xD7FB, + 0xE812, 0xD7FC, + 0xE813, 0xD7FD, + 0xE814, 0xD7FE, + 0xE816, 0xFE51, + 0xE817, 0xFE52, + 0xE818, 0xFE53, + 0xE81E, 0xFE59, + 0xE826, 0xFE61, + 0xE82B, 0xFE66, + 0xE82C, 0xFE67, + 0xE831, 0xFE6C, + 0xE832, 0xFE6D, + 0xE83B, 0xFE76, + 0xE843, 0xFE7E, + 0xE854, 0xFE90, + 0xE855, 0xFE91, + 0xE864, 0xFEA0, + 0xF92C, 0xFD9C, + 0xF979, 0xFD9D, + 0xF995, 0xFD9E, + 0xF9E7, 0xFD9F, + 0xF9F1, 0xFDA0, + 0xFA0C, 0xFE40, + 0xFA0D, 0xFE41, + 0xFA0E, 0xFE42, + 0xFA0F, 0xFE43, + 0xFA11, 0xFE44, + 0xFA13, 0xFE45, + 0xFA14, 0xFE46, + 0xFA18, 0xFE47, + 0xFA1F, 0xFE48, + 0xFA20, 0xFE49, + 0xFA21, 0xFE4A, + 0xFA23, 0xFE4B, + 0xFA24, 0xFE4C, + 0xFA27, 0xFE4D, + 0xFA28, 0xFE4E, + 0xFA29, 0xFE4F, + 0xFE30, 0xA955, + 0xFE31, 0xA6F2, + 0xFE33, 0xA6F4, + 0xFE34, 0xA6F5, + 0xFE35, 0xA6E0, + 0xFE36, 0xA6E1, + 0xFE37, 0xA6F0, + 0xFE38, 0xA6F1, + 0xFE39, 0xA6E2, + 0xFE3A, 0xA6E3, + 0xFE3B, 0xA6EE, + 0xFE3C, 0xA6EF, + 0xFE3D, 0xA6E6, + 0xFE3E, 0xA6E7, + 0xFE3F, 0xA6E4, + 0xFE40, 0xA6E5, + 0xFE41, 0xA6E8, + 0xFE42, 0xA6E9, + 0xFE43, 0xA6EA, + 0xFE44, 0xA6EB, + 0xFE49, 0xA968, + 0xFE4A, 0xA969, + 0xFE4B, 0xA96A, + 0xFE4C, 0xA96B, + 0xFE4D, 0xA96C, + 0xFE4E, 0xA96D, + 0xFE4F, 0xA96E, + 0xFE50, 0xA96F, + 0xFE51, 0xA970, + 0xFE52, 0xA971, + 0xFE54, 0xA972, + 0xFE55, 0xA973, + 0xFE56, 0xA974, + 0xFE57, 0xA975, + 0xFE59, 0xA976, + 0xFE5A, 0xA977, + 0xFE5B, 0xA978, + 0xFE5C, 0xA979, + 0xFE5D, 0xA97A, + 0xFE5E, 0xA97B, + 0xFE5F, 0xA97C, + 0xFE60, 0xA97D, + 0xFE61, 0xA97E, + 0xFE62, 0xA980, + 0xFE63, 0xA981, + 0xFE64, 0xA982, + 0xFE65, 0xA983, + 0xFE66, 0xA984, + 0xFE68, 0xA985, + 0xFE69, 0xA986, + 0xFE6A, 0xA987, + 0xFE6B, 0xA988, + 0xFFE2, 0xA956, + 0xFFE4, 0xA957 +}; + +static const unsigned short int gb18030_fourbyte_lookup[] = { + 0x0080, 0x8130, 0x8130, + 0x0081, 0x8130, 0x8131, + 0x0082, 0x8130, 0x8132, + 0x0083, 0x8130, 0x8133, + 0x0084, 0x8130, 0x8134, + 0x0085, 0x8130, 0x8135, + 0x0086, 0x8130, 0x8136, + 0x0087, 0x8130, 0x8137, + 0x0088, 0x8130, 0x8138, + 0x0089, 0x8130, 0x8139, + 0x008A, 0x8130, 0x8230, + 0x008B, 0x8130, 0x8231, + 0x008C, 0x8130, 0x8232, + 0x008D, 0x8130, 0x8233, + 0x008E, 0x8130, 0x8234, + 0x008F, 0x8130, 0x8235, + 0x0090, 0x8130, 0x8236, + 0x0091, 0x8130, 0x8237, + 0x0092, 0x8130, 0x8238, + 0x0093, 0x8130, 0x8239, + 0x0094, 0x8130, 0x8330, + 0x0095, 0x8130, 0x8331, + 0x0096, 0x8130, 0x8332, + 0x0097, 0x8130, 0x8333, + 0x0098, 0x8130, 0x8334, + 0x0099, 0x8130, 0x8335, + 0x009A, 0x8130, 0x8336, + 0x009B, 0x8130, 0x8337, + 0x009C, 0x8130, 0x8338, + 0x009D, 0x8130, 0x8339, + 0x009E, 0x8130, 0x8430, + 0x009F, 0x8130, 0x8431, + 0x00A0, 0x8130, 0x8432, + 0x00A1, 0x8130, 0x8433, + 0x00A2, 0x8130, 0x8434, + 0x00A3, 0x8130, 0x8435, + 0x00A5, 0x8130, 0x8436, + 0x00A6, 0x8130, 0x8437, + 0x00A9, 0x8130, 0x8438, + 0x00AA, 0x8130, 0x8439, + 0x00AB, 0x8130, 0x8530, + 0x00AC, 0x8130, 0x8531, + 0x00AD, 0x8130, 0x8532, + 0x00AE, 0x8130, 0x8533, + 0x00AF, 0x8130, 0x8534, + 0x00B2, 0x8130, 0x8535, + 0x00B3, 0x8130, 0x8536, + 0x00B4, 0x8130, 0x8537, + 0x00B5, 0x8130, 0x8538, + 0x00B6, 0x8130, 0x8539, + 0x00B8, 0x8130, 0x8630, + 0x00B9, 0x8130, 0x8631, + 0x00BA, 0x8130, 0x8632, + 0x00BB, 0x8130, 0x8633, + 0x00BC, 0x8130, 0x8634, + 0x00BD, 0x8130, 0x8635, + 0x00BE, 0x8130, 0x8636, + 0x00BF, 0x8130, 0x8637, + 0x00C0, 0x8130, 0x8638, + 0x00C1, 0x8130, 0x8639, + 0x00C2, 0x8130, 0x8730, + 0x00C3, 0x8130, 0x8731, + 0x00C4, 0x8130, 0x8732, + 0x00C5, 0x8130, 0x8733, + 0x00C6, 0x8130, 0x8734, + 0x00C7, 0x8130, 0x8735, + 0x00C8, 0x8130, 0x8736, + 0x00C9, 0x8130, 0x8737, + 0x00CA, 0x8130, 0x8738, + 0x00CB, 0x8130, 0x8739, + 0x00CC, 0x8130, 0x8830, + 0x00CD, 0x8130, 0x8831, + 0x00CE, 0x8130, 0x8832, + 0x00CF, 0x8130, 0x8833, + 0x00D0, 0x8130, 0x8834, + 0x00D1, 0x8130, 0x8835, + 0x00D2, 0x8130, 0x8836, + 0x00D3, 0x8130, 0x8837, + 0x00D4, 0x8130, 0x8838, + 0x00D5, 0x8130, 0x8839, + 0x00D6, 0x8130, 0x8930, + 0x00D8, 0x8130, 0x8931, + 0x00D9, 0x8130, 0x8932, + 0x00DA, 0x8130, 0x8933, + 0x00DB, 0x8130, 0x8934, + 0x00DC, 0x8130, 0x8935, + 0x00DD, 0x8130, 0x8936, + 0x00DE, 0x8130, 0x8937, + 0x00DF, 0x8130, 0x8938, + 0x00E2, 0x8130, 0x8939, + 0x00E3, 0x8130, 0x8A30, + 0x00E4, 0x8130, 0x8A31, + 0x00E5, 0x8130, 0x8A32, + 0x00E6, 0x8130, 0x8A33, + 0x00E7, 0x8130, 0x8A34, + 0x00EB, 0x8130, 0x8A35, + 0x00EE, 0x8130, 0x8A36, + 0x00EF, 0x8130, 0x8A37, + 0x00F0, 0x8130, 0x8A38, + 0x00F1, 0x8130, 0x8A39, + 0x00F4, 0x8130, 0x8B30, + 0x00F5, 0x8130, 0x8B31, + 0x00F6, 0x8130, 0x8B32, + 0x00F8, 0x8130, 0x8B33, + 0x00FB, 0x8130, 0x8B34, + 0x00FD, 0x8130, 0x8B35, + 0x00FE, 0x8130, 0x8B36, + 0x00FF, 0x8130, 0x8B37, + 0x0100, 0x8130, 0x8B38, + 0x0102, 0x8130, 0x8B39, + 0x0103, 0x8130, 0x8C30, + 0x0104, 0x8130, 0x8C31, + 0x0105, 0x8130, 0x8C32, + 0x0106, 0x8130, 0x8C33, + 0x0107, 0x8130, 0x8C34, + 0x0108, 0x8130, 0x8C35, + 0x0109, 0x8130, 0x8C36, + 0x010A, 0x8130, 0x8C37, + 0x010B, 0x8130, 0x8C38, + 0x010C, 0x8130, 0x8C39, + 0x010D, 0x8130, 0x8D30, + 0x010E, 0x8130, 0x8D31, + 0x010F, 0x8130, 0x8D32, + 0x0110, 0x8130, 0x8D33, + 0x0111, 0x8130, 0x8D34, + 0x0112, 0x8130, 0x8D35, + 0x0114, 0x8130, 0x8D36, + 0x0115, 0x8130, 0x8D37, + 0x0116, 0x8130, 0x8D38, + 0x0117, 0x8130, 0x8D39, + 0x0118, 0x8130, 0x8E30, + 0x0119, 0x8130, 0x8E31, + 0x011A, 0x8130, 0x8E32, + 0x011C, 0x8130, 0x8E33, + 0x011D, 0x8130, 0x8E34, + 0x011E, 0x8130, 0x8E35, + 0x011F, 0x8130, 0x8E36, + 0x0120, 0x8130, 0x8E37, + 0x0121, 0x8130, 0x8E38, + 0x0122, 0x8130, 0x8E39, + 0x0123, 0x8130, 0x8F30, + 0x0124, 0x8130, 0x8F31, + 0x0125, 0x8130, 0x8F32, + 0x0126, 0x8130, 0x8F33, + 0x0127, 0x8130, 0x8F34, + 0x0128, 0x8130, 0x8F35, + 0x0129, 0x8130, 0x8F36, + 0x012A, 0x8130, 0x8F37, + 0x012C, 0x8130, 0x8F38, + 0x012D, 0x8130, 0x8F39, + 0x012E, 0x8130, 0x9030, + 0x012F, 0x8130, 0x9031, + 0x0130, 0x8130, 0x9032, + 0x0131, 0x8130, 0x9033, + 0x0132, 0x8130, 0x9034, + 0x0133, 0x8130, 0x9035, + 0x0134, 0x8130, 0x9036, + 0x0135, 0x8130, 0x9037, + 0x0136, 0x8130, 0x9038, + 0x0137, 0x8130, 0x9039, + 0x0138, 0x8130, 0x9130, + 0x0139, 0x8130, 0x9131, + 0x013A, 0x8130, 0x9132, + 0x013B, 0x8130, 0x9133, + 0x013C, 0x8130, 0x9134, + 0x013D, 0x8130, 0x9135, + 0x013E, 0x8130, 0x9136, + 0x013F, 0x8130, 0x9137, + 0x0140, 0x8130, 0x9138, + 0x0141, 0x8130, 0x9139, + 0x0142, 0x8130, 0x9230, + 0x0143, 0x8130, 0x9231, + 0x0145, 0x8130, 0x9232, + 0x0146, 0x8130, 0x9233, + 0x0147, 0x8130, 0x9234, + 0x0149, 0x8130, 0x9235, + 0x014A, 0x8130, 0x9236, + 0x014B, 0x8130, 0x9237, + 0x014C, 0x8130, 0x9238, + 0x014E, 0x8130, 0x9239, + 0x014F, 0x8130, 0x9330, + 0x0150, 0x8130, 0x9331, + 0x0151, 0x8130, 0x9332, + 0x0152, 0x8130, 0x9333, + 0x0153, 0x8130, 0x9334, + 0x0154, 0x8130, 0x9335, + 0x0155, 0x8130, 0x9336, + 0x0156, 0x8130, 0x9337, + 0x0157, 0x8130, 0x9338, + 0x0158, 0x8130, 0x9339, + 0x0159, 0x8130, 0x9430, + 0x015A, 0x8130, 0x9431, + 0x015B, 0x8130, 0x9432, + 0x015C, 0x8130, 0x9433, + 0x015D, 0x8130, 0x9434, + 0x015E, 0x8130, 0x9435, + 0x015F, 0x8130, 0x9436, + 0x0160, 0x8130, 0x9437, + 0x0161, 0x8130, 0x9438, + 0x0162, 0x8130, 0x9439, + 0x0163, 0x8130, 0x9530, + 0x0164, 0x8130, 0x9531, + 0x0165, 0x8130, 0x9532, + 0x0166, 0x8130, 0x9533, + 0x0167, 0x8130, 0x9534, + 0x0168, 0x8130, 0x9535, + 0x0169, 0x8130, 0x9536, + 0x016A, 0x8130, 0x9537, + 0x016C, 0x8130, 0x9538, + 0x016D, 0x8130, 0x9539, + 0x016E, 0x8130, 0x9630, + 0x016F, 0x8130, 0x9631, + 0x0170, 0x8130, 0x9632, + 0x0171, 0x8130, 0x9633, + 0x0172, 0x8130, 0x9634, + 0x0173, 0x8130, 0x9635, + 0x0174, 0x8130, 0x9636, + 0x0175, 0x8130, 0x9637, + 0x0176, 0x8130, 0x9638, + 0x0177, 0x8130, 0x9639, + 0x0178, 0x8130, 0x9730, + 0x0179, 0x8130, 0x9731, + 0x017A, 0x8130, 0x9732, + 0x017B, 0x8130, 0x9733, + 0x017C, 0x8130, 0x9734, + 0x017D, 0x8130, 0x9735, + 0x017E, 0x8130, 0x9736, + 0x017F, 0x8130, 0x9737, + 0x0180, 0x8130, 0x9738, + 0x0181, 0x8130, 0x9739, + 0x0182, 0x8130, 0x9830, + 0x0183, 0x8130, 0x9831, + 0x0184, 0x8130, 0x9832, + 0x0185, 0x8130, 0x9833, + 0x0186, 0x8130, 0x9834, + 0x0187, 0x8130, 0x9835, + 0x0188, 0x8130, 0x9836, + 0x0189, 0x8130, 0x9837, + 0x018A, 0x8130, 0x9838, + 0x018B, 0x8130, 0x9839, + 0x018C, 0x8130, 0x9930, + 0x018D, 0x8130, 0x9931, + 0x018E, 0x8130, 0x9932, + 0x018F, 0x8130, 0x9933, + 0x0190, 0x8130, 0x9934, + 0x0191, 0x8130, 0x9935, + 0x0192, 0x8130, 0x9936, + 0x0193, 0x8130, 0x9937, + 0x0194, 0x8130, 0x9938, + 0x0195, 0x8130, 0x9939, + 0x0196, 0x8130, 0x9A30, + 0x0197, 0x8130, 0x9A31, + 0x0198, 0x8130, 0x9A32, + 0x0199, 0x8130, 0x9A33, + 0x019A, 0x8130, 0x9A34, + 0x019B, 0x8130, 0x9A35, + 0x019C, 0x8130, 0x9A36, + 0x019D, 0x8130, 0x9A37, + 0x019E, 0x8130, 0x9A38, + 0x019F, 0x8130, 0x9A39, + 0x01A0, 0x8130, 0x9B30, + 0x01A1, 0x8130, 0x9B31, + 0x01A2, 0x8130, 0x9B32, + 0x01A3, 0x8130, 0x9B33, + 0x01A4, 0x8130, 0x9B34, + 0x01A5, 0x8130, 0x9B35, + 0x01A6, 0x8130, 0x9B36, + 0x01A7, 0x8130, 0x9B37, + 0x01A8, 0x8130, 0x9B38, + 0x01A9, 0x8130, 0x9B39, + 0x01AA, 0x8130, 0x9C30, + 0x01AB, 0x8130, 0x9C31, + 0x01AC, 0x8130, 0x9C32, + 0x01AD, 0x8130, 0x9C33, + 0x01AE, 0x8130, 0x9C34, + 0x01AF, 0x8130, 0x9C35, + 0x01B0, 0x8130, 0x9C36, + 0x01B1, 0x8130, 0x9C37, + 0x01B2, 0x8130, 0x9C38, + 0x01B3, 0x8130, 0x9C39, + 0x01B4, 0x8130, 0x9D30, + 0x01B5, 0x8130, 0x9D31, + 0x01B6, 0x8130, 0x9D32, + 0x01B7, 0x8130, 0x9D33, + 0x01B8, 0x8130, 0x9D34, + 0x01B9, 0x8130, 0x9D35, + 0x01BA, 0x8130, 0x9D36, + 0x01BB, 0x8130, 0x9D37, + 0x01BC, 0x8130, 0x9D38, + 0x01BD, 0x8130, 0x9D39, + 0x01BE, 0x8130, 0x9E30, + 0x01BF, 0x8130, 0x9E31, + 0x01C0, 0x8130, 0x9E32, + 0x01C1, 0x8130, 0x9E33, + 0x01C2, 0x8130, 0x9E34, + 0x01C3, 0x8130, 0x9E35, + 0x01C4, 0x8130, 0x9E36, + 0x01C5, 0x8130, 0x9E37, + 0x01C6, 0x8130, 0x9E38, + 0x01C7, 0x8130, 0x9E39, + 0x01C8, 0x8130, 0x9F30, + 0x01C9, 0x8130, 0x9F31, + 0x01CA, 0x8130, 0x9F32, + 0x01CB, 0x8130, 0x9F33, + 0x01CC, 0x8130, 0x9F34, + 0x01CD, 0x8130, 0x9F35, + 0x01CF, 0x8130, 0x9F36, + 0x01D1, 0x8130, 0x9F37, + 0x01D3, 0x8130, 0x9F38, + 0x01D5, 0x8130, 0x9F39, + 0x01D7, 0x8130, 0xA030, + 0x01D9, 0x8130, 0xA031, + 0x01DB, 0x8130, 0xA032, + 0x01DD, 0x8130, 0xA033, + 0x01DE, 0x8130, 0xA034, + 0x01DF, 0x8130, 0xA035, + 0x01E0, 0x8130, 0xA036, + 0x01E1, 0x8130, 0xA037, + 0x01E2, 0x8130, 0xA038, + 0x01E3, 0x8130, 0xA039, + 0x01E4, 0x8130, 0xA130, + 0x01E5, 0x8130, 0xA131, + 0x01E6, 0x8130, 0xA132, + 0x01E7, 0x8130, 0xA133, + 0x01E8, 0x8130, 0xA134, + 0x01E9, 0x8130, 0xA135, + 0x01EA, 0x8130, 0xA136, + 0x01EB, 0x8130, 0xA137, + 0x01EC, 0x8130, 0xA138, + 0x01ED, 0x8130, 0xA139, + 0x01EE, 0x8130, 0xA230, + 0x01EF, 0x8130, 0xA231, + 0x01F0, 0x8130, 0xA232, + 0x01F1, 0x8130, 0xA233, + 0x01F2, 0x8130, 0xA234, + 0x01F3, 0x8130, 0xA235, + 0x01F4, 0x8130, 0xA236, + 0x01F5, 0x8130, 0xA237, + 0x01F6, 0x8130, 0xA238, + 0x01F7, 0x8130, 0xA239, + 0x01F8, 0x8130, 0xA330, + 0x01FA, 0x8130, 0xA331, + 0x01FB, 0x8130, 0xA332, + 0x01FC, 0x8130, 0xA333, + 0x01FD, 0x8130, 0xA334, + 0x01FE, 0x8130, 0xA335, + 0x01FF, 0x8130, 0xA336, + 0x0200, 0x8130, 0xA337, + 0x0201, 0x8130, 0xA338, + 0x0202, 0x8130, 0xA339, + 0x0203, 0x8130, 0xA430, + 0x0204, 0x8130, 0xA431, + 0x0205, 0x8130, 0xA432, + 0x0206, 0x8130, 0xA433, + 0x0207, 0x8130, 0xA434, + 0x0208, 0x8130, 0xA435, + 0x0209, 0x8130, 0xA436, + 0x020A, 0x8130, 0xA437, + 0x020B, 0x8130, 0xA438, + 0x020C, 0x8130, 0xA439, + 0x020D, 0x8130, 0xA530, + 0x020E, 0x8130, 0xA531, + 0x020F, 0x8130, 0xA532, + 0x0210, 0x8130, 0xA533, + 0x0211, 0x8130, 0xA534, + 0x0212, 0x8130, 0xA535, + 0x0213, 0x8130, 0xA536, + 0x0214, 0x8130, 0xA537, + 0x0215, 0x8130, 0xA538, + 0x0216, 0x8130, 0xA539, + 0x0217, 0x8130, 0xA630, + 0x0218, 0x8130, 0xA631, + 0x0219, 0x8130, 0xA632, + 0x021A, 0x8130, 0xA633, + 0x021B, 0x8130, 0xA634, + 0x021C, 0x8130, 0xA635, + 0x021D, 0x8130, 0xA636, + 0x021E, 0x8130, 0xA637, + 0x021F, 0x8130, 0xA638, + 0x0220, 0x8130, 0xA639, + 0x0221, 0x8130, 0xA730, + 0x0222, 0x8130, 0xA731, + 0x0223, 0x8130, 0xA732, + 0x0224, 0x8130, 0xA733, + 0x0225, 0x8130, 0xA734, + 0x0226, 0x8130, 0xA735, + 0x0227, 0x8130, 0xA736, + 0x0228, 0x8130, 0xA737, + 0x0229, 0x8130, 0xA738, + 0x022A, 0x8130, 0xA739, + 0x022B, 0x8130, 0xA830, + 0x022C, 0x8130, 0xA831, + 0x022D, 0x8130, 0xA832, + 0x022E, 0x8130, 0xA833, + 0x022F, 0x8130, 0xA834, + 0x0230, 0x8130, 0xA835, + 0x0231, 0x8130, 0xA836, + 0x0232, 0x8130, 0xA837, + 0x0233, 0x8130, 0xA838, + 0x0234, 0x8130, 0xA839, + 0x0235, 0x8130, 0xA930, + 0x0236, 0x8130, 0xA931, + 0x0237, 0x8130, 0xA932, + 0x0238, 0x8130, 0xA933, + 0x0239, 0x8130, 0xA934, + 0x023A, 0x8130, 0xA935, + 0x023B, 0x8130, 0xA936, + 0x023C, 0x8130, 0xA937, + 0x023D, 0x8130, 0xA938, + 0x023E, 0x8130, 0xA939, + 0x023F, 0x8130, 0xAA30, + 0x0240, 0x8130, 0xAA31, + 0x0241, 0x8130, 0xAA32, + 0x0242, 0x8130, 0xAA33, + 0x0243, 0x8130, 0xAA34, + 0x0244, 0x8130, 0xAA35, + 0x0245, 0x8130, 0xAA36, + 0x0246, 0x8130, 0xAA37, + 0x0247, 0x8130, 0xAA38, + 0x0248, 0x8130, 0xAA39, + 0x0249, 0x8130, 0xAB30, + 0x024A, 0x8130, 0xAB31, + 0x024B, 0x8130, 0xAB32, + 0x024C, 0x8130, 0xAB33, + 0x024D, 0x8130, 0xAB34, + 0x024E, 0x8130, 0xAB35, + 0x024F, 0x8130, 0xAB36, + 0x0250, 0x8130, 0xAB37, + 0x0252, 0x8130, 0xAB38, + 0x0253, 0x8130, 0xAB39, + 0x0254, 0x8130, 0xAC30, + 0x0255, 0x8130, 0xAC31, + 0x0256, 0x8130, 0xAC32, + 0x0257, 0x8130, 0xAC33, + 0x0258, 0x8130, 0xAC34, + 0x0259, 0x8130, 0xAC35, + 0x025A, 0x8130, 0xAC36, + 0x025B, 0x8130, 0xAC37, + 0x025C, 0x8130, 0xAC38, + 0x025D, 0x8130, 0xAC39, + 0x025E, 0x8130, 0xAD30, + 0x025F, 0x8130, 0xAD31, + 0x0260, 0x8130, 0xAD32, + 0x0262, 0x8130, 0xAD33, + 0x0263, 0x8130, 0xAD34, + 0x0264, 0x8130, 0xAD35, + 0x0265, 0x8130, 0xAD36, + 0x0266, 0x8130, 0xAD37, + 0x0267, 0x8130, 0xAD38, + 0x0268, 0x8130, 0xAD39, + 0x0269, 0x8130, 0xAE30, + 0x026A, 0x8130, 0xAE31, + 0x026B, 0x8130, 0xAE32, + 0x026C, 0x8130, 0xAE33, + 0x026D, 0x8130, 0xAE34, + 0x026E, 0x8130, 0xAE35, + 0x026F, 0x8130, 0xAE36, + 0x0270, 0x8130, 0xAE37, + 0x0271, 0x8130, 0xAE38, + 0x0272, 0x8130, 0xAE39, + 0x0273, 0x8130, 0xAF30, + 0x0274, 0x8130, 0xAF31, + 0x0275, 0x8130, 0xAF32, + 0x0276, 0x8130, 0xAF33, + 0x0277, 0x8130, 0xAF34, + 0x0278, 0x8130, 0xAF35, + 0x0279, 0x8130, 0xAF36, + 0x027A, 0x8130, 0xAF37, + 0x027B, 0x8130, 0xAF38, + 0x027C, 0x8130, 0xAF39, + 0x027D, 0x8130, 0xB030, + 0x027E, 0x8130, 0xB031, + 0x027F, 0x8130, 0xB032, + 0x0280, 0x8130, 0xB033, + 0x0281, 0x8130, 0xB034, + 0x0282, 0x8130, 0xB035, + 0x0283, 0x8130, 0xB036, + 0x0284, 0x8130, 0xB037, + 0x0285, 0x8130, 0xB038, + 0x0286, 0x8130, 0xB039, + 0x0287, 0x8130, 0xB130, + 0x0288, 0x8130, 0xB131, + 0x0289, 0x8130, 0xB132, + 0x028A, 0x8130, 0xB133, + 0x028B, 0x8130, 0xB134, + 0x028C, 0x8130, 0xB135, + 0x028D, 0x8130, 0xB136, + 0x028E, 0x8130, 0xB137, + 0x028F, 0x8130, 0xB138, + 0x0290, 0x8130, 0xB139, + 0x0291, 0x8130, 0xB230, + 0x0292, 0x8130, 0xB231, + 0x0293, 0x8130, 0xB232, + 0x0294, 0x8130, 0xB233, + 0x0295, 0x8130, 0xB234, + 0x0296, 0x8130, 0xB235, + 0x0297, 0x8130, 0xB236, + 0x0298, 0x8130, 0xB237, + 0x0299, 0x8130, 0xB238, + 0x029A, 0x8130, 0xB239, + 0x029B, 0x8130, 0xB330, + 0x029C, 0x8130, 0xB331, + 0x029D, 0x8130, 0xB332, + 0x029E, 0x8130, 0xB333, + 0x029F, 0x8130, 0xB334, + 0x02A0, 0x8130, 0xB335, + 0x02A1, 0x8130, 0xB336, + 0x02A2, 0x8130, 0xB337, + 0x02A3, 0x8130, 0xB338, + 0x02A4, 0x8130, 0xB339, + 0x02A5, 0x8130, 0xB430, + 0x02A6, 0x8130, 0xB431, + 0x02A7, 0x8130, 0xB432, + 0x02A8, 0x8130, 0xB433, + 0x02A9, 0x8130, 0xB434, + 0x02AA, 0x8130, 0xB435, + 0x02AB, 0x8130, 0xB436, + 0x02AC, 0x8130, 0xB437, + 0x02AD, 0x8130, 0xB438, + 0x02AE, 0x8130, 0xB439, + 0x02AF, 0x8130, 0xB530, + 0x02B0, 0x8130, 0xB531, + 0x02B1, 0x8130, 0xB532, + 0x02B2, 0x8130, 0xB533, + 0x02B3, 0x8130, 0xB534, + 0x02B4, 0x8130, 0xB535, + 0x02B5, 0x8130, 0xB536, + 0x02B6, 0x8130, 0xB537, + 0x02B7, 0x8130, 0xB538, + 0x02B8, 0x8130, 0xB539, + 0x02B9, 0x8130, 0xB630, + 0x02BA, 0x8130, 0xB631, + 0x02BB, 0x8130, 0xB632, + 0x02BC, 0x8130, 0xB633, + 0x02BD, 0x8130, 0xB634, + 0x02BE, 0x8130, 0xB635, + 0x02BF, 0x8130, 0xB636, + 0x02C0, 0x8130, 0xB637, + 0x02C1, 0x8130, 0xB638, + 0x02C2, 0x8130, 0xB639, + 0x02C3, 0x8130, 0xB730, + 0x02C4, 0x8130, 0xB731, + 0x02C5, 0x8130, 0xB732, + 0x02C6, 0x8130, 0xB733, + 0x02C8, 0x8130, 0xB734, + 0x02CC, 0x8130, 0xB735, + 0x02CD, 0x8130, 0xB736, + 0x02CE, 0x8130, 0xB737, + 0x02CF, 0x8130, 0xB738, + 0x02D0, 0x8130, 0xB739, + 0x02D1, 0x8130, 0xB830, + 0x02D2, 0x8130, 0xB831, + 0x02D3, 0x8130, 0xB832, + 0x02D4, 0x8130, 0xB833, + 0x02D5, 0x8130, 0xB834, + 0x02D6, 0x8130, 0xB835, + 0x02D7, 0x8130, 0xB836, + 0x02D8, 0x8130, 0xB837, + 0x02DA, 0x8130, 0xB838, + 0x02DB, 0x8130, 0xB839, + 0x02DC, 0x8130, 0xB930, + 0x02DD, 0x8130, 0xB931, + 0x02DE, 0x8130, 0xB932, + 0x02DF, 0x8130, 0xB933, + 0x02E0, 0x8130, 0xB934, + 0x02E1, 0x8130, 0xB935, + 0x02E2, 0x8130, 0xB936, + 0x02E3, 0x8130, 0xB937, + 0x02E4, 0x8130, 0xB938, + 0x02E5, 0x8130, 0xB939, + 0x02E6, 0x8130, 0xBA30, + 0x02E7, 0x8130, 0xBA31, + 0x02E8, 0x8130, 0xBA32, + 0x02E9, 0x8130, 0xBA33, + 0x02EA, 0x8130, 0xBA34, + 0x02EB, 0x8130, 0xBA35, + 0x02EC, 0x8130, 0xBA36, + 0x02ED, 0x8130, 0xBA37, + 0x02EE, 0x8130, 0xBA38, + 0x02EF, 0x8130, 0xBA39, + 0x02F0, 0x8130, 0xBB30, + 0x02F1, 0x8130, 0xBB31, + 0x02F2, 0x8130, 0xBB32, + 0x02F3, 0x8130, 0xBB33, + 0x02F4, 0x8130, 0xBB34, + 0x02F5, 0x8130, 0xBB35, + 0x02F6, 0x8130, 0xBB36, + 0x02F7, 0x8130, 0xBB37, + 0x02F8, 0x8130, 0xBB38, + 0x02F9, 0x8130, 0xBB39, + 0x02FA, 0x8130, 0xBC30, + 0x02FB, 0x8130, 0xBC31, + 0x02FC, 0x8130, 0xBC32, + 0x02FD, 0x8130, 0xBC33, + 0x02FE, 0x8130, 0xBC34, + 0x02FF, 0x8130, 0xBC35, + 0x0300, 0x8130, 0xBC36, + 0x0301, 0x8130, 0xBC37, + 0x0302, 0x8130, 0xBC38, + 0x0303, 0x8130, 0xBC39, + 0x0304, 0x8130, 0xBD30, + 0x0305, 0x8130, 0xBD31, + 0x0306, 0x8130, 0xBD32, + 0x0307, 0x8130, 0xBD33, + 0x0308, 0x8130, 0xBD34, + 0x0309, 0x8130, 0xBD35, + 0x030A, 0x8130, 0xBD36, + 0x030B, 0x8130, 0xBD37, + 0x030C, 0x8130, 0xBD38, + 0x030D, 0x8130, 0xBD39, + 0x030E, 0x8130, 0xBE30, + 0x030F, 0x8130, 0xBE31, + 0x0310, 0x8130, 0xBE32, + 0x0311, 0x8130, 0xBE33, + 0x0312, 0x8130, 0xBE34, + 0x0313, 0x8130, 0xBE35, + 0x0314, 0x8130, 0xBE36, + 0x0315, 0x8130, 0xBE37, + 0x0316, 0x8130, 0xBE38, + 0x0317, 0x8130, 0xBE39, + 0x0318, 0x8130, 0xBF30, + 0x0319, 0x8130, 0xBF31, + 0x031A, 0x8130, 0xBF32, + 0x031B, 0x8130, 0xBF33, + 0x031C, 0x8130, 0xBF34, + 0x031D, 0x8130, 0xBF35, + 0x031E, 0x8130, 0xBF36, + 0x031F, 0x8130, 0xBF37, + 0x0320, 0x8130, 0xBF38, + 0x0321, 0x8130, 0xBF39, + 0x0322, 0x8130, 0xC030, + 0x0323, 0x8130, 0xC031, + 0x0324, 0x8130, 0xC032, + 0x0325, 0x8130, 0xC033, + 0x0326, 0x8130, 0xC034, + 0x0327, 0x8130, 0xC035, + 0x0328, 0x8130, 0xC036, + 0x0329, 0x8130, 0xC037, + 0x032A, 0x8130, 0xC038, + 0x032B, 0x8130, 0xC039, + 0x032C, 0x8130, 0xC130, + 0x032D, 0x8130, 0xC131, + 0x032E, 0x8130, 0xC132, + 0x032F, 0x8130, 0xC133, + 0x0330, 0x8130, 0xC134, + 0x0331, 0x8130, 0xC135, + 0x0332, 0x8130, 0xC136, + 0x0333, 0x8130, 0xC137, + 0x0334, 0x8130, 0xC138, + 0x0335, 0x8130, 0xC139, + 0x0336, 0x8130, 0xC230, + 0x0337, 0x8130, 0xC231, + 0x0338, 0x8130, 0xC232, + 0x0339, 0x8130, 0xC233, + 0x033A, 0x8130, 0xC234, + 0x033B, 0x8130, 0xC235, + 0x033C, 0x8130, 0xC236, + 0x033D, 0x8130, 0xC237, + 0x033E, 0x8130, 0xC238, + 0x033F, 0x8130, 0xC239, + 0x0340, 0x8130, 0xC330, + 0x0341, 0x8130, 0xC331, + 0x0342, 0x8130, 0xC332, + 0x0343, 0x8130, 0xC333, + 0x0344, 0x8130, 0xC334, + 0x0345, 0x8130, 0xC335, + 0x0346, 0x8130, 0xC336, + 0x0347, 0x8130, 0xC337, + 0x0348, 0x8130, 0xC338, + 0x0349, 0x8130, 0xC339, + 0x034A, 0x8130, 0xC430, + 0x034B, 0x8130, 0xC431, + 0x034C, 0x8130, 0xC432, + 0x034D, 0x8130, 0xC433, + 0x034E, 0x8130, 0xC434, + 0x034F, 0x8130, 0xC435, + 0x0350, 0x8130, 0xC436, + 0x0351, 0x8130, 0xC437, + 0x0352, 0x8130, 0xC438, + 0x0353, 0x8130, 0xC439, + 0x0354, 0x8130, 0xC530, + 0x0355, 0x8130, 0xC531, + 0x0356, 0x8130, 0xC532, + 0x0357, 0x8130, 0xC533, + 0x0358, 0x8130, 0xC534, + 0x0359, 0x8130, 0xC535, + 0x035A, 0x8130, 0xC536, + 0x035B, 0x8130, 0xC537, + 0x035C, 0x8130, 0xC538, + 0x035D, 0x8130, 0xC539, + 0x035E, 0x8130, 0xC630, + 0x035F, 0x8130, 0xC631, + 0x0360, 0x8130, 0xC632, + 0x0361, 0x8130, 0xC633, + 0x0362, 0x8130, 0xC634, + 0x0363, 0x8130, 0xC635, + 0x0364, 0x8130, 0xC636, + 0x0365, 0x8130, 0xC637, + 0x0366, 0x8130, 0xC638, + 0x0367, 0x8130, 0xC639, + 0x0368, 0x8130, 0xC730, + 0x0369, 0x8130, 0xC731, + 0x036A, 0x8130, 0xC732, + 0x036B, 0x8130, 0xC733, + 0x036C, 0x8130, 0xC734, + 0x036D, 0x8130, 0xC735, + 0x036E, 0x8130, 0xC736, + 0x036F, 0x8130, 0xC737, + 0x0370, 0x8130, 0xC738, + 0x0371, 0x8130, 0xC739, + 0x0372, 0x8130, 0xC830, + 0x0373, 0x8130, 0xC831, + 0x0374, 0x8130, 0xC832, + 0x0375, 0x8130, 0xC833, + 0x0376, 0x8130, 0xC834, + 0x0377, 0x8130, 0xC835, + 0x0378, 0x8130, 0xC836, + 0x0379, 0x8130, 0xC837, + 0x037A, 0x8130, 0xC838, + 0x037B, 0x8130, 0xC839, + 0x037C, 0x8130, 0xC930, + 0x037D, 0x8130, 0xC931, + 0x037E, 0x8130, 0xC932, + 0x037F, 0x8130, 0xC933, + 0x0380, 0x8130, 0xC934, + 0x0381, 0x8130, 0xC935, + 0x0382, 0x8130, 0xC936, + 0x0383, 0x8130, 0xC937, + 0x0384, 0x8130, 0xC938, + 0x0385, 0x8130, 0xC939, + 0x0386, 0x8130, 0xCA30, + 0x0387, 0x8130, 0xCA31, + 0x0388, 0x8130, 0xCA32, + 0x0389, 0x8130, 0xCA33, + 0x038A, 0x8130, 0xCA34, + 0x038B, 0x8130, 0xCA35, + 0x038C, 0x8130, 0xCA36, + 0x038D, 0x8130, 0xCA37, + 0x038E, 0x8130, 0xCA38, + 0x038F, 0x8130, 0xCA39, + 0x0390, 0x8130, 0xCB30, + 0x03A2, 0x8130, 0xCB31, + 0x03AA, 0x8130, 0xCB32, + 0x03AB, 0x8130, 0xCB33, + 0x03AC, 0x8130, 0xCB34, + 0x03AD, 0x8130, 0xCB35, + 0x03AE, 0x8130, 0xCB36, + 0x03AF, 0x8130, 0xCB37, + 0x03B0, 0x8130, 0xCB38, + 0x03C2, 0x8130, 0xCB39, + 0x03CA, 0x8130, 0xCC30, + 0x03CB, 0x8130, 0xCC31, + 0x03CC, 0x8130, 0xCC32, + 0x03CD, 0x8130, 0xCC33, + 0x03CE, 0x8130, 0xCC34, + 0x03CF, 0x8130, 0xCC35, + 0x03D0, 0x8130, 0xCC36, + 0x03D1, 0x8130, 0xCC37, + 0x03D2, 0x8130, 0xCC38, + 0x03D3, 0x8130, 0xCC39, + 0x03D4, 0x8130, 0xCD30, + 0x03D5, 0x8130, 0xCD31, + 0x03D6, 0x8130, 0xCD32, + 0x03D7, 0x8130, 0xCD33, + 0x03D8, 0x8130, 0xCD34, + 0x03D9, 0x8130, 0xCD35, + 0x03DA, 0x8130, 0xCD36, + 0x03DB, 0x8130, 0xCD37, + 0x03DC, 0x8130, 0xCD38, + 0x03DD, 0x8130, 0xCD39, + 0x03DE, 0x8130, 0xCE30, + 0x03DF, 0x8130, 0xCE31, + 0x03E0, 0x8130, 0xCE32, + 0x03E1, 0x8130, 0xCE33, + 0x03E2, 0x8130, 0xCE34, + 0x03E3, 0x8130, 0xCE35, + 0x03E4, 0x8130, 0xCE36, + 0x03E5, 0x8130, 0xCE37, + 0x03E6, 0x8130, 0xCE38, + 0x03E7, 0x8130, 0xCE39, + 0x03E8, 0x8130, 0xCF30, + 0x03E9, 0x8130, 0xCF31, + 0x03EA, 0x8130, 0xCF32, + 0x03EB, 0x8130, 0xCF33, + 0x03EC, 0x8130, 0xCF34, + 0x03ED, 0x8130, 0xCF35, + 0x03EE, 0x8130, 0xCF36, + 0x03EF, 0x8130, 0xCF37, + 0x03F0, 0x8130, 0xCF38, + 0x03F1, 0x8130, 0xCF39, + 0x03F2, 0x8130, 0xD030, + 0x03F3, 0x8130, 0xD031, + 0x03F4, 0x8130, 0xD032, + 0x03F5, 0x8130, 0xD033, + 0x03F6, 0x8130, 0xD034, + 0x03F7, 0x8130, 0xD035, + 0x03F8, 0x8130, 0xD036, + 0x03F9, 0x8130, 0xD037, + 0x03FA, 0x8130, 0xD038, + 0x03FB, 0x8130, 0xD039, + 0x03FC, 0x8130, 0xD130, + 0x03FD, 0x8130, 0xD131, + 0x03FE, 0x8130, 0xD132, + 0x03FF, 0x8130, 0xD133, + 0x0400, 0x8130, 0xD134, + 0x0402, 0x8130, 0xD135, + 0x0403, 0x8130, 0xD136, + 0x0404, 0x8130, 0xD137, + 0x0405, 0x8130, 0xD138, + 0x0406, 0x8130, 0xD139, + 0x0407, 0x8130, 0xD230, + 0x0408, 0x8130, 0xD231, + 0x0409, 0x8130, 0xD232, + 0x040A, 0x8130, 0xD233, + 0x040B, 0x8130, 0xD234, + 0x040C, 0x8130, 0xD235, + 0x040D, 0x8130, 0xD236, + 0x040E, 0x8130, 0xD237, + 0x040F, 0x8130, 0xD238, + 0x0450, 0x8130, 0xD239, + 0x2011, 0x8136, 0xA532, + 0x2012, 0x8136, 0xA533, + 0x2017, 0x8136, 0xA534, + 0x201A, 0x8136, 0xA535, + 0x201B, 0x8136, 0xA536, + 0x201E, 0x8136, 0xA537, + 0x201F, 0x8136, 0xA538, + 0x2020, 0x8136, 0xA539, + 0x2021, 0x8136, 0xA630, + 0x2022, 0x8136, 0xA631, + 0x2023, 0x8136, 0xA632, + 0x2024, 0x8136, 0xA633, + 0x2027, 0x8136, 0xA634, + 0x2028, 0x8136, 0xA635, + 0x2029, 0x8136, 0xA636, + 0x202A, 0x8136, 0xA637, + 0x202B, 0x8136, 0xA638, + 0x202C, 0x8136, 0xA639, + 0x202D, 0x8136, 0xA730, + 0x202E, 0x8136, 0xA731, + 0x202F, 0x8136, 0xA732, + 0x2031, 0x8136, 0xA733, + 0x2034, 0x8136, 0xA734, + 0x2036, 0x8136, 0xA735, + 0x2037, 0x8136, 0xA736, + 0x2038, 0x8136, 0xA737, + 0x2039, 0x8136, 0xA738, + 0x203A, 0x8136, 0xA739, + 0x203C, 0x8136, 0xA830, + 0x203D, 0x8136, 0xA831, + 0x203E, 0x8136, 0xA832, + 0x203F, 0x8136, 0xA833, + 0x2040, 0x8136, 0xA834, + 0x2041, 0x8136, 0xA835, + 0x2042, 0x8136, 0xA836, + 0x2043, 0x8136, 0xA837, + 0x2044, 0x8136, 0xA838, + 0x2045, 0x8136, 0xA839, + 0x2046, 0x8136, 0xA930, + 0x2047, 0x8136, 0xA931, + 0x2048, 0x8136, 0xA932, + 0x2049, 0x8136, 0xA933, + 0x204A, 0x8136, 0xA934, + 0x204B, 0x8136, 0xA935, + 0x204C, 0x8136, 0xA936, + 0x204D, 0x8136, 0xA937, + 0x204E, 0x8136, 0xA938, + 0x204F, 0x8136, 0xA939, + 0x2050, 0x8136, 0xAA30, + 0x2051, 0x8136, 0xAA31, + 0x2052, 0x8136, 0xAA32, + 0x2053, 0x8136, 0xAA33, + 0x2054, 0x8136, 0xAA34, + 0x2055, 0x8136, 0xAA35, + 0x2056, 0x8136, 0xAA36, + 0x2057, 0x8136, 0xAA37, + 0x2058, 0x8136, 0xAA38, + 0x2059, 0x8136, 0xAA39, + 0x205A, 0x8136, 0xAB30, + 0x205B, 0x8136, 0xAB31, + 0x205C, 0x8136, 0xAB32, + 0x205D, 0x8136, 0xAB33, + 0x205E, 0x8136, 0xAB34, + 0x205F, 0x8136, 0xAB35, + 0x2060, 0x8136, 0xAB36, + 0x2061, 0x8136, 0xAB37, + 0x2062, 0x8136, 0xAB38, + 0x2063, 0x8136, 0xAB39, + 0x2064, 0x8136, 0xAC30, + 0x2065, 0x8136, 0xAC31, + 0x2066, 0x8136, 0xAC32, + 0x2067, 0x8136, 0xAC33, + 0x2068, 0x8136, 0xAC34, + 0x2069, 0x8136, 0xAC35, + 0x206A, 0x8136, 0xAC36, + 0x206B, 0x8136, 0xAC37, + 0x206C, 0x8136, 0xAC38, + 0x206D, 0x8136, 0xAC39, + 0x206E, 0x8136, 0xAD30, + 0x206F, 0x8136, 0xAD31, + 0x2070, 0x8136, 0xAD32, + 0x2071, 0x8136, 0xAD33, + 0x2072, 0x8136, 0xAD34, + 0x2073, 0x8136, 0xAD35, + 0x2074, 0x8136, 0xAD36, + 0x2075, 0x8136, 0xAD37, + 0x2076, 0x8136, 0xAD38, + 0x2077, 0x8136, 0xAD39, + 0x2078, 0x8136, 0xAE30, + 0x2079, 0x8136, 0xAE31, + 0x207A, 0x8136, 0xAE32, + 0x207B, 0x8136, 0xAE33, + 0x207C, 0x8136, 0xAE34, + 0x207D, 0x8136, 0xAE35, + 0x207E, 0x8136, 0xAE36, + 0x207F, 0x8136, 0xAE37, + 0x2080, 0x8136, 0xAE38, + 0x2081, 0x8136, 0xAE39, + 0x2082, 0x8136, 0xAF30, + 0x2083, 0x8136, 0xAF31, + 0x2084, 0x8136, 0xAF32, + 0x2085, 0x8136, 0xAF33, + 0x2086, 0x8136, 0xAF34, + 0x2087, 0x8136, 0xAF35, + 0x2088, 0x8136, 0xAF36, + 0x2089, 0x8136, 0xAF37, + 0x208A, 0x8136, 0xAF38, + 0x208B, 0x8136, 0xAF39, + 0x208C, 0x8136, 0xB030, + 0x208D, 0x8136, 0xB031, + 0x208E, 0x8136, 0xB032, + 0x208F, 0x8136, 0xB033, + 0x2090, 0x8136, 0xB034, + 0x2091, 0x8136, 0xB035, + 0x2092, 0x8136, 0xB036, + 0x2093, 0x8136, 0xB037, + 0x2094, 0x8136, 0xB038, + 0x2095, 0x8136, 0xB039, + 0x2096, 0x8136, 0xB130, + 0x2097, 0x8136, 0xB131, + 0x2098, 0x8136, 0xB132, + 0x2099, 0x8136, 0xB133, + 0x209A, 0x8136, 0xB134, + 0x209B, 0x8136, 0xB135, + 0x209C, 0x8136, 0xB136, + 0x209D, 0x8136, 0xB137, + 0x209E, 0x8136, 0xB138, + 0x209F, 0x8136, 0xB139, + 0x20A0, 0x8136, 0xB230, + 0x20A1, 0x8136, 0xB231, + 0x20A2, 0x8136, 0xB232, + 0x20A3, 0x8136, 0xB233, + 0x20A4, 0x8136, 0xB234, + 0x20A5, 0x8136, 0xB235, + 0x20A6, 0x8136, 0xB236, + 0x20A7, 0x8136, 0xB237, + 0x20A8, 0x8136, 0xB238, + 0x20A9, 0x8136, 0xB239, + 0x20AA, 0x8136, 0xB330, + 0x20AB, 0x8136, 0xB331, + 0x20AD, 0x8136, 0xB332, + 0x20AE, 0x8136, 0xB333, + 0x20AF, 0x8136, 0xB334, + 0x20B0, 0x8136, 0xB335, + 0x20B1, 0x8136, 0xB336, + 0x20B2, 0x8136, 0xB337, + 0x20B3, 0x8136, 0xB338, + 0x20B4, 0x8136, 0xB339, + 0x20B5, 0x8136, 0xB430, + 0x20B6, 0x8136, 0xB431, + 0x20B7, 0x8136, 0xB432, + 0x20B8, 0x8136, 0xB433, + 0x20B9, 0x8136, 0xB434, + 0x20BA, 0x8136, 0xB435, + 0x20BB, 0x8136, 0xB436, + 0x20BC, 0x8136, 0xB437, + 0x20BD, 0x8136, 0xB438, + 0x20BE, 0x8136, 0xB439, + 0x20BF, 0x8136, 0xB530, + 0x20C0, 0x8136, 0xB531, + 0x20C1, 0x8136, 0xB532, + 0x20C2, 0x8136, 0xB533, + 0x20C3, 0x8136, 0xB534, + 0x20C4, 0x8136, 0xB535, + 0x20C5, 0x8136, 0xB536, + 0x20C6, 0x8136, 0xB537, + 0x20C7, 0x8136, 0xB538, + 0x20C8, 0x8136, 0xB539, + 0x20C9, 0x8136, 0xB630, + 0x20CA, 0x8136, 0xB631, + 0x20CB, 0x8136, 0xB632, + 0x20CC, 0x8136, 0xB633, + 0x20CD, 0x8136, 0xB634, + 0x20CE, 0x8136, 0xB635, + 0x20CF, 0x8136, 0xB636, + 0x20D0, 0x8136, 0xB637, + 0x20D1, 0x8136, 0xB638, + 0x20D2, 0x8136, 0xB639, + 0x20D3, 0x8136, 0xB730, + 0x20D4, 0x8136, 0xB731, + 0x20D5, 0x8136, 0xB732, + 0x20D6, 0x8136, 0xB733, + 0x20D7, 0x8136, 0xB734, + 0x20D8, 0x8136, 0xB735, + 0x20D9, 0x8136, 0xB736, + 0x20DA, 0x8136, 0xB737, + 0x20DB, 0x8136, 0xB738, + 0x20DC, 0x8136, 0xB739, + 0x20DD, 0x8136, 0xB830, + 0x20DE, 0x8136, 0xB831, + 0x20DF, 0x8136, 0xB832, + 0x20E0, 0x8136, 0xB833, + 0x20E1, 0x8136, 0xB834, + 0x20E2, 0x8136, 0xB835, + 0x20E3, 0x8136, 0xB836, + 0x20E4, 0x8136, 0xB837, + 0x20E5, 0x8136, 0xB838, + 0x20E6, 0x8136, 0xB839, + 0x20E7, 0x8136, 0xB930, + 0x20E8, 0x8136, 0xB931, + 0x20E9, 0x8136, 0xB932, + 0x20EA, 0x8136, 0xB933, + 0x20EB, 0x8136, 0xB934, + 0x20EC, 0x8136, 0xB935, + 0x20ED, 0x8136, 0xB936, + 0x20EE, 0x8136, 0xB937, + 0x20EF, 0x8136, 0xB938, + 0x20F0, 0x8136, 0xB939, + 0x20F1, 0x8136, 0xBA30, + 0x20F2, 0x8136, 0xBA31, + 0x20F3, 0x8136, 0xBA32, + 0x20F4, 0x8136, 0xBA33, + 0x20F5, 0x8136, 0xBA34, + 0x20F6, 0x8136, 0xBA35, + 0x20F7, 0x8136, 0xBA36, + 0x20F8, 0x8136, 0xBA37, + 0x20F9, 0x8136, 0xBA38, + 0x20FA, 0x8136, 0xBA39, + 0x20FB, 0x8136, 0xBB30, + 0x20FC, 0x8136, 0xBB31, + 0x20FD, 0x8136, 0xBB32, + 0x20FE, 0x8136, 0xBB33, + 0x20FF, 0x8136, 0xBB34, + 0x2100, 0x8136, 0xBB35, + 0x2101, 0x8136, 0xBB36, + 0x2102, 0x8136, 0xBB37, + 0x2104, 0x8136, 0xBB38, + 0x2106, 0x8136, 0xBB39, + 0x2107, 0x8136, 0xBC30, + 0x2108, 0x8136, 0xBC31, + 0x210A, 0x8136, 0xBC32, + 0x210B, 0x8136, 0xBC33, + 0x210C, 0x8136, 0xBC34, + 0x210D, 0x8136, 0xBC35, + 0x210E, 0x8136, 0xBC36, + 0x210F, 0x8136, 0xBC37, + 0x2110, 0x8136, 0xBC38, + 0x2111, 0x8136, 0xBC39, + 0x2112, 0x8136, 0xBD30, + 0x2113, 0x8136, 0xBD31, + 0x2114, 0x8136, 0xBD32, + 0x2115, 0x8136, 0xBD33, + 0x2117, 0x8136, 0xBD34, + 0x2118, 0x8136, 0xBD35, + 0x2119, 0x8136, 0xBD36, + 0x211A, 0x8136, 0xBD37, + 0x211B, 0x8136, 0xBD38, + 0x211C, 0x8136, 0xBD39, + 0x211D, 0x8136, 0xBE30, + 0x211E, 0x8136, 0xBE31, + 0x211F, 0x8136, 0xBE32, + 0x2120, 0x8136, 0xBE33, + 0x2122, 0x8136, 0xBE34, + 0x2123, 0x8136, 0xBE35, + 0x2124, 0x8136, 0xBE36, + 0x2125, 0x8136, 0xBE37, + 0x2126, 0x8136, 0xBE38, + 0x2127, 0x8136, 0xBE39, + 0x2128, 0x8136, 0xBF30, + 0x2129, 0x8136, 0xBF31, + 0x212A, 0x8136, 0xBF32, + 0x212B, 0x8136, 0xBF33, + 0x212C, 0x8136, 0xBF34, + 0x212D, 0x8136, 0xBF35, + 0x212E, 0x8136, 0xBF36, + 0x212F, 0x8136, 0xBF37, + 0x2130, 0x8136, 0xBF38, + 0x2131, 0x8136, 0xBF39, + 0x2132, 0x8136, 0xC030, + 0x2133, 0x8136, 0xC031, + 0x2134, 0x8136, 0xC032, + 0x2135, 0x8136, 0xC033, + 0x2136, 0x8136, 0xC034, + 0x2137, 0x8136, 0xC035, + 0x2138, 0x8136, 0xC036, + 0x2139, 0x8136, 0xC037, + 0x213A, 0x8136, 0xC038, + 0x213B, 0x8136, 0xC039, + 0x213C, 0x8136, 0xC130, + 0x213D, 0x8136, 0xC131, + 0x213E, 0x8136, 0xC132, + 0x213F, 0x8136, 0xC133, + 0x2140, 0x8136, 0xC134, + 0x2141, 0x8136, 0xC135, + 0x2142, 0x8136, 0xC136, + 0x2143, 0x8136, 0xC137, + 0x2144, 0x8136, 0xC138, + 0x2145, 0x8136, 0xC139, + 0x2146, 0x8136, 0xC230, + 0x2147, 0x8136, 0xC231, + 0x2148, 0x8136, 0xC232, + 0x2149, 0x8136, 0xC233, + 0x214A, 0x8136, 0xC234, + 0x214B, 0x8136, 0xC235, + 0x214C, 0x8136, 0xC236, + 0x214D, 0x8136, 0xC237, + 0x214E, 0x8136, 0xC238, + 0x214F, 0x8136, 0xC239, + 0x2150, 0x8136, 0xC330, + 0x2151, 0x8136, 0xC331, + 0x2152, 0x8136, 0xC332, + 0x2153, 0x8136, 0xC333, + 0x2154, 0x8136, 0xC334, + 0x2155, 0x8136, 0xC335, + 0x2156, 0x8136, 0xC336, + 0x2157, 0x8136, 0xC337, + 0x2158, 0x8136, 0xC338, + 0x2159, 0x8136, 0xC339, + 0x215A, 0x8136, 0xC430, + 0x215B, 0x8136, 0xC431, + 0x215C, 0x8136, 0xC432, + 0x215D, 0x8136, 0xC433, + 0x215E, 0x8136, 0xC434, + 0x215F, 0x8136, 0xC435, + 0x216C, 0x8136, 0xC436, + 0x216D, 0x8136, 0xC437, + 0x216E, 0x8136, 0xC438, + 0x216F, 0x8136, 0xC439, + 0x217A, 0x8136, 0xC530, + 0x217B, 0x8136, 0xC531, + 0x217C, 0x8136, 0xC532, + 0x217D, 0x8136, 0xC533, + 0x217E, 0x8136, 0xC534, + 0x217F, 0x8136, 0xC535, + 0x2180, 0x8136, 0xC536, + 0x2181, 0x8136, 0xC537, + 0x2182, 0x8136, 0xC538, + 0x2183, 0x8136, 0xC539, + 0x2184, 0x8136, 0xC630, + 0x2185, 0x8136, 0xC631, + 0x2186, 0x8136, 0xC632, + 0x2187, 0x8136, 0xC633, + 0x2188, 0x8136, 0xC634, + 0x2189, 0x8136, 0xC635, + 0x218A, 0x8136, 0xC636, + 0x218B, 0x8136, 0xC637, + 0x218C, 0x8136, 0xC638, + 0x218D, 0x8136, 0xC639, + 0x218E, 0x8136, 0xC730, + 0x218F, 0x8136, 0xC731, + 0x2194, 0x8136, 0xC732, + 0x2195, 0x8136, 0xC733, + 0x219A, 0x8136, 0xC734, + 0x219B, 0x8136, 0xC735, + 0x219C, 0x8136, 0xC736, + 0x219D, 0x8136, 0xC737, + 0x219E, 0x8136, 0xC738, + 0x219F, 0x8136, 0xC739, + 0x21A0, 0x8136, 0xC830, + 0x21A1, 0x8136, 0xC831, + 0x21A2, 0x8136, 0xC832, + 0x21A3, 0x8136, 0xC833, + 0x21A4, 0x8136, 0xC834, + 0x21A5, 0x8136, 0xC835, + 0x21A6, 0x8136, 0xC836, + 0x21A7, 0x8136, 0xC837, + 0x21A8, 0x8136, 0xC838, + 0x21A9, 0x8136, 0xC839, + 0x21AA, 0x8136, 0xC930, + 0x21AB, 0x8136, 0xC931, + 0x21AC, 0x8136, 0xC932, + 0x21AD, 0x8136, 0xC933, + 0x21AE, 0x8136, 0xC934, + 0x21AF, 0x8136, 0xC935, + 0x21B0, 0x8136, 0xC936, + 0x21B1, 0x8136, 0xC937, + 0x21B2, 0x8136, 0xC938, + 0x21B3, 0x8136, 0xC939, + 0x21B4, 0x8136, 0xCA30, + 0x21B5, 0x8136, 0xCA31, + 0x21B6, 0x8136, 0xCA32, + 0x21B7, 0x8136, 0xCA33, + 0x21B8, 0x8136, 0xCA34, + 0x21B9, 0x8136, 0xCA35, + 0x21BA, 0x8136, 0xCA36, + 0x21BB, 0x8136, 0xCA37, + 0x21BC, 0x8136, 0xCA38, + 0x21BD, 0x8136, 0xCA39, + 0x21BE, 0x8136, 0xCB30, + 0x21BF, 0x8136, 0xCB31, + 0x21C0, 0x8136, 0xCB32, + 0x21C1, 0x8136, 0xCB33, + 0x21C2, 0x8136, 0xCB34, + 0x21C3, 0x8136, 0xCB35, + 0x21C4, 0x8136, 0xCB36, + 0x21C5, 0x8136, 0xCB37, + 0x21C6, 0x8136, 0xCB38, + 0x21C7, 0x8136, 0xCB39, + 0x21C8, 0x8136, 0xCC30, + 0x21C9, 0x8136, 0xCC31, + 0x21CA, 0x8136, 0xCC32, + 0x21CB, 0x8136, 0xCC33, + 0x21CC, 0x8136, 0xCC34, + 0x21CD, 0x8136, 0xCC35, + 0x21CE, 0x8136, 0xCC36, + 0x21CF, 0x8136, 0xCC37, + 0x21D0, 0x8136, 0xCC38, + 0x21D1, 0x8136, 0xCC39, + 0x21D2, 0x8136, 0xCD30, + 0x21D3, 0x8136, 0xCD31, + 0x21D4, 0x8136, 0xCD32, + 0x21D5, 0x8136, 0xCD33, + 0x21D6, 0x8136, 0xCD34, + 0x21D7, 0x8136, 0xCD35, + 0x21D8, 0x8136, 0xCD36, + 0x21D9, 0x8136, 0xCD37, + 0x21DA, 0x8136, 0xCD38, + 0x21DB, 0x8136, 0xCD39, + 0x21DC, 0x8136, 0xCE30, + 0x21DD, 0x8136, 0xCE31, + 0x21DE, 0x8136, 0xCE32, + 0x21DF, 0x8136, 0xCE33, + 0x21E0, 0x8136, 0xCE34, + 0x21E1, 0x8136, 0xCE35, + 0x21E2, 0x8136, 0xCE36, + 0x21E3, 0x8136, 0xCE37, + 0x21E4, 0x8136, 0xCE38, + 0x21E5, 0x8136, 0xCE39, + 0x21E6, 0x8136, 0xCF30, + 0x21E7, 0x8136, 0xCF31, + 0x21E8, 0x8136, 0xCF32, + 0x21E9, 0x8136, 0xCF33, + 0x21EA, 0x8136, 0xCF34, + 0x21EB, 0x8136, 0xCF35, + 0x21EC, 0x8136, 0xCF36, + 0x21ED, 0x8136, 0xCF37, + 0x21EE, 0x8136, 0xCF38, + 0x21EF, 0x8136, 0xCF39, + 0x21F0, 0x8136, 0xD030, + 0x21F1, 0x8136, 0xD031, + 0x21F2, 0x8136, 0xD032, + 0x21F3, 0x8136, 0xD033, + 0x21F4, 0x8136, 0xD034, + 0x21F5, 0x8136, 0xD035, + 0x21F6, 0x8136, 0xD036, + 0x21F7, 0x8136, 0xD037, + 0x21F8, 0x8136, 0xD038, + 0x21F9, 0x8136, 0xD039, + 0x21FA, 0x8136, 0xD130, + 0x21FB, 0x8136, 0xD131, + 0x21FC, 0x8136, 0xD132, + 0x21FD, 0x8136, 0xD133, + 0x21FE, 0x8136, 0xD134, + 0x21FF, 0x8136, 0xD135, + 0x2200, 0x8136, 0xD136, + 0x2201, 0x8136, 0xD137, + 0x2202, 0x8136, 0xD138, + 0x2203, 0x8136, 0xD139, + 0x2204, 0x8136, 0xD230, + 0x2205, 0x8136, 0xD231, + 0x2206, 0x8136, 0xD232, + 0x2207, 0x8136, 0xD233, + 0x2209, 0x8136, 0xD234, + 0x220A, 0x8136, 0xD235, + 0x220B, 0x8136, 0xD236, + 0x220C, 0x8136, 0xD237, + 0x220D, 0x8136, 0xD238, + 0x220E, 0x8136, 0xD239, + 0x2210, 0x8136, 0xD330, + 0x2212, 0x8136, 0xD331, + 0x2213, 0x8136, 0xD332, + 0x2214, 0x8136, 0xD333, + 0x2216, 0x8136, 0xD334, + 0x2217, 0x8136, 0xD335, + 0x2218, 0x8136, 0xD336, + 0x2219, 0x8136, 0xD337, + 0x221B, 0x8136, 0xD338, + 0x221C, 0x8136, 0xD339, + 0x2221, 0x8136, 0xD430, + 0x2222, 0x8136, 0xD431, + 0x2224, 0x8136, 0xD432, + 0x2226, 0x8136, 0xD433, + 0x222C, 0x8136, 0xD434, + 0x222D, 0x8136, 0xD435, + 0x222F, 0x8136, 0xD436, + 0x2230, 0x8136, 0xD437, + 0x2231, 0x8136, 0xD438, + 0x2232, 0x8136, 0xD439, + 0x2233, 0x8136, 0xD530, + 0x2238, 0x8136, 0xD531, + 0x2239, 0x8136, 0xD532, + 0x223A, 0x8136, 0xD533, + 0x223B, 0x8136, 0xD534, + 0x223C, 0x8136, 0xD535, + 0x223E, 0x8136, 0xD536, + 0x223F, 0x8136, 0xD537, + 0x2240, 0x8136, 0xD538, + 0x2241, 0x8136, 0xD539, + 0x2242, 0x8136, 0xD630, + 0x2243, 0x8136, 0xD631, + 0x2244, 0x8136, 0xD632, + 0x2245, 0x8136, 0xD633, + 0x2246, 0x8136, 0xD634, + 0x2247, 0x8136, 0xD635, + 0x2249, 0x8136, 0xD636, + 0x224A, 0x8136, 0xD637, + 0x224B, 0x8136, 0xD638, + 0x224D, 0x8136, 0xD639, + 0x224E, 0x8136, 0xD730, + 0x224F, 0x8136, 0xD731, + 0x2250, 0x8136, 0xD732, + 0x2251, 0x8136, 0xD733, + 0x2253, 0x8136, 0xD734, + 0x2254, 0x8136, 0xD735, + 0x2255, 0x8136, 0xD736, + 0x2256, 0x8136, 0xD737, + 0x2257, 0x8136, 0xD738, + 0x2258, 0x8136, 0xD739, + 0x2259, 0x8136, 0xD830, + 0x225A, 0x8136, 0xD831, + 0x225B, 0x8136, 0xD832, + 0x225C, 0x8136, 0xD833, + 0x225D, 0x8136, 0xD834, + 0x225E, 0x8136, 0xD835, + 0x225F, 0x8136, 0xD836, + 0x2262, 0x8136, 0xD837, + 0x2263, 0x8136, 0xD838, + 0x2268, 0x8136, 0xD839, + 0x2269, 0x8136, 0xD930, + 0x226A, 0x8136, 0xD931, + 0x226B, 0x8136, 0xD932, + 0x226C, 0x8136, 0xD933, + 0x226D, 0x8136, 0xD934, + 0x2270, 0x8136, 0xD935, + 0x2271, 0x8136, 0xD936, + 0x2272, 0x8136, 0xD937, + 0x2273, 0x8136, 0xD938, + 0x2274, 0x8136, 0xD939, + 0x2275, 0x8136, 0xDA30, + 0x2276, 0x8136, 0xDA31, + 0x2277, 0x8136, 0xDA32, + 0x2278, 0x8136, 0xDA33, + 0x2279, 0x8136, 0xDA34, + 0x227A, 0x8136, 0xDA35, + 0x227B, 0x8136, 0xDA36, + 0x227C, 0x8136, 0xDA37, + 0x227D, 0x8136, 0xDA38, + 0x227E, 0x8136, 0xDA39, + 0x227F, 0x8136, 0xDB30, + 0x2280, 0x8136, 0xDB31, + 0x2281, 0x8136, 0xDB32, + 0x2282, 0x8136, 0xDB33, + 0x2283, 0x8136, 0xDB34, + 0x2284, 0x8136, 0xDB35, + 0x2285, 0x8136, 0xDB36, + 0x2286, 0x8136, 0xDB37, + 0x2287, 0x8136, 0xDB38, + 0x2288, 0x8136, 0xDB39, + 0x2289, 0x8136, 0xDC30, + 0x228A, 0x8136, 0xDC31, + 0x228B, 0x8136, 0xDC32, + 0x228C, 0x8136, 0xDC33, + 0x228D, 0x8136, 0xDC34, + 0x228E, 0x8136, 0xDC35, + 0x228F, 0x8136, 0xDC36, + 0x2290, 0x8136, 0xDC37, + 0x2291, 0x8136, 0xDC38, + 0x2292, 0x8136, 0xDC39, + 0x2293, 0x8136, 0xDD30, + 0x2294, 0x8136, 0xDD31, + 0x2296, 0x8136, 0xDD32, + 0x2297, 0x8136, 0xDD33, + 0x2298, 0x8136, 0xDD34, + 0x229A, 0x8136, 0xDD35, + 0x229B, 0x8136, 0xDD36, + 0x229C, 0x8136, 0xDD37, + 0x229D, 0x8136, 0xDD38, + 0x229E, 0x8136, 0xDD39, + 0x229F, 0x8136, 0xDE30, + 0x22A0, 0x8136, 0xDE31, + 0x22A1, 0x8136, 0xDE32, + 0x22A2, 0x8136, 0xDE33, + 0x22A3, 0x8136, 0xDE34, + 0x22A4, 0x8136, 0xDE35, + 0x22A6, 0x8136, 0xDE36, + 0x22A7, 0x8136, 0xDE37, + 0x22A8, 0x8136, 0xDE38, + 0x22A9, 0x8136, 0xDE39, + 0x22AA, 0x8136, 0xDF30, + 0x22AB, 0x8136, 0xDF31, + 0x22AC, 0x8136, 0xDF32, + 0x22AD, 0x8136, 0xDF33, + 0x22AE, 0x8136, 0xDF34, + 0x22AF, 0x8136, 0xDF35, + 0x22B0, 0x8136, 0xDF36, + 0x22B1, 0x8136, 0xDF37, + 0x22B2, 0x8136, 0xDF38, + 0x22B3, 0x8136, 0xDF39, + 0x22B4, 0x8136, 0xE030, + 0x22B5, 0x8136, 0xE031, + 0x22B6, 0x8136, 0xE032, + 0x22B7, 0x8136, 0xE033, + 0x22B8, 0x8136, 0xE034, + 0x22B9, 0x8136, 0xE035, + 0x22BA, 0x8136, 0xE036, + 0x22BB, 0x8136, 0xE037, + 0x22BC, 0x8136, 0xE038, + 0x22BD, 0x8136, 0xE039, + 0x22BE, 0x8136, 0xE130, + 0x22C0, 0x8136, 0xE131, + 0x22C1, 0x8136, 0xE132, + 0x22C2, 0x8136, 0xE133, + 0x22C3, 0x8136, 0xE134, + 0x22C4, 0x8136, 0xE135, + 0x22C5, 0x8136, 0xE136, + 0x22C6, 0x8136, 0xE137, + 0x22C7, 0x8136, 0xE138, + 0x22C8, 0x8136, 0xE139, + 0x22C9, 0x8136, 0xE230, + 0x22CA, 0x8136, 0xE231, + 0x22CB, 0x8136, 0xE232, + 0x22CC, 0x8136, 0xE233, + 0x22CD, 0x8136, 0xE234, + 0x22CE, 0x8136, 0xE235, + 0x22CF, 0x8136, 0xE236, + 0x22D0, 0x8136, 0xE237, + 0x22D1, 0x8136, 0xE238, + 0x22D2, 0x8136, 0xE239, + 0x22D3, 0x8136, 0xE330, + 0x22D4, 0x8136, 0xE331, + 0x22D5, 0x8136, 0xE332, + 0x22D6, 0x8136, 0xE333, + 0x22D7, 0x8136, 0xE334, + 0x22D8, 0x8136, 0xE335, + 0x22D9, 0x8136, 0xE336, + 0x22DA, 0x8136, 0xE337, + 0x22DB, 0x8136, 0xE338, + 0x22DC, 0x8136, 0xE339, + 0x22DD, 0x8136, 0xE430, + 0x22DE, 0x8136, 0xE431, + 0x22DF, 0x8136, 0xE432, + 0x22E0, 0x8136, 0xE433, + 0x22E1, 0x8136, 0xE434, + 0x22E2, 0x8136, 0xE435, + 0x22E3, 0x8136, 0xE436, + 0x22E4, 0x8136, 0xE437, + 0x22E5, 0x8136, 0xE438, + 0x22E6, 0x8136, 0xE439, + 0x22E7, 0x8136, 0xE530, + 0x22E8, 0x8136, 0xE531, + 0x22E9, 0x8136, 0xE532, + 0x22EA, 0x8136, 0xE533, + 0x22EB, 0x8136, 0xE534, + 0x22EC, 0x8136, 0xE535, + 0x22ED, 0x8136, 0xE536, + 0x22EE, 0x8136, 0xE537, + 0x22EF, 0x8136, 0xE538, + 0x22F0, 0x8136, 0xE539, + 0x22F1, 0x8136, 0xE630, + 0x22F2, 0x8136, 0xE631, + 0x22F3, 0x8136, 0xE632, + 0x22F4, 0x8136, 0xE633, + 0x22F5, 0x8136, 0xE634, + 0x22F6, 0x8136, 0xE635, + 0x22F7, 0x8136, 0xE636, + 0x22F8, 0x8136, 0xE637, + 0x22F9, 0x8136, 0xE638, + 0x22FA, 0x8136, 0xE639, + 0x22FB, 0x8136, 0xE730, + 0x22FC, 0x8136, 0xE731, + 0x22FD, 0x8136, 0xE732, + 0x22FE, 0x8136, 0xE733, + 0x22FF, 0x8136, 0xE734, + 0x2300, 0x8136, 0xE735, + 0x2301, 0x8136, 0xE736, + 0x2302, 0x8136, 0xE737, + 0x2303, 0x8136, 0xE738, + 0x2304, 0x8136, 0xE739, + 0x2305, 0x8136, 0xE830, + 0x2306, 0x8136, 0xE831, + 0x2307, 0x8136, 0xE832, + 0x2308, 0x8136, 0xE833, + 0x2309, 0x8136, 0xE834, + 0x230A, 0x8136, 0xE835, + 0x230B, 0x8136, 0xE836, + 0x230C, 0x8136, 0xE837, + 0x230D, 0x8136, 0xE838, + 0x230E, 0x8136, 0xE839, + 0x230F, 0x8136, 0xE930, + 0x2310, 0x8136, 0xE931, + 0x2311, 0x8136, 0xE932, + 0x2313, 0x8136, 0xE933, + 0x2314, 0x8136, 0xE934, + 0x2315, 0x8136, 0xE935, + 0x2316, 0x8136, 0xE936, + 0x2317, 0x8136, 0xE937, + 0x2318, 0x8136, 0xE938, + 0x2319, 0x8136, 0xE939, + 0x231A, 0x8136, 0xEA30, + 0x231B, 0x8136, 0xEA31, + 0x231C, 0x8136, 0xEA32, + 0x231D, 0x8136, 0xEA33, + 0x231E, 0x8136, 0xEA34, + 0x231F, 0x8136, 0xEA35, + 0x2320, 0x8136, 0xEA36, + 0x2321, 0x8136, 0xEA37, + 0x2322, 0x8136, 0xEA38, + 0x2323, 0x8136, 0xEA39, + 0x2324, 0x8136, 0xEB30, + 0x2325, 0x8136, 0xEB31, + 0x2326, 0x8136, 0xEB32, + 0x2327, 0x8136, 0xEB33, + 0x2328, 0x8136, 0xEB34, + 0x2329, 0x8136, 0xEB35, + 0x232A, 0x8136, 0xEB36, + 0x232B, 0x8136, 0xEB37, + 0x232C, 0x8136, 0xEB38, + 0x232D, 0x8136, 0xEB39, + 0x232E, 0x8136, 0xEC30, + 0x232F, 0x8136, 0xEC31, + 0x2330, 0x8136, 0xEC32, + 0x2331, 0x8136, 0xEC33, + 0x2332, 0x8136, 0xEC34, + 0x2333, 0x8136, 0xEC35, + 0x2334, 0x8136, 0xEC36, + 0x2335, 0x8136, 0xEC37, + 0x2336, 0x8136, 0xEC38, + 0x2337, 0x8136, 0xEC39, + 0x2338, 0x8136, 0xED30, + 0x2339, 0x8136, 0xED31, + 0x233A, 0x8136, 0xED32, + 0x233B, 0x8136, 0xED33, + 0x233C, 0x8136, 0xED34, + 0x233D, 0x8136, 0xED35, + 0x233E, 0x8136, 0xED36, + 0x233F, 0x8136, 0xED37, + 0x2340, 0x8136, 0xED38, + 0x2341, 0x8136, 0xED39, + 0x2342, 0x8136, 0xEE30, + 0x2343, 0x8136, 0xEE31, + 0x2344, 0x8136, 0xEE32, + 0x2345, 0x8136, 0xEE33, + 0x2346, 0x8136, 0xEE34, + 0x2347, 0x8136, 0xEE35, + 0x2348, 0x8136, 0xEE36, + 0x2349, 0x8136, 0xEE37, + 0x234A, 0x8136, 0xEE38, + 0x234B, 0x8136, 0xEE39, + 0x234C, 0x8136, 0xEF30, + 0x234D, 0x8136, 0xEF31, + 0x234E, 0x8136, 0xEF32, + 0x234F, 0x8136, 0xEF33, + 0x2350, 0x8136, 0xEF34, + 0x2351, 0x8136, 0xEF35, + 0x2352, 0x8136, 0xEF36, + 0x2353, 0x8136, 0xEF37, + 0x2354, 0x8136, 0xEF38, + 0x2355, 0x8136, 0xEF39, + 0x2356, 0x8136, 0xF030, + 0x2357, 0x8136, 0xF031, + 0x2358, 0x8136, 0xF032, + 0x2359, 0x8136, 0xF033, + 0x235A, 0x8136, 0xF034, + 0x235B, 0x8136, 0xF035, + 0x235C, 0x8136, 0xF036, + 0x235D, 0x8136, 0xF037, + 0x235E, 0x8136, 0xF038, + 0x235F, 0x8136, 0xF039, + 0x2360, 0x8136, 0xF130, + 0x2361, 0x8136, 0xF131, + 0x2362, 0x8136, 0xF132, + 0x2363, 0x8136, 0xF133, + 0x2364, 0x8136, 0xF134, + 0x2365, 0x8136, 0xF135, + 0x2366, 0x8136, 0xF136, + 0x2367, 0x8136, 0xF137, + 0x2368, 0x8136, 0xF138, + 0x2369, 0x8136, 0xF139, + 0x236A, 0x8136, 0xF230, + 0x236B, 0x8136, 0xF231, + 0x236C, 0x8136, 0xF232, + 0x236D, 0x8136, 0xF233, + 0x236E, 0x8136, 0xF234, + 0x236F, 0x8136, 0xF235, + 0x2370, 0x8136, 0xF236, + 0x2371, 0x8136, 0xF237, + 0x2372, 0x8136, 0xF238, + 0x2373, 0x8136, 0xF239, + 0x2374, 0x8136, 0xF330, + 0x2375, 0x8136, 0xF331, + 0x2376, 0x8136, 0xF332, + 0x2377, 0x8136, 0xF333, + 0x2378, 0x8136, 0xF334, + 0x2379, 0x8136, 0xF335, + 0x237A, 0x8136, 0xF336, + 0x237B, 0x8136, 0xF337, + 0x237C, 0x8136, 0xF338, + 0x237D, 0x8136, 0xF339, + 0x237E, 0x8136, 0xF430, + 0x237F, 0x8136, 0xF431, + 0x2380, 0x8136, 0xF432, + 0x2381, 0x8136, 0xF433, + 0x2382, 0x8136, 0xF434, + 0x2383, 0x8136, 0xF435, + 0x2384, 0x8136, 0xF436, + 0x2385, 0x8136, 0xF437, + 0x2386, 0x8136, 0xF438, + 0x2387, 0x8136, 0xF439, + 0x2388, 0x8136, 0xF530, + 0x2389, 0x8136, 0xF531, + 0x238A, 0x8136, 0xF532, + 0x238B, 0x8136, 0xF533, + 0x238C, 0x8136, 0xF534, + 0x238D, 0x8136, 0xF535, + 0x238E, 0x8136, 0xF536, + 0x238F, 0x8136, 0xF537, + 0x2390, 0x8136, 0xF538, + 0x2391, 0x8136, 0xF539, + 0x2392, 0x8136, 0xF630, + 0x2393, 0x8136, 0xF631, + 0x2394, 0x8136, 0xF632, + 0x2395, 0x8136, 0xF633, + 0x2396, 0x8136, 0xF634, + 0x2397, 0x8136, 0xF635, + 0x2398, 0x8136, 0xF636, + 0x2399, 0x8136, 0xF637, + 0x239A, 0x8136, 0xF638, + 0x239B, 0x8136, 0xF639, + 0x239C, 0x8136, 0xF730, + 0x239D, 0x8136, 0xF731, + 0x239E, 0x8136, 0xF732, + 0x239F, 0x8136, 0xF733, + 0x23A0, 0x8136, 0xF734, + 0x23A1, 0x8136, 0xF735, + 0x23A2, 0x8136, 0xF736, + 0x23A3, 0x8136, 0xF737, + 0x23A4, 0x8136, 0xF738, + 0x23A5, 0x8136, 0xF739, + 0x23A6, 0x8136, 0xF830, + 0x23A7, 0x8136, 0xF831, + 0x23A8, 0x8136, 0xF832, + 0x23A9, 0x8136, 0xF833, + 0x23AA, 0x8136, 0xF834, + 0x23AB, 0x8136, 0xF835, + 0x23AC, 0x8136, 0xF836, + 0x23AD, 0x8136, 0xF837, + 0x23AE, 0x8136, 0xF838, + 0x23AF, 0x8136, 0xF839, + 0x23B0, 0x8136, 0xF930, + 0x23B1, 0x8136, 0xF931, + 0x23B2, 0x8136, 0xF932, + 0x23B3, 0x8136, 0xF933, + 0x23B4, 0x8136, 0xF934, + 0x23B5, 0x8136, 0xF935, + 0x23B6, 0x8136, 0xF936, + 0x23B7, 0x8136, 0xF937, + 0x23B8, 0x8136, 0xF938, + 0x23B9, 0x8136, 0xF939, + 0x23BA, 0x8136, 0xFA30, + 0x23BB, 0x8136, 0xFA31, + 0x23BC, 0x8136, 0xFA32, + 0x23BD, 0x8136, 0xFA33, + 0x23BE, 0x8136, 0xFA34, + 0x23BF, 0x8136, 0xFA35, + 0x23C0, 0x8136, 0xFA36, + 0x23C1, 0x8136, 0xFA37, + 0x23C2, 0x8136, 0xFA38, + 0x23C3, 0x8136, 0xFA39, + 0x23C4, 0x8136, 0xFB30, + 0x23C5, 0x8136, 0xFB31, + 0x23C6, 0x8136, 0xFB32, + 0x23C7, 0x8136, 0xFB33, + 0x23C8, 0x8136, 0xFB34, + 0x23C9, 0x8136, 0xFB35, + 0x23CA, 0x8136, 0xFB36, + 0x23CB, 0x8136, 0xFB37, + 0x23CC, 0x8136, 0xFB38, + 0x23CD, 0x8136, 0xFB39, + 0x23CE, 0x8136, 0xFC30, + 0x23CF, 0x8136, 0xFC31, + 0x23D0, 0x8136, 0xFC32, + 0x23D1, 0x8136, 0xFC33, + 0x23D2, 0x8136, 0xFC34, + 0x23D3, 0x8136, 0xFC35, + 0x23D4, 0x8136, 0xFC36, + 0x23D5, 0x8136, 0xFC37, + 0x23D6, 0x8136, 0xFC38, + 0x23D7, 0x8136, 0xFC39, + 0x23D8, 0x8136, 0xFD30, + 0x23D9, 0x8136, 0xFD31, + 0x23DA, 0x8136, 0xFD32, + 0x23DB, 0x8136, 0xFD33, + 0x23DC, 0x8136, 0xFD34, + 0x23DD, 0x8136, 0xFD35, + 0x23DE, 0x8136, 0xFD36, + 0x23DF, 0x8136, 0xFD37, + 0x23E0, 0x8136, 0xFD38, + 0x23E1, 0x8136, 0xFD39, + 0x23E2, 0x8136, 0xFE30, + 0x23E3, 0x8136, 0xFE31, + 0x23E4, 0x8136, 0xFE32, + 0x23E5, 0x8136, 0xFE33, + 0x23E6, 0x8136, 0xFE34, + 0x23E7, 0x8136, 0xFE35, + 0x23E8, 0x8136, 0xFE36, + 0x23E9, 0x8136, 0xFE37, + 0x23EA, 0x8136, 0xFE38, + 0x23EB, 0x8136, 0xFE39, + 0x23EC, 0x8137, 0x8130, + 0x23ED, 0x8137, 0x8131, + 0x23EE, 0x8137, 0x8132, + 0x23EF, 0x8137, 0x8133, + 0x23F0, 0x8137, 0x8134, + 0x23F1, 0x8137, 0x8135, + 0x23F2, 0x8137, 0x8136, + 0x23F3, 0x8137, 0x8137, + 0x23F4, 0x8137, 0x8138, + 0x23F5, 0x8137, 0x8139, + 0x23F6, 0x8137, 0x8230, + 0x23F7, 0x8137, 0x8231, + 0x23F8, 0x8137, 0x8232, + 0x23F9, 0x8137, 0x8233, + 0x23FA, 0x8137, 0x8234, + 0x23FB, 0x8137, 0x8235, + 0x23FC, 0x8137, 0x8236, + 0x23FD, 0x8137, 0x8237, + 0x23FE, 0x8137, 0x8238, + 0x23FF, 0x8137, 0x8239, + 0x2400, 0x8137, 0x8330, + 0x2401, 0x8137, 0x8331, + 0x2402, 0x8137, 0x8332, + 0x2403, 0x8137, 0x8333, + 0x2404, 0x8137, 0x8334, + 0x2405, 0x8137, 0x8335, + 0x2406, 0x8137, 0x8336, + 0x2407, 0x8137, 0x8337, + 0x2408, 0x8137, 0x8338, + 0x2409, 0x8137, 0x8339, + 0x240A, 0x8137, 0x8430, + 0x240B, 0x8137, 0x8431, + 0x240C, 0x8137, 0x8432, + 0x240D, 0x8137, 0x8433, + 0x240E, 0x8137, 0x8434, + 0x240F, 0x8137, 0x8435, + 0x2410, 0x8137, 0x8436, + 0x2411, 0x8137, 0x8437, + 0x2412, 0x8137, 0x8438, + 0x2413, 0x8137, 0x8439, + 0x2414, 0x8137, 0x8530, + 0x2415, 0x8137, 0x8531, + 0x2416, 0x8137, 0x8532, + 0x2417, 0x8137, 0x8533, + 0x2418, 0x8137, 0x8534, + 0x2419, 0x8137, 0x8535, + 0x241A, 0x8137, 0x8536, + 0x241B, 0x8137, 0x8537, + 0x241C, 0x8137, 0x8538, + 0x241D, 0x8137, 0x8539, + 0x241E, 0x8137, 0x8630, + 0x241F, 0x8137, 0x8631, + 0x2420, 0x8137, 0x8632, + 0x2421, 0x8137, 0x8633, + 0x2422, 0x8137, 0x8634, + 0x2423, 0x8137, 0x8635, + 0x2424, 0x8137, 0x8636, + 0x2425, 0x8137, 0x8637, + 0x2426, 0x8137, 0x8638, + 0x2427, 0x8137, 0x8639, + 0x2428, 0x8137, 0x8730, + 0x2429, 0x8137, 0x8731, + 0x242A, 0x8137, 0x8732, + 0x242B, 0x8137, 0x8733, + 0x242C, 0x8137, 0x8734, + 0x242D, 0x8137, 0x8735, + 0x242E, 0x8137, 0x8736, + 0x242F, 0x8137, 0x8737, + 0x2430, 0x8137, 0x8738, + 0x2431, 0x8137, 0x8739, + 0x2432, 0x8137, 0x8830, + 0x2433, 0x8137, 0x8831, + 0x2434, 0x8137, 0x8832, + 0x2435, 0x8137, 0x8833, + 0x2436, 0x8137, 0x8834, + 0x2437, 0x8137, 0x8835, + 0x2438, 0x8137, 0x8836, + 0x2439, 0x8137, 0x8837, + 0x243A, 0x8137, 0x8838, + 0x243B, 0x8137, 0x8839, + 0x243C, 0x8137, 0x8930, + 0x243D, 0x8137, 0x8931, + 0x243E, 0x8137, 0x8932, + 0x243F, 0x8137, 0x8933, + 0x2440, 0x8137, 0x8934, + 0x2441, 0x8137, 0x8935, + 0x2442, 0x8137, 0x8936, + 0x2443, 0x8137, 0x8937, + 0x2444, 0x8137, 0x8938, + 0x2445, 0x8137, 0x8939, + 0x2446, 0x8137, 0x8A30, + 0x2447, 0x8137, 0x8A31, + 0x2448, 0x8137, 0x8A32, + 0x2449, 0x8137, 0x8A33, + 0x244A, 0x8137, 0x8A34, + 0x244B, 0x8137, 0x8A35, + 0x244C, 0x8137, 0x8A36, + 0x244D, 0x8137, 0x8A37, + 0x244E, 0x8137, 0x8A38, + 0x244F, 0x8137, 0x8A39, + 0x2450, 0x8137, 0x8B30, + 0x2451, 0x8137, 0x8B31, + 0x2452, 0x8137, 0x8B32, + 0x2453, 0x8137, 0x8B33, + 0x2454, 0x8137, 0x8B34, + 0x2455, 0x8137, 0x8B35, + 0x2456, 0x8137, 0x8B36, + 0x2457, 0x8137, 0x8B37, + 0x2458, 0x8137, 0x8B38, + 0x2459, 0x8137, 0x8B39, + 0x245A, 0x8137, 0x8C30, + 0x245B, 0x8137, 0x8C31, + 0x245C, 0x8137, 0x8C32, + 0x245D, 0x8137, 0x8C33, + 0x245E, 0x8137, 0x8C34, + 0x245F, 0x8137, 0x8C35, + 0x246A, 0x8137, 0x8C36, + 0x246B, 0x8137, 0x8C37, + 0x246C, 0x8137, 0x8C38, + 0x246D, 0x8137, 0x8C39, + 0x246E, 0x8137, 0x8D30, + 0x246F, 0x8137, 0x8D31, + 0x2470, 0x8137, 0x8D32, + 0x2471, 0x8137, 0x8D33, + 0x2472, 0x8137, 0x8D34, + 0x2473, 0x8137, 0x8D35, + 0x249C, 0x8137, 0x8D36, + 0x249D, 0x8137, 0x8D37, + 0x249E, 0x8137, 0x8D38, + 0x249F, 0x8137, 0x8D39, + 0x24A0, 0x8137, 0x8E30, + 0x24A1, 0x8137, 0x8E31, + 0x24A2, 0x8137, 0x8E32, + 0x24A3, 0x8137, 0x8E33, + 0x24A4, 0x8137, 0x8E34, + 0x24A5, 0x8137, 0x8E35, + 0x24A6, 0x8137, 0x8E36, + 0x24A7, 0x8137, 0x8E37, + 0x24A8, 0x8137, 0x8E38, + 0x24A9, 0x8137, 0x8E39, + 0x24AA, 0x8137, 0x8F30, + 0x24AB, 0x8137, 0x8F31, + 0x24AC, 0x8137, 0x8F32, + 0x24AD, 0x8137, 0x8F33, + 0x24AE, 0x8137, 0x8F34, + 0x24AF, 0x8137, 0x8F35, + 0x24B0, 0x8137, 0x8F36, + 0x24B1, 0x8137, 0x8F37, + 0x24B2, 0x8137, 0x8F38, + 0x24B3, 0x8137, 0x8F39, + 0x24B4, 0x8137, 0x9030, + 0x24B5, 0x8137, 0x9031, + 0x24B6, 0x8137, 0x9032, + 0x24B7, 0x8137, 0x9033, + 0x24B8, 0x8137, 0x9034, + 0x24B9, 0x8137, 0x9035, + 0x24BA, 0x8137, 0x9036, + 0x24BB, 0x8137, 0x9037, + 0x24BC, 0x8137, 0x9038, + 0x24BD, 0x8137, 0x9039, + 0x24BE, 0x8137, 0x9130, + 0x24BF, 0x8137, 0x9131, + 0x24C0, 0x8137, 0x9132, + 0x24C1, 0x8137, 0x9133, + 0x24C2, 0x8137, 0x9134, + 0x24C3, 0x8137, 0x9135, + 0x24C4, 0x8137, 0x9136, + 0x24C5, 0x8137, 0x9137, + 0x24C6, 0x8137, 0x9138, + 0x24C7, 0x8137, 0x9139, + 0x24C8, 0x8137, 0x9230, + 0x24C9, 0x8137, 0x9231, + 0x24CA, 0x8137, 0x9232, + 0x24CB, 0x8137, 0x9233, + 0x24CC, 0x8137, 0x9234, + 0x24CD, 0x8137, 0x9235, + 0x24CE, 0x8137, 0x9236, + 0x24CF, 0x8137, 0x9237, + 0x24D0, 0x8137, 0x9238, + 0x24D1, 0x8137, 0x9239, + 0x24D2, 0x8137, 0x9330, + 0x24D3, 0x8137, 0x9331, + 0x24D4, 0x8137, 0x9332, + 0x24D5, 0x8137, 0x9333, + 0x24D6, 0x8137, 0x9334, + 0x24D7, 0x8137, 0x9335, + 0x24D8, 0x8137, 0x9336, + 0x24D9, 0x8137, 0x9337, + 0x24DA, 0x8137, 0x9338, + 0x24DB, 0x8137, 0x9339, + 0x24DC, 0x8137, 0x9430, + 0x24DD, 0x8137, 0x9431, + 0x24DE, 0x8137, 0x9432, + 0x24DF, 0x8137, 0x9433, + 0x24E0, 0x8137, 0x9434, + 0x24E1, 0x8137, 0x9435, + 0x24E2, 0x8137, 0x9436, + 0x24E3, 0x8137, 0x9437, + 0x24E4, 0x8137, 0x9438, + 0x24E5, 0x8137, 0x9439, + 0x24E6, 0x8137, 0x9530, + 0x24E7, 0x8137, 0x9531, + 0x24E8, 0x8137, 0x9532, + 0x24E9, 0x8137, 0x9533, + 0x24EA, 0x8137, 0x9534, + 0x24EB, 0x8137, 0x9535, + 0x24EC, 0x8137, 0x9536, + 0x24ED, 0x8137, 0x9537, + 0x24EE, 0x8137, 0x9538, + 0x24EF, 0x8137, 0x9539, + 0x24F0, 0x8137, 0x9630, + 0x24F1, 0x8137, 0x9631, + 0x24F2, 0x8137, 0x9632, + 0x24F3, 0x8137, 0x9633, + 0x24F4, 0x8137, 0x9634, + 0x24F5, 0x8137, 0x9635, + 0x24F6, 0x8137, 0x9636, + 0x24F7, 0x8137, 0x9637, + 0x24F8, 0x8137, 0x9638, + 0x24F9, 0x8137, 0x9639, + 0x24FA, 0x8137, 0x9730, + 0x24FB, 0x8137, 0x9731, + 0x24FC, 0x8137, 0x9732, + 0x24FD, 0x8137, 0x9733, + 0x24FE, 0x8137, 0x9734, + 0x24FF, 0x8137, 0x9735, + 0x254C, 0x8137, 0x9736, + 0x254D, 0x8137, 0x9737, + 0x254E, 0x8137, 0x9738, + 0x254F, 0x8137, 0x9739, + 0x2574, 0x8137, 0x9830, + 0x2575, 0x8137, 0x9831, + 0x2576, 0x8137, 0x9832, + 0x2577, 0x8137, 0x9833, + 0x2578, 0x8137, 0x9834, + 0x2579, 0x8137, 0x9835, + 0x257A, 0x8137, 0x9836, + 0x257B, 0x8137, 0x9837, + 0x257C, 0x8137, 0x9838, + 0x257D, 0x8137, 0x9839, + 0x257E, 0x8137, 0x9930, + 0x257F, 0x8137, 0x9931, + 0x2580, 0x8137, 0x9932, + 0x2590, 0x8137, 0x9933, + 0x2591, 0x8137, 0x9934, + 0x2592, 0x8137, 0x9935, + 0x2596, 0x8137, 0x9936, + 0x2597, 0x8137, 0x9937, + 0x2598, 0x8137, 0x9938, + 0x2599, 0x8137, 0x9939, + 0x259A, 0x8137, 0x9A30, + 0x259B, 0x8137, 0x9A31, + 0x259C, 0x8137, 0x9A32, + 0x259D, 0x8137, 0x9A33, + 0x259E, 0x8137, 0x9A34, + 0x259F, 0x8137, 0x9A35, + 0x25A2, 0x8137, 0x9A36, + 0x25A3, 0x8137, 0x9A37, + 0x25A4, 0x8137, 0x9A38, + 0x25A5, 0x8137, 0x9A39, + 0x25A6, 0x8137, 0x9B30, + 0x25A7, 0x8137, 0x9B31, + 0x25A8, 0x8137, 0x9B32, + 0x25A9, 0x8137, 0x9B33, + 0x25AA, 0x8137, 0x9B34, + 0x25AB, 0x8137, 0x9B35, + 0x25AC, 0x8137, 0x9B36, + 0x25AD, 0x8137, 0x9B37, + 0x25AE, 0x8137, 0x9B38, + 0x25AF, 0x8137, 0x9B39, + 0x25B0, 0x8137, 0x9C30, + 0x25B1, 0x8137, 0x9C31, + 0x25B4, 0x8137, 0x9C32, + 0x25B5, 0x8137, 0x9C33, + 0x25B6, 0x8137, 0x9C34, + 0x25B7, 0x8137, 0x9C35, + 0x25B8, 0x8137, 0x9C36, + 0x25B9, 0x8137, 0x9C37, + 0x25BA, 0x8137, 0x9C38, + 0x25BB, 0x8137, 0x9C39, + 0x25BE, 0x8137, 0x9D30, + 0x25BF, 0x8137, 0x9D31, + 0x25C0, 0x8137, 0x9D32, + 0x25C1, 0x8137, 0x9D33, + 0x25C2, 0x8137, 0x9D34, + 0x25C3, 0x8137, 0x9D35, + 0x25C4, 0x8137, 0x9D36, + 0x25C5, 0x8137, 0x9D37, + 0x25C8, 0x8137, 0x9D38, + 0x25C9, 0x8137, 0x9D39, + 0x25CA, 0x8137, 0x9E30, + 0x25CC, 0x8137, 0x9E31, + 0x25CD, 0x8137, 0x9E32, + 0x25D0, 0x8137, 0x9E33, + 0x25D1, 0x8137, 0x9E34, + 0x25D2, 0x8137, 0x9E35, + 0x25D3, 0x8137, 0x9E36, + 0x25D4, 0x8137, 0x9E37, + 0x25D5, 0x8137, 0x9E38, + 0x25D6, 0x8137, 0x9E39, + 0x25D7, 0x8137, 0x9F30, + 0x25D8, 0x8137, 0x9F31, + 0x25D9, 0x8137, 0x9F32, + 0x25DA, 0x8137, 0x9F33, + 0x25DB, 0x8137, 0x9F34, + 0x25DC, 0x8137, 0x9F35, + 0x25DD, 0x8137, 0x9F36, + 0x25DE, 0x8137, 0x9F37, + 0x25DF, 0x8137, 0x9F38, + 0x25E0, 0x8137, 0x9F39, + 0x25E1, 0x8137, 0xA030, + 0x25E6, 0x8137, 0xA031, + 0x25E7, 0x8137, 0xA032, + 0x25E8, 0x8137, 0xA033, + 0x25E9, 0x8137, 0xA034, + 0x25EA, 0x8137, 0xA035, + 0x25EB, 0x8137, 0xA036, + 0x25EC, 0x8137, 0xA037, + 0x25ED, 0x8137, 0xA038, + 0x25EE, 0x8137, 0xA039, + 0x25EF, 0x8137, 0xA130, + 0x25F0, 0x8137, 0xA131, + 0x25F1, 0x8137, 0xA132, + 0x25F2, 0x8137, 0xA133, + 0x25F3, 0x8137, 0xA134, + 0x25F4, 0x8137, 0xA135, + 0x25F5, 0x8137, 0xA136, + 0x25F6, 0x8137, 0xA137, + 0x25F7, 0x8137, 0xA138, + 0x25F8, 0x8137, 0xA139, + 0x25F9, 0x8137, 0xA230, + 0x25FA, 0x8137, 0xA231, + 0x25FB, 0x8137, 0xA232, + 0x25FC, 0x8137, 0xA233, + 0x25FD, 0x8137, 0xA234, + 0x25FE, 0x8137, 0xA235, + 0x25FF, 0x8137, 0xA236, + 0x2600, 0x8137, 0xA237, + 0x2601, 0x8137, 0xA238, + 0x2602, 0x8137, 0xA239, + 0x2603, 0x8137, 0xA330, + 0x2604, 0x8137, 0xA331, + 0x2607, 0x8137, 0xA332, + 0x2608, 0x8137, 0xA333, + 0x260A, 0x8137, 0xA334, + 0x260B, 0x8137, 0xA335, + 0x260C, 0x8137, 0xA336, + 0x260D, 0x8137, 0xA337, + 0x260E, 0x8137, 0xA338, + 0x260F, 0x8137, 0xA339, + 0x2610, 0x8137, 0xA430, + 0x2611, 0x8137, 0xA431, + 0x2612, 0x8137, 0xA432, + 0x2613, 0x8137, 0xA433, + 0x2614, 0x8137, 0xA434, + 0x2615, 0x8137, 0xA435, + 0x2616, 0x8137, 0xA436, + 0x2617, 0x8137, 0xA437, + 0x2618, 0x8137, 0xA438, + 0x2619, 0x8137, 0xA439, + 0x261A, 0x8137, 0xA530, + 0x261B, 0x8137, 0xA531, + 0x261C, 0x8137, 0xA532, + 0x261D, 0x8137, 0xA533, + 0x261E, 0x8137, 0xA534, + 0x261F, 0x8137, 0xA535, + 0x2620, 0x8137, 0xA536, + 0x2621, 0x8137, 0xA537, + 0x2622, 0x8137, 0xA538, + 0x2623, 0x8137, 0xA539, + 0x2624, 0x8137, 0xA630, + 0x2625, 0x8137, 0xA631, + 0x2626, 0x8137, 0xA632, + 0x2627, 0x8137, 0xA633, + 0x2628, 0x8137, 0xA634, + 0x2629, 0x8137, 0xA635, + 0x262A, 0x8137, 0xA636, + 0x262B, 0x8137, 0xA637, + 0x262C, 0x8137, 0xA638, + 0x262D, 0x8137, 0xA639, + 0x262E, 0x8137, 0xA730, + 0x262F, 0x8137, 0xA731, + 0x2630, 0x8137, 0xA732, + 0x2631, 0x8137, 0xA733, + 0x2632, 0x8137, 0xA734, + 0x2633, 0x8137, 0xA735, + 0x2634, 0x8137, 0xA736, + 0x2635, 0x8137, 0xA737, + 0x2636, 0x8137, 0xA738, + 0x2637, 0x8137, 0xA739, + 0x2638, 0x8137, 0xA830, + 0x2639, 0x8137, 0xA831, + 0x263A, 0x8137, 0xA832, + 0x263B, 0x8137, 0xA833, + 0x263C, 0x8137, 0xA834, + 0x263D, 0x8137, 0xA835, + 0x263E, 0x8137, 0xA836, + 0x263F, 0x8137, 0xA837, + 0x2641, 0x8137, 0xA838, + 0x2E82, 0x8138, 0xFD39, + 0x2E83, 0x8138, 0xFE30, + 0x2E85, 0x8138, 0xFE31, + 0x2E86, 0x8138, 0xFE32, + 0x2E87, 0x8138, 0xFE33, + 0x2E89, 0x8138, 0xFE34, + 0x2E8A, 0x8138, 0xFE35, + 0x2E8D, 0x8138, 0xFE36, + 0x2E8E, 0x8138, 0xFE37, + 0x2E8F, 0x8138, 0xFE38, + 0x2E90, 0x8138, 0xFE39, + 0x2E91, 0x8139, 0x8130, + 0x2E92, 0x8139, 0x8131, + 0x2E93, 0x8139, 0x8132, + 0x2E94, 0x8139, 0x8133, + 0x2E95, 0x8139, 0x8134, + 0x2E96, 0x8139, 0x8135, + 0x2E98, 0x8139, 0x8136, + 0x2E99, 0x8139, 0x8137, + 0x2E9A, 0x8139, 0x8138, + 0x2E9B, 0x8139, 0x8139, + 0x2E9C, 0x8139, 0x8230, + 0x2E9D, 0x8139, 0x8231, + 0x2E9E, 0x8139, 0x8232, + 0x2E9F, 0x8139, 0x8233, + 0x2EA0, 0x8139, 0x8234, + 0x2EA1, 0x8139, 0x8235, + 0x2EA2, 0x8139, 0x8236, + 0x2EA3, 0x8139, 0x8237, + 0x2EA4, 0x8139, 0x8238, + 0x2EA5, 0x8139, 0x8239, + 0x2EA6, 0x8139, 0x8330, + 0x2EA8, 0x8139, 0x8331, + 0x2EA9, 0x8139, 0x8332, + 0x2EAB, 0x8139, 0x8333, + 0x2EAC, 0x8139, 0x8334, + 0x2EAD, 0x8139, 0x8335, + 0x2EAF, 0x8139, 0x8336, + 0x2EB0, 0x8139, 0x8337, + 0x2EB1, 0x8139, 0x8338, + 0x2EB2, 0x8139, 0x8339, + 0x2EB4, 0x8139, 0x8430, + 0x2EB5, 0x8139, 0x8431, + 0x2EB8, 0x8139, 0x8432, + 0x2EB9, 0x8139, 0x8433, + 0x2EBA, 0x8139, 0x8434, + 0x2EBC, 0x8139, 0x8435, + 0x2EBD, 0x8139, 0x8436, + 0x2EBE, 0x8139, 0x8437, + 0x2EBF, 0x8139, 0x8438, + 0x2EC0, 0x8139, 0x8439, + 0x2EC1, 0x8139, 0x8530, + 0x2EC2, 0x8139, 0x8531, + 0x2EC3, 0x8139, 0x8532, + 0x2EC4, 0x8139, 0x8533, + 0x2EC5, 0x8139, 0x8534, + 0x2EC6, 0x8139, 0x8535, + 0x2EC7, 0x8139, 0x8536, + 0x2EC8, 0x8139, 0x8537, + 0x2EC9, 0x8139, 0x8538, + 0x2ECB, 0x8139, 0x8539, + 0x2ECC, 0x8139, 0x8630, + 0x2ECD, 0x8139, 0x8631, + 0x2ECE, 0x8139, 0x8632, + 0x2ECF, 0x8139, 0x8633, + 0x2ED0, 0x8139, 0x8634, + 0x2ED1, 0x8139, 0x8635, + 0x2ED2, 0x8139, 0x8636, + 0x2ED3, 0x8139, 0x8637, + 0x2ED4, 0x8139, 0x8638, + 0x2ED5, 0x8139, 0x8639, + 0x2ED6, 0x8139, 0x8730, + 0x2ED7, 0x8139, 0x8731, + 0x2ED8, 0x8139, 0x8732, + 0x2ED9, 0x8139, 0x8733, + 0x2EDA, 0x8139, 0x8734, + 0x2EDB, 0x8139, 0x8735, + 0x2EDC, 0x8139, 0x8736, + 0x2EDD, 0x8139, 0x8737, + 0x2EDE, 0x8139, 0x8738, + 0x2EDF, 0x8139, 0x8739, + 0x2EE0, 0x8139, 0x8830, + 0x2EE1, 0x8139, 0x8831, + 0x2EE2, 0x8139, 0x8832, + 0x2EE3, 0x8139, 0x8833, + 0x2EE4, 0x8139, 0x8834, + 0x2EE5, 0x8139, 0x8835, + 0x2EE6, 0x8139, 0x8836, + 0x2EE7, 0x8139, 0x8837, + 0x2EE8, 0x8139, 0x8838, + 0x2EE9, 0x8139, 0x8839, + 0x2EEA, 0x8139, 0x8930, + 0x2EEB, 0x8139, 0x8931, + 0x2EEC, 0x8139, 0x8932, + 0x2EED, 0x8139, 0x8933, + 0x2EEE, 0x8139, 0x8934, + 0x2EEF, 0x8139, 0x8935, + 0x2EF0, 0x8139, 0x8936, + 0x2EF1, 0x8139, 0x8937, + 0x2EF2, 0x8139, 0x8938, + 0x2EF3, 0x8139, 0x8939, + 0x2EF4, 0x8139, 0x8A30, + 0x2EF5, 0x8139, 0x8A31, + 0x2EF6, 0x8139, 0x8A32, + 0x2EF7, 0x8139, 0x8A33, + 0x2EF8, 0x8139, 0x8A34, + 0x2EF9, 0x8139, 0x8A35, + 0x2EFA, 0x8139, 0x8A36, + 0x2EFB, 0x8139, 0x8A37, + 0x2EFC, 0x8139, 0x8A38, + 0x2EFD, 0x8139, 0x8A39, + 0x2EFE, 0x8139, 0x8B30, + 0x2EFF, 0x8139, 0x8B31, + 0x2F00, 0x8139, 0x8B32, + 0x2F01, 0x8139, 0x8B33, + 0x2F02, 0x8139, 0x8B34, + 0x2F03, 0x8139, 0x8B35, + 0x2F04, 0x8139, 0x8B36, + 0x2F05, 0x8139, 0x8B37, + 0x2F06, 0x8139, 0x8B38, + 0x2F07, 0x8139, 0x8B39, + 0x2F08, 0x8139, 0x8C30, + 0x2F09, 0x8139, 0x8C31, + 0x2F0A, 0x8139, 0x8C32, + 0x2F0B, 0x8139, 0x8C33, + 0x2F0C, 0x8139, 0x8C34, + 0x2F0D, 0x8139, 0x8C35, + 0x2F0E, 0x8139, 0x8C36, + 0x2F0F, 0x8139, 0x8C37, + 0x2F10, 0x8139, 0x8C38, + 0x2F11, 0x8139, 0x8C39, + 0x2F12, 0x8139, 0x8D30, + 0x2F13, 0x8139, 0x8D31, + 0x2F14, 0x8139, 0x8D32, + 0x2F15, 0x8139, 0x8D33, + 0x2F16, 0x8139, 0x8D34, + 0x2F17, 0x8139, 0x8D35, + 0x2F18, 0x8139, 0x8D36, + 0x2F19, 0x8139, 0x8D37, + 0x2F1A, 0x8139, 0x8D38, + 0x2F1B, 0x8139, 0x8D39, + 0x2F1C, 0x8139, 0x8E30, + 0x2F1D, 0x8139, 0x8E31, + 0x2F1E, 0x8139, 0x8E32, + 0x2F1F, 0x8139, 0x8E33, + 0x2F20, 0x8139, 0x8E34, + 0x2F21, 0x8139, 0x8E35, + 0x2F22, 0x8139, 0x8E36, + 0x2F23, 0x8139, 0x8E37, + 0x2F24, 0x8139, 0x8E38, + 0x2F25, 0x8139, 0x8E39, + 0x2F26, 0x8139, 0x8F30, + 0x2F27, 0x8139, 0x8F31, + 0x2F28, 0x8139, 0x8F32, + 0x2F29, 0x8139, 0x8F33, + 0x2F2A, 0x8139, 0x8F34, + 0x2F2B, 0x8139, 0x8F35, + 0x2F2C, 0x8139, 0x8F36, + 0x2F2D, 0x8139, 0x8F37, + 0x2F2E, 0x8139, 0x8F38, + 0x2F2F, 0x8139, 0x8F39, + 0x2F30, 0x8139, 0x9030, + 0x2F31, 0x8139, 0x9031, + 0x2F32, 0x8139, 0x9032, + 0x2F33, 0x8139, 0x9033, + 0x2F34, 0x8139, 0x9034, + 0x2F35, 0x8139, 0x9035, + 0x2F36, 0x8139, 0x9036, + 0x2F37, 0x8139, 0x9037, + 0x2F38, 0x8139, 0x9038, + 0x2F39, 0x8139, 0x9039, + 0x2F3A, 0x8139, 0x9130, + 0x2F3B, 0x8139, 0x9131, + 0x2F3C, 0x8139, 0x9132, + 0x2F3D, 0x8139, 0x9133, + 0x2F3E, 0x8139, 0x9134, + 0x2F3F, 0x8139, 0x9135, + 0x2F40, 0x8139, 0x9136, + 0x2F41, 0x8139, 0x9137, + 0x2F42, 0x8139, 0x9138, + 0x2F43, 0x8139, 0x9139, + 0x2F44, 0x8139, 0x9230, + 0x2F45, 0x8139, 0x9231, + 0x2F46, 0x8139, 0x9232, + 0x2F47, 0x8139, 0x9233, + 0x2F48, 0x8139, 0x9234, + 0x2F49, 0x8139, 0x9235, + 0x2F4A, 0x8139, 0x9236, + 0x2F4B, 0x8139, 0x9237, + 0x2F4C, 0x8139, 0x9238, + 0x2F4D, 0x8139, 0x9239, + 0x2F4E, 0x8139, 0x9330, + 0x2F4F, 0x8139, 0x9331, + 0x2F50, 0x8139, 0x9332, + 0x2F51, 0x8139, 0x9333, + 0x2F52, 0x8139, 0x9334, + 0x2F53, 0x8139, 0x9335, + 0x2F54, 0x8139, 0x9336, + 0x2F55, 0x8139, 0x9337, + 0x2F56, 0x8139, 0x9338, + 0x2F57, 0x8139, 0x9339, + 0x2F58, 0x8139, 0x9430, + 0x2F59, 0x8139, 0x9431, + 0x2F5A, 0x8139, 0x9432, + 0x2F5B, 0x8139, 0x9433, + 0x2F5C, 0x8139, 0x9434, + 0x2F5D, 0x8139, 0x9435, + 0x2F5E, 0x8139, 0x9436, + 0x2F5F, 0x8139, 0x9437, + 0x2F60, 0x8139, 0x9438, + 0x2F61, 0x8139, 0x9439, + 0x2F62, 0x8139, 0x9530, + 0x2F63, 0x8139, 0x9531, + 0x2F64, 0x8139, 0x9532, + 0x2F65, 0x8139, 0x9533, + 0x2F66, 0x8139, 0x9534, + 0x2F67, 0x8139, 0x9535, + 0x2F68, 0x8139, 0x9536, + 0x2F69, 0x8139, 0x9537, + 0x2F6A, 0x8139, 0x9538, + 0x2F6B, 0x8139, 0x9539, + 0x2F6C, 0x8139, 0x9630, + 0x2F6D, 0x8139, 0x9631, + 0x2F6E, 0x8139, 0x9632, + 0x2F6F, 0x8139, 0x9633, + 0x2F70, 0x8139, 0x9634, + 0x2F71, 0x8139, 0x9635, + 0x2F72, 0x8139, 0x9636, + 0x2F73, 0x8139, 0x9637, + 0x2F74, 0x8139, 0x9638, + 0x2F75, 0x8139, 0x9639, + 0x2F76, 0x8139, 0x9730, + 0x2F77, 0x8139, 0x9731, + 0x2F78, 0x8139, 0x9732, + 0x2F79, 0x8139, 0x9733, + 0x2F7A, 0x8139, 0x9734, + 0x2F7B, 0x8139, 0x9735, + 0x2F7C, 0x8139, 0x9736, + 0x2F7D, 0x8139, 0x9737, + 0x2F7E, 0x8139, 0x9738, + 0x2F7F, 0x8139, 0x9739, + 0x2F80, 0x8139, 0x9830, + 0x2F81, 0x8139, 0x9831, + 0x2F82, 0x8139, 0x9832, + 0x2F83, 0x8139, 0x9833, + 0x2F84, 0x8139, 0x9834, + 0x2F85, 0x8139, 0x9835, + 0x2F86, 0x8139, 0x9836, + 0x2F87, 0x8139, 0x9837, + 0x2F88, 0x8139, 0x9838, + 0x2F89, 0x8139, 0x9839, + 0x2F8A, 0x8139, 0x9930, + 0x2F8B, 0x8139, 0x9931, + 0x2F8C, 0x8139, 0x9932, + 0x2F8D, 0x8139, 0x9933, + 0x2F8E, 0x8139, 0x9934, + 0x2F8F, 0x8139, 0x9935, + 0x2F90, 0x8139, 0x9936, + 0x2F91, 0x8139, 0x9937, + 0x2F92, 0x8139, 0x9938, + 0x2F93, 0x8139, 0x9939, + 0x2F94, 0x8139, 0x9A30, + 0x2F95, 0x8139, 0x9A31, + 0x2F96, 0x8139, 0x9A32, + 0x2F97, 0x8139, 0x9A33, + 0x2F98, 0x8139, 0x9A34, + 0x2F99, 0x8139, 0x9A35, + 0x2F9A, 0x8139, 0x9A36, + 0x2F9B, 0x8139, 0x9A37, + 0x2F9C, 0x8139, 0x9A38, + 0x2F9D, 0x8139, 0x9A39, + 0x2F9E, 0x8139, 0x9B30, + 0x2F9F, 0x8139, 0x9B31, + 0x2FA0, 0x8139, 0x9B32, + 0x2FA1, 0x8139, 0x9B33, + 0x2FA2, 0x8139, 0x9B34, + 0x2FA3, 0x8139, 0x9B35, + 0x2FA4, 0x8139, 0x9B36, + 0x2FA5, 0x8139, 0x9B37, + 0x2FA6, 0x8139, 0x9B38, + 0x2FA7, 0x8139, 0x9B39, + 0x2FA8, 0x8139, 0x9C30, + 0x2FA9, 0x8139, 0x9C31, + 0x2FAA, 0x8139, 0x9C32, + 0x2FAB, 0x8139, 0x9C33, + 0x2FAC, 0x8139, 0x9C34, + 0x2FAD, 0x8139, 0x9C35, + 0x2FAE, 0x8139, 0x9C36, + 0x2FAF, 0x8139, 0x9C37, + 0x2FB0, 0x8139, 0x9C38, + 0x2FB1, 0x8139, 0x9C39, + 0x2FB2, 0x8139, 0x9D30, + 0x2FB3, 0x8139, 0x9D31, + 0x2FB4, 0x8139, 0x9D32, + 0x2FB5, 0x8139, 0x9D33, + 0x2FB6, 0x8139, 0x9D34, + 0x2FB7, 0x8139, 0x9D35, + 0x2FB8, 0x8139, 0x9D36, + 0x2FB9, 0x8139, 0x9D37, + 0x2FBA, 0x8139, 0x9D38, + 0x2FBB, 0x8139, 0x9D39, + 0x2FBC, 0x8139, 0x9E30, + 0x2FBD, 0x8139, 0x9E31, + 0x2FBE, 0x8139, 0x9E32, + 0x2FBF, 0x8139, 0x9E33, + 0x2FC0, 0x8139, 0x9E34, + 0x2FC1, 0x8139, 0x9E35, + 0x2FC2, 0x8139, 0x9E36, + 0x2FC3, 0x8139, 0x9E37, + 0x2FC4, 0x8139, 0x9E38, + 0x2FC5, 0x8139, 0x9E39, + 0x2FC6, 0x8139, 0x9F30, + 0x2FC7, 0x8139, 0x9F31, + 0x2FC8, 0x8139, 0x9F32, + 0x2FC9, 0x8139, 0x9F33, + 0x2FCA, 0x8139, 0x9F34, + 0x2FCB, 0x8139, 0x9F35, + 0x2FCC, 0x8139, 0x9F36, + 0x2FCD, 0x8139, 0x9F37, + 0x2FCE, 0x8139, 0x9F38, + 0x2FCF, 0x8139, 0x9F39, + 0x2FD0, 0x8139, 0xA030, + 0x2FD1, 0x8139, 0xA031, + 0x2FD2, 0x8139, 0xA032, + 0x2FD3, 0x8139, 0xA033, + 0x2FD4, 0x8139, 0xA034, + 0x2FD5, 0x8139, 0xA035, + 0x2FD6, 0x8139, 0xA036, + 0x2FD7, 0x8139, 0xA037, + 0x2FD8, 0x8139, 0xA038, + 0x2FD9, 0x8139, 0xA039, + 0x2FDA, 0x8139, 0xA130, + 0x2FDB, 0x8139, 0xA131, + 0x2FDC, 0x8139, 0xA132, + 0x2FDD, 0x8139, 0xA133, + 0x2FDE, 0x8139, 0xA134, + 0x2FDF, 0x8139, 0xA135, + 0x2FE0, 0x8139, 0xA136, + 0x2FE1, 0x8139, 0xA137, + 0x2FE2, 0x8139, 0xA138, + 0x2FE3, 0x8139, 0xA139, + 0x2FE4, 0x8139, 0xA230, + 0x2FE5, 0x8139, 0xA231, + 0x2FE6, 0x8139, 0xA232, + 0x2FE7, 0x8139, 0xA233, + 0x2FE8, 0x8139, 0xA234, + 0x2FE9, 0x8139, 0xA235, + 0x2FEA, 0x8139, 0xA236, + 0x2FEB, 0x8139, 0xA237, + 0x2FEC, 0x8139, 0xA238, + 0x2FED, 0x8139, 0xA239, + 0x2FEE, 0x8139, 0xA330, + 0x2FEF, 0x8139, 0xA331, + 0x2FFC, 0x8139, 0xA332, + 0x2FFD, 0x8139, 0xA333, + 0x2FFE, 0x8139, 0xA334, + 0x2FFF, 0x8139, 0xA335, + 0x3004, 0x8139, 0xA336, + 0x3018, 0x8139, 0xA337, + 0x3019, 0x8139, 0xA338, + 0x301A, 0x8139, 0xA339, + 0x301B, 0x8139, 0xA430, + 0x301C, 0x8139, 0xA431, + 0x301F, 0x8139, 0xA432, + 0x3020, 0x8139, 0xA433, + 0x302A, 0x8139, 0xA434, + 0x302B, 0x8139, 0xA435, + 0x302C, 0x8139, 0xA436, + 0x302D, 0x8139, 0xA437, + 0x302E, 0x8139, 0xA438, + 0x302F, 0x8139, 0xA439, + 0x3030, 0x8139, 0xA530, + 0x3031, 0x8139, 0xA531, + 0x3032, 0x8139, 0xA532, + 0x3033, 0x8139, 0xA533, + 0x3034, 0x8139, 0xA534, + 0x3035, 0x8139, 0xA535, + 0x3036, 0x8139, 0xA536, + 0x3037, 0x8139, 0xA537, + 0x3038, 0x8139, 0xA538, + 0x3039, 0x8139, 0xA539, + 0x303A, 0x8139, 0xA630, + 0x303B, 0x8139, 0xA631, + 0x303C, 0x8139, 0xA632, + 0x303D, 0x8139, 0xA633, + 0x303F, 0x8139, 0xA634, + 0x3040, 0x8139, 0xA635, + 0x3094, 0x8139, 0xA636, + 0x3095, 0x8139, 0xA637, + 0x3096, 0x8139, 0xA638, + 0x3097, 0x8139, 0xA639, + 0x3098, 0x8139, 0xA730, + 0x3099, 0x8139, 0xA731, + 0x309A, 0x8139, 0xA732, + 0x309F, 0x8139, 0xA733, + 0x30A0, 0x8139, 0xA734, + 0x30F7, 0x8139, 0xA735, + 0x30F8, 0x8139, 0xA736, + 0x30F9, 0x8139, 0xA737, + 0x30FA, 0x8139, 0xA738, + 0x30FB, 0x8139, 0xA739, + 0x30FF, 0x8139, 0xA830, + 0x3100, 0x8139, 0xA831, + 0x3101, 0x8139, 0xA832, + 0x3102, 0x8139, 0xA833, + 0x3103, 0x8139, 0xA834, + 0x3104, 0x8139, 0xA835, + 0x312A, 0x8139, 0xA836, + 0x312B, 0x8139, 0xA837, + 0x312C, 0x8139, 0xA838, + 0x312D, 0x8139, 0xA839, + 0x312E, 0x8139, 0xA930, + 0x312F, 0x8139, 0xA931, + 0x3130, 0x8139, 0xA932, + 0x3131, 0x8139, 0xA933, + 0x3132, 0x8139, 0xA934, + 0x3133, 0x8139, 0xA935, + 0x3134, 0x8139, 0xA936, + 0x3135, 0x8139, 0xA937, + 0x3136, 0x8139, 0xA938, + 0x3137, 0x8139, 0xA939, + 0x3138, 0x8139, 0xAA30, + 0x3139, 0x8139, 0xAA31, + 0x313A, 0x8139, 0xAA32, + 0x313B, 0x8139, 0xAA33, + 0x313C, 0x8139, 0xAA34, + 0x313D, 0x8139, 0xAA35, + 0x313E, 0x8139, 0xAA36, + 0x313F, 0x8139, 0xAA37, + 0x3140, 0x8139, 0xAA38, + 0x3141, 0x8139, 0xAA39, + 0x3142, 0x8139, 0xAB30, + 0x3143, 0x8139, 0xAB31, + 0x3144, 0x8139, 0xAB32, + 0x3145, 0x8139, 0xAB33, + 0x3146, 0x8139, 0xAB34, + 0x3147, 0x8139, 0xAB35, + 0x3148, 0x8139, 0xAB36, + 0x3149, 0x8139, 0xAB37, + 0x314A, 0x8139, 0xAB38, + 0x314B, 0x8139, 0xAB39, + 0x314C, 0x8139, 0xAC30, + 0x314D, 0x8139, 0xAC31, + 0x314E, 0x8139, 0xAC32, + 0x314F, 0x8139, 0xAC33, + 0x3150, 0x8139, 0xAC34, + 0x3151, 0x8139, 0xAC35, + 0x3152, 0x8139, 0xAC36, + 0x3153, 0x8139, 0xAC37, + 0x3154, 0x8139, 0xAC38, + 0x3155, 0x8139, 0xAC39, + 0x3156, 0x8139, 0xAD30, + 0x3157, 0x8139, 0xAD31, + 0x3158, 0x8139, 0xAD32, + 0x3159, 0x8139, 0xAD33, + 0x315A, 0x8139, 0xAD34, + 0x315B, 0x8139, 0xAD35, + 0x315C, 0x8139, 0xAD36, + 0x315D, 0x8139, 0xAD37, + 0x315E, 0x8139, 0xAD38, + 0x315F, 0x8139, 0xAD39, + 0x3160, 0x8139, 0xAE30, + 0x3161, 0x8139, 0xAE31, + 0x3162, 0x8139, 0xAE32, + 0x3163, 0x8139, 0xAE33, + 0x3164, 0x8139, 0xAE34, + 0x3165, 0x8139, 0xAE35, + 0x3166, 0x8139, 0xAE36, + 0x3167, 0x8139, 0xAE37, + 0x3168, 0x8139, 0xAE38, + 0x3169, 0x8139, 0xAE39, + 0x316A, 0x8139, 0xAF30, + 0x316B, 0x8139, 0xAF31, + 0x316C, 0x8139, 0xAF32, + 0x316D, 0x8139, 0xAF33, + 0x316E, 0x8139, 0xAF34, + 0x316F, 0x8139, 0xAF35, + 0x3170, 0x8139, 0xAF36, + 0x3171, 0x8139, 0xAF37, + 0x3172, 0x8139, 0xAF38, + 0x3173, 0x8139, 0xAF39, + 0x3174, 0x8139, 0xB030, + 0x3175, 0x8139, 0xB031, + 0x3176, 0x8139, 0xB032, + 0x3177, 0x8139, 0xB033, + 0x3178, 0x8139, 0xB034, + 0x3179, 0x8139, 0xB035, + 0x317A, 0x8139, 0xB036, + 0x317B, 0x8139, 0xB037, + 0x317C, 0x8139, 0xB038, + 0x317D, 0x8139, 0xB039, + 0x317E, 0x8139, 0xB130, + 0x317F, 0x8139, 0xB131, + 0x3180, 0x8139, 0xB132, + 0x3181, 0x8139, 0xB133, + 0x3182, 0x8139, 0xB134, + 0x3183, 0x8139, 0xB135, + 0x3184, 0x8139, 0xB136, + 0x3185, 0x8139, 0xB137, + 0x3186, 0x8139, 0xB138, + 0x3187, 0x8139, 0xB139, + 0x3188, 0x8139, 0xB230, + 0x3189, 0x8139, 0xB231, + 0x318A, 0x8139, 0xB232, + 0x318B, 0x8139, 0xB233, + 0x318C, 0x8139, 0xB234, + 0x318D, 0x8139, 0xB235, + 0x318E, 0x8139, 0xB236, + 0x318F, 0x8139, 0xB237, + 0x3190, 0x8139, 0xB238, + 0x3191, 0x8139, 0xB239, + 0x3192, 0x8139, 0xB330, + 0x3193, 0x8139, 0xB331, + 0x3194, 0x8139, 0xB332, + 0x3195, 0x8139, 0xB333, + 0x3196, 0x8139, 0xB334, + 0x3197, 0x8139, 0xB335, + 0x3198, 0x8139, 0xB336, + 0x3199, 0x8139, 0xB337, + 0x319A, 0x8139, 0xB338, + 0x319B, 0x8139, 0xB339, + 0x319C, 0x8139, 0xB430, + 0x319D, 0x8139, 0xB431, + 0x319E, 0x8139, 0xB432, + 0x319F, 0x8139, 0xB433, + 0x31A0, 0x8139, 0xB434, + 0x31A1, 0x8139, 0xB435, + 0x31A2, 0x8139, 0xB436, + 0x31A3, 0x8139, 0xB437, + 0x31A4, 0x8139, 0xB438, + 0x31A5, 0x8139, 0xB439, + 0x31A6, 0x8139, 0xB530, + 0x31A7, 0x8139, 0xB531, + 0x31A8, 0x8139, 0xB532, + 0x31A9, 0x8139, 0xB533, + 0x31AA, 0x8139, 0xB534, + 0x31AB, 0x8139, 0xB535, + 0x31AC, 0x8139, 0xB536, + 0x31AD, 0x8139, 0xB537, + 0x31AE, 0x8139, 0xB538, + 0x31AF, 0x8139, 0xB539, + 0x31B0, 0x8139, 0xB630, + 0x31B1, 0x8139, 0xB631, + 0x31B2, 0x8139, 0xB632, + 0x31B3, 0x8139, 0xB633, + 0x31B4, 0x8139, 0xB634, + 0x31B5, 0x8139, 0xB635, + 0x31B6, 0x8139, 0xB636, + 0x31B7, 0x8139, 0xB637, + 0x31B8, 0x8139, 0xB638, + 0x31B9, 0x8139, 0xB639, + 0x31BA, 0x8139, 0xB730, + 0x31BB, 0x8139, 0xB731, + 0x31BC, 0x8139, 0xB732, + 0x31BD, 0x8139, 0xB733, + 0x31BE, 0x8139, 0xB734, + 0x31BF, 0x8139, 0xB735, + 0x31C0, 0x8139, 0xB736, + 0x31C1, 0x8139, 0xB737, + 0x31C2, 0x8139, 0xB738, + 0x31C3, 0x8139, 0xB739, + 0x31C4, 0x8139, 0xB830, + 0x31C5, 0x8139, 0xB831, + 0x31C6, 0x8139, 0xB832, + 0x31C7, 0x8139, 0xB833, + 0x31C8, 0x8139, 0xB834, + 0x31C9, 0x8139, 0xB835, + 0x31CA, 0x8139, 0xB836, + 0x31CB, 0x8139, 0xB837, + 0x31CC, 0x8139, 0xB838, + 0x31CD, 0x8139, 0xB839, + 0x31CE, 0x8139, 0xB930, + 0x31CF, 0x8139, 0xB931, + 0x31D0, 0x8139, 0xB932, + 0x31D1, 0x8139, 0xB933, + 0x31D2, 0x8139, 0xB934, + 0x31D3, 0x8139, 0xB935, + 0x31D4, 0x8139, 0xB936, + 0x31D5, 0x8139, 0xB937, + 0x31D6, 0x8139, 0xB938, + 0x31D7, 0x8139, 0xB939, + 0x31D8, 0x8139, 0xBA30, + 0x31D9, 0x8139, 0xBA31, + 0x31DA, 0x8139, 0xBA32, + 0x31DB, 0x8139, 0xBA33, + 0x31DC, 0x8139, 0xBA34, + 0x31DD, 0x8139, 0xBA35, + 0x31DE, 0x8139, 0xBA36, + 0x31DF, 0x8139, 0xBA37, + 0x31E0, 0x8139, 0xBA38, + 0x31E1, 0x8139, 0xBA39, + 0x31E2, 0x8139, 0xBB30, + 0x31E3, 0x8139, 0xBB31, + 0x31E4, 0x8139, 0xBB32, + 0x31E5, 0x8139, 0xBB33, + 0x31E6, 0x8139, 0xBB34, + 0x31E7, 0x8139, 0xBB35, + 0x31E8, 0x8139, 0xBB36, + 0x31E9, 0x8139, 0xBB37, + 0x31EA, 0x8139, 0xBB38, + 0x31EB, 0x8139, 0xBB39, + 0x31EC, 0x8139, 0xBC30, + 0x31ED, 0x8139, 0xBC31, + 0x31EE, 0x8139, 0xBC32, + 0x31EF, 0x8139, 0xBC33, + 0x31F0, 0x8139, 0xBC34, + 0x31F1, 0x8139, 0xBC35, + 0x31F2, 0x8139, 0xBC36, + 0x31F3, 0x8139, 0xBC37, + 0x31F4, 0x8139, 0xBC38, + 0x31F5, 0x8139, 0xBC39, + 0x31F6, 0x8139, 0xBD30, + 0x31F7, 0x8139, 0xBD31, + 0x31F8, 0x8139, 0xBD32, + 0x31F9, 0x8139, 0xBD33, + 0x31FA, 0x8139, 0xBD34, + 0x31FB, 0x8139, 0xBD35, + 0x31FC, 0x8139, 0xBD36, + 0x31FD, 0x8139, 0xBD37, + 0x31FE, 0x8139, 0xBD38, + 0x31FF, 0x8139, 0xBD39, + 0x3200, 0x8139, 0xBE30, + 0x3201, 0x8139, 0xBE31, + 0x3202, 0x8139, 0xBE32, + 0x3203, 0x8139, 0xBE33, + 0x3204, 0x8139, 0xBE34, + 0x3205, 0x8139, 0xBE35, + 0x3206, 0x8139, 0xBE36, + 0x3207, 0x8139, 0xBE37, + 0x3208, 0x8139, 0xBE38, + 0x3209, 0x8139, 0xBE39, + 0x320A, 0x8139, 0xBF30, + 0x320B, 0x8139, 0xBF31, + 0x320C, 0x8139, 0xBF32, + 0x320D, 0x8139, 0xBF33, + 0x320E, 0x8139, 0xBF34, + 0x320F, 0x8139, 0xBF35, + 0x3210, 0x8139, 0xBF36, + 0x3211, 0x8139, 0xBF37, + 0x3212, 0x8139, 0xBF38, + 0x3213, 0x8139, 0xBF39, + 0x3214, 0x8139, 0xC030, + 0x3215, 0x8139, 0xC031, + 0x3216, 0x8139, 0xC032, + 0x3217, 0x8139, 0xC033, + 0x3218, 0x8139, 0xC034, + 0x3219, 0x8139, 0xC035, + 0x321A, 0x8139, 0xC036, + 0x321B, 0x8139, 0xC037, + 0x321C, 0x8139, 0xC038, + 0x321D, 0x8139, 0xC039, + 0x321E, 0x8139, 0xC130, + 0x321F, 0x8139, 0xC131, + 0x322A, 0x8139, 0xC132, + 0x322B, 0x8139, 0xC133, + 0x322C, 0x8139, 0xC134, + 0x322D, 0x8139, 0xC135, + 0x322E, 0x8139, 0xC136, + 0x322F, 0x8139, 0xC137, + 0x3230, 0x8139, 0xC138, + 0x3232, 0x8139, 0xC139, + 0x3233, 0x8139, 0xC230, + 0x3234, 0x8139, 0xC231, + 0x3235, 0x8139, 0xC232, + 0x3236, 0x8139, 0xC233, + 0x3237, 0x8139, 0xC234, + 0x3238, 0x8139, 0xC235, + 0x3239, 0x8139, 0xC236, + 0x323A, 0x8139, 0xC237, + 0x323B, 0x8139, 0xC238, + 0x323C, 0x8139, 0xC239, + 0x323D, 0x8139, 0xC330, + 0x323E, 0x8139, 0xC331, + 0x323F, 0x8139, 0xC332, + 0x3240, 0x8139, 0xC333, + 0x3241, 0x8139, 0xC334, + 0x3242, 0x8139, 0xC335, + 0x3243, 0x8139, 0xC336, + 0x3244, 0x8139, 0xC337, + 0x3245, 0x8139, 0xC338, + 0x3246, 0x8139, 0xC339, + 0x3247, 0x8139, 0xC430, + 0x3248, 0x8139, 0xC431, + 0x3249, 0x8139, 0xC432, + 0x324A, 0x8139, 0xC433, + 0x324B, 0x8139, 0xC434, + 0x324C, 0x8139, 0xC435, + 0x324D, 0x8139, 0xC436, + 0x324E, 0x8139, 0xC437, + 0x324F, 0x8139, 0xC438, + 0x3250, 0x8139, 0xC439, + 0x3251, 0x8139, 0xC530, + 0x3252, 0x8139, 0xC531, + 0x3253, 0x8139, 0xC532, + 0x3254, 0x8139, 0xC533, + 0x3255, 0x8139, 0xC534, + 0x3256, 0x8139, 0xC535, + 0x3257, 0x8139, 0xC536, + 0x3258, 0x8139, 0xC537, + 0x3259, 0x8139, 0xC538, + 0x325A, 0x8139, 0xC539, + 0x325B, 0x8139, 0xC630, + 0x325C, 0x8139, 0xC631, + 0x325D, 0x8139, 0xC632, + 0x325E, 0x8139, 0xC633, + 0x325F, 0x8139, 0xC634, + 0x3260, 0x8139, 0xC635, + 0x3261, 0x8139, 0xC636, + 0x3262, 0x8139, 0xC637, + 0x3263, 0x8139, 0xC638, + 0x3264, 0x8139, 0xC639, + 0x3265, 0x8139, 0xC730, + 0x3266, 0x8139, 0xC731, + 0x3267, 0x8139, 0xC732, + 0x3268, 0x8139, 0xC733, + 0x3269, 0x8139, 0xC734, + 0x326A, 0x8139, 0xC735, + 0x326B, 0x8139, 0xC736, + 0x326C, 0x8139, 0xC737, + 0x326D, 0x8139, 0xC738, + 0x326E, 0x8139, 0xC739, + 0x326F, 0x8139, 0xC830, + 0x3270, 0x8139, 0xC831, + 0x3271, 0x8139, 0xC832, + 0x3272, 0x8139, 0xC833, + 0x3273, 0x8139, 0xC834, + 0x3274, 0x8139, 0xC835, + 0x3275, 0x8139, 0xC836, + 0x3276, 0x8139, 0xC837, + 0x3277, 0x8139, 0xC838, + 0x3278, 0x8139, 0xC839, + 0x3279, 0x8139, 0xC930, + 0x327A, 0x8139, 0xC931, + 0x327B, 0x8139, 0xC932, + 0x327C, 0x8139, 0xC933, + 0x327D, 0x8139, 0xC934, + 0x327E, 0x8139, 0xC935, + 0x327F, 0x8139, 0xC936, + 0x3280, 0x8139, 0xC937, + 0x3281, 0x8139, 0xC938, + 0x3282, 0x8139, 0xC939, + 0x3283, 0x8139, 0xCA30, + 0x3284, 0x8139, 0xCA31, + 0x3285, 0x8139, 0xCA32, + 0x3286, 0x8139, 0xCA33, + 0x3287, 0x8139, 0xCA34, + 0x3288, 0x8139, 0xCA35, + 0x3289, 0x8139, 0xCA36, + 0x328A, 0x8139, 0xCA37, + 0x328B, 0x8139, 0xCA38, + 0x328C, 0x8139, 0xCA39, + 0x328D, 0x8139, 0xCB30, + 0x328E, 0x8139, 0xCB31, + 0x328F, 0x8139, 0xCB32, + 0x3290, 0x8139, 0xCB33, + 0x3291, 0x8139, 0xCB34, + 0x3292, 0x8139, 0xCB35, + 0x3293, 0x8139, 0xCB36, + 0x3294, 0x8139, 0xCB37, + 0x3295, 0x8139, 0xCB38, + 0x3296, 0x8139, 0xCB39, + 0x3297, 0x8139, 0xCC30, + 0x3298, 0x8139, 0xCC31, + 0x3299, 0x8139, 0xCC32, + 0x329A, 0x8139, 0xCC33, + 0x329B, 0x8139, 0xCC34, + 0x329C, 0x8139, 0xCC35, + 0x329D, 0x8139, 0xCC36, + 0x329E, 0x8139, 0xCC37, + 0x329F, 0x8139, 0xCC38, + 0x32A0, 0x8139, 0xCC39, + 0x32A1, 0x8139, 0xCD30, + 0x32A2, 0x8139, 0xCD31, + 0x32A4, 0x8139, 0xCD32, + 0x32A5, 0x8139, 0xCD33, + 0x32A6, 0x8139, 0xCD34, + 0x32A7, 0x8139, 0xCD35, + 0x32A8, 0x8139, 0xCD36, + 0x32A9, 0x8139, 0xCD37, + 0x32AA, 0x8139, 0xCD38, + 0x32AB, 0x8139, 0xCD39, + 0x32AC, 0x8139, 0xCE30, + 0x32AD, 0x8139, 0xCE31, + 0x32AE, 0x8139, 0xCE32, + 0x32AF, 0x8139, 0xCE33, + 0x32B0, 0x8139, 0xCE34, + 0x32B1, 0x8139, 0xCE35, + 0x32B2, 0x8139, 0xCE36, + 0x32B3, 0x8139, 0xCE37, + 0x32B4, 0x8139, 0xCE38, + 0x32B5, 0x8139, 0xCE39, + 0x32B6, 0x8139, 0xCF30, + 0x32B7, 0x8139, 0xCF31, + 0x32B8, 0x8139, 0xCF32, + 0x32B9, 0x8139, 0xCF33, + 0x32BA, 0x8139, 0xCF34, + 0x32BB, 0x8139, 0xCF35, + 0x32BC, 0x8139, 0xCF36, + 0x32BD, 0x8139, 0xCF37, + 0x32BE, 0x8139, 0xCF38, + 0x32BF, 0x8139, 0xCF39, + 0x32C0, 0x8139, 0xD030, + 0x32C1, 0x8139, 0xD031, + 0x32C2, 0x8139, 0xD032, + 0x32C3, 0x8139, 0xD033, + 0x32C4, 0x8139, 0xD034, + 0x32C5, 0x8139, 0xD035, + 0x32C6, 0x8139, 0xD036, + 0x32C7, 0x8139, 0xD037, + 0x32C8, 0x8139, 0xD038, + 0x32C9, 0x8139, 0xD039, + 0x32CA, 0x8139, 0xD130, + 0x32CB, 0x8139, 0xD131, + 0x32CC, 0x8139, 0xD132, + 0x32CD, 0x8139, 0xD133, + 0x32CE, 0x8139, 0xD134, + 0x32CF, 0x8139, 0xD135, + 0x32D0, 0x8139, 0xD136, + 0x32D1, 0x8139, 0xD137, + 0x32D2, 0x8139, 0xD138, + 0x32D3, 0x8139, 0xD139, + 0x32D4, 0x8139, 0xD230, + 0x32D5, 0x8139, 0xD231, + 0x32D6, 0x8139, 0xD232, + 0x32D7, 0x8139, 0xD233, + 0x32D8, 0x8139, 0xD234, + 0x32D9, 0x8139, 0xD235, + 0x32DA, 0x8139, 0xD236, + 0x32DB, 0x8139, 0xD237, + 0x32DC, 0x8139, 0xD238, + 0x32DD, 0x8139, 0xD239, + 0x32DE, 0x8139, 0xD330, + 0x32DF, 0x8139, 0xD331, + 0x32E0, 0x8139, 0xD332, + 0x32E1, 0x8139, 0xD333, + 0x32E2, 0x8139, 0xD334, + 0x32E3, 0x8139, 0xD335, + 0x32E4, 0x8139, 0xD336, + 0x32E5, 0x8139, 0xD337, + 0x32E6, 0x8139, 0xD338, + 0x32E7, 0x8139, 0xD339, + 0x32E8, 0x8139, 0xD430, + 0x32E9, 0x8139, 0xD431, + 0x32EA, 0x8139, 0xD432, + 0x32EB, 0x8139, 0xD433, + 0x32EC, 0x8139, 0xD434, + 0x32ED, 0x8139, 0xD435, + 0x32EE, 0x8139, 0xD436, + 0x32EF, 0x8139, 0xD437, + 0x32F0, 0x8139, 0xD438, + 0x32F1, 0x8139, 0xD439, + 0x32F2, 0x8139, 0xD530, + 0x32F3, 0x8139, 0xD531, + 0x32F4, 0x8139, 0xD532, + 0x32F5, 0x8139, 0xD533, + 0x32F6, 0x8139, 0xD534, + 0x32F7, 0x8139, 0xD535, + 0x32F8, 0x8139, 0xD536, + 0x32F9, 0x8139, 0xD537, + 0x32FA, 0x8139, 0xD538, + 0x32FB, 0x8139, 0xD539, + 0x32FC, 0x8139, 0xD630, + 0x32FD, 0x8139, 0xD631, + 0x32FE, 0x8139, 0xD632, + 0x32FF, 0x8139, 0xD633, + 0x3300, 0x8139, 0xD634, + 0x3301, 0x8139, 0xD635, + 0x3302, 0x8139, 0xD636, + 0x3303, 0x8139, 0xD637, + 0x3304, 0x8139, 0xD638, + 0x3305, 0x8139, 0xD639, + 0x3306, 0x8139, 0xD730, + 0x3307, 0x8139, 0xD731, + 0x3308, 0x8139, 0xD732, + 0x3309, 0x8139, 0xD733, + 0x330A, 0x8139, 0xD734, + 0x330B, 0x8139, 0xD735, + 0x330C, 0x8139, 0xD736, + 0x330D, 0x8139, 0xD737, + 0x330E, 0x8139, 0xD738, + 0x330F, 0x8139, 0xD739, + 0x3310, 0x8139, 0xD830, + 0x3311, 0x8139, 0xD831, + 0x3312, 0x8139, 0xD832, + 0x3313, 0x8139, 0xD833, + 0x3314, 0x8139, 0xD834, + 0x3315, 0x8139, 0xD835, + 0x3316, 0x8139, 0xD836, + 0x3317, 0x8139, 0xD837, + 0x3318, 0x8139, 0xD838, + 0x3319, 0x8139, 0xD839, + 0x331A, 0x8139, 0xD930, + 0x331B, 0x8139, 0xD931, + 0x331C, 0x8139, 0xD932, + 0x331D, 0x8139, 0xD933, + 0x331E, 0x8139, 0xD934, + 0x331F, 0x8139, 0xD935, + 0x3320, 0x8139, 0xD936, + 0x3321, 0x8139, 0xD937, + 0x3322, 0x8139, 0xD938, + 0x3323, 0x8139, 0xD939, + 0x3324, 0x8139, 0xDA30, + 0x3325, 0x8139, 0xDA31, + 0x3326, 0x8139, 0xDA32, + 0x3327, 0x8139, 0xDA33, + 0x3328, 0x8139, 0xDA34, + 0x3329, 0x8139, 0xDA35, + 0x332A, 0x8139, 0xDA36, + 0x332B, 0x8139, 0xDA37, + 0x332C, 0x8139, 0xDA38, + 0x332D, 0x8139, 0xDA39, + 0x332E, 0x8139, 0xDB30, + 0x332F, 0x8139, 0xDB31, + 0x3330, 0x8139, 0xDB32, + 0x3331, 0x8139, 0xDB33, + 0x3332, 0x8139, 0xDB34, + 0x3333, 0x8139, 0xDB35, + 0x3334, 0x8139, 0xDB36, + 0x3335, 0x8139, 0xDB37, + 0x3336, 0x8139, 0xDB38, + 0x3337, 0x8139, 0xDB39, + 0x3338, 0x8139, 0xDC30, + 0x3339, 0x8139, 0xDC31, + 0x333A, 0x8139, 0xDC32, + 0x333B, 0x8139, 0xDC33, + 0x333C, 0x8139, 0xDC34, + 0x333D, 0x8139, 0xDC35, + 0x333E, 0x8139, 0xDC36, + 0x333F, 0x8139, 0xDC37, + 0x3340, 0x8139, 0xDC38, + 0x3341, 0x8139, 0xDC39, + 0x3342, 0x8139, 0xDD30, + 0x3343, 0x8139, 0xDD31, + 0x3344, 0x8139, 0xDD32, + 0x3345, 0x8139, 0xDD33, + 0x3346, 0x8139, 0xDD34, + 0x3347, 0x8139, 0xDD35, + 0x3348, 0x8139, 0xDD36, + 0x3349, 0x8139, 0xDD37, + 0x334A, 0x8139, 0xDD38, + 0x334B, 0x8139, 0xDD39, + 0x334C, 0x8139, 0xDE30, + 0x334D, 0x8139, 0xDE31, + 0x334E, 0x8139, 0xDE32, + 0x334F, 0x8139, 0xDE33, + 0x3350, 0x8139, 0xDE34, + 0x3351, 0x8139, 0xDE35, + 0x3352, 0x8139, 0xDE36, + 0x3353, 0x8139, 0xDE37, + 0x3354, 0x8139, 0xDE38, + 0x3355, 0x8139, 0xDE39, + 0x3356, 0x8139, 0xDF30, + 0x3357, 0x8139, 0xDF31, + 0x3358, 0x8139, 0xDF32, + 0x3359, 0x8139, 0xDF33, + 0x335A, 0x8139, 0xDF34, + 0x335B, 0x8139, 0xDF35, + 0x335C, 0x8139, 0xDF36, + 0x335D, 0x8139, 0xDF37, + 0x335E, 0x8139, 0xDF38, + 0x335F, 0x8139, 0xDF39, + 0x3360, 0x8139, 0xE030, + 0x3361, 0x8139, 0xE031, + 0x3362, 0x8139, 0xE032, + 0x3363, 0x8139, 0xE033, + 0x3364, 0x8139, 0xE034, + 0x3365, 0x8139, 0xE035, + 0x3366, 0x8139, 0xE036, + 0x3367, 0x8139, 0xE037, + 0x3368, 0x8139, 0xE038, + 0x3369, 0x8139, 0xE039, + 0x336A, 0x8139, 0xE130, + 0x336B, 0x8139, 0xE131, + 0x336C, 0x8139, 0xE132, + 0x336D, 0x8139, 0xE133, + 0x336E, 0x8139, 0xE134, + 0x336F, 0x8139, 0xE135, + 0x3370, 0x8139, 0xE136, + 0x3371, 0x8139, 0xE137, + 0x3372, 0x8139, 0xE138, + 0x3373, 0x8139, 0xE139, + 0x3374, 0x8139, 0xE230, + 0x3375, 0x8139, 0xE231, + 0x3376, 0x8139, 0xE232, + 0x3377, 0x8139, 0xE233, + 0x3378, 0x8139, 0xE234, + 0x3379, 0x8139, 0xE235, + 0x337A, 0x8139, 0xE236, + 0x337B, 0x8139, 0xE237, + 0x337C, 0x8139, 0xE238, + 0x337D, 0x8139, 0xE239, + 0x337E, 0x8139, 0xE330, + 0x337F, 0x8139, 0xE331, + 0x3380, 0x8139, 0xE332, + 0x3381, 0x8139, 0xE333, + 0x3382, 0x8139, 0xE334, + 0x3383, 0x8139, 0xE335, + 0x3384, 0x8139, 0xE336, + 0x3385, 0x8139, 0xE337, + 0x3386, 0x8139, 0xE338, + 0x3387, 0x8139, 0xE339, + 0x3388, 0x8139, 0xE430, + 0x3389, 0x8139, 0xE431, + 0x338A, 0x8139, 0xE432, + 0x338B, 0x8139, 0xE433, + 0x338C, 0x8139, 0xE434, + 0x338D, 0x8139, 0xE435, + 0x3390, 0x8139, 0xE436, + 0x3391, 0x8139, 0xE437, + 0x3392, 0x8139, 0xE438, + 0x3393, 0x8139, 0xE439, + 0x3394, 0x8139, 0xE530, + 0x3395, 0x8139, 0xE531, + 0x3396, 0x8139, 0xE532, + 0x3397, 0x8139, 0xE533, + 0x3398, 0x8139, 0xE534, + 0x3399, 0x8139, 0xE535, + 0x339A, 0x8139, 0xE536, + 0x339B, 0x8139, 0xE537, + 0x339F, 0x8139, 0xE538, + 0x33A0, 0x8139, 0xE539, + 0x33A2, 0x8139, 0xE630, + 0x33A3, 0x8139, 0xE631, + 0x33A4, 0x8139, 0xE632, + 0x33A5, 0x8139, 0xE633, + 0x33A6, 0x8139, 0xE634, + 0x33A7, 0x8139, 0xE635, + 0x33A8, 0x8139, 0xE636, + 0x33A9, 0x8139, 0xE637, + 0x33AA, 0x8139, 0xE638, + 0x33AB, 0x8139, 0xE639, + 0x33AC, 0x8139, 0xE730, + 0x33AD, 0x8139, 0xE731, + 0x33AE, 0x8139, 0xE732, + 0x33AF, 0x8139, 0xE733, + 0x33B0, 0x8139, 0xE734, + 0x33B1, 0x8139, 0xE735, + 0x33B2, 0x8139, 0xE736, + 0x33B3, 0x8139, 0xE737, + 0x33B4, 0x8139, 0xE738, + 0x33B5, 0x8139, 0xE739, + 0x33B6, 0x8139, 0xE830, + 0x33B7, 0x8139, 0xE831, + 0x33B8, 0x8139, 0xE832, + 0x33B9, 0x8139, 0xE833, + 0x33BA, 0x8139, 0xE834, + 0x33BB, 0x8139, 0xE835, + 0x33BC, 0x8139, 0xE836, + 0x33BD, 0x8139, 0xE837, + 0x33BE, 0x8139, 0xE838, + 0x33BF, 0x8139, 0xE839, + 0x33C0, 0x8139, 0xE930, + 0x33C1, 0x8139, 0xE931, + 0x33C2, 0x8139, 0xE932, + 0x33C3, 0x8139, 0xE933, + 0x33C5, 0x8139, 0xE934, + 0x33C6, 0x8139, 0xE935, + 0x33C7, 0x8139, 0xE936, + 0x33C8, 0x8139, 0xE937, + 0x33C9, 0x8139, 0xE938, + 0x33CA, 0x8139, 0xE939, + 0x33CB, 0x8139, 0xEA30, + 0x33CC, 0x8139, 0xEA31, + 0x33CD, 0x8139, 0xEA32, + 0x33CF, 0x8139, 0xEA33, + 0x33D0, 0x8139, 0xEA34, + 0x33D3, 0x8139, 0xEA35, + 0x33D4, 0x8139, 0xEA36, + 0x33D6, 0x8139, 0xEA37, + 0x33D7, 0x8139, 0xEA38, + 0x33D8, 0x8139, 0xEA39, + 0x33D9, 0x8139, 0xEB30, + 0x33DA, 0x8139, 0xEB31, + 0x33DB, 0x8139, 0xEB32, + 0x33DC, 0x8139, 0xEB33, + 0x33DD, 0x8139, 0xEB34, + 0x33DE, 0x8139, 0xEB35, + 0x33DF, 0x8139, 0xEB36, + 0x33E0, 0x8139, 0xEB37, + 0x33E1, 0x8139, 0xEB38, + 0x33E2, 0x8139, 0xEB39, + 0x33E3, 0x8139, 0xEC30, + 0x33E4, 0x8139, 0xEC31, + 0x33E5, 0x8139, 0xEC32, + 0x33E6, 0x8139, 0xEC33, + 0x33E7, 0x8139, 0xEC34, + 0x33E8, 0x8139, 0xEC35, + 0x33E9, 0x8139, 0xEC36, + 0x33EA, 0x8139, 0xEC37, + 0x33EB, 0x8139, 0xEC38, + 0x33EC, 0x8139, 0xEC39, + 0x33ED, 0x8139, 0xED30, + 0x33EE, 0x8139, 0xED31, + 0x33EF, 0x8139, 0xED32, + 0x33F0, 0x8139, 0xED33, + 0x33F1, 0x8139, 0xED34, + 0x33F2, 0x8139, 0xED35, + 0x33F3, 0x8139, 0xED36, + 0x33F4, 0x8139, 0xED37, + 0x33F5, 0x8139, 0xED38, + 0x33F6, 0x8139, 0xED39, + 0x33F7, 0x8139, 0xEE30, + 0x33F8, 0x8139, 0xEE31, + 0x33F9, 0x8139, 0xEE32, + 0x33FA, 0x8139, 0xEE33, + 0x33FB, 0x8139, 0xEE34, + 0x33FC, 0x8139, 0xEE35, + 0x33FD, 0x8139, 0xEE36, + 0x33FE, 0x8139, 0xEE37, + 0x33FF, 0x8139, 0xEE38, + 0x3400, 0x8139, 0xEE39, + 0x3401, 0x8139, 0xEF30, + 0x3402, 0x8139, 0xEF31, + 0x3403, 0x8139, 0xEF32, + 0x3404, 0x8139, 0xEF33, + 0x3405, 0x8139, 0xEF34, + 0x3406, 0x8139, 0xEF35, + 0x3407, 0x8139, 0xEF36, + 0x3408, 0x8139, 0xEF37, + 0x3409, 0x8139, 0xEF38, + 0x340A, 0x8139, 0xEF39, + 0x340B, 0x8139, 0xF030, + 0x340C, 0x8139, 0xF031, + 0x340D, 0x8139, 0xF032, + 0x340E, 0x8139, 0xF033, + 0x340F, 0x8139, 0xF034, + 0x3410, 0x8139, 0xF035, + 0x3411, 0x8139, 0xF036, + 0x3412, 0x8139, 0xF037, + 0x3413, 0x8139, 0xF038, + 0x3414, 0x8139, 0xF039, + 0x3415, 0x8139, 0xF130, + 0x3416, 0x8139, 0xF131, + 0x3417, 0x8139, 0xF132, + 0x3418, 0x8139, 0xF133, + 0x3419, 0x8139, 0xF134, + 0x341A, 0x8139, 0xF135, + 0x341B, 0x8139, 0xF136, + 0x341C, 0x8139, 0xF137, + 0x341D, 0x8139, 0xF138, + 0x341E, 0x8139, 0xF139, + 0x341F, 0x8139, 0xF230, + 0x3420, 0x8139, 0xF231, + 0x3421, 0x8139, 0xF232, + 0x3422, 0x8139, 0xF233, + 0x3423, 0x8139, 0xF234, + 0x3424, 0x8139, 0xF235, + 0x3425, 0x8139, 0xF236, + 0x3426, 0x8139, 0xF237, + 0x3427, 0x8139, 0xF238, + 0x3428, 0x8139, 0xF239, + 0x3429, 0x8139, 0xF330, + 0x342A, 0x8139, 0xF331, + 0x342B, 0x8139, 0xF332, + 0x342C, 0x8139, 0xF333, + 0x342D, 0x8139, 0xF334, + 0x342E, 0x8139, 0xF335, + 0x342F, 0x8139, 0xF336, + 0x3430, 0x8139, 0xF337, + 0x3431, 0x8139, 0xF338, + 0x3432, 0x8139, 0xF339, + 0x3433, 0x8139, 0xF430, + 0x3434, 0x8139, 0xF431, + 0x3435, 0x8139, 0xF432, + 0x3436, 0x8139, 0xF433, + 0x3437, 0x8139, 0xF434, + 0x3438, 0x8139, 0xF435, + 0x3439, 0x8139, 0xF436, + 0x343A, 0x8139, 0xF437, + 0x343B, 0x8139, 0xF438, + 0x343C, 0x8139, 0xF439, + 0x343D, 0x8139, 0xF530, + 0x343E, 0x8139, 0xF531, + 0x343F, 0x8139, 0xF532, + 0x3440, 0x8139, 0xF533, + 0x3441, 0x8139, 0xF534, + 0x3442, 0x8139, 0xF535, + 0x3443, 0x8139, 0xF536, + 0x3444, 0x8139, 0xF537, + 0x3445, 0x8139, 0xF538, + 0x3446, 0x8139, 0xF539, + 0x3448, 0x8139, 0xF630, + 0x3449, 0x8139, 0xF631, + 0x344A, 0x8139, 0xF632, + 0x344B, 0x8139, 0xF633, + 0x344C, 0x8139, 0xF634, + 0x344D, 0x8139, 0xF635, + 0x344E, 0x8139, 0xF636, + 0x344F, 0x8139, 0xF637, + 0x3450, 0x8139, 0xF638, + 0x3451, 0x8139, 0xF639, + 0x3452, 0x8139, 0xF730, + 0x3453, 0x8139, 0xF731, + 0x3454, 0x8139, 0xF732, + 0x3455, 0x8139, 0xF733, + 0x3456, 0x8139, 0xF734, + 0x3457, 0x8139, 0xF735, + 0x3458, 0x8139, 0xF736, + 0x3459, 0x8139, 0xF737, + 0x345A, 0x8139, 0xF738, + 0x345B, 0x8139, 0xF739, + 0x345C, 0x8139, 0xF830, + 0x345D, 0x8139, 0xF831, + 0x345E, 0x8139, 0xF832, + 0x345F, 0x8139, 0xF833, + 0x3460, 0x8139, 0xF834, + 0x3461, 0x8139, 0xF835, + 0x3462, 0x8139, 0xF836, + 0x3463, 0x8139, 0xF837, + 0x3464, 0x8139, 0xF838, + 0x3465, 0x8139, 0xF839, + 0x3466, 0x8139, 0xF930, + 0x3467, 0x8139, 0xF931, + 0x3468, 0x8139, 0xF932, + 0x3469, 0x8139, 0xF933, + 0x346A, 0x8139, 0xF934, + 0x346B, 0x8139, 0xF935, + 0x346C, 0x8139, 0xF936, + 0x346D, 0x8139, 0xF937, + 0x346E, 0x8139, 0xF938, + 0x346F, 0x8139, 0xF939, + 0x3470, 0x8139, 0xFA30, + 0x3471, 0x8139, 0xFA31, + 0x3472, 0x8139, 0xFA32, + 0x3474, 0x8139, 0xFA33, + 0x3475, 0x8139, 0xFA34, + 0x3476, 0x8139, 0xFA35, + 0x3477, 0x8139, 0xFA36, + 0x3478, 0x8139, 0xFA37, + 0x3479, 0x8139, 0xFA38, + 0x347A, 0x8139, 0xFA39, + 0x347B, 0x8139, 0xFB30, + 0x347C, 0x8139, 0xFB31, + 0x347D, 0x8139, 0xFB32, + 0x347E, 0x8139, 0xFB33, + 0x347F, 0x8139, 0xFB34, + 0x3480, 0x8139, 0xFB35, + 0x3481, 0x8139, 0xFB36, + 0x3482, 0x8139, 0xFB37, + 0x3483, 0x8139, 0xFB38, + 0x3484, 0x8139, 0xFB39, + 0x3485, 0x8139, 0xFC30, + 0x3486, 0x8139, 0xFC31, + 0x3487, 0x8139, 0xFC32, + 0x3488, 0x8139, 0xFC33, + 0x3489, 0x8139, 0xFC34, + 0x348A, 0x8139, 0xFC35, + 0x348B, 0x8139, 0xFC36, + 0x348C, 0x8139, 0xFC37, + 0x348D, 0x8139, 0xFC38, + 0x348E, 0x8139, 0xFC39, + 0x348F, 0x8139, 0xFD30, + 0x3490, 0x8139, 0xFD31, + 0x3491, 0x8139, 0xFD32, + 0x3492, 0x8139, 0xFD33, + 0x3493, 0x8139, 0xFD34, + 0x3494, 0x8139, 0xFD35, + 0x3495, 0x8139, 0xFD36, + 0x3496, 0x8139, 0xFD37, + 0x3497, 0x8139, 0xFD38, + 0x3498, 0x8139, 0xFD39, + 0x3499, 0x8139, 0xFE30, + 0x349A, 0x8139, 0xFE31, + 0x349B, 0x8139, 0xFE32, + 0x349C, 0x8139, 0xFE33, + 0x349D, 0x8139, 0xFE34, + 0x349E, 0x8139, 0xFE35, + 0x349F, 0x8139, 0xFE36, + 0x34A0, 0x8139, 0xFE37, + 0x34A1, 0x8139, 0xFE38, + 0x34A2, 0x8139, 0xFE39, + 0x34A3, 0x8230, 0x8130, + 0x34A4, 0x8230, 0x8131, + 0x34A5, 0x8230, 0x8132, + 0x34A6, 0x8230, 0x8133, + 0x34A7, 0x8230, 0x8134, + 0x34A8, 0x8230, 0x8135, + 0x34A9, 0x8230, 0x8136, + 0x34AA, 0x8230, 0x8137, + 0x34AB, 0x8230, 0x8138, + 0x34AC, 0x8230, 0x8139, + 0x34AD, 0x8230, 0x8230, + 0x34AE, 0x8230, 0x8231, + 0x34AF, 0x8230, 0x8232, + 0x34B0, 0x8230, 0x8233, + 0x34B1, 0x8230, 0x8234, + 0x34B2, 0x8230, 0x8235, + 0x34B3, 0x8230, 0x8236, + 0x34B4, 0x8230, 0x8237, + 0x34B5, 0x8230, 0x8238, + 0x34B6, 0x8230, 0x8239, + 0x34B7, 0x8230, 0x8330, + 0x34B8, 0x8230, 0x8331, + 0x34B9, 0x8230, 0x8332, + 0x34BA, 0x8230, 0x8333, + 0x34BB, 0x8230, 0x8334, + 0x34BC, 0x8230, 0x8335, + 0x34BD, 0x8230, 0x8336, + 0x34BE, 0x8230, 0x8337, + 0x34BF, 0x8230, 0x8338, + 0x34C0, 0x8230, 0x8339, + 0x34C1, 0x8230, 0x8430, + 0x34C2, 0x8230, 0x8431, + 0x34C3, 0x8230, 0x8432, + 0x34C4, 0x8230, 0x8433, + 0x34C5, 0x8230, 0x8434, + 0x34C6, 0x8230, 0x8435, + 0x34C7, 0x8230, 0x8436, + 0x34C8, 0x8230, 0x8437, + 0x34C9, 0x8230, 0x8438, + 0x34CA, 0x8230, 0x8439, + 0x34CB, 0x8230, 0x8530, + 0x34CC, 0x8230, 0x8531, + 0x34CD, 0x8230, 0x8532, + 0x34CE, 0x8230, 0x8533, + 0x34CF, 0x8230, 0x8534, + 0x34D0, 0x8230, 0x8535, + 0x34D1, 0x8230, 0x8536, + 0x34D2, 0x8230, 0x8537, + 0x34D3, 0x8230, 0x8538, + 0x34D4, 0x8230, 0x8539, + 0x34D5, 0x8230, 0x8630, + 0x34D6, 0x8230, 0x8631, + 0x34D7, 0x8230, 0x8632, + 0x34D8, 0x8230, 0x8633, + 0x34D9, 0x8230, 0x8634, + 0x34DA, 0x8230, 0x8635, + 0x34DB, 0x8230, 0x8636, + 0x34DC, 0x8230, 0x8637, + 0x34DD, 0x8230, 0x8638, + 0x34DE, 0x8230, 0x8639, + 0x34DF, 0x8230, 0x8730, + 0x34E0, 0x8230, 0x8731, + 0x34E1, 0x8230, 0x8732, + 0x34E2, 0x8230, 0x8733, + 0x34E3, 0x8230, 0x8734, + 0x34E4, 0x8230, 0x8735, + 0x34E5, 0x8230, 0x8736, + 0x34E6, 0x8230, 0x8737, + 0x34E7, 0x8230, 0x8738, + 0x34E8, 0x8230, 0x8739, + 0x34E9, 0x8230, 0x8830, + 0x34EA, 0x8230, 0x8831, + 0x34EB, 0x8230, 0x8832, + 0x34EC, 0x8230, 0x8833, + 0x34ED, 0x8230, 0x8834, + 0x34EE, 0x8230, 0x8835, + 0x34EF, 0x8230, 0x8836, + 0x34F0, 0x8230, 0x8837, + 0x34F1, 0x8230, 0x8838, + 0x34F2, 0x8230, 0x8839, + 0x34F3, 0x8230, 0x8930, + 0x34F4, 0x8230, 0x8931, + 0x34F5, 0x8230, 0x8932, + 0x34F6, 0x8230, 0x8933, + 0x34F7, 0x8230, 0x8934, + 0x34F8, 0x8230, 0x8935, + 0x34F9, 0x8230, 0x8936, + 0x34FA, 0x8230, 0x8937, + 0x34FB, 0x8230, 0x8938, + 0x34FC, 0x8230, 0x8939, + 0x34FD, 0x8230, 0x8A30, + 0x34FE, 0x8230, 0x8A31, + 0x34FF, 0x8230, 0x8A32, + 0x3500, 0x8230, 0x8A33, + 0x3501, 0x8230, 0x8A34, + 0x3502, 0x8230, 0x8A35, + 0x3503, 0x8230, 0x8A36, + 0x3504, 0x8230, 0x8A37, + 0x3505, 0x8230, 0x8A38, + 0x3506, 0x8230, 0x8A39, + 0x3507, 0x8230, 0x8B30, + 0x3508, 0x8230, 0x8B31, + 0x3509, 0x8230, 0x8B32, + 0x350A, 0x8230, 0x8B33, + 0x350B, 0x8230, 0x8B34, + 0x350C, 0x8230, 0x8B35, + 0x350D, 0x8230, 0x8B36, + 0x350E, 0x8230, 0x8B37, + 0x350F, 0x8230, 0x8B38, + 0x3510, 0x8230, 0x8B39, + 0x3511, 0x8230, 0x8C30, + 0x3512, 0x8230, 0x8C31, + 0x3513, 0x8230, 0x8C32, + 0x3514, 0x8230, 0x8C33, + 0x3515, 0x8230, 0x8C34, + 0x3516, 0x8230, 0x8C35, + 0x3517, 0x8230, 0x8C36, + 0x3518, 0x8230, 0x8C37, + 0x3519, 0x8230, 0x8C38, + 0x351A, 0x8230, 0x8C39, + 0x351B, 0x8230, 0x8D30, + 0x351C, 0x8230, 0x8D31, + 0x351D, 0x8230, 0x8D32, + 0x351E, 0x8230, 0x8D33, + 0x351F, 0x8230, 0x8D34, + 0x3520, 0x8230, 0x8D35, + 0x3521, 0x8230, 0x8D36, + 0x3522, 0x8230, 0x8D37, + 0x3523, 0x8230, 0x8D38, + 0x3524, 0x8230, 0x8D39, + 0x3525, 0x8230, 0x8E30, + 0x3526, 0x8230, 0x8E31, + 0x3527, 0x8230, 0x8E32, + 0x3528, 0x8230, 0x8E33, + 0x3529, 0x8230, 0x8E34, + 0x352A, 0x8230, 0x8E35, + 0x352B, 0x8230, 0x8E36, + 0x352C, 0x8230, 0x8E37, + 0x352D, 0x8230, 0x8E38, + 0x352E, 0x8230, 0x8E39, + 0x352F, 0x8230, 0x8F30, + 0x3530, 0x8230, 0x8F31, + 0x3531, 0x8230, 0x8F32, + 0x3532, 0x8230, 0x8F33, + 0x3533, 0x8230, 0x8F34, + 0x3534, 0x8230, 0x8F35, + 0x3535, 0x8230, 0x8F36, + 0x3536, 0x8230, 0x8F37, + 0x3537, 0x8230, 0x8F38, + 0x3538, 0x8230, 0x8F39, + 0x3539, 0x8230, 0x9030, + 0x353A, 0x8230, 0x9031, + 0x353B, 0x8230, 0x9032, + 0x353C, 0x8230, 0x9033, + 0x353D, 0x8230, 0x9034, + 0x353E, 0x8230, 0x9035, + 0x353F, 0x8230, 0x9036, + 0x3540, 0x8230, 0x9037, + 0x3541, 0x8230, 0x9038, + 0x3542, 0x8230, 0x9039, + 0x3543, 0x8230, 0x9130, + 0x3544, 0x8230, 0x9131, + 0x3545, 0x8230, 0x9132, + 0x3546, 0x8230, 0x9133, + 0x3547, 0x8230, 0x9134, + 0x3548, 0x8230, 0x9135, + 0x3549, 0x8230, 0x9136, + 0x354A, 0x8230, 0x9137, + 0x354B, 0x8230, 0x9138, + 0x354C, 0x8230, 0x9139, + 0x354D, 0x8230, 0x9230, + 0x354E, 0x8230, 0x9231, + 0x354F, 0x8230, 0x9232, + 0x3550, 0x8230, 0x9233, + 0x3551, 0x8230, 0x9234, + 0x3552, 0x8230, 0x9235, + 0x3553, 0x8230, 0x9236, + 0x3554, 0x8230, 0x9237, + 0x3555, 0x8230, 0x9238, + 0x3556, 0x8230, 0x9239, + 0x3557, 0x8230, 0x9330, + 0x3558, 0x8230, 0x9331, + 0x3559, 0x8230, 0x9332, + 0x355A, 0x8230, 0x9333, + 0x355B, 0x8230, 0x9334, + 0x355C, 0x8230, 0x9335, + 0x355D, 0x8230, 0x9336, + 0x355E, 0x8230, 0x9337, + 0x355F, 0x8230, 0x9338, + 0x3560, 0x8230, 0x9339, + 0x3561, 0x8230, 0x9430, + 0x3562, 0x8230, 0x9431, + 0x3563, 0x8230, 0x9432, + 0x3564, 0x8230, 0x9433, + 0x3565, 0x8230, 0x9434, + 0x3566, 0x8230, 0x9435, + 0x3567, 0x8230, 0x9436, + 0x3568, 0x8230, 0x9437, + 0x3569, 0x8230, 0x9438, + 0x356A, 0x8230, 0x9439, + 0x356B, 0x8230, 0x9530, + 0x356C, 0x8230, 0x9531, + 0x356D, 0x8230, 0x9532, + 0x356E, 0x8230, 0x9533, + 0x356F, 0x8230, 0x9534, + 0x3570, 0x8230, 0x9535, + 0x3571, 0x8230, 0x9536, + 0x3572, 0x8230, 0x9537, + 0x3573, 0x8230, 0x9538, + 0x3574, 0x8230, 0x9539, + 0x3575, 0x8230, 0x9630, + 0x3576, 0x8230, 0x9631, + 0x3577, 0x8230, 0x9632, + 0x3578, 0x8230, 0x9633, + 0x3579, 0x8230, 0x9634, + 0x357A, 0x8230, 0x9635, + 0x357B, 0x8230, 0x9636, + 0x357C, 0x8230, 0x9637, + 0x357D, 0x8230, 0x9638, + 0x357E, 0x8230, 0x9639, + 0x357F, 0x8230, 0x9730, + 0x3580, 0x8230, 0x9731, + 0x3581, 0x8230, 0x9732, + 0x3582, 0x8230, 0x9733, + 0x3583, 0x8230, 0x9734, + 0x3584, 0x8230, 0x9735, + 0x3585, 0x8230, 0x9736, + 0x3586, 0x8230, 0x9737, + 0x3587, 0x8230, 0x9738, + 0x3588, 0x8230, 0x9739, + 0x3589, 0x8230, 0x9830, + 0x358A, 0x8230, 0x9831, + 0x358B, 0x8230, 0x9832, + 0x358C, 0x8230, 0x9833, + 0x358D, 0x8230, 0x9834, + 0x358E, 0x8230, 0x9835, + 0x358F, 0x8230, 0x9836, + 0x3590, 0x8230, 0x9837, + 0x3591, 0x8230, 0x9838, + 0x3592, 0x8230, 0x9839, + 0x3593, 0x8230, 0x9930, + 0x3594, 0x8230, 0x9931, + 0x3595, 0x8230, 0x9932, + 0x3596, 0x8230, 0x9933, + 0x3597, 0x8230, 0x9934, + 0x3598, 0x8230, 0x9935, + 0x3599, 0x8230, 0x9936, + 0x359A, 0x8230, 0x9937, + 0x359B, 0x8230, 0x9938, + 0x359C, 0x8230, 0x9939, + 0x359D, 0x8230, 0x9A30, + 0x359F, 0x8230, 0x9A31, + 0x35A0, 0x8230, 0x9A32, + 0x35A1, 0x8230, 0x9A33, + 0x35A2, 0x8230, 0x9A34, + 0x35A3, 0x8230, 0x9A35, + 0x35A4, 0x8230, 0x9A36, + 0x35A5, 0x8230, 0x9A37, + 0x35A6, 0x8230, 0x9A38, + 0x35A7, 0x8230, 0x9A39, + 0x35A8, 0x8230, 0x9B30, + 0x35A9, 0x8230, 0x9B31, + 0x35AA, 0x8230, 0x9B32, + 0x35AB, 0x8230, 0x9B33, + 0x35AC, 0x8230, 0x9B34, + 0x35AD, 0x8230, 0x9B35, + 0x35AE, 0x8230, 0x9B36, + 0x35AF, 0x8230, 0x9B37, + 0x35B0, 0x8230, 0x9B38, + 0x35B1, 0x8230, 0x9B39, + 0x35B2, 0x8230, 0x9C30, + 0x35B3, 0x8230, 0x9C31, + 0x35B4, 0x8230, 0x9C32, + 0x35B5, 0x8230, 0x9C33, + 0x35B6, 0x8230, 0x9C34, + 0x35B7, 0x8230, 0x9C35, + 0x35B8, 0x8230, 0x9C36, + 0x35B9, 0x8230, 0x9C37, + 0x35BA, 0x8230, 0x9C38, + 0x35BB, 0x8230, 0x9C39, + 0x35BC, 0x8230, 0x9D30, + 0x35BD, 0x8230, 0x9D31, + 0x35BE, 0x8230, 0x9D32, + 0x35BF, 0x8230, 0x9D33, + 0x35C0, 0x8230, 0x9D34, + 0x35C1, 0x8230, 0x9D35, + 0x35C2, 0x8230, 0x9D36, + 0x35C3, 0x8230, 0x9D37, + 0x35C4, 0x8230, 0x9D38, + 0x35C5, 0x8230, 0x9D39, + 0x35C6, 0x8230, 0x9E30, + 0x35C7, 0x8230, 0x9E31, + 0x35C8, 0x8230, 0x9E32, + 0x35C9, 0x8230, 0x9E33, + 0x35CA, 0x8230, 0x9E34, + 0x35CB, 0x8230, 0x9E35, + 0x35CC, 0x8230, 0x9E36, + 0x35CD, 0x8230, 0x9E37, + 0x35CE, 0x8230, 0x9E38, + 0x35CF, 0x8230, 0x9E39, + 0x35D0, 0x8230, 0x9F30, + 0x35D1, 0x8230, 0x9F31, + 0x35D2, 0x8230, 0x9F32, + 0x35D3, 0x8230, 0x9F33, + 0x35D4, 0x8230, 0x9F34, + 0x35D5, 0x8230, 0x9F35, + 0x35D6, 0x8230, 0x9F36, + 0x35D7, 0x8230, 0x9F37, + 0x35D8, 0x8230, 0x9F38, + 0x35D9, 0x8230, 0x9F39, + 0x35DA, 0x8230, 0xA030, + 0x35DB, 0x8230, 0xA031, + 0x35DC, 0x8230, 0xA032, + 0x35DD, 0x8230, 0xA033, + 0x35DE, 0x8230, 0xA034, + 0x35DF, 0x8230, 0xA035, + 0x35E0, 0x8230, 0xA036, + 0x35E1, 0x8230, 0xA037, + 0x35E2, 0x8230, 0xA038, + 0x35E3, 0x8230, 0xA039, + 0x35E4, 0x8230, 0xA130, + 0x35E5, 0x8230, 0xA131, + 0x35E6, 0x8230, 0xA132, + 0x35E7, 0x8230, 0xA133, + 0x35E8, 0x8230, 0xA134, + 0x35E9, 0x8230, 0xA135, + 0x35EA, 0x8230, 0xA136, + 0x35EB, 0x8230, 0xA137, + 0x35EC, 0x8230, 0xA138, + 0x35ED, 0x8230, 0xA139, + 0x35EE, 0x8230, 0xA230, + 0x35EF, 0x8230, 0xA231, + 0x35F0, 0x8230, 0xA232, + 0x35F1, 0x8230, 0xA233, + 0x35F2, 0x8230, 0xA234, + 0x35F3, 0x8230, 0xA235, + 0x35F4, 0x8230, 0xA236, + 0x35F5, 0x8230, 0xA237, + 0x35F6, 0x8230, 0xA238, + 0x35F7, 0x8230, 0xA239, + 0x35F8, 0x8230, 0xA330, + 0x35F9, 0x8230, 0xA331, + 0x35FA, 0x8230, 0xA332, + 0x35FB, 0x8230, 0xA333, + 0x35FC, 0x8230, 0xA334, + 0x35FD, 0x8230, 0xA335, + 0x35FE, 0x8230, 0xA336, + 0x35FF, 0x8230, 0xA337, + 0x3600, 0x8230, 0xA338, + 0x3601, 0x8230, 0xA339, + 0x3602, 0x8230, 0xA430, + 0x3603, 0x8230, 0xA431, + 0x3604, 0x8230, 0xA432, + 0x3605, 0x8230, 0xA433, + 0x3606, 0x8230, 0xA434, + 0x3607, 0x8230, 0xA435, + 0x3608, 0x8230, 0xA436, + 0x3609, 0x8230, 0xA437, + 0x360A, 0x8230, 0xA438, + 0x360B, 0x8230, 0xA439, + 0x360C, 0x8230, 0xA530, + 0x360D, 0x8230, 0xA531, + 0x360F, 0x8230, 0xA532, + 0x3610, 0x8230, 0xA533, + 0x3611, 0x8230, 0xA534, + 0x3612, 0x8230, 0xA535, + 0x3613, 0x8230, 0xA536, + 0x3614, 0x8230, 0xA537, + 0x3615, 0x8230, 0xA538, + 0x3616, 0x8230, 0xA539, + 0x3617, 0x8230, 0xA630, + 0x3618, 0x8230, 0xA631, + 0x3619, 0x8230, 0xA632, + 0x3919, 0x8230, 0xF238, + 0x391A, 0x8230, 0xF239, + 0x391B, 0x8230, 0xF330, + 0x391C, 0x8230, 0xF331, + 0x391D, 0x8230, 0xF332, + 0x391E, 0x8230, 0xF333, + 0x391F, 0x8230, 0xF334, + 0x3920, 0x8230, 0xF335, + 0x3921, 0x8230, 0xF336, + 0x3922, 0x8230, 0xF337, + 0x3923, 0x8230, 0xF338, + 0x3924, 0x8230, 0xF339, + 0x3925, 0x8230, 0xF430, + 0x3926, 0x8230, 0xF431, + 0x3927, 0x8230, 0xF432, + 0x3928, 0x8230, 0xF433, + 0x3929, 0x8230, 0xF434, + 0x392A, 0x8230, 0xF435, + 0x392B, 0x8230, 0xF436, + 0x392C, 0x8230, 0xF437, + 0x392D, 0x8230, 0xF438, + 0x392E, 0x8230, 0xF439, + 0x392F, 0x8230, 0xF530, + 0x3930, 0x8230, 0xF531, + 0x3931, 0x8230, 0xF532, + 0x3932, 0x8230, 0xF533, + 0x3933, 0x8230, 0xF534, + 0x3934, 0x8230, 0xF535, + 0x3935, 0x8230, 0xF536, + 0x3936, 0x8230, 0xF537, + 0x3937, 0x8230, 0xF538, + 0x3938, 0x8230, 0xF539, + 0x3939, 0x8230, 0xF630, + 0x393A, 0x8230, 0xF631, + 0x393B, 0x8230, 0xF632, + 0x393C, 0x8230, 0xF633, + 0x393D, 0x8230, 0xF634, + 0x393E, 0x8230, 0xF635, + 0x393F, 0x8230, 0xF636, + 0x3940, 0x8230, 0xF637, + 0x3941, 0x8230, 0xF638, + 0x3942, 0x8230, 0xF639, + 0x3943, 0x8230, 0xF730, + 0x3944, 0x8230, 0xF731, + 0x3945, 0x8230, 0xF732, + 0x3946, 0x8230, 0xF733, + 0x3947, 0x8230, 0xF734, + 0x3948, 0x8230, 0xF735, + 0x3949, 0x8230, 0xF736, + 0x394A, 0x8230, 0xF737, + 0x394B, 0x8230, 0xF738, + 0x394C, 0x8230, 0xF739, + 0x394D, 0x8230, 0xF830, + 0x394E, 0x8230, 0xF831, + 0x394F, 0x8230, 0xF832, + 0x3950, 0x8230, 0xF833, + 0x3951, 0x8230, 0xF834, + 0x3952, 0x8230, 0xF835, + 0x3953, 0x8230, 0xF836, + 0x3954, 0x8230, 0xF837, + 0x3955, 0x8230, 0xF838, + 0x3956, 0x8230, 0xF839, + 0x3957, 0x8230, 0xF930, + 0x3958, 0x8230, 0xF931, + 0x3959, 0x8230, 0xF932, + 0x395A, 0x8230, 0xF933, + 0x395B, 0x8230, 0xF934, + 0x395C, 0x8230, 0xF935, + 0x395D, 0x8230, 0xF936, + 0x395E, 0x8230, 0xF937, + 0x395F, 0x8230, 0xF938, + 0x3960, 0x8230, 0xF939, + 0x3961, 0x8230, 0xFA30, + 0x3962, 0x8230, 0xFA31, + 0x3963, 0x8230, 0xFA32, + 0x3964, 0x8230, 0xFA33, + 0x3965, 0x8230, 0xFA34, + 0x3966, 0x8230, 0xFA35, + 0x3967, 0x8230, 0xFA36, + 0x3968, 0x8230, 0xFA37, + 0x3969, 0x8230, 0xFA38, + 0x396A, 0x8230, 0xFA39, + 0x396B, 0x8230, 0xFB30, + 0x396C, 0x8230, 0xFB31, + 0x396D, 0x8230, 0xFB32, + 0x396F, 0x8230, 0xFB33, + 0x3970, 0x8230, 0xFB34, + 0x3971, 0x8230, 0xFB35, + 0x3972, 0x8230, 0xFB36, + 0x3973, 0x8230, 0xFB37, + 0x3974, 0x8230, 0xFB38, + 0x3975, 0x8230, 0xFB39, + 0x3976, 0x8230, 0xFC30, + 0x3977, 0x8230, 0xFC31, + 0x3978, 0x8230, 0xFC32, + 0x3979, 0x8230, 0xFC33, + 0x397A, 0x8230, 0xFC34, + 0x397B, 0x8230, 0xFC35, + 0x397C, 0x8230, 0xFC36, + 0x397D, 0x8230, 0xFC37, + 0x397E, 0x8230, 0xFC38, + 0x397F, 0x8230, 0xFC39, + 0x3980, 0x8230, 0xFD30, + 0x3981, 0x8230, 0xFD31, + 0x3982, 0x8230, 0xFD32, + 0x3983, 0x8230, 0xFD33, + 0x3984, 0x8230, 0xFD34, + 0x3985, 0x8230, 0xFD35, + 0x3986, 0x8230, 0xFD36, + 0x3987, 0x8230, 0xFD37, + 0x3988, 0x8230, 0xFD38, + 0x3989, 0x8230, 0xFD39, + 0x398A, 0x8230, 0xFE30, + 0x398B, 0x8230, 0xFE31, + 0x398C, 0x8230, 0xFE32, + 0x398D, 0x8230, 0xFE33, + 0x398E, 0x8230, 0xFE34, + 0x398F, 0x8230, 0xFE35, + 0x3990, 0x8230, 0xFE36, + 0x3991, 0x8230, 0xFE37, + 0x3992, 0x8230, 0xFE38, + 0x3993, 0x8230, 0xFE39, + 0x3994, 0x8231, 0x8130, + 0x3995, 0x8231, 0x8131, + 0x3996, 0x8231, 0x8132, + 0x3997, 0x8231, 0x8133, + 0x3998, 0x8231, 0x8134, + 0x3999, 0x8231, 0x8135, + 0x399A, 0x8231, 0x8136, + 0x399B, 0x8231, 0x8137, + 0x399C, 0x8231, 0x8138, + 0x399D, 0x8231, 0x8139, + 0x399E, 0x8231, 0x8230, + 0x399F, 0x8231, 0x8231, + 0x39A0, 0x8231, 0x8232, + 0x39A1, 0x8231, 0x8233, + 0x39A2, 0x8231, 0x8234, + 0x39A3, 0x8231, 0x8235, + 0x39A4, 0x8231, 0x8236, + 0x39A5, 0x8231, 0x8237, + 0x39A6, 0x8231, 0x8238, + 0x39A7, 0x8231, 0x8239, + 0x39A8, 0x8231, 0x8330, + 0x39A9, 0x8231, 0x8331, + 0x39AA, 0x8231, 0x8332, + 0x39AB, 0x8231, 0x8333, + 0x39AC, 0x8231, 0x8334, + 0x39AD, 0x8231, 0x8335, + 0x39AE, 0x8231, 0x8336, + 0x39AF, 0x8231, 0x8337, + 0x39B0, 0x8231, 0x8338, + 0x39B1, 0x8231, 0x8339, + 0x39B2, 0x8231, 0x8430, + 0x39B3, 0x8231, 0x8431, + 0x39B4, 0x8231, 0x8432, + 0x39B5, 0x8231, 0x8433, + 0x39B6, 0x8231, 0x8434, + 0x39B7, 0x8231, 0x8435, + 0x39B8, 0x8231, 0x8436, + 0x39B9, 0x8231, 0x8437, + 0x39BA, 0x8231, 0x8438, + 0x39BB, 0x8231, 0x8439, + 0x39BC, 0x8231, 0x8530, + 0x39BD, 0x8231, 0x8531, + 0x39BE, 0x8231, 0x8532, + 0x39BF, 0x8231, 0x8533, + 0x39C0, 0x8231, 0x8534, + 0x39C1, 0x8231, 0x8535, + 0x39C2, 0x8231, 0x8536, + 0x39C3, 0x8231, 0x8537, + 0x39C4, 0x8231, 0x8538, + 0x39C5, 0x8231, 0x8539, + 0x39C6, 0x8231, 0x8630, + 0x39C7, 0x8231, 0x8631, + 0x39C8, 0x8231, 0x8632, + 0x39C9, 0x8231, 0x8633, + 0x39CA, 0x8231, 0x8634, + 0x39CB, 0x8231, 0x8635, + 0x39CC, 0x8231, 0x8636, + 0x39CD, 0x8231, 0x8637, + 0x39CE, 0x8231, 0x8638, + 0x39D1, 0x8231, 0x8639, + 0x39D2, 0x8231, 0x8730, + 0x39D3, 0x8231, 0x8731, + 0x39D4, 0x8231, 0x8732, + 0x39D5, 0x8231, 0x8733, + 0x39D6, 0x8231, 0x8734, + 0x39D7, 0x8231, 0x8735, + 0x39D8, 0x8231, 0x8736, + 0x39D9, 0x8231, 0x8737, + 0x39DA, 0x8231, 0x8738, + 0x39DB, 0x8231, 0x8739, + 0x39DC, 0x8231, 0x8830, + 0x39DD, 0x8231, 0x8831, + 0x39DE, 0x8231, 0x8832, + 0x39E0, 0x8231, 0x8833, + 0x39E1, 0x8231, 0x8834, + 0x39E2, 0x8231, 0x8835, + 0x39E3, 0x8231, 0x8836, + 0x39E4, 0x8231, 0x8837, + 0x39E5, 0x8231, 0x8838, + 0x39E6, 0x8231, 0x8839, + 0x39E7, 0x8231, 0x8930, + 0x39E8, 0x8231, 0x8931, + 0x39E9, 0x8231, 0x8932, + 0x39EA, 0x8231, 0x8933, + 0x39EB, 0x8231, 0x8934, + 0x39EC, 0x8231, 0x8935, + 0x39ED, 0x8231, 0x8936, + 0x39EE, 0x8231, 0x8937, + 0x39EF, 0x8231, 0x8938, + 0x39F0, 0x8231, 0x8939, + 0x39F1, 0x8231, 0x8A30, + 0x39F2, 0x8231, 0x8A31, + 0x39F3, 0x8231, 0x8A32, + 0x39F4, 0x8231, 0x8A33, + 0x39F5, 0x8231, 0x8A34, + 0x39F6, 0x8231, 0x8A35, + 0x39F7, 0x8231, 0x8A36, + 0x39F8, 0x8231, 0x8A37, + 0x39F9, 0x8231, 0x8A38, + 0x39FA, 0x8231, 0x8A39, + 0x39FB, 0x8231, 0x8B30, + 0x39FC, 0x8231, 0x8B31, + 0x39FD, 0x8231, 0x8B32, + 0x39FE, 0x8231, 0x8B33, + 0x39FF, 0x8231, 0x8B34, + 0x3A00, 0x8231, 0x8B35, + 0x3A01, 0x8231, 0x8B36, + 0x3A02, 0x8231, 0x8B37, + 0x3A03, 0x8231, 0x8B38, + 0x3A04, 0x8231, 0x8B39, + 0x3A05, 0x8231, 0x8C30, + 0x3A06, 0x8231, 0x8C31, + 0x3A07, 0x8231, 0x8C32, + 0x3A08, 0x8231, 0x8C33, + 0x3A09, 0x8231, 0x8C34, + 0x3A0A, 0x8231, 0x8C35, + 0x3A0B, 0x8231, 0x8C36, + 0x3A0C, 0x8231, 0x8C37, + 0x3A0D, 0x8231, 0x8C38, + 0x3A0E, 0x8231, 0x8C39, + 0x3A0F, 0x8231, 0x8D30, + 0x3A10, 0x8231, 0x8D31, + 0x3A11, 0x8231, 0x8D32, + 0x3A12, 0x8231, 0x8D33, + 0x3A13, 0x8231, 0x8D34, + 0x3A14, 0x8231, 0x8D35, + 0x3A15, 0x8231, 0x8D36, + 0x3A16, 0x8231, 0x8D37, + 0x3A17, 0x8231, 0x8D38, + 0x3A18, 0x8231, 0x8D39, + 0x3A19, 0x8231, 0x8E30, + 0x3A1A, 0x8231, 0x8E31, + 0x3A1B, 0x8231, 0x8E32, + 0x3A1C, 0x8231, 0x8E33, + 0x3A1D, 0x8231, 0x8E34, + 0x3A1E, 0x8231, 0x8E35, + 0x3A1F, 0x8231, 0x8E36, + 0x3A20, 0x8231, 0x8E37, + 0x3A21, 0x8231, 0x8E38, + 0x3A22, 0x8231, 0x8E39, + 0x3A23, 0x8231, 0x8F30, + 0x3A24, 0x8231, 0x8F31, + 0x3A25, 0x8231, 0x8F32, + 0x3A26, 0x8231, 0x8F33, + 0x3A27, 0x8231, 0x8F34, + 0x3A28, 0x8231, 0x8F35, + 0x3A29, 0x8231, 0x8F36, + 0x3A2A, 0x8231, 0x8F37, + 0x3A2B, 0x8231, 0x8F38, + 0x3A2C, 0x8231, 0x8F39, + 0x3A2D, 0x8231, 0x9030, + 0x3A2E, 0x8231, 0x9031, + 0x3A2F, 0x8231, 0x9032, + 0x3A30, 0x8231, 0x9033, + 0x3A31, 0x8231, 0x9034, + 0x3A32, 0x8231, 0x9035, + 0x3A33, 0x8231, 0x9036, + 0x3A34, 0x8231, 0x9037, + 0x3A35, 0x8231, 0x9038, + 0x3A36, 0x8231, 0x9039, + 0x3A37, 0x8231, 0x9130, + 0x3A38, 0x8231, 0x9131, + 0x3A39, 0x8231, 0x9132, + 0x3A3A, 0x8231, 0x9133, + 0x3A3B, 0x8231, 0x9134, + 0x3A3C, 0x8231, 0x9135, + 0x3A3D, 0x8231, 0x9136, + 0x3A3E, 0x8231, 0x9137, + 0x3A3F, 0x8231, 0x9138, + 0x3A40, 0x8231, 0x9139, + 0x3A41, 0x8231, 0x9230, + 0x3A42, 0x8231, 0x9231, + 0x3A43, 0x8231, 0x9232, + 0x3A44, 0x8231, 0x9233, + 0x3A45, 0x8231, 0x9234, + 0x3A46, 0x8231, 0x9235, + 0x3A47, 0x8231, 0x9236, + 0x3A48, 0x8231, 0x9237, + 0x3A49, 0x8231, 0x9238, + 0x3A4A, 0x8231, 0x9239, + 0x3A4B, 0x8231, 0x9330, + 0x3A4C, 0x8231, 0x9331, + 0x3A4D, 0x8231, 0x9332, + 0x3A4E, 0x8231, 0x9333, + 0x3A4F, 0x8231, 0x9334, + 0x3A50, 0x8231, 0x9335, + 0x3A51, 0x8231, 0x9336, + 0x3A52, 0x8231, 0x9337, + 0x3A53, 0x8231, 0x9338, + 0x3A54, 0x8231, 0x9339, + 0x3A55, 0x8231, 0x9430, + 0x3A56, 0x8231, 0x9431, + 0x3A57, 0x8231, 0x9432, + 0x3A58, 0x8231, 0x9433, + 0x3A59, 0x8231, 0x9434, + 0x3A5A, 0x8231, 0x9435, + 0x3A5B, 0x8231, 0x9436, + 0x3A5C, 0x8231, 0x9437, + 0x3A5D, 0x8231, 0x9438, + 0x3A5E, 0x8231, 0x9439, + 0x3A5F, 0x8231, 0x9530, + 0x3A60, 0x8231, 0x9531, + 0x3A61, 0x8231, 0x9532, + 0x3A62, 0x8231, 0x9533, + 0x3A63, 0x8231, 0x9534, + 0x3A64, 0x8231, 0x9535, + 0x3A65, 0x8231, 0x9536, + 0x3A66, 0x8231, 0x9537, + 0x3A67, 0x8231, 0x9538, + 0x3A68, 0x8231, 0x9539, + 0x3A69, 0x8231, 0x9630, + 0x3A6A, 0x8231, 0x9631, + 0x3A6B, 0x8231, 0x9632, + 0x3A6C, 0x8231, 0x9633, + 0x3A6D, 0x8231, 0x9634, + 0x3A6E, 0x8231, 0x9635, + 0x3A6F, 0x8231, 0x9636, + 0x3A70, 0x8231, 0x9637, + 0x3A71, 0x8231, 0x9638, + 0x3A72, 0x8231, 0x9639, + 0x3A74, 0x8231, 0x9730, + 0x3A75, 0x8231, 0x9731, + 0x3A76, 0x8231, 0x9732, + 0x3A77, 0x8231, 0x9733, + 0x3A78, 0x8231, 0x9734, + 0x3A79, 0x8231, 0x9735, + 0x3A7A, 0x8231, 0x9736, + 0x3A7B, 0x8231, 0x9737, + 0x3A7C, 0x8231, 0x9738, + 0x3A7D, 0x8231, 0x9739, + 0x3A7E, 0x8231, 0x9830, + 0x3A7F, 0x8231, 0x9831, + 0x3A80, 0x8231, 0x9832, + 0x3A81, 0x8231, 0x9833, + 0x3A82, 0x8231, 0x9834, + 0x3A83, 0x8231, 0x9835, + 0x3A84, 0x8231, 0x9836, + 0x3A85, 0x8231, 0x9837, + 0x3A86, 0x8231, 0x9838, + 0x3A87, 0x8231, 0x9839, + 0x3A88, 0x8231, 0x9930, + 0x3A89, 0x8231, 0x9931, + 0x3A8A, 0x8231, 0x9932, + 0x3A8B, 0x8231, 0x9933, + 0x3A8C, 0x8231, 0x9934, + 0x3A8D, 0x8231, 0x9935, + 0x3A8E, 0x8231, 0x9936, + 0x3A8F, 0x8231, 0x9937, + 0x3A90, 0x8231, 0x9938, + 0x3A91, 0x8231, 0x9939, + 0x3A92, 0x8231, 0x9A30, + 0x3A93, 0x8231, 0x9A31, + 0x3A94, 0x8231, 0x9A32, + 0x3A95, 0x8231, 0x9A33, + 0x3A96, 0x8231, 0x9A34, + 0x3A97, 0x8231, 0x9A35, + 0x3A98, 0x8231, 0x9A36, + 0x3A99, 0x8231, 0x9A37, + 0x3A9A, 0x8231, 0x9A38, + 0x3A9B, 0x8231, 0x9A39, + 0x3A9C, 0x8231, 0x9B30, + 0x3A9D, 0x8231, 0x9B31, + 0x3A9E, 0x8231, 0x9B32, + 0x3A9F, 0x8231, 0x9B33, + 0x3AA0, 0x8231, 0x9B34, + 0x3AA1, 0x8231, 0x9B35, + 0x3AA2, 0x8231, 0x9B36, + 0x3AA3, 0x8231, 0x9B37, + 0x3AA4, 0x8231, 0x9B38, + 0x3AA5, 0x8231, 0x9B39, + 0x3AA6, 0x8231, 0x9C30, + 0x3AA7, 0x8231, 0x9C31, + 0x3AA8, 0x8231, 0x9C32, + 0x3AA9, 0x8231, 0x9C33, + 0x3AAA, 0x8231, 0x9C34, + 0x3AAB, 0x8231, 0x9C35, + 0x3AAC, 0x8231, 0x9C36, + 0x3AAD, 0x8231, 0x9C37, + 0x3AAE, 0x8231, 0x9C38, + 0x3AAF, 0x8231, 0x9C39, + 0x3AB0, 0x8231, 0x9D30, + 0x3AB1, 0x8231, 0x9D31, + 0x3AB2, 0x8231, 0x9D32, + 0x3AB3, 0x8231, 0x9D33, + 0x3AB4, 0x8231, 0x9D34, + 0x3AB5, 0x8231, 0x9D35, + 0x3AB6, 0x8231, 0x9D36, + 0x3AB7, 0x8231, 0x9D37, + 0x3AB8, 0x8231, 0x9D38, + 0x3AB9, 0x8231, 0x9D39, + 0x3ABA, 0x8231, 0x9E30, + 0x3ABB, 0x8231, 0x9E31, + 0x3ABC, 0x8231, 0x9E32, + 0x3ABD, 0x8231, 0x9E33, + 0x3ABE, 0x8231, 0x9E34, + 0x3ABF, 0x8231, 0x9E35, + 0x3AC0, 0x8231, 0x9E36, + 0x3AC1, 0x8231, 0x9E37, + 0x3AC2, 0x8231, 0x9E38, + 0x3AC3, 0x8231, 0x9E39, + 0x3AC4, 0x8231, 0x9F30, + 0x3AC5, 0x8231, 0x9F31, + 0x3AC6, 0x8231, 0x9F32, + 0x3AC7, 0x8231, 0x9F33, + 0x3AC8, 0x8231, 0x9F34, + 0x3AC9, 0x8231, 0x9F35, + 0x3ACA, 0x8231, 0x9F36, + 0x3ACB, 0x8231, 0x9F37, + 0x3ACC, 0x8231, 0x9F38, + 0x3ACD, 0x8231, 0x9F39, + 0x3ACE, 0x8231, 0xA030, + 0x3ACF, 0x8231, 0xA031, + 0x3AD0, 0x8231, 0xA032, + 0x3AD1, 0x8231, 0xA033, + 0x3AD2, 0x8231, 0xA034, + 0x3AD3, 0x8231, 0xA035, + 0x3AD4, 0x8231, 0xA036, + 0x3AD5, 0x8231, 0xA037, + 0x3AD6, 0x8231, 0xA038, + 0x3AD7, 0x8231, 0xA039, + 0x3AD8, 0x8231, 0xA130, + 0x3AD9, 0x8231, 0xA131, + 0x3ADA, 0x8231, 0xA132, + 0x3ADB, 0x8231, 0xA133, + 0x3ADC, 0x8231, 0xA134, + 0x3ADD, 0x8231, 0xA135, + 0x3ADE, 0x8231, 0xA136, + 0x3ADF, 0x8231, 0xA137, + 0x3AE0, 0x8231, 0xA138, + 0x3AE1, 0x8231, 0xA139, + 0x3AE2, 0x8231, 0xA230, + 0x3AE3, 0x8231, 0xA231, + 0x3AE4, 0x8231, 0xA232, + 0x3AE5, 0x8231, 0xA233, + 0x3AE6, 0x8231, 0xA234, + 0x3AE7, 0x8231, 0xA235, + 0x3AE8, 0x8231, 0xA236, + 0x3AE9, 0x8231, 0xA237, + 0x3AEA, 0x8231, 0xA238, + 0x3AEB, 0x8231, 0xA239, + 0x3AEC, 0x8231, 0xA330, + 0x3AED, 0x8231, 0xA331, + 0x3AEE, 0x8231, 0xA332, + 0x3AEF, 0x8231, 0xA333, + 0x3AF0, 0x8231, 0xA334, + 0x3AF1, 0x8231, 0xA335, + 0x3AF2, 0x8231, 0xA336, + 0x3AF3, 0x8231, 0xA337, + 0x3AF4, 0x8231, 0xA338, + 0x3AF5, 0x8231, 0xA339, + 0x3AF6, 0x8231, 0xA430, + 0x3AF7, 0x8231, 0xA431, + 0x3AF8, 0x8231, 0xA432, + 0x3AF9, 0x8231, 0xA433, + 0x3AFA, 0x8231, 0xA434, + 0x3AFB, 0x8231, 0xA435, + 0x3AFC, 0x8231, 0xA436, + 0x3AFD, 0x8231, 0xA437, + 0x3AFE, 0x8231, 0xA438, + 0x3AFF, 0x8231, 0xA439, + 0x3B00, 0x8231, 0xA530, + 0x3B01, 0x8231, 0xA531, + 0x3B02, 0x8231, 0xA532, + 0x3B03, 0x8231, 0xA533, + 0x3B04, 0x8231, 0xA534, + 0x3B05, 0x8231, 0xA535, + 0x3B06, 0x8231, 0xA536, + 0x3B07, 0x8231, 0xA537, + 0x3B08, 0x8231, 0xA538, + 0x3B09, 0x8231, 0xA539, + 0x3B0A, 0x8231, 0xA630, + 0x3B0B, 0x8231, 0xA631, + 0x3B0C, 0x8231, 0xA632, + 0x3B0D, 0x8231, 0xA633, + 0x3B0E, 0x8231, 0xA634, + 0x3B0F, 0x8231, 0xA635, + 0x3B10, 0x8231, 0xA636, + 0x3B11, 0x8231, 0xA637, + 0x3B12, 0x8231, 0xA638, + 0x3B13, 0x8231, 0xA639, + 0x3B14, 0x8231, 0xA730, + 0x3B15, 0x8231, 0xA731, + 0x3B16, 0x8231, 0xA732, + 0x3B17, 0x8231, 0xA733, + 0x3B18, 0x8231, 0xA734, + 0x3B19, 0x8231, 0xA735, + 0x3B1A, 0x8231, 0xA736, + 0x3B1B, 0x8231, 0xA737, + 0x3B1C, 0x8231, 0xA738, + 0x3B1D, 0x8231, 0xA739, + 0x3B1E, 0x8231, 0xA830, + 0x3B1F, 0x8231, 0xA831, + 0x3B20, 0x8231, 0xA832, + 0x3B21, 0x8231, 0xA833, + 0x3B22, 0x8231, 0xA834, + 0x3B23, 0x8231, 0xA835, + 0x3B24, 0x8231, 0xA836, + 0x3B25, 0x8231, 0xA837, + 0x3B26, 0x8231, 0xA838, + 0x3B27, 0x8231, 0xA839, + 0x3B28, 0x8231, 0xA930, + 0x3B29, 0x8231, 0xA931, + 0x3B2A, 0x8231, 0xA932, + 0x3B2B, 0x8231, 0xA933, + 0x3B2C, 0x8231, 0xA934, + 0x3B2D, 0x8231, 0xA935, + 0x3B2E, 0x8231, 0xA936, + 0x3B2F, 0x8231, 0xA937, + 0x3B30, 0x8231, 0xA938, + 0x3B31, 0x8231, 0xA939, + 0x3B32, 0x8231, 0xAA30, + 0x3B33, 0x8231, 0xAA31, + 0x3B34, 0x8231, 0xAA32, + 0x3B35, 0x8231, 0xAA33, + 0x3B36, 0x8231, 0xAA34, + 0x3B37, 0x8231, 0xAA35, + 0x3B38, 0x8231, 0xAA36, + 0x3B39, 0x8231, 0xAA37, + 0x3B3A, 0x8231, 0xAA38, + 0x3B3B, 0x8231, 0xAA39, + 0x3B3C, 0x8231, 0xAB30, + 0x3B3D, 0x8231, 0xAB31, + 0x3B3E, 0x8231, 0xAB32, + 0x3B3F, 0x8231, 0xAB33, + 0x3B40, 0x8231, 0xAB34, + 0x3B41, 0x8231, 0xAB35, + 0x3B42, 0x8231, 0xAB36, + 0x3B43, 0x8231, 0xAB37, + 0x3B44, 0x8231, 0xAB38, + 0x3B45, 0x8231, 0xAB39, + 0x3B46, 0x8231, 0xAC30, + 0x3B47, 0x8231, 0xAC31, + 0x3B48, 0x8231, 0xAC32, + 0x3B49, 0x8231, 0xAC33, + 0x3B4A, 0x8231, 0xAC34, + 0x3B4B, 0x8231, 0xAC35, + 0x3B4C, 0x8231, 0xAC36, + 0x3B4D, 0x8231, 0xAC37, + 0x3B4F, 0x8231, 0xAC38, + 0x3B50, 0x8231, 0xAC39, + 0x3B51, 0x8231, 0xAD30, + 0x3B52, 0x8231, 0xAD31, + 0x3B53, 0x8231, 0xAD32, + 0x3B54, 0x8231, 0xAD33, + 0x3B55, 0x8231, 0xAD34, + 0x3B56, 0x8231, 0xAD35, + 0x3B57, 0x8231, 0xAD36, + 0x3B58, 0x8231, 0xAD37, + 0x3B59, 0x8231, 0xAD38, + 0x3B5A, 0x8231, 0xAD39, + 0x3B5B, 0x8231, 0xAE30, + 0x3B5C, 0x8231, 0xAE31, + 0x3B5D, 0x8231, 0xAE32, + 0x3B5E, 0x8231, 0xAE33, + 0x3B5F, 0x8231, 0xAE34, + 0x3B60, 0x8231, 0xAE35, + 0x3B61, 0x8231, 0xAE36, + 0x3B62, 0x8231, 0xAE37, + 0x3B63, 0x8231, 0xAE38, + 0x3B64, 0x8231, 0xAE39, + 0x3B65, 0x8231, 0xAF30, + 0x3B66, 0x8231, 0xAF31, + 0x3B67, 0x8231, 0xAF32, + 0x3B68, 0x8231, 0xAF33, + 0x3B69, 0x8231, 0xAF34, + 0x3B6A, 0x8231, 0xAF35, + 0x3B6B, 0x8231, 0xAF36, + 0x3B6C, 0x8231, 0xAF37, + 0x3B6D, 0x8231, 0xAF38, + 0x3B6E, 0x8231, 0xAF39, + 0x3B6F, 0x8231, 0xB030, + 0x3B70, 0x8231, 0xB031, + 0x3B71, 0x8231, 0xB032, + 0x3B72, 0x8231, 0xB033, + 0x3B73, 0x8231, 0xB034, + 0x3B74, 0x8231, 0xB035, + 0x3B75, 0x8231, 0xB036, + 0x3B76, 0x8231, 0xB037, + 0x3B77, 0x8231, 0xB038, + 0x3B78, 0x8231, 0xB039, + 0x3B79, 0x8231, 0xB130, + 0x3B7A, 0x8231, 0xB131, + 0x3B7B, 0x8231, 0xB132, + 0x3B7C, 0x8231, 0xB133, + 0x3B7D, 0x8231, 0xB134, + 0x3B7E, 0x8231, 0xB135, + 0x3B7F, 0x8231, 0xB136, + 0x3B80, 0x8231, 0xB137, + 0x3B81, 0x8231, 0xB138, + 0x3B82, 0x8231, 0xB139, + 0x3B83, 0x8231, 0xB230, + 0x3B84, 0x8231, 0xB231, + 0x3B85, 0x8231, 0xB232, + 0x3B86, 0x8231, 0xB233, + 0x3B87, 0x8231, 0xB234, + 0x3B88, 0x8231, 0xB235, + 0x3B89, 0x8231, 0xB236, + 0x3B8A, 0x8231, 0xB237, + 0x3B8B, 0x8231, 0xB238, + 0x3B8C, 0x8231, 0xB239, + 0x3B8D, 0x8231, 0xB330, + 0x3B8E, 0x8231, 0xB331, + 0x3B8F, 0x8231, 0xB332, + 0x3B90, 0x8231, 0xB333, + 0x3B91, 0x8231, 0xB334, + 0x3B92, 0x8231, 0xB335, + 0x3B93, 0x8231, 0xB336, + 0x3B94, 0x8231, 0xB337, + 0x3B95, 0x8231, 0xB338, + 0x3B96, 0x8231, 0xB339, + 0x3B97, 0x8231, 0xB430, + 0x3B98, 0x8231, 0xB431, + 0x3B99, 0x8231, 0xB432, + 0x3B9A, 0x8231, 0xB433, + 0x3B9B, 0x8231, 0xB434, + 0x3B9C, 0x8231, 0xB435, + 0x3B9D, 0x8231, 0xB436, + 0x3B9E, 0x8231, 0xB437, + 0x3B9F, 0x8231, 0xB438, + 0x3BA0, 0x8231, 0xB439, + 0x3BA1, 0x8231, 0xB530, + 0x3BA2, 0x8231, 0xB531, + 0x3BA3, 0x8231, 0xB532, + 0x3BA4, 0x8231, 0xB533, + 0x3BA5, 0x8231, 0xB534, + 0x3BA6, 0x8231, 0xB535, + 0x3BA7, 0x8231, 0xB536, + 0x3BA8, 0x8231, 0xB537, + 0x3BA9, 0x8231, 0xB538, + 0x3BAA, 0x8231, 0xB539, + 0x3BAB, 0x8231, 0xB630, + 0x3BAC, 0x8231, 0xB631, + 0x3BAD, 0x8231, 0xB632, + 0x3BAE, 0x8231, 0xB633, + 0x3BAF, 0x8231, 0xB634, + 0x3BB0, 0x8231, 0xB635, + 0x3BB1, 0x8231, 0xB636, + 0x3BB2, 0x8231, 0xB637, + 0x3BB3, 0x8231, 0xB638, + 0x3BB4, 0x8231, 0xB639, + 0x3BB5, 0x8231, 0xB730, + 0x3BB6, 0x8231, 0xB731, + 0x3BB7, 0x8231, 0xB732, + 0x3BB8, 0x8231, 0xB733, + 0x3BB9, 0x8231, 0xB734, + 0x3BBA, 0x8231, 0xB735, + 0x3BBB, 0x8231, 0xB736, + 0x3BBC, 0x8231, 0xB737, + 0x3BBD, 0x8231, 0xB738, + 0x3BBE, 0x8231, 0xB739, + 0x3BBF, 0x8231, 0xB830, + 0x3BC0, 0x8231, 0xB831, + 0x3BC1, 0x8231, 0xB832, + 0x3BC2, 0x8231, 0xB833, + 0x3BC3, 0x8231, 0xB834, + 0x3BC4, 0x8231, 0xB835, + 0x3BC5, 0x8231, 0xB836, + 0x3BC6, 0x8231, 0xB837, + 0x3BC7, 0x8231, 0xB838, + 0x3BC8, 0x8231, 0xB839, + 0x3BC9, 0x8231, 0xB930, + 0x3BCA, 0x8231, 0xB931, + 0x3BCB, 0x8231, 0xB932, + 0x3BCC, 0x8231, 0xB933, + 0x3BCD, 0x8231, 0xB934, + 0x3BCE, 0x8231, 0xB935, + 0x3BCF, 0x8231, 0xB936, + 0x3BD0, 0x8231, 0xB937, + 0x3BD1, 0x8231, 0xB938, + 0x3BD2, 0x8231, 0xB939, + 0x3BD3, 0x8231, 0xBA30, + 0x3BD4, 0x8231, 0xBA31, + 0x3BD5, 0x8231, 0xBA32, + 0x3BD6, 0x8231, 0xBA33, + 0x3BD7, 0x8231, 0xBA34, + 0x3BD8, 0x8231, 0xBA35, + 0x3BD9, 0x8231, 0xBA36, + 0x3BDA, 0x8231, 0xBA37, + 0x3BDB, 0x8231, 0xBA38, + 0x3BDC, 0x8231, 0xBA39, + 0x3BDD, 0x8231, 0xBB30, + 0x3BDE, 0x8231, 0xBB31, + 0x3BDF, 0x8231, 0xBB32, + 0x3BE0, 0x8231, 0xBB33, + 0x3BE1, 0x8231, 0xBB34, + 0x3BE2, 0x8231, 0xBB35, + 0x3BE3, 0x8231, 0xBB36, + 0x3BE4, 0x8231, 0xBB37, + 0x3BE5, 0x8231, 0xBB38, + 0x3BE6, 0x8231, 0xBB39, + 0x3BE7, 0x8231, 0xBC30, + 0x3BE8, 0x8231, 0xBC31, + 0x3BE9, 0x8231, 0xBC32, + 0x3BEA, 0x8231, 0xBC33, + 0x3BEB, 0x8231, 0xBC34, + 0x3BEC, 0x8231, 0xBC35, + 0x3BED, 0x8231, 0xBC36, + 0x3BEE, 0x8231, 0xBC37, + 0x3BEF, 0x8231, 0xBC38, + 0x3BF0, 0x8231, 0xBC39, + 0x3BF1, 0x8231, 0xBD30, + 0x3BF2, 0x8231, 0xBD31, + 0x3BF3, 0x8231, 0xBD32, + 0x3BF4, 0x8231, 0xBD33, + 0x3BF5, 0x8231, 0xBD34, + 0x3BF6, 0x8231, 0xBD35, + 0x3BF7, 0x8231, 0xBD36, + 0x3BF8, 0x8231, 0xBD37, + 0x3BF9, 0x8231, 0xBD38, + 0x3BFA, 0x8231, 0xBD39, + 0x3BFB, 0x8231, 0xBE30, + 0x3BFC, 0x8231, 0xBE31, + 0x3BFD, 0x8231, 0xBE32, + 0x3BFE, 0x8231, 0xBE33, + 0x3BFF, 0x8231, 0xBE34, + 0x3C00, 0x8231, 0xBE35, + 0x3C01, 0x8231, 0xBE36, + 0x3C02, 0x8231, 0xBE37, + 0x3C03, 0x8231, 0xBE38, + 0x3C04, 0x8231, 0xBE39, + 0x3C05, 0x8231, 0xBF30, + 0x3C06, 0x8231, 0xBF31, + 0x3C07, 0x8231, 0xBF32, + 0x3C08, 0x8231, 0xBF33, + 0x3C09, 0x8231, 0xBF34, + 0x3C0A, 0x8231, 0xBF35, + 0x3C0B, 0x8231, 0xBF36, + 0x3C0C, 0x8231, 0xBF37, + 0x3C0D, 0x8231, 0xBF38, + 0x3C0E, 0x8231, 0xBF39, + 0x3C0F, 0x8231, 0xC030, + 0x3C10, 0x8231, 0xC031, + 0x3C11, 0x8231, 0xC032, + 0x3C12, 0x8231, 0xC033, + 0x3C13, 0x8231, 0xC034, + 0x3C14, 0x8231, 0xC035, + 0x3C15, 0x8231, 0xC036, + 0x3C16, 0x8231, 0xC037, + 0x3C17, 0x8231, 0xC038, + 0x3C18, 0x8231, 0xC039, + 0x3C19, 0x8231, 0xC130, + 0x3C1A, 0x8231, 0xC131, + 0x3C1B, 0x8231, 0xC132, + 0x3C1C, 0x8231, 0xC133, + 0x3C1D, 0x8231, 0xC134, + 0x3C1E, 0x8231, 0xC135, + 0x3C1F, 0x8231, 0xC136, + 0x3C20, 0x8231, 0xC137, + 0x3C21, 0x8231, 0xC138, + 0x3C22, 0x8231, 0xC139, + 0x3C23, 0x8231, 0xC230, + 0x3C24, 0x8231, 0xC231, + 0x3C25, 0x8231, 0xC232, + 0x3C26, 0x8231, 0xC233, + 0x3C27, 0x8231, 0xC234, + 0x3C28, 0x8231, 0xC235, + 0x3C29, 0x8231, 0xC236, + 0x3C2A, 0x8231, 0xC237, + 0x3C2B, 0x8231, 0xC238, + 0x3C2C, 0x8231, 0xC239, + 0x3C2D, 0x8231, 0xC330, + 0x3C2E, 0x8231, 0xC331, + 0x3C2F, 0x8231, 0xC332, + 0x3C30, 0x8231, 0xC333, + 0x3C31, 0x8231, 0xC334, + 0x3C32, 0x8231, 0xC335, + 0x3C33, 0x8231, 0xC336, + 0x3C34, 0x8231, 0xC337, + 0x3C35, 0x8231, 0xC338, + 0x3C36, 0x8231, 0xC339, + 0x3C37, 0x8231, 0xC430, + 0x3C38, 0x8231, 0xC431, + 0x3C39, 0x8231, 0xC432, + 0x3C3A, 0x8231, 0xC433, + 0x3C3B, 0x8231, 0xC434, + 0x3C3C, 0x8231, 0xC435, + 0x3C3D, 0x8231, 0xC436, + 0x3C3E, 0x8231, 0xC437, + 0x3C3F, 0x8231, 0xC438, + 0x3C40, 0x8231, 0xC439, + 0x3C41, 0x8231, 0xC530, + 0x3C42, 0x8231, 0xC531, + 0x3C43, 0x8231, 0xC532, + 0x3C44, 0x8231, 0xC533, + 0x3C45, 0x8231, 0xC534, + 0x3C46, 0x8231, 0xC535, + 0x3C47, 0x8231, 0xC536, + 0x3C48, 0x8231, 0xC537, + 0x3C49, 0x8231, 0xC538, + 0x3C4A, 0x8231, 0xC539, + 0x3C4B, 0x8231, 0xC630, + 0x3C4C, 0x8231, 0xC631, + 0x3C4D, 0x8231, 0xC632, + 0x3C4E, 0x8231, 0xC633, + 0x3C4F, 0x8231, 0xC634, + 0x3C50, 0x8231, 0xC635, + 0x3C51, 0x8231, 0xC636, + 0x3C52, 0x8231, 0xC637, + 0x3C53, 0x8231, 0xC638, + 0x3C54, 0x8231, 0xC639, + 0x3C55, 0x8231, 0xC730, + 0x3C56, 0x8231, 0xC731, + 0x3C57, 0x8231, 0xC732, + 0x3C58, 0x8231, 0xC733, + 0x3C59, 0x8231, 0xC734, + 0x3C5A, 0x8231, 0xC735, + 0x3C5B, 0x8231, 0xC736, + 0x3C5C, 0x8231, 0xC737, + 0x3C5D, 0x8231, 0xC738, + 0x3C5E, 0x8231, 0xC739, + 0x3C5F, 0x8231, 0xC830, + 0x3C60, 0x8231, 0xC831, + 0x3C61, 0x8231, 0xC832, + 0x3C62, 0x8231, 0xC833, + 0x3C63, 0x8231, 0xC834, + 0x3C64, 0x8231, 0xC835, + 0x3C65, 0x8231, 0xC836, + 0x3C66, 0x8231, 0xC837, + 0x3C67, 0x8231, 0xC838, + 0x3C68, 0x8231, 0xC839, + 0x3C69, 0x8231, 0xC930, + 0x3C6A, 0x8231, 0xC931, + 0x3C6B, 0x8231, 0xC932, + 0x3C6C, 0x8231, 0xC933, + 0x3C6D, 0x8231, 0xC934, + 0x3C6F, 0x8231, 0xC935, + 0x3C70, 0x8231, 0xC936, + 0x3C71, 0x8231, 0xC937, + 0x3C72, 0x8231, 0xC938, + 0x3C73, 0x8231, 0xC939, + 0x3C74, 0x8231, 0xCA30, + 0x3C75, 0x8231, 0xCA31, + 0x3C76, 0x8231, 0xCA32, + 0x3C77, 0x8231, 0xCA33, + 0x3C78, 0x8231, 0xCA34, + 0x3C79, 0x8231, 0xCA35, + 0x3C7A, 0x8231, 0xCA36, + 0x3C7B, 0x8231, 0xCA37, + 0x3C7C, 0x8231, 0xCA38, + 0x3C7D, 0x8231, 0xCA39, + 0x3C7E, 0x8231, 0xCB30, + 0x3C7F, 0x8231, 0xCB31, + 0x3C80, 0x8231, 0xCB32, + 0x3C81, 0x8231, 0xCB33, + 0x3C82, 0x8231, 0xCB34, + 0x3C83, 0x8231, 0xCB35, + 0x3C84, 0x8231, 0xCB36, + 0x3C85, 0x8231, 0xCB37, + 0x3C86, 0x8231, 0xCB38, + 0x3C87, 0x8231, 0xCB39, + 0x3C88, 0x8231, 0xCC30, + 0x3C89, 0x8231, 0xCC31, + 0x3C8A, 0x8231, 0xCC32, + 0x3C8B, 0x8231, 0xCC33, + 0x3C8C, 0x8231, 0xCC34, + 0x3C8D, 0x8231, 0xCC35, + 0x3C8E, 0x8231, 0xCC36, + 0x3C8F, 0x8231, 0xCC37, + 0x3C90, 0x8231, 0xCC38, + 0x3C91, 0x8231, 0xCC39, + 0x3C92, 0x8231, 0xCD30, + 0x3C93, 0x8231, 0xCD31, + 0x3C94, 0x8231, 0xCD32, + 0x3C95, 0x8231, 0xCD33, + 0x3C96, 0x8231, 0xCD34, + 0x3C97, 0x8231, 0xCD35, + 0x3C98, 0x8231, 0xCD36, + 0x3C99, 0x8231, 0xCD37, + 0x3C9A, 0x8231, 0xCD38, + 0x3C9B, 0x8231, 0xCD39, + 0x3C9C, 0x8231, 0xCE30, + 0x3C9D, 0x8231, 0xCE31, + 0x3C9E, 0x8231, 0xCE32, + 0x3C9F, 0x8231, 0xCE33, + 0x3CA0, 0x8231, 0xCE34, + 0x3CA1, 0x8231, 0xCE35, + 0x3CA2, 0x8231, 0xCE36, + 0x3CA3, 0x8231, 0xCE37, + 0x3CA4, 0x8231, 0xCE38, + 0x3CA5, 0x8231, 0xCE39, + 0x3CA6, 0x8231, 0xCF30, + 0x3CA7, 0x8231, 0xCF31, + 0x3CA8, 0x8231, 0xCF32, + 0x3CA9, 0x8231, 0xCF33, + 0x3CAA, 0x8231, 0xCF34, + 0x3CAB, 0x8231, 0xCF35, + 0x3CAC, 0x8231, 0xCF36, + 0x3CAD, 0x8231, 0xCF37, + 0x3CAE, 0x8231, 0xCF38, + 0x3CAF, 0x8231, 0xCF39, + 0x3CB0, 0x8231, 0xD030, + 0x3CB1, 0x8231, 0xD031, + 0x3CB2, 0x8231, 0xD032, + 0x3CB3, 0x8231, 0xD033, + 0x3CB4, 0x8231, 0xD034, + 0x3CB5, 0x8231, 0xD035, + 0x3CB6, 0x8231, 0xD036, + 0x3CB7, 0x8231, 0xD037, + 0x3CB8, 0x8231, 0xD038, + 0x3CB9, 0x8231, 0xD039, + 0x3CBA, 0x8231, 0xD130, + 0x3CBB, 0x8231, 0xD131, + 0x3CBC, 0x8231, 0xD132, + 0x3CBD, 0x8231, 0xD133, + 0x3CBE, 0x8231, 0xD134, + 0x3CBF, 0x8231, 0xD135, + 0x3CC0, 0x8231, 0xD136, + 0x3CC1, 0x8231, 0xD137, + 0x3CC2, 0x8231, 0xD138, + 0x3CC3, 0x8231, 0xD139, + 0x3CC4, 0x8231, 0xD230, + 0x3CC5, 0x8231, 0xD231, + 0x3CC6, 0x8231, 0xD232, + 0x3CC7, 0x8231, 0xD233, + 0x3CC8, 0x8231, 0xD234, + 0x3CC9, 0x8231, 0xD235, + 0x3CCA, 0x8231, 0xD236, + 0x3CCB, 0x8231, 0xD237, + 0x3CCC, 0x8231, 0xD238, + 0x3CCD, 0x8231, 0xD239, + 0x3CCE, 0x8231, 0xD330, + 0x3CCF, 0x8231, 0xD331, + 0x3CD0, 0x8231, 0xD332, + 0x3CD1, 0x8231, 0xD333, + 0x3CD2, 0x8231, 0xD334, + 0x3CD3, 0x8231, 0xD335, + 0x3CD4, 0x8231, 0xD336, + 0x3CD5, 0x8231, 0xD337, + 0x3CD6, 0x8231, 0xD338, + 0x3CD7, 0x8231, 0xD339, + 0x3CD8, 0x8231, 0xD430, + 0x3CD9, 0x8231, 0xD431, + 0x3CDA, 0x8231, 0xD432, + 0x3CDB, 0x8231, 0xD433, + 0x3CDC, 0x8231, 0xD434, + 0x3CDD, 0x8231, 0xD435, + 0x3CDE, 0x8231, 0xD436, + 0x3CDF, 0x8231, 0xD437, + 0x4057, 0x8232, 0xAF33, + 0x4058, 0x8232, 0xAF34, + 0x4059, 0x8232, 0xAF35, + 0x405A, 0x8232, 0xAF36, + 0x405B, 0x8232, 0xAF37, + 0x405C, 0x8232, 0xAF38, + 0x405D, 0x8232, 0xAF39, + 0x405E, 0x8232, 0xB030, + 0x405F, 0x8232, 0xB031, + 0x4060, 0x8232, 0xB032, + 0x4061, 0x8232, 0xB033, + 0x4062, 0x8232, 0xB034, + 0x4063, 0x8232, 0xB035, + 0x4064, 0x8232, 0xB036, + 0x4065, 0x8232, 0xB037, + 0x4066, 0x8232, 0xB038, + 0x4067, 0x8232, 0xB039, + 0x4068, 0x8232, 0xB130, + 0x4069, 0x8232, 0xB131, + 0x406A, 0x8232, 0xB132, + 0x406B, 0x8232, 0xB133, + 0x406C, 0x8232, 0xB134, + 0x406D, 0x8232, 0xB135, + 0x406E, 0x8232, 0xB136, + 0x406F, 0x8232, 0xB137, + 0x4070, 0x8232, 0xB138, + 0x4071, 0x8232, 0xB139, + 0x4072, 0x8232, 0xB230, + 0x4073, 0x8232, 0xB231, + 0x4074, 0x8232, 0xB232, + 0x4075, 0x8232, 0xB233, + 0x4076, 0x8232, 0xB234, + 0x4077, 0x8232, 0xB235, + 0x4078, 0x8232, 0xB236, + 0x4079, 0x8232, 0xB237, + 0x407A, 0x8232, 0xB238, + 0x407B, 0x8232, 0xB239, + 0x407C, 0x8232, 0xB330, + 0x407D, 0x8232, 0xB331, + 0x407E, 0x8232, 0xB332, + 0x407F, 0x8232, 0xB333, + 0x4080, 0x8232, 0xB334, + 0x4081, 0x8232, 0xB335, + 0x4082, 0x8232, 0xB336, + 0x4083, 0x8232, 0xB337, + 0x4084, 0x8232, 0xB338, + 0x4085, 0x8232, 0xB339, + 0x4086, 0x8232, 0xB430, + 0x4087, 0x8232, 0xB431, + 0x4088, 0x8232, 0xB432, + 0x4089, 0x8232, 0xB433, + 0x408A, 0x8232, 0xB434, + 0x408B, 0x8232, 0xB435, + 0x408C, 0x8232, 0xB436, + 0x408D, 0x8232, 0xB437, + 0x408E, 0x8232, 0xB438, + 0x408F, 0x8232, 0xB439, + 0x4090, 0x8232, 0xB530, + 0x4091, 0x8232, 0xB531, + 0x4092, 0x8232, 0xB532, + 0x4093, 0x8232, 0xB533, + 0x4094, 0x8232, 0xB534, + 0x4095, 0x8232, 0xB535, + 0x4096, 0x8232, 0xB536, + 0x4097, 0x8232, 0xB537, + 0x4098, 0x8232, 0xB538, + 0x4099, 0x8232, 0xB539, + 0x409A, 0x8232, 0xB630, + 0x409B, 0x8232, 0xB631, + 0x409C, 0x8232, 0xB632, + 0x409D, 0x8232, 0xB633, + 0x409E, 0x8232, 0xB634, + 0x409F, 0x8232, 0xB635, + 0x40A0, 0x8232, 0xB636, + 0x40A1, 0x8232, 0xB637, + 0x40A2, 0x8232, 0xB638, + 0x40A3, 0x8232, 0xB639, + 0x40A4, 0x8232, 0xB730, + 0x40A5, 0x8232, 0xB731, + 0x40A6, 0x8232, 0xB732, + 0x40A7, 0x8232, 0xB733, + 0x40A8, 0x8232, 0xB734, + 0x40A9, 0x8232, 0xB735, + 0x40AA, 0x8232, 0xB736, + 0x40AB, 0x8232, 0xB737, + 0x40AC, 0x8232, 0xB738, + 0x40AD, 0x8232, 0xB739, + 0x40AE, 0x8232, 0xB830, + 0x40AF, 0x8232, 0xB831, + 0x40B0, 0x8232, 0xB832, + 0x40B1, 0x8232, 0xB833, + 0x40B2, 0x8232, 0xB834, + 0x40B3, 0x8232, 0xB835, + 0x40B4, 0x8232, 0xB836, + 0x40B5, 0x8232, 0xB837, + 0x40B6, 0x8232, 0xB838, + 0x40B7, 0x8232, 0xB839, + 0x40B8, 0x8232, 0xB930, + 0x40B9, 0x8232, 0xB931, + 0x40BA, 0x8232, 0xB932, + 0x40BB, 0x8232, 0xB933, + 0x40BC, 0x8232, 0xB934, + 0x40BD, 0x8232, 0xB935, + 0x40BE, 0x8232, 0xB936, + 0x40BF, 0x8232, 0xB937, + 0x40C0, 0x8232, 0xB938, + 0x40C1, 0x8232, 0xB939, + 0x40C2, 0x8232, 0xBA30, + 0x40C3, 0x8232, 0xBA31, + 0x40C4, 0x8232, 0xBA32, + 0x40C5, 0x8232, 0xBA33, + 0x40C6, 0x8232, 0xBA34, + 0x40C7, 0x8232, 0xBA35, + 0x40C8, 0x8232, 0xBA36, + 0x40C9, 0x8232, 0xBA37, + 0x40CA, 0x8232, 0xBA38, + 0x40CB, 0x8232, 0xBA39, + 0x40CC, 0x8232, 0xBB30, + 0x40CD, 0x8232, 0xBB31, + 0x40CE, 0x8232, 0xBB32, + 0x40CF, 0x8232, 0xBB33, + 0x40D0, 0x8232, 0xBB34, + 0x40D1, 0x8232, 0xBB35, + 0x40D2, 0x8232, 0xBB36, + 0x40D3, 0x8232, 0xBB37, + 0x40D4, 0x8232, 0xBB38, + 0x40D5, 0x8232, 0xBB39, + 0x40D6, 0x8232, 0xBC30, + 0x40D7, 0x8232, 0xBC31, + 0x40D8, 0x8232, 0xBC32, + 0x40D9, 0x8232, 0xBC33, + 0x40DA, 0x8232, 0xBC34, + 0x40DB, 0x8232, 0xBC35, + 0x40DC, 0x8232, 0xBC36, + 0x40DD, 0x8232, 0xBC37, + 0x40DE, 0x8232, 0xBC38, + 0x40DF, 0x8232, 0xBC39, + 0x40E0, 0x8232, 0xBD30, + 0x40E1, 0x8232, 0xBD31, + 0x40E2, 0x8232, 0xBD32, + 0x40E3, 0x8232, 0xBD33, + 0x40E4, 0x8232, 0xBD34, + 0x40E5, 0x8232, 0xBD35, + 0x40E6, 0x8232, 0xBD36, + 0x40E7, 0x8232, 0xBD37, + 0x40E8, 0x8232, 0xBD38, + 0x40E9, 0x8232, 0xBD39, + 0x40EA, 0x8232, 0xBE30, + 0x40EB, 0x8232, 0xBE31, + 0x40EC, 0x8232, 0xBE32, + 0x40ED, 0x8232, 0xBE33, + 0x40EE, 0x8232, 0xBE34, + 0x40EF, 0x8232, 0xBE35, + 0x40F0, 0x8232, 0xBE36, + 0x40F1, 0x8232, 0xBE37, + 0x40F2, 0x8232, 0xBE38, + 0x40F3, 0x8232, 0xBE39, + 0x40F4, 0x8232, 0xBF30, + 0x40F5, 0x8232, 0xBF31, + 0x40F6, 0x8232, 0xBF32, + 0x40F7, 0x8232, 0xBF33, + 0x40F8, 0x8232, 0xBF34, + 0x40F9, 0x8232, 0xBF35, + 0x40FA, 0x8232, 0xBF36, + 0x40FB, 0x8232, 0xBF37, + 0x40FC, 0x8232, 0xBF38, + 0x40FD, 0x8232, 0xBF39, + 0x40FE, 0x8232, 0xC030, + 0x40FF, 0x8232, 0xC031, + 0x4100, 0x8232, 0xC032, + 0x4101, 0x8232, 0xC033, + 0x4102, 0x8232, 0xC034, + 0x4103, 0x8232, 0xC035, + 0x4104, 0x8232, 0xC036, + 0x4105, 0x8232, 0xC037, + 0x4106, 0x8232, 0xC038, + 0x4107, 0x8232, 0xC039, + 0x4108, 0x8232, 0xC130, + 0x4109, 0x8232, 0xC131, + 0x410A, 0x8232, 0xC132, + 0x410B, 0x8232, 0xC133, + 0x410C, 0x8232, 0xC134, + 0x410D, 0x8232, 0xC135, + 0x410E, 0x8232, 0xC136, + 0x410F, 0x8232, 0xC137, + 0x4110, 0x8232, 0xC138, + 0x4111, 0x8232, 0xC139, + 0x4112, 0x8232, 0xC230, + 0x4113, 0x8232, 0xC231, + 0x4114, 0x8232, 0xC232, + 0x4115, 0x8232, 0xC233, + 0x4116, 0x8232, 0xC234, + 0x4117, 0x8232, 0xC235, + 0x4118, 0x8232, 0xC236, + 0x4119, 0x8232, 0xC237, + 0x411A, 0x8232, 0xC238, + 0x411B, 0x8232, 0xC239, + 0x411C, 0x8232, 0xC330, + 0x411D, 0x8232, 0xC331, + 0x411E, 0x8232, 0xC332, + 0x411F, 0x8232, 0xC333, + 0x4120, 0x8232, 0xC334, + 0x4121, 0x8232, 0xC335, + 0x4122, 0x8232, 0xC336, + 0x4123, 0x8232, 0xC337, + 0x4124, 0x8232, 0xC338, + 0x4125, 0x8232, 0xC339, + 0x4126, 0x8232, 0xC430, + 0x4127, 0x8232, 0xC431, + 0x4128, 0x8232, 0xC432, + 0x4129, 0x8232, 0xC433, + 0x412A, 0x8232, 0xC434, + 0x412B, 0x8232, 0xC435, + 0x412C, 0x8232, 0xC436, + 0x412D, 0x8232, 0xC437, + 0x412E, 0x8232, 0xC438, + 0x412F, 0x8232, 0xC439, + 0x4130, 0x8232, 0xC530, + 0x4131, 0x8232, 0xC531, + 0x4132, 0x8232, 0xC532, + 0x4133, 0x8232, 0xC533, + 0x4134, 0x8232, 0xC534, + 0x4135, 0x8232, 0xC535, + 0x4136, 0x8232, 0xC536, + 0x4137, 0x8232, 0xC537, + 0x4138, 0x8232, 0xC538, + 0x4139, 0x8232, 0xC539, + 0x413A, 0x8232, 0xC630, + 0x413B, 0x8232, 0xC631, + 0x413C, 0x8232, 0xC632, + 0x413D, 0x8232, 0xC633, + 0x413E, 0x8232, 0xC634, + 0x413F, 0x8232, 0xC635, + 0x4140, 0x8232, 0xC636, + 0x4141, 0x8232, 0xC637, + 0x4142, 0x8232, 0xC638, + 0x4143, 0x8232, 0xC639, + 0x4144, 0x8232, 0xC730, + 0x4145, 0x8232, 0xC731, + 0x4146, 0x8232, 0xC732, + 0x4147, 0x8232, 0xC733, + 0x4148, 0x8232, 0xC734, + 0x4149, 0x8232, 0xC735, + 0x414A, 0x8232, 0xC736, + 0x414B, 0x8232, 0xC737, + 0x414C, 0x8232, 0xC738, + 0x414D, 0x8232, 0xC739, + 0x414E, 0x8232, 0xC830, + 0x414F, 0x8232, 0xC831, + 0x4150, 0x8232, 0xC832, + 0x4151, 0x8232, 0xC833, + 0x4152, 0x8232, 0xC834, + 0x4153, 0x8232, 0xC835, + 0x4154, 0x8232, 0xC836, + 0x4155, 0x8232, 0xC837, + 0x4156, 0x8232, 0xC838, + 0x4157, 0x8232, 0xC839, + 0x4158, 0x8232, 0xC930, + 0x4159, 0x8232, 0xC931, + 0x415A, 0x8232, 0xC932, + 0x415B, 0x8232, 0xC933, + 0x415C, 0x8232, 0xC934, + 0x415D, 0x8232, 0xC935, + 0x415E, 0x8232, 0xC936, + 0x4338, 0x8232, 0xF838, + 0x4339, 0x8232, 0xF839, + 0x433A, 0x8232, 0xF930, + 0x433B, 0x8232, 0xF931, + 0x433C, 0x8232, 0xF932, + 0x433D, 0x8232, 0xF933, + 0x433E, 0x8232, 0xF934, + 0x433F, 0x8232, 0xF935, + 0x4340, 0x8232, 0xF936, + 0x4341, 0x8232, 0xF937, + 0x4342, 0x8232, 0xF938, + 0x4343, 0x8232, 0xF939, + 0x4344, 0x8232, 0xFA30, + 0x4345, 0x8232, 0xFA31, + 0x4346, 0x8232, 0xFA32, + 0x4347, 0x8232, 0xFA33, + 0x4348, 0x8232, 0xFA34, + 0x4349, 0x8232, 0xFA35, + 0x434A, 0x8232, 0xFA36, + 0x434B, 0x8232, 0xFA37, + 0x434C, 0x8232, 0xFA38, + 0x434D, 0x8232, 0xFA39, + 0x434E, 0x8232, 0xFB30, + 0x434F, 0x8232, 0xFB31, + 0x4350, 0x8232, 0xFB32, + 0x4351, 0x8232, 0xFB33, + 0x4352, 0x8232, 0xFB34, + 0x4353, 0x8232, 0xFB35, + 0x4354, 0x8232, 0xFB36, + 0x4355, 0x8232, 0xFB37, + 0x4356, 0x8232, 0xFB38, + 0x4357, 0x8232, 0xFB39, + 0x4358, 0x8232, 0xFC30, + 0x4359, 0x8232, 0xFC31, + 0x435A, 0x8232, 0xFC32, + 0x435B, 0x8232, 0xFC33, + 0x435C, 0x8232, 0xFC34, + 0x435D, 0x8232, 0xFC35, + 0x435E, 0x8232, 0xFC36, + 0x435F, 0x8232, 0xFC37, + 0x4360, 0x8232, 0xFC38, + 0x4361, 0x8232, 0xFC39, + 0x4362, 0x8232, 0xFD30, + 0x4363, 0x8232, 0xFD31, + 0x4364, 0x8232, 0xFD32, + 0x4365, 0x8232, 0xFD33, + 0x4366, 0x8232, 0xFD34, + 0x4367, 0x8232, 0xFD35, + 0x4368, 0x8232, 0xFD36, + 0x4369, 0x8232, 0xFD37, + 0x436A, 0x8232, 0xFD38, + 0x436B, 0x8232, 0xFD39, + 0x436C, 0x8232, 0xFE30, + 0x436D, 0x8232, 0xFE31, + 0x436E, 0x8232, 0xFE32, + 0x436F, 0x8232, 0xFE33, + 0x4370, 0x8232, 0xFE34, + 0x4371, 0x8232, 0xFE35, + 0x4372, 0x8232, 0xFE36, + 0x4373, 0x8232, 0xFE37, + 0x4374, 0x8232, 0xFE38, + 0x4375, 0x8232, 0xFE39, + 0x4376, 0x8233, 0x8130, + 0x4377, 0x8233, 0x8131, + 0x4378, 0x8233, 0x8132, + 0x4379, 0x8233, 0x8133, + 0x437A, 0x8233, 0x8134, + 0x437B, 0x8233, 0x8135, + 0x437C, 0x8233, 0x8136, + 0x437D, 0x8233, 0x8137, + 0x437E, 0x8233, 0x8138, + 0x437F, 0x8233, 0x8139, + 0x4380, 0x8233, 0x8230, + 0x4381, 0x8233, 0x8231, + 0x4382, 0x8233, 0x8232, + 0x4383, 0x8233, 0x8233, + 0x4384, 0x8233, 0x8234, + 0x4385, 0x8233, 0x8235, + 0x4386, 0x8233, 0x8236, + 0x4387, 0x8233, 0x8237, + 0x4388, 0x8233, 0x8238, + 0x4389, 0x8233, 0x8239, + 0x438A, 0x8233, 0x8330, + 0x438B, 0x8233, 0x8331, + 0x438C, 0x8233, 0x8332, + 0x438D, 0x8233, 0x8333, + 0x438E, 0x8233, 0x8334, + 0x438F, 0x8233, 0x8335, + 0x4390, 0x8233, 0x8336, + 0x4391, 0x8233, 0x8337, + 0x4392, 0x8233, 0x8338, + 0x4393, 0x8233, 0x8339, + 0x4394, 0x8233, 0x8430, + 0x4395, 0x8233, 0x8431, + 0x4396, 0x8233, 0x8432, + 0x4397, 0x8233, 0x8433, + 0x4398, 0x8233, 0x8434, + 0x4399, 0x8233, 0x8435, + 0x439A, 0x8233, 0x8436, + 0x439B, 0x8233, 0x8437, + 0x439C, 0x8233, 0x8438, + 0x439D, 0x8233, 0x8439, + 0x439E, 0x8233, 0x8530, + 0x439F, 0x8233, 0x8531, + 0x43A0, 0x8233, 0x8532, + 0x43A1, 0x8233, 0x8533, + 0x43A2, 0x8233, 0x8534, + 0x43A3, 0x8233, 0x8535, + 0x43A4, 0x8233, 0x8536, + 0x43A5, 0x8233, 0x8537, + 0x43A6, 0x8233, 0x8538, + 0x43A7, 0x8233, 0x8539, + 0x43A8, 0x8233, 0x8630, + 0x43A9, 0x8233, 0x8631, + 0x43AA, 0x8233, 0x8632, + 0x43AB, 0x8233, 0x8633, + 0x43AD, 0x8233, 0x8634, + 0x43AE, 0x8233, 0x8635, + 0x43AF, 0x8233, 0x8636, + 0x43B0, 0x8233, 0x8637, + 0x43B2, 0x8233, 0x8638, + 0x43B3, 0x8233, 0x8639, + 0x43B4, 0x8233, 0x8730, + 0x43B5, 0x8233, 0x8731, + 0x43B6, 0x8233, 0x8732, + 0x43B7, 0x8233, 0x8733, + 0x43B8, 0x8233, 0x8734, + 0x43B9, 0x8233, 0x8735, + 0x43BA, 0x8233, 0x8736, + 0x43BB, 0x8233, 0x8737, + 0x43BC, 0x8233, 0x8738, + 0x43BD, 0x8233, 0x8739, + 0x43BE, 0x8233, 0x8830, + 0x43BF, 0x8233, 0x8831, + 0x43C0, 0x8233, 0x8832, + 0x43C1, 0x8233, 0x8833, + 0x43C2, 0x8233, 0x8834, + 0x43C3, 0x8233, 0x8835, + 0x43C4, 0x8233, 0x8836, + 0x43C5, 0x8233, 0x8837, + 0x43C6, 0x8233, 0x8838, + 0x43C7, 0x8233, 0x8839, + 0x43C8, 0x8233, 0x8930, + 0x43C9, 0x8233, 0x8931, + 0x43CA, 0x8233, 0x8932, + 0x43CB, 0x8233, 0x8933, + 0x43CC, 0x8233, 0x8934, + 0x43CD, 0x8233, 0x8935, + 0x43CE, 0x8233, 0x8936, + 0x43CF, 0x8233, 0x8937, + 0x43D0, 0x8233, 0x8938, + 0x43D1, 0x8233, 0x8939, + 0x43D2, 0x8233, 0x8A30, + 0x43D3, 0x8233, 0x8A31, + 0x43D4, 0x8233, 0x8A32, + 0x43D5, 0x8233, 0x8A33, + 0x43D6, 0x8233, 0x8A34, + 0x43D7, 0x8233, 0x8A35, + 0x43D8, 0x8233, 0x8A36, + 0x43D9, 0x8233, 0x8A37, + 0x43DA, 0x8233, 0x8A38, + 0x43DB, 0x8233, 0x8A39, + 0x43DC, 0x8233, 0x8B30, + 0x43DE, 0x8233, 0x8B31, + 0x43DF, 0x8233, 0x8B32, + 0x43E0, 0x8233, 0x8B33, + 0x43E1, 0x8233, 0x8B34, + 0x43E2, 0x8233, 0x8B35, + 0x43E3, 0x8233, 0x8B36, + 0x43E4, 0x8233, 0x8B37, + 0x43E5, 0x8233, 0x8B38, + 0x43E6, 0x8233, 0x8B39, + 0x43E7, 0x8233, 0x8C30, + 0x43E8, 0x8233, 0x8C31, + 0x43E9, 0x8233, 0x8C32, + 0x43EA, 0x8233, 0x8C33, + 0x43EB, 0x8233, 0x8C34, + 0x43EC, 0x8233, 0x8C35, + 0x43ED, 0x8233, 0x8C36, + 0x43EE, 0x8233, 0x8C37, + 0x43EF, 0x8233, 0x8C38, + 0x43F0, 0x8233, 0x8C39, + 0x43F1, 0x8233, 0x8D30, + 0x43F2, 0x8233, 0x8D31, + 0x43F3, 0x8233, 0x8D32, + 0x43F4, 0x8233, 0x8D33, + 0x43F5, 0x8233, 0x8D34, + 0x43F6, 0x8233, 0x8D35, + 0x43F7, 0x8233, 0x8D36, + 0x43F8, 0x8233, 0x8D37, + 0x43F9, 0x8233, 0x8D38, + 0x43FA, 0x8233, 0x8D39, + 0x43FB, 0x8233, 0x8E30, + 0x43FC, 0x8233, 0x8E31, + 0x43FD, 0x8233, 0x8E32, + 0x43FE, 0x8233, 0x8E33, + 0x43FF, 0x8233, 0x8E34, + 0x4400, 0x8233, 0x8E35, + 0x4401, 0x8233, 0x8E36, + 0x4402, 0x8233, 0x8E37, + 0x4403, 0x8233, 0x8E38, + 0x4404, 0x8233, 0x8E39, + 0x4405, 0x8233, 0x8F30, + 0x4406, 0x8233, 0x8F31, + 0x4407, 0x8233, 0x8F32, + 0x4408, 0x8233, 0x8F33, + 0x4409, 0x8233, 0x8F34, + 0x440A, 0x8233, 0x8F35, + 0x440B, 0x8233, 0x8F36, + 0x440C, 0x8233, 0x8F37, + 0x440D, 0x8233, 0x8F38, + 0x440E, 0x8233, 0x8F39, + 0x440F, 0x8233, 0x9030, + 0x4410, 0x8233, 0x9031, + 0x4411, 0x8233, 0x9032, + 0x4412, 0x8233, 0x9033, + 0x4413, 0x8233, 0x9034, + 0x4414, 0x8233, 0x9035, + 0x4415, 0x8233, 0x9036, + 0x4416, 0x8233, 0x9037, + 0x4417, 0x8233, 0x9038, + 0x4418, 0x8233, 0x9039, + 0x4419, 0x8233, 0x9130, + 0x441A, 0x8233, 0x9131, + 0x441B, 0x8233, 0x9132, + 0x441C, 0x8233, 0x9133, + 0x441D, 0x8233, 0x9134, + 0x441E, 0x8233, 0x9135, + 0x441F, 0x8233, 0x9136, + 0x4420, 0x8233, 0x9137, + 0x4421, 0x8233, 0x9138, + 0x4422, 0x8233, 0x9139, + 0x4423, 0x8233, 0x9230, + 0x4424, 0x8233, 0x9231, + 0x4425, 0x8233, 0x9232, + 0x4426, 0x8233, 0x9233, + 0x4427, 0x8233, 0x9234, + 0x4428, 0x8233, 0x9235, + 0x4429, 0x8233, 0x9236, + 0x442A, 0x8233, 0x9237, + 0x442B, 0x8233, 0x9238, + 0x442C, 0x8233, 0x9239, + 0x442D, 0x8233, 0x9330, + 0x442E, 0x8233, 0x9331, + 0x442F, 0x8233, 0x9332, + 0x4430, 0x8233, 0x9333, + 0x4431, 0x8233, 0x9334, + 0x4432, 0x8233, 0x9335, + 0x4433, 0x8233, 0x9336, + 0x4434, 0x8233, 0x9337, + 0x4435, 0x8233, 0x9338, + 0x4436, 0x8233, 0x9339, + 0x4437, 0x8233, 0x9430, + 0x4438, 0x8233, 0x9431, + 0x4439, 0x8233, 0x9432, + 0x443A, 0x8233, 0x9433, + 0x443B, 0x8233, 0x9434, + 0x443C, 0x8233, 0x9435, + 0x443D, 0x8233, 0x9436, + 0x443E, 0x8233, 0x9437, + 0x443F, 0x8233, 0x9438, + 0x4440, 0x8233, 0x9439, + 0x4441, 0x8233, 0x9530, + 0x4442, 0x8233, 0x9531, + 0x4443, 0x8233, 0x9532, + 0x4444, 0x8233, 0x9533, + 0x4445, 0x8233, 0x9534, + 0x4446, 0x8233, 0x9535, + 0x4447, 0x8233, 0x9536, + 0x4448, 0x8233, 0x9537, + 0x4449, 0x8233, 0x9538, + 0x444A, 0x8233, 0x9539, + 0x444B, 0x8233, 0x9630, + 0x444C, 0x8233, 0x9631, + 0x444D, 0x8233, 0x9632, + 0x444E, 0x8233, 0x9633, + 0x444F, 0x8233, 0x9634, + 0x4450, 0x8233, 0x9635, + 0x4451, 0x8233, 0x9636, + 0x4452, 0x8233, 0x9637, + 0x4453, 0x8233, 0x9638, + 0x4454, 0x8233, 0x9639, + 0x4455, 0x8233, 0x9730, + 0x4456, 0x8233, 0x9731, + 0x4457, 0x8233, 0x9732, + 0x4458, 0x8233, 0x9733, + 0x4459, 0x8233, 0x9734, + 0x445A, 0x8233, 0x9735, + 0x445B, 0x8233, 0x9736, + 0x445C, 0x8233, 0x9737, + 0x445D, 0x8233, 0x9738, + 0x445E, 0x8233, 0x9739, + 0x445F, 0x8233, 0x9830, + 0x4460, 0x8233, 0x9831, + 0x4461, 0x8233, 0x9832, + 0x4462, 0x8233, 0x9833, + 0x4463, 0x8233, 0x9834, + 0x4464, 0x8233, 0x9835, + 0x4465, 0x8233, 0x9836, + 0x4466, 0x8233, 0x9837, + 0x4467, 0x8233, 0x9838, + 0x4468, 0x8233, 0x9839, + 0x4469, 0x8233, 0x9930, + 0x446A, 0x8233, 0x9931, + 0x446B, 0x8233, 0x9932, + 0x446C, 0x8233, 0x9933, + 0x446D, 0x8233, 0x9934, + 0x446E, 0x8233, 0x9935, + 0x446F, 0x8233, 0x9936, + 0x4470, 0x8233, 0x9937, + 0x4471, 0x8233, 0x9938, + 0x4472, 0x8233, 0x9939, + 0x4473, 0x8233, 0x9A30, + 0x4474, 0x8233, 0x9A31, + 0x4475, 0x8233, 0x9A32, + 0x4476, 0x8233, 0x9A33, + 0x4477, 0x8233, 0x9A34, + 0x4478, 0x8233, 0x9A35, + 0x4479, 0x8233, 0x9A36, + 0x447A, 0x8233, 0x9A37, + 0x447B, 0x8233, 0x9A38, + 0x447C, 0x8233, 0x9A39, + 0x447D, 0x8233, 0x9B30, + 0x447E, 0x8233, 0x9B31, + 0x447F, 0x8233, 0x9B32, + 0x4480, 0x8233, 0x9B33, + 0x4481, 0x8233, 0x9B34, + 0x4482, 0x8233, 0x9B35, + 0x4483, 0x8233, 0x9B36, + 0x4484, 0x8233, 0x9B37, + 0x4485, 0x8233, 0x9B38, + 0x4486, 0x8233, 0x9B39, + 0x4487, 0x8233, 0x9C30, + 0x4488, 0x8233, 0x9C31, + 0x4489, 0x8233, 0x9C32, + 0x448A, 0x8233, 0x9C33, + 0x448B, 0x8233, 0x9C34, + 0x448C, 0x8233, 0x9C35, + 0x448D, 0x8233, 0x9C36, + 0x448E, 0x8233, 0x9C37, + 0x448F, 0x8233, 0x9C38, + 0x4490, 0x8233, 0x9C39, + 0x4491, 0x8233, 0x9D30, + 0x4492, 0x8233, 0x9D31, + 0x4493, 0x8233, 0x9D32, + 0x4494, 0x8233, 0x9D33, + 0x4495, 0x8233, 0x9D34, + 0x4496, 0x8233, 0x9D35, + 0x4497, 0x8233, 0x9D36, + 0x4498, 0x8233, 0x9D37, + 0x4499, 0x8233, 0x9D38, + 0x449A, 0x8233, 0x9D39, + 0x449B, 0x8233, 0x9E30, + 0x449C, 0x8233, 0x9E31, + 0x449D, 0x8233, 0x9E32, + 0x449E, 0x8233, 0x9E33, + 0x449F, 0x8233, 0x9E34, + 0x44A0, 0x8233, 0x9E35, + 0x44A1, 0x8233, 0x9E36, + 0x44A2, 0x8233, 0x9E37, + 0x44A3, 0x8233, 0x9E38, + 0x44A4, 0x8233, 0x9E39, + 0x44A5, 0x8233, 0x9F30, + 0x44A6, 0x8233, 0x9F31, + 0x44A7, 0x8233, 0x9F32, + 0x44A8, 0x8233, 0x9F33, + 0x44A9, 0x8233, 0x9F34, + 0x44AA, 0x8233, 0x9F35, + 0x44AB, 0x8233, 0x9F36, + 0x44AC, 0x8233, 0x9F37, + 0x44AD, 0x8233, 0x9F38, + 0x44AE, 0x8233, 0x9F39, + 0x44AF, 0x8233, 0xA030, + 0x44B0, 0x8233, 0xA031, + 0x44B1, 0x8233, 0xA032, + 0x44B2, 0x8233, 0xA033, + 0x44B3, 0x8233, 0xA034, + 0x44B4, 0x8233, 0xA035, + 0x44B5, 0x8233, 0xA036, + 0x44B6, 0x8233, 0xA037, + 0x44B7, 0x8233, 0xA038, + 0x44B8, 0x8233, 0xA039, + 0x44B9, 0x8233, 0xA130, + 0x44BA, 0x8233, 0xA131, + 0x44BB, 0x8233, 0xA132, + 0x44BC, 0x8233, 0xA133, + 0x44BD, 0x8233, 0xA134, + 0x44BE, 0x8233, 0xA135, + 0x44BF, 0x8233, 0xA136, + 0x44C0, 0x8233, 0xA137, + 0x44C1, 0x8233, 0xA138, + 0x44C2, 0x8233, 0xA139, + 0x44C3, 0x8233, 0xA230, + 0x44C4, 0x8233, 0xA231, + 0x44C5, 0x8233, 0xA232, + 0x44C6, 0x8233, 0xA233, + 0x44C7, 0x8233, 0xA234, + 0x44C8, 0x8233, 0xA235, + 0x44C9, 0x8233, 0xA236, + 0x44CA, 0x8233, 0xA237, + 0x44CB, 0x8233, 0xA238, + 0x44CC, 0x8233, 0xA239, + 0x44CD, 0x8233, 0xA330, + 0x44CE, 0x8233, 0xA331, + 0x44CF, 0x8233, 0xA332, + 0x44D0, 0x8233, 0xA333, + 0x44D1, 0x8233, 0xA334, + 0x44D2, 0x8233, 0xA335, + 0x44D3, 0x8233, 0xA336, + 0x44D4, 0x8233, 0xA337, + 0x44D5, 0x8233, 0xA338, + 0x464D, 0x8233, 0xC932, + 0x464E, 0x8233, 0xC933, + 0x464F, 0x8233, 0xC934, + 0x4650, 0x8233, 0xC935, + 0x4651, 0x8233, 0xC936, + 0x4652, 0x8233, 0xC937, + 0x4653, 0x8233, 0xC938, + 0x4654, 0x8233, 0xC939, + 0x4655, 0x8233, 0xCA30, + 0x4656, 0x8233, 0xCA31, + 0x4657, 0x8233, 0xCA32, + 0x4658, 0x8233, 0xCA33, + 0x4659, 0x8233, 0xCA34, + 0x465A, 0x8233, 0xCA35, + 0x465B, 0x8233, 0xCA36, + 0x465C, 0x8233, 0xCA37, + 0x465D, 0x8233, 0xCA38, + 0x465E, 0x8233, 0xCA39, + 0x465F, 0x8233, 0xCB30, + 0x4660, 0x8233, 0xCB31, + 0x4662, 0x8233, 0xCB32, + 0x4663, 0x8233, 0xCB33, + 0x4664, 0x8233, 0xCB34, + 0x4665, 0x8233, 0xCB35, + 0x4666, 0x8233, 0xCB36, + 0x4667, 0x8233, 0xCB37, + 0x4668, 0x8233, 0xCB38, + 0x4669, 0x8233, 0xCB39, + 0x466A, 0x8233, 0xCC30, + 0x466B, 0x8233, 0xCC31, + 0x466C, 0x8233, 0xCC32, + 0x466D, 0x8233, 0xCC33, + 0x466E, 0x8233, 0xCC34, + 0x466F, 0x8233, 0xCC35, + 0x4670, 0x8233, 0xCC36, + 0x4671, 0x8233, 0xCC37, + 0x4672, 0x8233, 0xCC38, + 0x4673, 0x8233, 0xCC39, + 0x4674, 0x8233, 0xCD30, + 0x4675, 0x8233, 0xCD31, + 0x4676, 0x8233, 0xCD32, + 0x4677, 0x8233, 0xCD33, + 0x4678, 0x8233, 0xCD34, + 0x4679, 0x8233, 0xCD35, + 0x467A, 0x8233, 0xCD36, + 0x467B, 0x8233, 0xCD37, + 0x467C, 0x8233, 0xCD38, + 0x467D, 0x8233, 0xCD39, + 0x467E, 0x8233, 0xCE30, + 0x467F, 0x8233, 0xCE31, + 0x4680, 0x8233, 0xCE32, + 0x4681, 0x8233, 0xCE33, + 0x4682, 0x8233, 0xCE34, + 0x4683, 0x8233, 0xCE35, + 0x4684, 0x8233, 0xCE36, + 0x4685, 0x8233, 0xCE37, + 0x4686, 0x8233, 0xCE38, + 0x4687, 0x8233, 0xCE39, + 0x4688, 0x8233, 0xCF30, + 0x4689, 0x8233, 0xCF31, + 0x468A, 0x8233, 0xCF32, + 0x468B, 0x8233, 0xCF33, + 0x468C, 0x8233, 0xCF34, + 0x468D, 0x8233, 0xCF35, + 0x468E, 0x8233, 0xCF36, + 0x468F, 0x8233, 0xCF37, + 0x4690, 0x8233, 0xCF38, + 0x4691, 0x8233, 0xCF39, + 0x4692, 0x8233, 0xD030, + 0x4693, 0x8233, 0xD031, + 0x4694, 0x8233, 0xD032, + 0x4695, 0x8233, 0xD033, + 0x4696, 0x8233, 0xD034, + 0x4697, 0x8233, 0xD035, + 0x4698, 0x8233, 0xD036, + 0x4699, 0x8233, 0xD037, + 0x469A, 0x8233, 0xD038, + 0x469B, 0x8233, 0xD039, + 0x469C, 0x8233, 0xD130, + 0x469D, 0x8233, 0xD131, + 0x469E, 0x8233, 0xD132, + 0x469F, 0x8233, 0xD133, + 0x46A0, 0x8233, 0xD134, + 0x46A1, 0x8233, 0xD135, + 0x46A2, 0x8233, 0xD136, + 0x46A3, 0x8233, 0xD137, + 0x46A4, 0x8233, 0xD138, + 0x46A5, 0x8233, 0xD139, + 0x46A6, 0x8233, 0xD230, + 0x46A7, 0x8233, 0xD231, + 0x46A8, 0x8233, 0xD232, + 0x46A9, 0x8233, 0xD233, + 0x46AA, 0x8233, 0xD234, + 0x46AB, 0x8233, 0xD235, + 0x46AC, 0x8233, 0xD236, + 0x46AD, 0x8233, 0xD237, + 0x46AE, 0x8233, 0xD238, + 0x46AF, 0x8233, 0xD239, + 0x46B0, 0x8233, 0xD330, + 0x46B1, 0x8233, 0xD331, + 0x46B2, 0x8233, 0xD332, + 0x46B3, 0x8233, 0xD333, + 0x46B4, 0x8233, 0xD334, + 0x46B5, 0x8233, 0xD335, + 0x46B6, 0x8233, 0xD336, + 0x46B7, 0x8233, 0xD337, + 0x46B8, 0x8233, 0xD338, + 0x46B9, 0x8233, 0xD339, + 0x46BA, 0x8233, 0xD430, + 0x46BB, 0x8233, 0xD431, + 0x46BC, 0x8233, 0xD432, + 0x46BD, 0x8233, 0xD433, + 0x46BE, 0x8233, 0xD434, + 0x46BF, 0x8233, 0xD435, + 0x46C0, 0x8233, 0xD436, + 0x46C1, 0x8233, 0xD437, + 0x46C2, 0x8233, 0xD438, + 0x46C3, 0x8233, 0xD439, + 0x46C4, 0x8233, 0xD530, + 0x46C5, 0x8233, 0xD531, + 0x46C6, 0x8233, 0xD532, + 0x46C7, 0x8233, 0xD533, + 0x46C8, 0x8233, 0xD534, + 0x46C9, 0x8233, 0xD535, + 0x46CA, 0x8233, 0xD536, + 0x46CB, 0x8233, 0xD537, + 0x46CC, 0x8233, 0xD538, + 0x46CD, 0x8233, 0xD539, + 0x46CE, 0x8233, 0xD630, + 0x46CF, 0x8233, 0xD631, + 0x46D0, 0x8233, 0xD632, + 0x46D1, 0x8233, 0xD633, + 0x46D2, 0x8233, 0xD634, + 0x46D3, 0x8233, 0xD635, + 0x46D4, 0x8233, 0xD636, + 0x46D5, 0x8233, 0xD637, + 0x46D6, 0x8233, 0xD638, + 0x46D7, 0x8233, 0xD639, + 0x46D8, 0x8233, 0xD730, + 0x46D9, 0x8233, 0xD731, + 0x46DA, 0x8233, 0xD732, + 0x46DB, 0x8233, 0xD733, + 0x46DC, 0x8233, 0xD734, + 0x46DD, 0x8233, 0xD735, + 0x46DE, 0x8233, 0xD736, + 0x46DF, 0x8233, 0xD737, + 0x46E0, 0x8233, 0xD738, + 0x46E1, 0x8233, 0xD739, + 0x46E2, 0x8233, 0xD830, + 0x46E3, 0x8233, 0xD831, + 0x46E4, 0x8233, 0xD832, + 0x46E5, 0x8233, 0xD833, + 0x46E6, 0x8233, 0xD834, + 0x46E7, 0x8233, 0xD835, + 0x46E8, 0x8233, 0xD836, + 0x46E9, 0x8233, 0xD837, + 0x46EA, 0x8233, 0xD838, + 0x46EB, 0x8233, 0xD839, + 0x46EC, 0x8233, 0xD930, + 0x46ED, 0x8233, 0xD931, + 0x46EE, 0x8233, 0xD932, + 0x46EF, 0x8233, 0xD933, + 0x46F0, 0x8233, 0xD934, + 0x46F1, 0x8233, 0xD935, + 0x46F2, 0x8233, 0xD936, + 0x46F3, 0x8233, 0xD937, + 0x46F4, 0x8233, 0xD938, + 0x46F5, 0x8233, 0xD939, + 0x46F6, 0x8233, 0xDA30, + 0x46F7, 0x8233, 0xDA31, + 0x46F8, 0x8233, 0xDA32, + 0x46F9, 0x8233, 0xDA33, + 0x46FA, 0x8233, 0xDA34, + 0x46FB, 0x8233, 0xDA35, + 0x46FC, 0x8233, 0xDA36, + 0x46FD, 0x8233, 0xDA37, + 0x46FE, 0x8233, 0xDA38, + 0x46FF, 0x8233, 0xDA39, + 0x4700, 0x8233, 0xDB30, + 0x4701, 0x8233, 0xDB31, + 0x4702, 0x8233, 0xDB32, + 0x4703, 0x8233, 0xDB33, + 0x4704, 0x8233, 0xDB34, + 0x4705, 0x8233, 0xDB35, + 0x4706, 0x8233, 0xDB36, + 0x4707, 0x8233, 0xDB37, + 0x4708, 0x8233, 0xDB38, + 0x4709, 0x8233, 0xDB39, + 0x470A, 0x8233, 0xDC30, + 0x470B, 0x8233, 0xDC31, + 0x470C, 0x8233, 0xDC32, + 0x470D, 0x8233, 0xDC33, + 0x470E, 0x8233, 0xDC34, + 0x470F, 0x8233, 0xDC35, + 0x4710, 0x8233, 0xDC36, + 0x4711, 0x8233, 0xDC37, + 0x4712, 0x8233, 0xDC38, + 0x4713, 0x8233, 0xDC39, + 0x4714, 0x8233, 0xDD30, + 0x4715, 0x8233, 0xDD31, + 0x4716, 0x8233, 0xDD32, + 0x4717, 0x8233, 0xDD33, + 0x4718, 0x8233, 0xDD34, + 0x4719, 0x8233, 0xDD35, + 0x471A, 0x8233, 0xDD36, + 0x471B, 0x8233, 0xDD37, + 0x471C, 0x8233, 0xDD38, + 0x471D, 0x8233, 0xDD39, + 0x471E, 0x8233, 0xDE30, + 0x471F, 0x8233, 0xDE31, + 0x4720, 0x8233, 0xDE32, + 0x4721, 0x8233, 0xDE33, + 0x4722, 0x8233, 0xDE34, + 0x4724, 0x8233, 0xDE35, + 0x4725, 0x8233, 0xDE36, + 0x4726, 0x8233, 0xDE37, + 0x4727, 0x8233, 0xDE38, + 0x4728, 0x8233, 0xDE39, + 0x472A, 0x8233, 0xDF30, + 0x472B, 0x8233, 0xDF31, + 0x472C, 0x8233, 0xDF32, + 0x472D, 0x8233, 0xDF33, + 0x472E, 0x8233, 0xDF34, + 0x472F, 0x8233, 0xDF35, + 0x4730, 0x8233, 0xDF36, + 0x4731, 0x8233, 0xDF37, + 0x4732, 0x8233, 0xDF38, + 0x4733, 0x8233, 0xDF39, + 0x4734, 0x8233, 0xE030, + 0x4735, 0x8233, 0xE031, + 0x4736, 0x8233, 0xE032, + 0x4737, 0x8233, 0xE033, + 0x4738, 0x8233, 0xE034, + 0x4739, 0x8233, 0xE035, + 0x473A, 0x8233, 0xE036, + 0x473B, 0x8233, 0xE037, + 0x473C, 0x8233, 0xE038, + 0x473D, 0x8233, 0xE039, + 0x473E, 0x8233, 0xE130, + 0x473F, 0x8233, 0xE131, + 0x4740, 0x8233, 0xE132, + 0x4741, 0x8233, 0xE133, + 0x4742, 0x8233, 0xE134, + 0x4743, 0x8233, 0xE135, + 0x4744, 0x8233, 0xE136, + 0x4745, 0x8233, 0xE137, + 0x4746, 0x8233, 0xE138, + 0x4747, 0x8233, 0xE139, + 0x4748, 0x8233, 0xE230, + 0x4749, 0x8233, 0xE231, + 0x474A, 0x8233, 0xE232, + 0x474B, 0x8233, 0xE233, + 0x474C, 0x8233, 0xE234, + 0x474D, 0x8233, 0xE235, + 0x474E, 0x8233, 0xE236, + 0x474F, 0x8233, 0xE237, + 0x4750, 0x8233, 0xE238, + 0x4751, 0x8233, 0xE239, + 0x4752, 0x8233, 0xE330, + 0x4753, 0x8233, 0xE331, + 0x4754, 0x8233, 0xE332, + 0x4755, 0x8233, 0xE333, + 0x4756, 0x8233, 0xE334, + 0x4757, 0x8233, 0xE335, + 0x4758, 0x8233, 0xE336, + 0x4759, 0x8233, 0xE337, + 0x475A, 0x8233, 0xE338, + 0x475B, 0x8233, 0xE339, + 0x475C, 0x8233, 0xE430, + 0x475D, 0x8233, 0xE431, + 0x475E, 0x8233, 0xE432, + 0x475F, 0x8233, 0xE433, + 0x4760, 0x8233, 0xE434, + 0x4761, 0x8233, 0xE435, + 0x4762, 0x8233, 0xE436, + 0x4763, 0x8233, 0xE437, + 0x4764, 0x8233, 0xE438, + 0x4765, 0x8233, 0xE439, + 0x4766, 0x8233, 0xE530, + 0x4767, 0x8233, 0xE531, + 0x4768, 0x8233, 0xE532, + 0x4769, 0x8233, 0xE533, + 0x476A, 0x8233, 0xE534, + 0x476B, 0x8233, 0xE535, + 0x476C, 0x8233, 0xE536, + 0x476D, 0x8233, 0xE537, + 0x476E, 0x8233, 0xE538, + 0x476F, 0x8233, 0xE539, + 0x4770, 0x8233, 0xE630, + 0x4771, 0x8233, 0xE631, + 0x4772, 0x8233, 0xE632, + 0x4773, 0x8233, 0xE633, + 0x4774, 0x8233, 0xE634, + 0x4775, 0x8233, 0xE635, + 0x4776, 0x8233, 0xE636, + 0x4777, 0x8233, 0xE637, + 0x4778, 0x8233, 0xE638, + 0x4779, 0x8233, 0xE639, + 0x477A, 0x8233, 0xE730, + 0x477B, 0x8233, 0xE731, + 0x477D, 0x8233, 0xE732, + 0x477E, 0x8233, 0xE733, + 0x477F, 0x8233, 0xE734, + 0x4780, 0x8233, 0xE735, + 0x4781, 0x8233, 0xE736, + 0x4782, 0x8233, 0xE737, + 0x4783, 0x8233, 0xE738, + 0x4784, 0x8233, 0xE739, + 0x4785, 0x8233, 0xE830, + 0x4786, 0x8233, 0xE831, + 0x4787, 0x8233, 0xE832, + 0x4788, 0x8233, 0xE833, + 0x4789, 0x8233, 0xE834, + 0x478A, 0x8233, 0xE835, + 0x478B, 0x8233, 0xE836, + 0x478C, 0x8233, 0xE837, + 0x4948, 0x8234, 0x9639, + 0x4949, 0x8234, 0x9730, + 0x494A, 0x8234, 0x9731, + 0x494B, 0x8234, 0x9732, + 0x494C, 0x8234, 0x9733, + 0x494D, 0x8234, 0x9734, + 0x494E, 0x8234, 0x9735, + 0x494F, 0x8234, 0x9736, + 0x4950, 0x8234, 0x9737, + 0x4951, 0x8234, 0x9738, + 0x4952, 0x8234, 0x9739, + 0x4953, 0x8234, 0x9830, + 0x4954, 0x8234, 0x9831, + 0x4955, 0x8234, 0x9832, + 0x4956, 0x8234, 0x9833, + 0x4957, 0x8234, 0x9834, + 0x4958, 0x8234, 0x9835, + 0x4959, 0x8234, 0x9836, + 0x495A, 0x8234, 0x9837, + 0x495B, 0x8234, 0x9838, + 0x495C, 0x8234, 0x9839, + 0x495D, 0x8234, 0x9930, + 0x495E, 0x8234, 0x9931, + 0x495F, 0x8234, 0x9932, + 0x4960, 0x8234, 0x9933, + 0x4961, 0x8234, 0x9934, + 0x4962, 0x8234, 0x9935, + 0x4963, 0x8234, 0x9936, + 0x4964, 0x8234, 0x9937, + 0x4965, 0x8234, 0x9938, + 0x4966, 0x8234, 0x9939, + 0x4967, 0x8234, 0x9A30, + 0x4968, 0x8234, 0x9A31, + 0x4969, 0x8234, 0x9A32, + 0x496A, 0x8234, 0x9A33, + 0x496B, 0x8234, 0x9A34, + 0x496C, 0x8234, 0x9A35, + 0x496D, 0x8234, 0x9A36, + 0x496E, 0x8234, 0x9A37, + 0x496F, 0x8234, 0x9A38, + 0x4970, 0x8234, 0x9A39, + 0x4971, 0x8234, 0x9B30, + 0x4972, 0x8234, 0x9B31, + 0x4973, 0x8234, 0x9B32, + 0x4974, 0x8234, 0x9B33, + 0x4975, 0x8234, 0x9B34, + 0x4976, 0x8234, 0x9B35, + 0x4977, 0x8234, 0x9B36, + 0x4978, 0x8234, 0x9B37, + 0x4979, 0x8234, 0x9B38, + 0x497B, 0x8234, 0x9B39, + 0x497C, 0x8234, 0x9C30, + 0x497E, 0x8234, 0x9C31, + 0x497F, 0x8234, 0x9C32, + 0x4980, 0x8234, 0x9C33, + 0x4981, 0x8234, 0x9C34, + 0x4984, 0x8234, 0x9C35, + 0x4987, 0x8234, 0x9C36, + 0x4988, 0x8234, 0x9C37, + 0x4989, 0x8234, 0x9C38, + 0x498A, 0x8234, 0x9C39, + 0x498B, 0x8234, 0x9D30, + 0x498C, 0x8234, 0x9D31, + 0x498D, 0x8234, 0x9D32, + 0x498E, 0x8234, 0x9D33, + 0x498F, 0x8234, 0x9D34, + 0x4990, 0x8234, 0x9D35, + 0x4991, 0x8234, 0x9D36, + 0x4992, 0x8234, 0x9D37, + 0x4993, 0x8234, 0x9D38, + 0x4994, 0x8234, 0x9D39, + 0x4995, 0x8234, 0x9E30, + 0x4996, 0x8234, 0x9E31, + 0x4997, 0x8234, 0x9E32, + 0x4998, 0x8234, 0x9E33, + 0x4999, 0x8234, 0x9E34, + 0x499A, 0x8234, 0x9E35, + 0x499C, 0x8234, 0x9E36, + 0x499D, 0x8234, 0x9E37, + 0x499E, 0x8234, 0x9E38, + 0x49A0, 0x8234, 0x9E39, + 0x49A1, 0x8234, 0x9F30, + 0x49A2, 0x8234, 0x9F31, + 0x49A3, 0x8234, 0x9F32, + 0x49A4, 0x8234, 0x9F33, + 0x49A5, 0x8234, 0x9F34, + 0x49A6, 0x8234, 0x9F35, + 0x49A7, 0x8234, 0x9F36, + 0x49A8, 0x8234, 0x9F37, + 0x49A9, 0x8234, 0x9F38, + 0x49AA, 0x8234, 0x9F39, + 0x49AB, 0x8234, 0xA030, + 0x49AC, 0x8234, 0xA031, + 0x49AD, 0x8234, 0xA032, + 0x49AE, 0x8234, 0xA033, + 0x49AF, 0x8234, 0xA034, + 0x49B0, 0x8234, 0xA035, + 0x49B1, 0x8234, 0xA036, + 0x49B2, 0x8234, 0xA037, + 0x49B3, 0x8234, 0xA038, + 0x49B4, 0x8234, 0xA039, + 0x49B5, 0x8234, 0xA130, + 0x4C78, 0x8234, 0xE734, + 0x4C79, 0x8234, 0xE735, + 0x4C7A, 0x8234, 0xE736, + 0x4C7B, 0x8234, 0xE737, + 0x4C7C, 0x8234, 0xE738, + 0x4C7D, 0x8234, 0xE739, + 0x4C7E, 0x8234, 0xE830, + 0x4C7F, 0x8234, 0xE831, + 0x4C80, 0x8234, 0xE832, + 0x4C81, 0x8234, 0xE833, + 0x4C82, 0x8234, 0xE834, + 0x4C83, 0x8234, 0xE835, + 0x4C84, 0x8234, 0xE836, + 0x4C85, 0x8234, 0xE837, + 0x4C86, 0x8234, 0xE838, + 0x4C87, 0x8234, 0xE839, + 0x4C88, 0x8234, 0xE930, + 0x4C89, 0x8234, 0xE931, + 0x4C8A, 0x8234, 0xE932, + 0x4C8B, 0x8234, 0xE933, + 0x4C8C, 0x8234, 0xE934, + 0x4C8D, 0x8234, 0xE935, + 0x4C8E, 0x8234, 0xE936, + 0x4C8F, 0x8234, 0xE937, + 0x4C90, 0x8234, 0xE938, + 0x4C91, 0x8234, 0xE939, + 0x4C92, 0x8234, 0xEA30, + 0x4C93, 0x8234, 0xEA31, + 0x4C94, 0x8234, 0xEA32, + 0x4C95, 0x8234, 0xEA33, + 0x4C96, 0x8234, 0xEA34, + 0x4C97, 0x8234, 0xEA35, + 0x4C98, 0x8234, 0xEA36, + 0x4C99, 0x8234, 0xEA37, + 0x4C9A, 0x8234, 0xEA38, + 0x4C9B, 0x8234, 0xEA39, + 0x4C9C, 0x8234, 0xEB30, + 0x4C9D, 0x8234, 0xEB31, + 0x4C9E, 0x8234, 0xEB32, + 0x4CA4, 0x8234, 0xEB33, + 0x4CA5, 0x8234, 0xEB34, + 0x4CA6, 0x8234, 0xEB35, + 0x4CA7, 0x8234, 0xEB36, + 0x4CA8, 0x8234, 0xEB37, + 0x4CA9, 0x8234, 0xEB38, + 0x4CAA, 0x8234, 0xEB39, + 0x4CAB, 0x8234, 0xEC30, + 0x4CAC, 0x8234, 0xEC31, + 0x4CAD, 0x8234, 0xEC32, + 0x4CAE, 0x8234, 0xEC33, + 0x4CAF, 0x8234, 0xEC34, + 0x4CB0, 0x8234, 0xEC35, + 0x4CB1, 0x8234, 0xEC36, + 0x4CB2, 0x8234, 0xEC37, + 0x4CB3, 0x8234, 0xEC38, + 0x4CB4, 0x8234, 0xEC39, + 0x4CB5, 0x8234, 0xED30, + 0x4CB6, 0x8234, 0xED31, + 0x4CB7, 0x8234, 0xED32, + 0x4CB8, 0x8234, 0xED33, + 0x4CB9, 0x8234, 0xED34, + 0x4CBA, 0x8234, 0xED35, + 0x4CBB, 0x8234, 0xED36, + 0x4CBC, 0x8234, 0xED37, + 0x4CBD, 0x8234, 0xED38, + 0x4CBE, 0x8234, 0xED39, + 0x4CBF, 0x8234, 0xEE30, + 0x4CC0, 0x8234, 0xEE31, + 0x4CC1, 0x8234, 0xEE32, + 0x4CC2, 0x8234, 0xEE33, + 0x4CC3, 0x8234, 0xEE34, + 0x4CC4, 0x8234, 0xEE35, + 0x4CC5, 0x8234, 0xEE36, + 0x4CC6, 0x8234, 0xEE37, + 0x4CC7, 0x8234, 0xEE38, + 0x4CC8, 0x8234, 0xEE39, + 0x4CC9, 0x8234, 0xEF30, + 0x4CCA, 0x8234, 0xEF31, + 0x4CCB, 0x8234, 0xEF32, + 0x4CCC, 0x8234, 0xEF33, + 0x4CCD, 0x8234, 0xEF34, + 0x4CCE, 0x8234, 0xEF35, + 0x4CCF, 0x8234, 0xEF36, + 0x4CD0, 0x8234, 0xEF37, + 0x4CD1, 0x8234, 0xEF38, + 0x4CD2, 0x8234, 0xEF39, + 0x4CD3, 0x8234, 0xF030, + 0x4CD4, 0x8234, 0xF031, + 0x4CD5, 0x8234, 0xF032, + 0x4CD6, 0x8234, 0xF033, + 0x4CD7, 0x8234, 0xF034, + 0x4CD8, 0x8234, 0xF035, + 0x4CD9, 0x8234, 0xF036, + 0x4CDA, 0x8234, 0xF037, + 0x4CDB, 0x8234, 0xF038, + 0x4CDC, 0x8234, 0xF039, + 0x4CDD, 0x8234, 0xF130, + 0x4CDE, 0x8234, 0xF131, + 0x4CDF, 0x8234, 0xF132, + 0x4CE0, 0x8234, 0xF133, + 0x4CE1, 0x8234, 0xF134, + 0x4CE2, 0x8234, 0xF135, + 0x4CE3, 0x8234, 0xF136, + 0x4CE4, 0x8234, 0xF137, + 0x4CE5, 0x8234, 0xF138, + 0x4CE6, 0x8234, 0xF139, + 0x4CE7, 0x8234, 0xF230, + 0x4CE8, 0x8234, 0xF231, + 0x4CE9, 0x8234, 0xF232, + 0x4CEA, 0x8234, 0xF233, + 0x4CEB, 0x8234, 0xF234, + 0x4CEC, 0x8234, 0xF235, + 0x4CED, 0x8234, 0xF236, + 0x4CEE, 0x8234, 0xF237, + 0x4CEF, 0x8234, 0xF238, + 0x4CF0, 0x8234, 0xF239, + 0x4CF1, 0x8234, 0xF330, + 0x4CF2, 0x8234, 0xF331, + 0x4CF3, 0x8234, 0xF332, + 0x4CF4, 0x8234, 0xF333, + 0x4CF5, 0x8234, 0xF334, + 0x4CF6, 0x8234, 0xF335, + 0x4CF7, 0x8234, 0xF336, + 0x4CF8, 0x8234, 0xF337, + 0x4CF9, 0x8234, 0xF338, + 0x4CFA, 0x8234, 0xF339, + 0x4CFB, 0x8234, 0xF430, + 0x4CFC, 0x8234, 0xF431, + 0x4CFD, 0x8234, 0xF432, + 0x4CFE, 0x8234, 0xF433, + 0x4CFF, 0x8234, 0xF434, + 0x4D00, 0x8234, 0xF435, + 0x4D01, 0x8234, 0xF436, + 0x4D02, 0x8234, 0xF437, + 0x4D03, 0x8234, 0xF438, + 0x4D04, 0x8234, 0xF439, + 0x4D05, 0x8234, 0xF530, + 0x4D06, 0x8234, 0xF531, + 0x4D07, 0x8234, 0xF532, + 0x4D08, 0x8234, 0xF533, + 0x4D09, 0x8234, 0xF534, + 0x4D0A, 0x8234, 0xF535, + 0x4D0B, 0x8234, 0xF536, + 0x4D0C, 0x8234, 0xF537, + 0x4D0D, 0x8234, 0xF538, + 0x4D0E, 0x8234, 0xF539, + 0x4D0F, 0x8234, 0xF630, + 0x4D10, 0x8234, 0xF631, + 0x4D11, 0x8234, 0xF632, + 0x4D12, 0x8234, 0xF633, + 0x4D1A, 0x8234, 0xF634, + 0x4D1B, 0x8234, 0xF635, + 0x4D1C, 0x8234, 0xF636, + 0x4D1D, 0x8234, 0xF637, + 0x4D1E, 0x8234, 0xF638, + 0x4D1F, 0x8234, 0xF639, + 0x4D20, 0x8234, 0xF730, + 0x4D21, 0x8234, 0xF731, + 0x4D22, 0x8234, 0xF732, + 0x4D23, 0x8234, 0xF733, + 0x4D24, 0x8234, 0xF734, + 0x4D25, 0x8234, 0xF735, + 0x4D26, 0x8234, 0xF736, + 0x4D27, 0x8234, 0xF737, + 0x4D28, 0x8234, 0xF738, + 0x4D29, 0x8234, 0xF739, + 0x4D2A, 0x8234, 0xF830, + 0x4D2B, 0x8234, 0xF831, + 0x4D2C, 0x8234, 0xF832, + 0x4D2D, 0x8234, 0xF833, + 0x4D2E, 0x8234, 0xF834, + 0x4D2F, 0x8234, 0xF835, + 0x4D30, 0x8234, 0xF836, + 0x4D31, 0x8234, 0xF837, + 0x4D32, 0x8234, 0xF838, + 0x4D33, 0x8234, 0xF839, + 0x4D34, 0x8234, 0xF930, + 0x4D35, 0x8234, 0xF931, + 0x4D36, 0x8234, 0xF932, + 0x4D37, 0x8234, 0xF933, + 0x4D38, 0x8234, 0xF934, + 0x4D39, 0x8234, 0xF935, + 0x4D3A, 0x8234, 0xF936, + 0x4D3B, 0x8234, 0xF937, + 0x4D3C, 0x8234, 0xF938, + 0x4D3D, 0x8234, 0xF939, + 0x4D3E, 0x8234, 0xFA30, + 0x4D3F, 0x8234, 0xFA31, + 0x4D40, 0x8234, 0xFA32, + 0x4D41, 0x8234, 0xFA33, + 0x4D42, 0x8234, 0xFA34, + 0x4D43, 0x8234, 0xFA35, + 0x4D44, 0x8234, 0xFA36, + 0x4D45, 0x8234, 0xFA37, + 0x4D46, 0x8234, 0xFA38, + 0x4D47, 0x8234, 0xFA39, + 0x4D48, 0x8234, 0xFB30, + 0x4D49, 0x8234, 0xFB31, + 0x4D4A, 0x8234, 0xFB32, + 0x4D4B, 0x8234, 0xFB33, + 0x4D4C, 0x8234, 0xFB34, + 0x4D4D, 0x8234, 0xFB35, + 0x4D4E, 0x8234, 0xFB36, + 0x4D4F, 0x8234, 0xFB37, + 0x4D50, 0x8234, 0xFB38, + 0x4D51, 0x8234, 0xFB39, + 0x4D52, 0x8234, 0xFC30, + 0x4D53, 0x8234, 0xFC31, + 0x4D54, 0x8234, 0xFC32, + 0x4D55, 0x8234, 0xFC33, + 0x4D56, 0x8234, 0xFC34, + 0x4D57, 0x8234, 0xFC35, + 0x4D58, 0x8234, 0xFC36, + 0x4D59, 0x8234, 0xFC37, + 0x4D5A, 0x8234, 0xFC38, + 0x4D5B, 0x8234, 0xFC39, + 0x4D5C, 0x8234, 0xFD30, + 0x4D5D, 0x8234, 0xFD31, + 0x4D5E, 0x8234, 0xFD32, + 0x4D5F, 0x8234, 0xFD33, + 0x4D60, 0x8234, 0xFD34, + 0x4D61, 0x8234, 0xFD35, + 0x4D62, 0x8234, 0xFD36, + 0x4D63, 0x8234, 0xFD37, + 0x4D64, 0x8234, 0xFD38, + 0x4D65, 0x8234, 0xFD39, + 0x4D66, 0x8234, 0xFE30, + 0x4D67, 0x8234, 0xFE31, + 0x4D68, 0x8234, 0xFE32, + 0x4D69, 0x8234, 0xFE33, + 0x4D6A, 0x8234, 0xFE34, + 0x4D6B, 0x8234, 0xFE35, + 0x4D6C, 0x8234, 0xFE36, + 0x4D6D, 0x8234, 0xFE37, + 0x4D6E, 0x8234, 0xFE38, + 0x4D6F, 0x8234, 0xFE39, + 0x4D70, 0x8235, 0x8130, + 0x4D71, 0x8235, 0x8131, + 0x4D72, 0x8235, 0x8132, + 0x4D73, 0x8235, 0x8133, + 0x4D74, 0x8235, 0x8134, + 0x4D75, 0x8235, 0x8135, + 0x4D76, 0x8235, 0x8136, + 0x4D77, 0x8235, 0x8137, + 0x4D78, 0x8235, 0x8138, + 0x4D79, 0x8235, 0x8139, + 0x4D7A, 0x8235, 0x8230, + 0x4D7B, 0x8235, 0x8231, + 0x4D7C, 0x8235, 0x8232, + 0x4D7D, 0x8235, 0x8233, + 0x4D7E, 0x8235, 0x8234, + 0x4D7F, 0x8235, 0x8235, + 0x4D80, 0x8235, 0x8236, + 0x4D81, 0x8235, 0x8237, + 0x4D82, 0x8235, 0x8238, + 0x4D83, 0x8235, 0x8239, + 0x4D84, 0x8235, 0x8330, + 0x4D85, 0x8235, 0x8331, + 0x4D86, 0x8235, 0x8332, + 0x4D87, 0x8235, 0x8333, + 0x4D88, 0x8235, 0x8334, + 0x4D89, 0x8235, 0x8335, + 0x4D8A, 0x8235, 0x8336, + 0x4D8B, 0x8235, 0x8337, + 0x4D8C, 0x8235, 0x8338, + 0x4D8D, 0x8235, 0x8339, + 0x4D8E, 0x8235, 0x8430, + 0x4D8F, 0x8235, 0x8431, + 0x4D90, 0x8235, 0x8432, + 0x4D91, 0x8235, 0x8433, + 0x4D92, 0x8235, 0x8434, + 0x4D93, 0x8235, 0x8435, + 0x4D94, 0x8235, 0x8436, + 0x4D95, 0x8235, 0x8437, + 0x4D96, 0x8235, 0x8438, + 0x4D97, 0x8235, 0x8439, + 0x4D98, 0x8235, 0x8530, + 0x4D99, 0x8235, 0x8531, + 0x4D9A, 0x8235, 0x8532, + 0x4D9B, 0x8235, 0x8533, + 0x4D9C, 0x8235, 0x8534, + 0x4D9D, 0x8235, 0x8535, + 0x4D9E, 0x8235, 0x8536, + 0x4D9F, 0x8235, 0x8537, + 0x4DA0, 0x8235, 0x8538, + 0x4DA1, 0x8235, 0x8539, + 0x4DA2, 0x8235, 0x8630, + 0x4DA3, 0x8235, 0x8631, + 0x4DA4, 0x8235, 0x8632, + 0x4DA5, 0x8235, 0x8633, + 0x4DA6, 0x8235, 0x8634, + 0x4DA7, 0x8235, 0x8635, + 0x4DA8, 0x8235, 0x8636, + 0x4DA9, 0x8235, 0x8637, + 0x4DAA, 0x8235, 0x8638, + 0x4DAB, 0x8235, 0x8639, + 0x4DAC, 0x8235, 0x8730, + 0x4DAD, 0x8235, 0x8731, + 0x4DAF, 0x8235, 0x8732, + 0x4DB0, 0x8235, 0x8733, + 0x4DB1, 0x8235, 0x8734, + 0x4DB2, 0x8235, 0x8735, + 0x4DB3, 0x8235, 0x8736, + 0x4DB4, 0x8235, 0x8737, + 0x4DB5, 0x8235, 0x8738, + 0x4DB6, 0x8235, 0x8739, + 0x4DB7, 0x8235, 0x8830, + 0x4DB8, 0x8235, 0x8831, + 0x4DB9, 0x8235, 0x8832, + 0x4DBA, 0x8235, 0x8833, + 0x4DBB, 0x8235, 0x8834, + 0x4DBC, 0x8235, 0x8835, + 0x4DBD, 0x8235, 0x8836, + 0x4DBE, 0x8235, 0x8837, + 0x4DBF, 0x8235, 0x8838, + 0x4DC0, 0x8235, 0x8839, + 0x4DC1, 0x8235, 0x8930, + 0x4DC2, 0x8235, 0x8931, + 0x4DC3, 0x8235, 0x8932, + 0x4DC4, 0x8235, 0x8933, + 0x4DC5, 0x8235, 0x8934, + 0x4DC6, 0x8235, 0x8935, + 0x4DC7, 0x8235, 0x8936, + 0x4DC8, 0x8235, 0x8937, + 0x4DC9, 0x8235, 0x8938, + 0x4DCA, 0x8235, 0x8939, + 0x4DCB, 0x8235, 0x8A30, + 0x4DCC, 0x8235, 0x8A31, + 0x4DCD, 0x8235, 0x8A32, + 0x4DCE, 0x8235, 0x8A33, + 0x4DCF, 0x8235, 0x8A34, + 0x4DD0, 0x8235, 0x8A35, + 0x4DD1, 0x8235, 0x8A36, + 0x4DD2, 0x8235, 0x8A37, + 0x4DD3, 0x8235, 0x8A38, + 0x4DD4, 0x8235, 0x8A39, + 0x4DD5, 0x8235, 0x8B30, + 0x4DD6, 0x8235, 0x8B31, + 0x4DD7, 0x8235, 0x8B32, + 0x4DD8, 0x8235, 0x8B33, + 0x4DD9, 0x8235, 0x8B34, + 0x4DDA, 0x8235, 0x8B35, + 0x4DDB, 0x8235, 0x8B36, + 0x4DDC, 0x8235, 0x8B37, + 0x4DDD, 0x8235, 0x8B38, + 0x4DDE, 0x8235, 0x8B39, + 0x4DDF, 0x8235, 0x8C30, + 0x4DE0, 0x8235, 0x8C31, + 0x4DE1, 0x8235, 0x8C32, + 0x4DE2, 0x8235, 0x8C33, + 0x4DE3, 0x8235, 0x8C34, + 0x4DE4, 0x8235, 0x8C35, + 0x4DE5, 0x8235, 0x8C36, + 0x4DE6, 0x8235, 0x8C37, + 0x4DE7, 0x8235, 0x8C38, + 0x4DE8, 0x8235, 0x8C39, + 0x4DE9, 0x8235, 0x8D30, + 0x4DEA, 0x8235, 0x8D31, + 0x4DEB, 0x8235, 0x8D32, + 0x4DEC, 0x8235, 0x8D33, + 0x4DED, 0x8235, 0x8D34, + 0x4DEE, 0x8235, 0x8D35, + 0x4DEF, 0x8235, 0x8D36, + 0x4DF0, 0x8235, 0x8D37, + 0x4DF1, 0x8235, 0x8D38, + 0x4DF2, 0x8235, 0x8D39, + 0x4DF3, 0x8235, 0x8E30, + 0x4DF4, 0x8235, 0x8E31, + 0x4DF5, 0x8235, 0x8E32, + 0x4DF6, 0x8235, 0x8E33, + 0x4DF7, 0x8235, 0x8E34, + 0x4DF8, 0x8235, 0x8E35, + 0x4DF9, 0x8235, 0x8E36, + 0x4DFA, 0x8235, 0x8E37, + 0x4DFB, 0x8235, 0x8E38, + 0x4DFC, 0x8235, 0x8E39, + 0x4DFD, 0x8235, 0x8F30, + 0x4DFE, 0x8235, 0x8F31, + 0x4DFF, 0x8235, 0x8F32, + 0xE76C, 0x8336, 0xC739, + 0xE7C8, 0x8336, 0xC830, + 0xE7E7, 0x8336, 0xC831, + 0xE7E8, 0x8336, 0xC832, + 0xE7E9, 0x8336, 0xC833, + 0xE7EA, 0x8336, 0xC834, + 0xE7EB, 0x8336, 0xC835, + 0xE7EC, 0x8336, 0xC836, + 0xE7ED, 0x8336, 0xC837, + 0xE7EE, 0x8336, 0xC838, + 0xE7EF, 0x8336, 0xC839, + 0xE7F0, 0x8336, 0xC930, + 0xE7F1, 0x8336, 0xC931, + 0xE7F2, 0x8336, 0xC932, + 0xE7F3, 0x8336, 0xC933, + 0xE815, 0x8336, 0xC934, + 0xE819, 0x8336, 0xC935, + 0xE81A, 0x8336, 0xC936, + 0xE81B, 0x8336, 0xC937, + 0xE81C, 0x8336, 0xC938, + 0xE81D, 0x8336, 0xC939, + 0xE81F, 0x8336, 0xCA30, + 0xE820, 0x8336, 0xCA31, + 0xE821, 0x8336, 0xCA32, + 0xE822, 0x8336, 0xCA33, + 0xE823, 0x8336, 0xCA34, + 0xE824, 0x8336, 0xCA35, + 0xE825, 0x8336, 0xCA36, + 0xE827, 0x8336, 0xCA37, + 0xE828, 0x8336, 0xCA38, + 0xE829, 0x8336, 0xCA39, + 0xE82A, 0x8336, 0xCB30, + 0xE82D, 0x8336, 0xCB31, + 0xE82E, 0x8336, 0xCB32, + 0xE82F, 0x8336, 0xCB33, + 0xE830, 0x8336, 0xCB34, + 0xE833, 0x8336, 0xCB35, + 0xE834, 0x8336, 0xCB36, + 0xE835, 0x8336, 0xCB37, + 0xE836, 0x8336, 0xCB38, + 0xE837, 0x8336, 0xCB39, + 0xE838, 0x8336, 0xCC30, + 0xE839, 0x8336, 0xCC31, + 0xE83A, 0x8336, 0xCC32, + 0xE83C, 0x8336, 0xCC33, + 0xE83D, 0x8336, 0xCC34, + 0xE83E, 0x8336, 0xCC35, + 0xE83F, 0x8336, 0xCC36, + 0xE840, 0x8336, 0xCC37, + 0xE841, 0x8336, 0xCC38, + 0xE842, 0x8336, 0xCC39, + 0xE844, 0x8336, 0xCD30, + 0xE845, 0x8336, 0xCD31, + 0xE846, 0x8336, 0xCD32, + 0xE847, 0x8336, 0xCD33, + 0xE848, 0x8336, 0xCD34, + 0xE849, 0x8336, 0xCD35, + 0xE84A, 0x8336, 0xCD36, + 0xE84B, 0x8336, 0xCD37, + 0xE84C, 0x8336, 0xCD38, + 0xE84D, 0x8336, 0xCD39, + 0xE84E, 0x8336, 0xCE30, + 0xE84F, 0x8336, 0xCE31, + 0xE850, 0x8336, 0xCE32, + 0xE851, 0x8336, 0xCE33, + 0xE852, 0x8336, 0xCE34, + 0xE853, 0x8336, 0xCE35, + 0xE856, 0x8336, 0xCE36, + 0xE857, 0x8336, 0xCE37, + 0xE858, 0x8336, 0xCE38, + 0xE859, 0x8336, 0xCE39, + 0xE85A, 0x8336, 0xCF30, + 0xE85B, 0x8336, 0xCF31, + 0xE85C, 0x8336, 0xCF32, + 0xE85D, 0x8336, 0xCF33, + 0xE85E, 0x8336, 0xCF34, + 0xE85F, 0x8336, 0xCF35, + 0xE860, 0x8336, 0xCF36, + 0xE861, 0x8336, 0xCF37, + 0xE862, 0x8336, 0xCF38, + 0xE863, 0x8336, 0xCF39, + 0xF92D, 0x8430, 0x8535, + 0xF92E, 0x8430, 0x8536, + 0xF92F, 0x8430, 0x8537, + 0xF930, 0x8430, 0x8538, + 0xF931, 0x8430, 0x8539, + 0xF932, 0x8430, 0x8630, + 0xF933, 0x8430, 0x8631, + 0xF934, 0x8430, 0x8632, + 0xF935, 0x8430, 0x8633, + 0xF936, 0x8430, 0x8634, + 0xF937, 0x8430, 0x8635, + 0xF938, 0x8430, 0x8636, + 0xF939, 0x8430, 0x8637, + 0xF93A, 0x8430, 0x8638, + 0xF93B, 0x8430, 0x8639, + 0xF93C, 0x8430, 0x8730, + 0xF93D, 0x8430, 0x8731, + 0xF93E, 0x8430, 0x8732, + 0xF93F, 0x8430, 0x8733, + 0xF940, 0x8430, 0x8734, + 0xF941, 0x8430, 0x8735, + 0xF942, 0x8430, 0x8736, + 0xF943, 0x8430, 0x8737, + 0xF944, 0x8430, 0x8738, + 0xF945, 0x8430, 0x8739, + 0xF946, 0x8430, 0x8830, + 0xF947, 0x8430, 0x8831, + 0xF948, 0x8430, 0x8832, + 0xF949, 0x8430, 0x8833, + 0xF94A, 0x8430, 0x8834, + 0xF94B, 0x8430, 0x8835, + 0xF94C, 0x8430, 0x8836, + 0xF94D, 0x8430, 0x8837, + 0xF94E, 0x8430, 0x8838, + 0xF94F, 0x8430, 0x8839, + 0xF950, 0x8430, 0x8930, + 0xF951, 0x8430, 0x8931, + 0xF952, 0x8430, 0x8932, + 0xF953, 0x8430, 0x8933, + 0xF954, 0x8430, 0x8934, + 0xF955, 0x8430, 0x8935, + 0xF956, 0x8430, 0x8936, + 0xF957, 0x8430, 0x8937, + 0xF958, 0x8430, 0x8938, + 0xF959, 0x8430, 0x8939, + 0xF95A, 0x8430, 0x8A30, + 0xF95B, 0x8430, 0x8A31, + 0xF95C, 0x8430, 0x8A32, + 0xF95D, 0x8430, 0x8A33, + 0xF95E, 0x8430, 0x8A34, + 0xF95F, 0x8430, 0x8A35, + 0xF960, 0x8430, 0x8A36, + 0xF961, 0x8430, 0x8A37, + 0xF962, 0x8430, 0x8A38, + 0xF963, 0x8430, 0x8A39, + 0xF964, 0x8430, 0x8B30, + 0xF965, 0x8430, 0x8B31, + 0xF966, 0x8430, 0x8B32, + 0xF967, 0x8430, 0x8B33, + 0xF968, 0x8430, 0x8B34, + 0xF969, 0x8430, 0x8B35, + 0xF96A, 0x8430, 0x8B36, + 0xF96B, 0x8430, 0x8B37, + 0xF96C, 0x8430, 0x8B38, + 0xF96D, 0x8430, 0x8B39, + 0xF96E, 0x8430, 0x8C30, + 0xF96F, 0x8430, 0x8C31, + 0xF970, 0x8430, 0x8C32, + 0xF971, 0x8430, 0x8C33, + 0xF972, 0x8430, 0x8C34, + 0xF973, 0x8430, 0x8C35, + 0xF974, 0x8430, 0x8C36, + 0xF975, 0x8430, 0x8C37, + 0xF976, 0x8430, 0x8C38, + 0xF977, 0x8430, 0x8C39, + 0xF978, 0x8430, 0x8D30, + 0xF97A, 0x8430, 0x8D31, + 0xF97B, 0x8430, 0x8D32, + 0xF97C, 0x8430, 0x8D33, + 0xF97D, 0x8430, 0x8D34, + 0xF97E, 0x8430, 0x8D35, + 0xF97F, 0x8430, 0x8D36, + 0xF980, 0x8430, 0x8D37, + 0xF981, 0x8430, 0x8D38, + 0xF982, 0x8430, 0x8D39, + 0xF983, 0x8430, 0x8E30, + 0xF984, 0x8430, 0x8E31, + 0xF985, 0x8430, 0x8E32, + 0xF986, 0x8430, 0x8E33, + 0xF987, 0x8430, 0x8E34, + 0xF988, 0x8430, 0x8E35, + 0xF989, 0x8430, 0x8E36, + 0xF98A, 0x8430, 0x8E37, + 0xF98B, 0x8430, 0x8E38, + 0xF98C, 0x8430, 0x8E39, + 0xF98D, 0x8430, 0x8F30, + 0xF98E, 0x8430, 0x8F31, + 0xF98F, 0x8430, 0x8F32, + 0xF990, 0x8430, 0x8F33, + 0xF991, 0x8430, 0x8F34, + 0xF992, 0x8430, 0x8F35, + 0xF993, 0x8430, 0x8F36, + 0xF994, 0x8430, 0x8F37, + 0xF996, 0x8430, 0x8F38, + 0xF997, 0x8430, 0x8F39, + 0xF998, 0x8430, 0x9030, + 0xF999, 0x8430, 0x9031, + 0xF99A, 0x8430, 0x9032, + 0xF99B, 0x8430, 0x9033, + 0xF99C, 0x8430, 0x9034, + 0xF99D, 0x8430, 0x9035, + 0xF99E, 0x8430, 0x9036, + 0xF99F, 0x8430, 0x9037, + 0xF9A0, 0x8430, 0x9038, + 0xF9A1, 0x8430, 0x9039, + 0xF9A2, 0x8430, 0x9130, + 0xF9A3, 0x8430, 0x9131, + 0xF9A4, 0x8430, 0x9132, + 0xF9A5, 0x8430, 0x9133, + 0xF9A6, 0x8430, 0x9134, + 0xF9A7, 0x8430, 0x9135, + 0xF9A8, 0x8430, 0x9136, + 0xF9A9, 0x8430, 0x9137, + 0xF9AA, 0x8430, 0x9138, + 0xF9AB, 0x8430, 0x9139, + 0xF9AC, 0x8430, 0x9230, + 0xF9AD, 0x8430, 0x9231, + 0xF9AE, 0x8430, 0x9232, + 0xF9AF, 0x8430, 0x9233, + 0xF9B0, 0x8430, 0x9234, + 0xF9B1, 0x8430, 0x9235, + 0xF9B2, 0x8430, 0x9236, + 0xF9B3, 0x8430, 0x9237, + 0xF9B4, 0x8430, 0x9238, + 0xF9B5, 0x8430, 0x9239, + 0xF9B6, 0x8430, 0x9330, + 0xF9B7, 0x8430, 0x9331, + 0xF9B8, 0x8430, 0x9332, + 0xF9B9, 0x8430, 0x9333, + 0xF9BA, 0x8430, 0x9334, + 0xF9BB, 0x8430, 0x9335, + 0xF9BC, 0x8430, 0x9336, + 0xF9BD, 0x8430, 0x9337, + 0xF9BE, 0x8430, 0x9338, + 0xF9BF, 0x8430, 0x9339, + 0xF9C0, 0x8430, 0x9430, + 0xF9C1, 0x8430, 0x9431, + 0xF9C2, 0x8430, 0x9432, + 0xF9C3, 0x8430, 0x9433, + 0xF9C4, 0x8430, 0x9434, + 0xF9C5, 0x8430, 0x9435, + 0xF9C6, 0x8430, 0x9436, + 0xF9C7, 0x8430, 0x9437, + 0xF9C8, 0x8430, 0x9438, + 0xF9C9, 0x8430, 0x9439, + 0xF9CA, 0x8430, 0x9530, + 0xF9CB, 0x8430, 0x9531, + 0xF9CC, 0x8430, 0x9532, + 0xF9CD, 0x8430, 0x9533, + 0xF9CE, 0x8430, 0x9534, + 0xF9CF, 0x8430, 0x9535, + 0xF9D0, 0x8430, 0x9536, + 0xF9D1, 0x8430, 0x9537, + 0xF9D2, 0x8430, 0x9538, + 0xF9D3, 0x8430, 0x9539, + 0xF9D4, 0x8430, 0x9630, + 0xF9D5, 0x8430, 0x9631, + 0xF9D6, 0x8430, 0x9632, + 0xF9D7, 0x8430, 0x9633, + 0xF9D8, 0x8430, 0x9634, + 0xF9D9, 0x8430, 0x9635, + 0xF9DA, 0x8430, 0x9636, + 0xF9DB, 0x8430, 0x9637, + 0xF9DC, 0x8430, 0x9638, + 0xF9DD, 0x8430, 0x9639, + 0xF9DE, 0x8430, 0x9730, + 0xF9DF, 0x8430, 0x9731, + 0xF9E0, 0x8430, 0x9732, + 0xF9E1, 0x8430, 0x9733, + 0xF9E2, 0x8430, 0x9734, + 0xF9E3, 0x8430, 0x9735, + 0xF9E4, 0x8430, 0x9736, + 0xF9E5, 0x8430, 0x9737, + 0xF9E6, 0x8430, 0x9738, + 0xF9E8, 0x8430, 0x9739, + 0xF9E9, 0x8430, 0x9830, + 0xF9EA, 0x8430, 0x9831, + 0xF9EB, 0x8430, 0x9832, + 0xF9EC, 0x8430, 0x9833, + 0xF9ED, 0x8430, 0x9834, + 0xF9EE, 0x8430, 0x9835, + 0xF9EF, 0x8430, 0x9836, + 0xF9F0, 0x8430, 0x9837, + 0xF9F2, 0x8430, 0x9838, + 0xF9F3, 0x8430, 0x9839, + 0xF9F4, 0x8430, 0x9930, + 0xF9F5, 0x8430, 0x9931, + 0xF9F6, 0x8430, 0x9932, + 0xF9F7, 0x8430, 0x9933, + 0xF9F8, 0x8430, 0x9934, + 0xF9F9, 0x8430, 0x9935, + 0xF9FA, 0x8430, 0x9936, + 0xF9FB, 0x8430, 0x9937, + 0xF9FC, 0x8430, 0x9938, + 0xF9FD, 0x8430, 0x9939, + 0xF9FE, 0x8430, 0x9A30, + 0xF9FF, 0x8430, 0x9A31, + 0xFA00, 0x8430, 0x9A32, + 0xFA01, 0x8430, 0x9A33, + 0xFA02, 0x8430, 0x9A34, + 0xFA03, 0x8430, 0x9A35, + 0xFA04, 0x8430, 0x9A36, + 0xFA05, 0x8430, 0x9A37, + 0xFA06, 0x8430, 0x9A38, + 0xFA07, 0x8430, 0x9A39, + 0xFA08, 0x8430, 0x9B30, + 0xFA09, 0x8430, 0x9B31, + 0xFA0A, 0x8430, 0x9B32, + 0xFA0B, 0x8430, 0x9B33, + 0xFA10, 0x8430, 0x9B34, + 0xFA12, 0x8430, 0x9B35, + 0xFA15, 0x8430, 0x9B36, + 0xFA16, 0x8430, 0x9B37, + 0xFA17, 0x8430, 0x9B38, + 0xFA19, 0x8430, 0x9B39, + 0xFA1A, 0x8430, 0x9C30, + 0xFA1B, 0x8430, 0x9C31, + 0xFA1C, 0x8430, 0x9C32, + 0xFA1D, 0x8430, 0x9C33, + 0xFA1E, 0x8430, 0x9C34, + 0xFA22, 0x8430, 0x9C35, + 0xFA25, 0x8430, 0x9C36, + 0xFA26, 0x8430, 0x9C37, + 0xFE32, 0x8431, 0x8538, + 0xFE45, 0x8431, 0x8539, + 0xFE46, 0x8431, 0x8630, + 0xFE47, 0x8431, 0x8631, + 0xFE48, 0x8431, 0x8632, + 0xFE53, 0x8431, 0x8633, + 0xFE58, 0x8431, 0x8634, + 0xFE67, 0x8431, 0x8635, + 0xFE6C, 0x8431, 0x8636, + 0xFE6D, 0x8431, 0x8637, + 0xFE6E, 0x8431, 0x8638, + 0xFE6F, 0x8431, 0x8639, + 0xFE70, 0x8431, 0x8730, + 0xFE71, 0x8431, 0x8731, + 0xFE72, 0x8431, 0x8732, + 0xFE73, 0x8431, 0x8733, + 0xFE74, 0x8431, 0x8734, + 0xFE75, 0x8431, 0x8735, + 0xFE76, 0x8431, 0x8736, + 0xFE77, 0x8431, 0x8737, + 0xFE78, 0x8431, 0x8738, + 0xFE79, 0x8431, 0x8739, + 0xFE7A, 0x8431, 0x8830, + 0xFE7B, 0x8431, 0x8831, + 0xFE7C, 0x8431, 0x8832, + 0xFE7D, 0x8431, 0x8833, + 0xFE7E, 0x8431, 0x8834, + 0xFE7F, 0x8431, 0x8835, + 0xFE80, 0x8431, 0x8836, + 0xFE81, 0x8431, 0x8837, + 0xFE82, 0x8431, 0x8838, + 0xFE83, 0x8431, 0x8839, + 0xFE84, 0x8431, 0x8930, + 0xFE85, 0x8431, 0x8931, + 0xFE86, 0x8431, 0x8932, + 0xFE87, 0x8431, 0x8933, + 0xFE88, 0x8431, 0x8934, + 0xFE89, 0x8431, 0x8935, + 0xFE8A, 0x8431, 0x8936, + 0xFE8B, 0x8431, 0x8937, + 0xFE8C, 0x8431, 0x8938, + 0xFE8D, 0x8431, 0x8939, + 0xFE8E, 0x8431, 0x8A30, + 0xFE8F, 0x8431, 0x8A31, + 0xFE90, 0x8431, 0x8A32, + 0xFE91, 0x8431, 0x8A33, + 0xFE92, 0x8431, 0x8A34, + 0xFE93, 0x8431, 0x8A35, + 0xFE94, 0x8431, 0x8A36, + 0xFE95, 0x8431, 0x8A37, + 0xFE96, 0x8431, 0x8A38, + 0xFE97, 0x8431, 0x8A39, + 0xFE98, 0x8431, 0x8B30, + 0xFE99, 0x8431, 0x8B31, + 0xFE9A, 0x8431, 0x8B32, + 0xFE9B, 0x8431, 0x8B33, + 0xFE9C, 0x8431, 0x8B34, + 0xFE9D, 0x8431, 0x8B35, + 0xFE9E, 0x8431, 0x8B36, + 0xFE9F, 0x8431, 0x8B37, + 0xFEA0, 0x8431, 0x8B38, + 0xFEA1, 0x8431, 0x8B39, + 0xFEA2, 0x8431, 0x8C30, + 0xFEA3, 0x8431, 0x8C31, + 0xFEA4, 0x8431, 0x8C32, + 0xFEA5, 0x8431, 0x8C33, + 0xFEA6, 0x8431, 0x8C34, + 0xFEA7, 0x8431, 0x8C35, + 0xFEA8, 0x8431, 0x8C36, + 0xFEA9, 0x8431, 0x8C37, + 0xFEAA, 0x8431, 0x8C38, + 0xFEAB, 0x8431, 0x8C39, + 0xFEAC, 0x8431, 0x8D30, + 0xFEAD, 0x8431, 0x8D31, + 0xFEAE, 0x8431, 0x8D32, + 0xFEAF, 0x8431, 0x8D33, + 0xFEB0, 0x8431, 0x8D34, + 0xFEB1, 0x8431, 0x8D35, + 0xFEB2, 0x8431, 0x8D36, + 0xFEB3, 0x8431, 0x8D37, + 0xFEB4, 0x8431, 0x8D38, + 0xFEB5, 0x8431, 0x8D39, + 0xFEB6, 0x8431, 0x8E30, + 0xFEB7, 0x8431, 0x8E31, + 0xFEB8, 0x8431, 0x8E32, + 0xFEB9, 0x8431, 0x8E33, + 0xFEBA, 0x8431, 0x8E34, + 0xFEBB, 0x8431, 0x8E35, + 0xFEBC, 0x8431, 0x8E36, + 0xFEBD, 0x8431, 0x8E37, + 0xFEBE, 0x8431, 0x8E38, + 0xFEBF, 0x8431, 0x8E39, + 0xFEC0, 0x8431, 0x8F30, + 0xFEC1, 0x8431, 0x8F31, + 0xFEC2, 0x8431, 0x8F32, + 0xFEC3, 0x8431, 0x8F33, + 0xFEC4, 0x8431, 0x8F34, + 0xFEC5, 0x8431, 0x8F35, + 0xFEC6, 0x8431, 0x8F36, + 0xFEC7, 0x8431, 0x8F37, + 0xFEC8, 0x8431, 0x8F38, + 0xFEC9, 0x8431, 0x8F39, + 0xFECA, 0x8431, 0x9030, + 0xFECB, 0x8431, 0x9031, + 0xFECC, 0x8431, 0x9032, + 0xFECD, 0x8431, 0x9033, + 0xFECE, 0x8431, 0x9034, + 0xFECF, 0x8431, 0x9035, + 0xFED0, 0x8431, 0x9036, + 0xFED1, 0x8431, 0x9037, + 0xFED2, 0x8431, 0x9038, + 0xFED3, 0x8431, 0x9039, + 0xFED4, 0x8431, 0x9130, + 0xFED5, 0x8431, 0x9131, + 0xFED6, 0x8431, 0x9132, + 0xFED7, 0x8431, 0x9133, + 0xFED8, 0x8431, 0x9134, + 0xFED9, 0x8431, 0x9135, + 0xFEDA, 0x8431, 0x9136, + 0xFEDB, 0x8431, 0x9137, + 0xFEDC, 0x8431, 0x9138, + 0xFEDD, 0x8431, 0x9139, + 0xFEDE, 0x8431, 0x9230, + 0xFEDF, 0x8431, 0x9231, + 0xFEE0, 0x8431, 0x9232, + 0xFEE1, 0x8431, 0x9233, + 0xFEE2, 0x8431, 0x9234, + 0xFEE3, 0x8431, 0x9235, + 0xFEE4, 0x8431, 0x9236, + 0xFEE5, 0x8431, 0x9237, + 0xFEE6, 0x8431, 0x9238, + 0xFEE7, 0x8431, 0x9239, + 0xFEE8, 0x8431, 0x9330, + 0xFEE9, 0x8431, 0x9331, + 0xFEEA, 0x8431, 0x9332, + 0xFEEB, 0x8431, 0x9333, + 0xFEEC, 0x8431, 0x9334, + 0xFEED, 0x8431, 0x9335, + 0xFEEE, 0x8431, 0x9336, + 0xFEEF, 0x8431, 0x9337, + 0xFEF0, 0x8431, 0x9338, + 0xFEF1, 0x8431, 0x9339, + 0xFEF2, 0x8431, 0x9430, + 0xFEF3, 0x8431, 0x9431, + 0xFEF4, 0x8431, 0x9432, + 0xFEF5, 0x8431, 0x9433, + 0xFEF6, 0x8431, 0x9434, + 0xFEF7, 0x8431, 0x9435, + 0xFEF8, 0x8431, 0x9436, + 0xFEF9, 0x8431, 0x9437, + 0xFEFA, 0x8431, 0x9438, + 0xFEFB, 0x8431, 0x9439, + 0xFEFC, 0x8431, 0x9530, + 0xFEFD, 0x8431, 0x9531, + 0xFEFE, 0x8431, 0x9532, + 0xFEFF, 0x8431, 0x9533, + 0xFF00, 0x8431, 0x9534, + 0xFF5F, 0x8431, 0x9535, + 0xFF60, 0x8431, 0x9536, + 0xFF61, 0x8431, 0x9537, + 0xFF62, 0x8431, 0x9538, + 0xFF63, 0x8431, 0x9539, + 0xFF64, 0x8431, 0x9630, + 0xFF65, 0x8431, 0x9631, + 0xFF66, 0x8431, 0x9632, + 0xFF67, 0x8431, 0x9633, + 0xFF68, 0x8431, 0x9634, + 0xFF69, 0x8431, 0x9635, + 0xFF6A, 0x8431, 0x9636, + 0xFF6B, 0x8431, 0x9637, + 0xFF6C, 0x8431, 0x9638, + 0xFF6D, 0x8431, 0x9639, + 0xFF6E, 0x8431, 0x9730, + 0xFF6F, 0x8431, 0x9731, + 0xFF70, 0x8431, 0x9732, + 0xFF71, 0x8431, 0x9733, + 0xFF72, 0x8431, 0x9734, + 0xFF73, 0x8431, 0x9735, + 0xFF74, 0x8431, 0x9736, + 0xFF75, 0x8431, 0x9737, + 0xFF76, 0x8431, 0x9738, + 0xFF77, 0x8431, 0x9739, + 0xFF78, 0x8431, 0x9830, + 0xFF79, 0x8431, 0x9831, + 0xFF7A, 0x8431, 0x9832, + 0xFF7B, 0x8431, 0x9833, + 0xFF7C, 0x8431, 0x9834, + 0xFF7D, 0x8431, 0x9835, + 0xFF7E, 0x8431, 0x9836, + 0xFF7F, 0x8431, 0x9837, + 0xFF80, 0x8431, 0x9838, + 0xFF81, 0x8431, 0x9839, + 0xFF82, 0x8431, 0x9930, + 0xFF83, 0x8431, 0x9931, + 0xFF84, 0x8431, 0x9932, + 0xFF85, 0x8431, 0x9933, + 0xFF86, 0x8431, 0x9934, + 0xFF87, 0x8431, 0x9935, + 0xFF88, 0x8431, 0x9936, + 0xFF89, 0x8431, 0x9937, + 0xFF8A, 0x8431, 0x9938, + 0xFF8B, 0x8431, 0x9939, + 0xFF8C, 0x8431, 0x9A30, + 0xFF8D, 0x8431, 0x9A31, + 0xFF8E, 0x8431, 0x9A32, + 0xFF8F, 0x8431, 0x9A33, + 0xFF90, 0x8431, 0x9A34, + 0xFF91, 0x8431, 0x9A35, + 0xFF92, 0x8431, 0x9A36, + 0xFF93, 0x8431, 0x9A37, + 0xFF94, 0x8431, 0x9A38, + 0xFF95, 0x8431, 0x9A39, + 0xFF96, 0x8431, 0x9B30, + 0xFF97, 0x8431, 0x9B31, + 0xFF98, 0x8431, 0x9B32, + 0xFF99, 0x8431, 0x9B33, + 0xFF9A, 0x8431, 0x9B34, + 0xFF9B, 0x8431, 0x9B35, + 0xFF9C, 0x8431, 0x9B36, + 0xFF9D, 0x8431, 0x9B37, + 0xFF9E, 0x8431, 0x9B38, + 0xFF9F, 0x8431, 0x9B39, + 0xFFA0, 0x8431, 0x9C30, + 0xFFA1, 0x8431, 0x9C31, + 0xFFA2, 0x8431, 0x9C32, + 0xFFA3, 0x8431, 0x9C33, + 0xFFA4, 0x8431, 0x9C34, + 0xFFA5, 0x8431, 0x9C35, + 0xFFA6, 0x8431, 0x9C36, + 0xFFA7, 0x8431, 0x9C37, + 0xFFA8, 0x8431, 0x9C38, + 0xFFA9, 0x8431, 0x9C39, + 0xFFAA, 0x8431, 0x9D30, + 0xFFAB, 0x8431, 0x9D31, + 0xFFAC, 0x8431, 0x9D32, + 0xFFAD, 0x8431, 0x9D33, + 0xFFAE, 0x8431, 0x9D34, + 0xFFAF, 0x8431, 0x9D35, + 0xFFB0, 0x8431, 0x9D36, + 0xFFB1, 0x8431, 0x9D37, + 0xFFB2, 0x8431, 0x9D38, + 0xFFB3, 0x8431, 0x9D39, + 0xFFB4, 0x8431, 0x9E30, + 0xFFB5, 0x8431, 0x9E31, + 0xFFB6, 0x8431, 0x9E32, + 0xFFB7, 0x8431, 0x9E33, + 0xFFB8, 0x8431, 0x9E34, + 0xFFB9, 0x8431, 0x9E35, + 0xFFBA, 0x8431, 0x9E36, + 0xFFBB, 0x8431, 0x9E37, + 0xFFBC, 0x8431, 0x9E38, + 0xFFBD, 0x8431, 0x9E39, + 0xFFBE, 0x8431, 0x9F30, + 0xFFBF, 0x8431, 0x9F31, + 0xFFC0, 0x8431, 0x9F32, + 0xFFC1, 0x8431, 0x9F33, + 0xFFC2, 0x8431, 0x9F34, + 0xFFC3, 0x8431, 0x9F35, + 0xFFC4, 0x8431, 0x9F36, + 0xFFC5, 0x8431, 0x9F37, + 0xFFC6, 0x8431, 0x9F38, + 0xFFC7, 0x8431, 0x9F39, + 0xFFC8, 0x8431, 0xA030, + 0xFFC9, 0x8431, 0xA031, + 0xFFCA, 0x8431, 0xA032, + 0xFFCB, 0x8431, 0xA033, + 0xFFCC, 0x8431, 0xA034, + 0xFFCD, 0x8431, 0xA035, + 0xFFCE, 0x8431, 0xA036, + 0xFFCF, 0x8431, 0xA037, + 0xFFD0, 0x8431, 0xA038, + 0xFFD1, 0x8431, 0xA039, + 0xFFD2, 0x8431, 0xA130, + 0xFFD3, 0x8431, 0xA131, + 0xFFD4, 0x8431, 0xA132, + 0xFFD5, 0x8431, 0xA133, + 0xFFD6, 0x8431, 0xA134, + 0xFFD7, 0x8431, 0xA135, + 0xFFD8, 0x8431, 0xA136, + 0xFFD9, 0x8431, 0xA137, + 0xFFDA, 0x8431, 0xA138, + 0xFFDB, 0x8431, 0xA139, + 0xFFDC, 0x8431, 0xA230, + 0xFFDD, 0x8431, 0xA231, + 0xFFDE, 0x8431, 0xA232, + 0xFFDF, 0x8431, 0xA233 +}; \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/gb2312.h b/3rdparty/zint-2.6.1/backend/gb2312.h new file mode 100644 index 0000000..56cc4b2 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gb2312.h @@ -0,0 +1,7478 @@ +/* gb2312.h - Unicode to GB 2312-1980 lookup table + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +static const unsigned short int gb2312_lookup[] = { + 0x00A4, 0xA1E8, + 0x00A7, 0xA1EC, + 0x00A8, 0xA1A7, + 0x00B0, 0xA1E3, + 0x00B1, 0xA1C0, + 0x00B7, 0xA1A4, + 0x00D7, 0xA1C1, + 0x00E0, 0xA8A4, + 0x00E1, 0xA8A2, + 0x00E8, 0xA8A8, + 0x00E9, 0xA8A6, + 0x00EA, 0xA8BA, + 0x00EC, 0xA8AC, + 0x00ED, 0xA8AA, + 0x00F2, 0xA8B0, + 0x00F3, 0xA8AE, + 0x00F7, 0xA1C2, + 0x00F9, 0xA8B4, + 0x00FA, 0xA8B2, + 0x00FC, 0xA8B9, + 0x0101, 0xA8A1, + 0x0113, 0xA8A5, + 0x011B, 0xA8A7, + 0x012B, 0xA8A9, + 0x014D, 0xA8AD, + 0x016B, 0xA8B1, + 0x01CE, 0xA8A3, + 0x01D0, 0xA8AB, + 0x01D2, 0xA8AF, + 0x01D4, 0xA8B3, + 0x01D6, 0xA8B5, + 0x01D8, 0xA8B6, + 0x01DA, 0xA8B7, + 0x01DC, 0xA8B8, + 0x02C7, 0xA1A6, + 0x02C9, 0xA1A5, + 0x0391, 0xA6A1, + 0x0392, 0xA6A2, + 0x0393, 0xA6A3, + 0x0394, 0xA6A4, + 0x0395, 0xA6A5, + 0x0396, 0xA6A6, + 0x0397, 0xA6A7, + 0x0398, 0xA6A8, + 0x0399, 0xA6A9, + 0x039A, 0xA6AA, + 0x039B, 0xA6AB, + 0x039C, 0xA6AC, + 0x039D, 0xA6AD, + 0x039E, 0xA6AE, + 0x039F, 0xA6AF, + 0x03A0, 0xA6B0, + 0x03A1, 0xA6B1, + 0x03A3, 0xA6B2, + 0x03A4, 0xA6B3, + 0x03A5, 0xA6B4, + 0x03A6, 0xA6B5, + 0x03A7, 0xA6B6, + 0x03A8, 0xA6B7, + 0x03A9, 0xA6B8, + 0x03B1, 0xA6C1, + 0x03B2, 0xA6C2, + 0x03B3, 0xA6C3, + 0x03B4, 0xA6C4, + 0x03B5, 0xA6C5, + 0x03B6, 0xA6C6, + 0x03B7, 0xA6C7, + 0x03B8, 0xA6C8, + 0x03B9, 0xA6C9, + 0x03BA, 0xA6CA, + 0x03BB, 0xA6CB, + 0x03BC, 0xA6CC, + 0x03BD, 0xA6CD, + 0x03BE, 0xA6CE, + 0x03BF, 0xA6CF, + 0x03C0, 0xA6D0, + 0x03C1, 0xA6D1, + 0x03C3, 0xA6D2, + 0x03C4, 0xA6D3, + 0x03C5, 0xA6D4, + 0x03C6, 0xA6D5, + 0x03C7, 0xA6D6, + 0x03C8, 0xA6D7, + 0x03C9, 0xA6D8, + 0x0401, 0xA7A7, + 0x0410, 0xA7A1, + 0x0411, 0xA7A2, + 0x0412, 0xA7A3, + 0x0413, 0xA7A4, + 0x0414, 0xA7A5, + 0x0415, 0xA7A6, + 0x0416, 0xA7A8, + 0x0417, 0xA7A9, + 0x0418, 0xA7AA, + 0x0419, 0xA7AB, + 0x041A, 0xA7AC, + 0x041B, 0xA7AD, + 0x041C, 0xA7AE, + 0x041D, 0xA7AF, + 0x041E, 0xA7B0, + 0x041F, 0xA7B1, + 0x0420, 0xA7B2, + 0x0421, 0xA7B3, + 0x0422, 0xA7B4, + 0x0423, 0xA7B5, + 0x0424, 0xA7B6, + 0x0425, 0xA7B7, + 0x0426, 0xA7B8, + 0x0427, 0xA7B9, + 0x0428, 0xA7BA, + 0x0429, 0xA7BB, + 0x042A, 0xA7BC, + 0x042B, 0xA7BD, + 0x042C, 0xA7BE, + 0x042D, 0xA7BF, + 0x042E, 0xA7C0, + 0x042F, 0xA7C1, + 0x0430, 0xA7D1, + 0x0431, 0xA7D2, + 0x0432, 0xA7D3, + 0x0433, 0xA7D4, + 0x0434, 0xA7D5, + 0x0435, 0xA7D6, + 0x0436, 0xA7D8, + 0x0437, 0xA7D9, + 0x0438, 0xA7DA, + 0x0439, 0xA7DB, + 0x043A, 0xA7DC, + 0x043B, 0xA7DD, + 0x043C, 0xA7DE, + 0x043D, 0xA7DF, + 0x043E, 0xA7E0, + 0x043F, 0xA7E1, + 0x0440, 0xA7E2, + 0x0441, 0xA7E3, + 0x0442, 0xA7E4, + 0x0443, 0xA7E5, + 0x0444, 0xA7E6, + 0x0445, 0xA7E7, + 0x0446, 0xA7E8, + 0x0447, 0xA7E9, + 0x0448, 0xA7EA, + 0x0449, 0xA7EB, + 0x044A, 0xA7EC, + 0x044B, 0xA7ED, + 0x044C, 0xA7EE, + 0x044D, 0xA7EF, + 0x044E, 0xA7F0, + 0x044F, 0xA7F1, + 0x0451, 0xA7D7, + 0x2014, 0xA1AA, + 0x2016, 0xA1AC, + 0x2018, 0xA1AE, + 0x2019, 0xA1AF, + 0x201C, 0xA1B0, + 0x201D, 0xA1B1, + 0x2026, 0xA1AD, + 0x2030, 0xA1EB, + 0x2032, 0xA1E4, + 0x2033, 0xA1E5, + 0x203B, 0xA1F9, + 0x2103, 0xA1E6, + 0x2116, 0xA1ED, + 0x2160, 0xA2F1, + 0x2161, 0xA2F2, + 0x2162, 0xA2F3, + 0x2163, 0xA2F4, + 0x2164, 0xA2F5, + 0x2165, 0xA2F6, + 0x2166, 0xA2F7, + 0x2167, 0xA2F8, + 0x2168, 0xA2F9, + 0x2169, 0xA2FA, + 0x216A, 0xA2FB, + 0x216B, 0xA2FC, + 0x2190, 0xA1FB, + 0x2191, 0xA1FC, + 0x2192, 0xA1FA, + 0x2193, 0xA1FD, + 0x2208, 0xA1CA, + 0x220F, 0xA1C7, + 0x2211, 0xA1C6, + 0x221A, 0xA1CC, + 0x221D, 0xA1D8, + 0x221E, 0xA1DE, + 0x2220, 0xA1CF, + 0x2225, 0xA1CE, + 0x2227, 0xA1C4, + 0x2228, 0xA1C5, + 0x2229, 0xA1C9, + 0x222A, 0xA1C8, + 0x222B, 0xA1D2, + 0x222E, 0xA1D3, + 0x2234, 0xA1E0, + 0x2235, 0xA1DF, + 0x2236, 0xA1C3, + 0x2237, 0xA1CB, + 0x223D, 0xA1D7, + 0x2248, 0xA1D6, + 0x224C, 0xA1D5, + 0x2260, 0xA1D9, + 0x2261, 0xA1D4, + 0x2264, 0xA1DC, + 0x2265, 0xA1DD, + 0x226E, 0xA1DA, + 0x226F, 0xA1DB, + 0x2299, 0xA1D1, + 0x22A5, 0xA1CD, + 0x2312, 0xA1D0, + 0x2460, 0xA2D9, + 0x2461, 0xA2DA, + 0x2462, 0xA2DB, + 0x2463, 0xA2DC, + 0x2464, 0xA2DD, + 0x2465, 0xA2DE, + 0x2466, 0xA2DF, + 0x2467, 0xA2E0, + 0x2468, 0xA2E1, + 0x2469, 0xA2E2, + 0x2474, 0xA2C5, + 0x2475, 0xA2C6, + 0x2476, 0xA2C7, + 0x2477, 0xA2C8, + 0x2478, 0xA2C9, + 0x2479, 0xA2CA, + 0x247A, 0xA2CB, + 0x247B, 0xA2CC, + 0x247C, 0xA2CD, + 0x247D, 0xA2CE, + 0x247E, 0xA2CF, + 0x247F, 0xA2D0, + 0x2480, 0xA2D1, + 0x2481, 0xA2D2, + 0x2482, 0xA2D3, + 0x2483, 0xA2D4, + 0x2484, 0xA2D5, + 0x2485, 0xA2D6, + 0x2486, 0xA2D7, + 0x2487, 0xA2D8, + 0x2488, 0xA2B1, + 0x2489, 0xA2B2, + 0x248A, 0xA2B3, + 0x248B, 0xA2B4, + 0x248C, 0xA2B5, + 0x248D, 0xA2B6, + 0x248E, 0xA2B7, + 0x248F, 0xA2B8, + 0x2490, 0xA2B9, + 0x2491, 0xA2BA, + 0x2492, 0xA2BB, + 0x2493, 0xA2BC, + 0x2494, 0xA2BD, + 0x2495, 0xA2BE, + 0x2496, 0xA2BF, + 0x2497, 0xA2C0, + 0x2498, 0xA2C1, + 0x2499, 0xA2C2, + 0x249A, 0xA2C3, + 0x249B, 0xA2C4, + 0x2500, 0xA9A4, + 0x2501, 0xA9A5, + 0x2502, 0xA9A6, + 0x2503, 0xA9A7, + 0x2504, 0xA9A8, + 0x2505, 0xA9A9, + 0x2506, 0xA9AA, + 0x2507, 0xA9AB, + 0x2508, 0xA9AC, + 0x2509, 0xA9AD, + 0x250A, 0xA9AE, + 0x250B, 0xA9AF, + 0x250C, 0xA9B0, + 0x250D, 0xA9B1, + 0x250E, 0xA9B2, + 0x250F, 0xA9B3, + 0x2510, 0xA9B4, + 0x2511, 0xA9B5, + 0x2512, 0xA9B6, + 0x2513, 0xA9B7, + 0x2514, 0xA9B8, + 0x2515, 0xA9B9, + 0x2516, 0xA9BA, + 0x2517, 0xA9BB, + 0x2518, 0xA9BC, + 0x2519, 0xA9BD, + 0x251A, 0xA9BE, + 0x251B, 0xA9BF, + 0x251C, 0xA9C0, + 0x251D, 0xA9C1, + 0x251E, 0xA9C2, + 0x251F, 0xA9C3, + 0x2520, 0xA9C4, + 0x2521, 0xA9C5, + 0x2522, 0xA9C6, + 0x2523, 0xA9C7, + 0x2524, 0xA9C8, + 0x2525, 0xA9C9, + 0x2526, 0xA9CA, + 0x2527, 0xA9CB, + 0x2528, 0xA9CC, + 0x2529, 0xA9CD, + 0x252A, 0xA9CE, + 0x252B, 0xA9CF, + 0x252C, 0xA9D0, + 0x252D, 0xA9D1, + 0x252E, 0xA9D2, + 0x252F, 0xA9D3, + 0x2530, 0xA9D4, + 0x2531, 0xA9D5, + 0x2532, 0xA9D6, + 0x2533, 0xA9D7, + 0x2534, 0xA9D8, + 0x2535, 0xA9D9, + 0x2536, 0xA9DA, + 0x2537, 0xA9DB, + 0x2538, 0xA9DC, + 0x2539, 0xA9DD, + 0x253A, 0xA9DE, + 0x253B, 0xA9DF, + 0x253C, 0xA9E0, + 0x253D, 0xA9E1, + 0x253E, 0xA9E2, + 0x253F, 0xA9E3, + 0x2540, 0xA9E4, + 0x2541, 0xA9E5, + 0x2542, 0xA9E6, + 0x2543, 0xA9E7, + 0x2544, 0xA9E8, + 0x2545, 0xA9E9, + 0x2546, 0xA9EA, + 0x2547, 0xA9EB, + 0x2548, 0xA9EC, + 0x2549, 0xA9ED, + 0x254A, 0xA9EE, + 0x254B, 0xA9EF, + 0x25A0, 0xA1F6, + 0x25A1, 0xA1F5, + 0x25B2, 0xA1F8, + 0x25B3, 0xA1F7, + 0x25C6, 0xA1F4, + 0x25C7, 0xA1F3, + 0x25CB, 0xA1F0, + 0x25CE, 0xA1F2, + 0x25CF, 0xA1F1, + 0x2605, 0xA1EF, + 0x2606, 0xA1EE, + 0x2640, 0xA1E2, + 0x2642, 0xA1E1, + 0x3000, 0xA1A1, + 0x3001, 0xA1A2, + 0x3002, 0xA1A3, + 0x3003, 0xA1A8, + 0x3005, 0xA1A9, + 0x3008, 0xA1B4, + 0x3009, 0xA1B5, + 0x300A, 0xA1B6, + 0x300B, 0xA1B7, + 0x300C, 0xA1B8, + 0x300D, 0xA1B9, + 0x300E, 0xA1BA, + 0x300F, 0xA1BB, + 0x3010, 0xA1BE, + 0x3011, 0xA1BF, + 0x3013, 0xA1FE, + 0x3014, 0xA1B2, + 0x3015, 0xA1B3, + 0x3016, 0xA1BC, + 0x3017, 0xA1BD, + 0x3041, 0xA4A1, + 0x3042, 0xA4A2, + 0x3043, 0xA4A3, + 0x3044, 0xA4A4, + 0x3045, 0xA4A5, + 0x3046, 0xA4A6, + 0x3047, 0xA4A7, + 0x3048, 0xA4A8, + 0x3049, 0xA4A9, + 0x304A, 0xA4AA, + 0x304B, 0xA4AB, + 0x304C, 0xA4AC, + 0x304D, 0xA4AD, + 0x304E, 0xA4AE, + 0x304F, 0xA4AF, + 0x3050, 0xA4B0, + 0x3051, 0xA4B1, + 0x3052, 0xA4B2, + 0x3053, 0xA4B3, + 0x3054, 0xA4B4, + 0x3055, 0xA4B5, + 0x3056, 0xA4B6, + 0x3057, 0xA4B7, + 0x3058, 0xA4B8, + 0x3059, 0xA4B9, + 0x305A, 0xA4BA, + 0x305B, 0xA4BB, + 0x305C, 0xA4BC, + 0x305D, 0xA4BD, + 0x305E, 0xA4BE, + 0x305F, 0xA4BF, + 0x3060, 0xA4C0, + 0x3061, 0xA4C1, + 0x3062, 0xA4C2, + 0x3063, 0xA4C3, + 0x3064, 0xA4C4, + 0x3065, 0xA4C5, + 0x3066, 0xA4C6, + 0x3067, 0xA4C7, + 0x3068, 0xA4C8, + 0x3069, 0xA4C9, + 0x306A, 0xA4CA, + 0x306B, 0xA4CB, + 0x306C, 0xA4CC, + 0x306D, 0xA4CD, + 0x306E, 0xA4CE, + 0x306F, 0xA4CF, + 0x3070, 0xA4D0, + 0x3071, 0xA4D1, + 0x3072, 0xA4D2, + 0x3073, 0xA4D3, + 0x3074, 0xA4D4, + 0x3075, 0xA4D5, + 0x3076, 0xA4D6, + 0x3077, 0xA4D7, + 0x3078, 0xA4D8, + 0x3079, 0xA4D9, + 0x307A, 0xA4DA, + 0x307B, 0xA4DB, + 0x307C, 0xA4DC, + 0x307D, 0xA4DD, + 0x307E, 0xA4DE, + 0x307F, 0xA4DF, + 0x3080, 0xA4E0, + 0x3081, 0xA4E1, + 0x3082, 0xA4E2, + 0x3083, 0xA4E3, + 0x3084, 0xA4E4, + 0x3085, 0xA4E5, + 0x3086, 0xA4E6, + 0x3087, 0xA4E7, + 0x3088, 0xA4E8, + 0x3089, 0xA4E9, + 0x308A, 0xA4EA, + 0x308B, 0xA4EB, + 0x308C, 0xA4EC, + 0x308D, 0xA4ED, + 0x308E, 0xA4EE, + 0x308F, 0xA4EF, + 0x3090, 0xA4F0, + 0x3091, 0xA4F1, + 0x3092, 0xA4F2, + 0x3093, 0xA4F3, + 0x30A1, 0xA5A1, + 0x30A2, 0xA5A2, + 0x30A3, 0xA5A3, + 0x30A4, 0xA5A4, + 0x30A5, 0xA5A5, + 0x30A6, 0xA5A6, + 0x30A7, 0xA5A7, + 0x30A8, 0xA5A8, + 0x30A9, 0xA5A9, + 0x30AA, 0xA5AA, + 0x30AB, 0xA5AB, + 0x30AC, 0xA5AC, + 0x30AD, 0xA5AD, + 0x30AE, 0xA5AE, + 0x30AF, 0xA5AF, + 0x30B0, 0xA5B0, + 0x30B1, 0xA5B1, + 0x30B2, 0xA5B2, + 0x30B3, 0xA5B3, + 0x30B4, 0xA5B4, + 0x30B5, 0xA5B5, + 0x30B6, 0xA5B6, + 0x30B7, 0xA5B7, + 0x30B8, 0xA5B8, + 0x30B9, 0xA5B9, + 0x30BA, 0xA5BA, + 0x30BB, 0xA5BB, + 0x30BC, 0xA5BC, + 0x30BD, 0xA5BD, + 0x30BE, 0xA5BE, + 0x30BF, 0xA5BF, + 0x30C0, 0xA5C0, + 0x30C1, 0xA5C1, + 0x30C2, 0xA5C2, + 0x30C3, 0xA5C3, + 0x30C4, 0xA5C4, + 0x30C5, 0xA5C5, + 0x30C6, 0xA5C6, + 0x30C7, 0xA5C7, + 0x30C8, 0xA5C8, + 0x30C9, 0xA5C9, + 0x30CA, 0xA5CA, + 0x30CB, 0xA5CB, + 0x30CC, 0xA5CC, + 0x30CD, 0xA5CD, + 0x30CE, 0xA5CE, + 0x30CF, 0xA5CF, + 0x30D0, 0xA5D0, + 0x30D1, 0xA5D1, + 0x30D2, 0xA5D2, + 0x30D3, 0xA5D3, + 0x30D4, 0xA5D4, + 0x30D5, 0xA5D5, + 0x30D6, 0xA5D6, + 0x30D7, 0xA5D7, + 0x30D8, 0xA5D8, + 0x30D9, 0xA5D9, + 0x30DA, 0xA5DA, + 0x30DB, 0xA5DB, + 0x30DC, 0xA5DC, + 0x30DD, 0xA5DD, + 0x30DE, 0xA5DE, + 0x30DF, 0xA5DF, + 0x30E0, 0xA5E0, + 0x30E1, 0xA5E1, + 0x30E2, 0xA5E2, + 0x30E3, 0xA5E3, + 0x30E4, 0xA5E4, + 0x30E5, 0xA5E5, + 0x30E6, 0xA5E6, + 0x30E7, 0xA5E7, + 0x30E8, 0xA5E8, + 0x30E9, 0xA5E9, + 0x30EA, 0xA5EA, + 0x30EB, 0xA5EB, + 0x30EC, 0xA5EC, + 0x30ED, 0xA5ED, + 0x30EE, 0xA5EE, + 0x30EF, 0xA5EF, + 0x30F0, 0xA5F0, + 0x30F1, 0xA5F1, + 0x30F2, 0xA5F2, + 0x30F3, 0xA5F3, + 0x30F4, 0xA5F4, + 0x30F5, 0xA5F5, + 0x30F6, 0xA5F6, + 0x3105, 0xA8C5, + 0x3106, 0xA8C6, + 0x3107, 0xA8C7, + 0x3108, 0xA8C8, + 0x3109, 0xA8C9, + 0x310A, 0xA8CA, + 0x310B, 0xA8CB, + 0x310C, 0xA8CC, + 0x310D, 0xA8CD, + 0x310E, 0xA8CE, + 0x310F, 0xA8CF, + 0x3110, 0xA8D0, + 0x3111, 0xA8D1, + 0x3112, 0xA8D2, + 0x3113, 0xA8D3, + 0x3114, 0xA8D4, + 0x3115, 0xA8D5, + 0x3116, 0xA8D6, + 0x3117, 0xA8D7, + 0x3118, 0xA8D8, + 0x3119, 0xA8D9, + 0x311A, 0xA8DA, + 0x311B, 0xA8DB, + 0x311C, 0xA8DC, + 0x311D, 0xA8DD, + 0x311E, 0xA8DE, + 0x311F, 0xA8DF, + 0x3120, 0xA8E0, + 0x3121, 0xA8E1, + 0x3122, 0xA8E2, + 0x3123, 0xA8E3, + 0x3124, 0xA8E4, + 0x3125, 0xA8E5, + 0x3126, 0xA8E6, + 0x3127, 0xA8E7, + 0x3128, 0xA8E8, + 0x3129, 0xA8E9, + 0x3220, 0xA2E5, + 0x3221, 0xA2E6, + 0x3222, 0xA2E7, + 0x3223, 0xA2E8, + 0x3224, 0xA2E9, + 0x3225, 0xA2EA, + 0x3226, 0xA2EB, + 0x3227, 0xA2EC, + 0x3228, 0xA2ED, + 0x3229, 0xA2EE, + 0x4E00, 0xD2BB, + 0x4E01, 0xB6A1, + 0x4E03, 0xC6DF, + 0x4E07, 0xCDF2, + 0x4E08, 0xD5C9, + 0x4E09, 0xC8FD, + 0x4E0A, 0xC9CF, + 0x4E0B, 0xCFC2, + 0x4E0C, 0xD8A2, + 0x4E0D, 0xB2BB, + 0x4E0E, 0xD3EB, + 0x4E10, 0xD8A4, + 0x4E11, 0xB3F3, + 0x4E13, 0xD7A8, + 0x4E14, 0xC7D2, + 0x4E15, 0xD8A7, + 0x4E16, 0xCAC0, + 0x4E18, 0xC7F0, + 0x4E19, 0xB1FB, + 0x4E1A, 0xD2B5, + 0x4E1B, 0xB4D4, + 0x4E1C, 0xB6AB, + 0x4E1D, 0xCBBF, + 0x4E1E, 0xD8A9, + 0x4E22, 0xB6AA, + 0x4E24, 0xC1BD, + 0x4E25, 0xD1CF, + 0x4E27, 0xC9A5, + 0x4E28, 0xD8AD, + 0x4E2A, 0xB8F6, + 0x4E2B, 0xD1BE, + 0x4E2C, 0xE3DC, + 0x4E2D, 0xD6D0, + 0x4E30, 0xB7E1, + 0x4E32, 0xB4AE, + 0x4E34, 0xC1D9, + 0x4E36, 0xD8BC, + 0x4E38, 0xCDE8, + 0x4E39, 0xB5A4, + 0x4E3A, 0xCEAA, + 0x4E3B, 0xD6F7, + 0x4E3D, 0xC0F6, + 0x4E3E, 0xBED9, + 0x4E3F, 0xD8AF, + 0x4E43, 0xC4CB, + 0x4E45, 0xBEC3, + 0x4E47, 0xD8B1, + 0x4E48, 0xC3B4, + 0x4E49, 0xD2E5, + 0x4E4B, 0xD6AE, + 0x4E4C, 0xCEDA, + 0x4E4D, 0xD5A7, + 0x4E4E, 0xBAF5, + 0x4E4F, 0xB7A6, + 0x4E50, 0xC0D6, + 0x4E52, 0xC6B9, + 0x4E53, 0xC5D2, + 0x4E54, 0xC7C7, + 0x4E56, 0xB9D4, + 0x4E58, 0xB3CB, + 0x4E59, 0xD2D2, + 0x4E5C, 0xD8BF, + 0x4E5D, 0xBEC5, + 0x4E5E, 0xC6F2, + 0x4E5F, 0xD2B2, + 0x4E60, 0xCFB0, + 0x4E61, 0xCFE7, + 0x4E66, 0xCAE9, + 0x4E69, 0xD8C0, + 0x4E70, 0xC2F2, + 0x4E71, 0xC2D2, + 0x4E73, 0xC8E9, + 0x4E7E, 0xC7AC, + 0x4E86, 0xC1CB, + 0x4E88, 0xD3E8, + 0x4E89, 0xD5F9, + 0x4E8B, 0xCAC2, + 0x4E8C, 0xB6FE, + 0x4E8D, 0xD8A1, + 0x4E8E, 0xD3DA, + 0x4E8F, 0xBFF7, + 0x4E91, 0xD4C6, + 0x4E92, 0xBBA5, + 0x4E93, 0xD8C1, + 0x4E94, 0xCEE5, + 0x4E95, 0xBEAE, + 0x4E98, 0xD8A8, + 0x4E9A, 0xD1C7, + 0x4E9B, 0xD0A9, + 0x4E9F, 0xD8BD, + 0x4EA0, 0xD9EF, + 0x4EA1, 0xCDF6, + 0x4EA2, 0xBFBA, + 0x4EA4, 0xBDBB, + 0x4EA5, 0xBAA5, + 0x4EA6, 0xD2E0, + 0x4EA7, 0xB2FA, + 0x4EA8, 0xBAE0, + 0x4EA9, 0xC4B6, + 0x4EAB, 0xCFED, + 0x4EAC, 0xBEA9, + 0x4EAD, 0xCDA4, + 0x4EAE, 0xC1C1, + 0x4EB2, 0xC7D7, + 0x4EB3, 0xD9F1, + 0x4EB5, 0xD9F4, + 0x4EBA, 0xC8CB, + 0x4EBB, 0xD8E9, + 0x4EBF, 0xD2DA, + 0x4EC0, 0xCAB2, + 0x4EC1, 0xC8CA, + 0x4EC2, 0xD8EC, + 0x4EC3, 0xD8EA, + 0x4EC4, 0xD8C6, + 0x4EC5, 0xBDF6, + 0x4EC6, 0xC6CD, + 0x4EC7, 0xB3F0, + 0x4EC9, 0xD8EB, + 0x4ECA, 0xBDF1, + 0x4ECB, 0xBDE9, + 0x4ECD, 0xC8D4, + 0x4ECE, 0xB4D3, + 0x4ED1, 0xC2D8, + 0x4ED3, 0xB2D6, + 0x4ED4, 0xD7D0, + 0x4ED5, 0xCACB, + 0x4ED6, 0xCBFB, + 0x4ED7, 0xD5CC, + 0x4ED8, 0xB8B6, + 0x4ED9, 0xCFC9, + 0x4EDD, 0xD9DA, + 0x4EDE, 0xD8F0, + 0x4EDF, 0xC7AA, + 0x4EE1, 0xD8EE, + 0x4EE3, 0xB4FA, + 0x4EE4, 0xC1EE, + 0x4EE5, 0xD2D4, + 0x4EE8, 0xD8ED, + 0x4EEA, 0xD2C7, + 0x4EEB, 0xD8EF, + 0x4EEC, 0xC3C7, + 0x4EF0, 0xD1F6, + 0x4EF2, 0xD6D9, + 0x4EF3, 0xD8F2, + 0x4EF5, 0xD8F5, + 0x4EF6, 0xBCFE, + 0x4EF7, 0xBCDB, + 0x4EFB, 0xC8CE, + 0x4EFD, 0xB7DD, + 0x4EFF, 0xB7C2, + 0x4F01, 0xC6F3, + 0x4F09, 0xD8F8, + 0x4F0A, 0xD2C1, + 0x4F0D, 0xCEE9, + 0x4F0E, 0xBCBF, + 0x4F0F, 0xB7FC, + 0x4F10, 0xB7A5, + 0x4F11, 0xD0DD, + 0x4F17, 0xD6DA, + 0x4F18, 0xD3C5, + 0x4F19, 0xBBEF, + 0x4F1A, 0xBBE1, + 0x4F1B, 0xD8F1, + 0x4F1E, 0xC9A1, + 0x4F1F, 0xCEB0, + 0x4F20, 0xB4AB, + 0x4F22, 0xD8F3, + 0x4F24, 0xC9CB, + 0x4F25, 0xD8F6, + 0x4F26, 0xC2D7, + 0x4F27, 0xD8F7, + 0x4F2A, 0xCEB1, + 0x4F2B, 0xD8F9, + 0x4F2F, 0xB2AE, + 0x4F30, 0xB9C0, + 0x4F32, 0xD9A3, + 0x4F34, 0xB0E9, + 0x4F36, 0xC1E6, + 0x4F38, 0xC9EC, + 0x4F3A, 0xCBC5, + 0x4F3C, 0xCBC6, + 0x4F3D, 0xD9A4, + 0x4F43, 0xB5E8, + 0x4F46, 0xB5AB, + 0x4F4D, 0xCEBB, + 0x4F4E, 0xB5CD, + 0x4F4F, 0xD7A1, + 0x4F50, 0xD7F4, + 0x4F51, 0xD3D3, + 0x4F53, 0xCCE5, + 0x4F55, 0xBACE, + 0x4F57, 0xD9A2, + 0x4F58, 0xD9DC, + 0x4F59, 0xD3E0, + 0x4F5A, 0xD8FD, + 0x4F5B, 0xB7F0, + 0x4F5C, 0xD7F7, + 0x4F5D, 0xD8FE, + 0x4F5E, 0xD8FA, + 0x4F5F, 0xD9A1, + 0x4F60, 0xC4E3, + 0x4F63, 0xD3B6, + 0x4F64, 0xD8F4, + 0x4F65, 0xD9DD, + 0x4F67, 0xD8FB, + 0x4F69, 0xC5E5, + 0x4F6C, 0xC0D0, + 0x4F6F, 0xD1F0, + 0x4F70, 0xB0DB, + 0x4F73, 0xBCD1, + 0x4F74, 0xD9A6, + 0x4F76, 0xD9A5, + 0x4F7B, 0xD9AC, + 0x4F7C, 0xD9AE, + 0x4F7E, 0xD9AB, + 0x4F7F, 0xCAB9, + 0x4F83, 0xD9A9, + 0x4F84, 0xD6B6, + 0x4F88, 0xB3DE, + 0x4F89, 0xD9A8, + 0x4F8B, 0xC0FD, + 0x4F8D, 0xCACC, + 0x4F8F, 0xD9AA, + 0x4F91, 0xD9A7, + 0x4F94, 0xD9B0, + 0x4F97, 0xB6B1, + 0x4F9B, 0xB9A9, + 0x4F9D, 0xD2C0, + 0x4FA0, 0xCFC0, + 0x4FA3, 0xC2C2, + 0x4FA5, 0xBDC4, + 0x4FA6, 0xD5EC, + 0x4FA7, 0xB2E0, + 0x4FA8, 0xC7C8, + 0x4FA9, 0xBFEB, + 0x4FAA, 0xD9AD, + 0x4FAC, 0xD9AF, + 0x4FAE, 0xCEEA, + 0x4FAF, 0xBAEE, + 0x4FB5, 0xC7D6, + 0x4FBF, 0xB1E3, + 0x4FC3, 0xB4D9, + 0x4FC4, 0xB6ED, + 0x4FC5, 0xD9B4, + 0x4FCA, 0xBFA1, + 0x4FCE, 0xD9DE, + 0x4FCF, 0xC7CE, + 0x4FD0, 0xC0FE, + 0x4FD1, 0xD9B8, + 0x4FD7, 0xCBD7, + 0x4FD8, 0xB7FD, + 0x4FDA, 0xD9B5, + 0x4FDC, 0xD9B7, + 0x4FDD, 0xB1A3, + 0x4FDE, 0xD3E1, + 0x4FDF, 0xD9B9, + 0x4FE1, 0xD0C5, + 0x4FE3, 0xD9B6, + 0x4FE6, 0xD9B1, + 0x4FE8, 0xD9B2, + 0x4FE9, 0xC1A9, + 0x4FEA, 0xD9B3, + 0x4FED, 0xBCF3, + 0x4FEE, 0xD0DE, + 0x4FEF, 0xB8A9, + 0x4FF1, 0xBEE3, + 0x4FF3, 0xD9BD, + 0x4FF8, 0xD9BA, + 0x4FFA, 0xB0B3, + 0x4FFE, 0xD9C2, + 0x500C, 0xD9C4, + 0x500D, 0xB1B6, + 0x500F, 0xD9BF, + 0x5012, 0xB5B9, + 0x5014, 0xBEF3, + 0x5018, 0xCCC8, + 0x5019, 0xBAF2, + 0x501A, 0xD2D0, + 0x501C, 0xD9C3, + 0x501F, 0xBDE8, + 0x5021, 0xB3AB, + 0x5025, 0xD9C5, + 0x5026, 0xBEEB, + 0x5028, 0xD9C6, + 0x5029, 0xD9BB, + 0x502A, 0xC4DF, + 0x502C, 0xD9BE, + 0x502D, 0xD9C1, + 0x502E, 0xD9C0, + 0x503A, 0xD5AE, + 0x503C, 0xD6B5, + 0x503E, 0xC7E3, + 0x5043, 0xD9C8, + 0x5047, 0xBCD9, + 0x5048, 0xD9CA, + 0x504C, 0xD9BC, + 0x504E, 0xD9CB, + 0x504F, 0xC6AB, + 0x5055, 0xD9C9, + 0x505A, 0xD7F6, + 0x505C, 0xCDA3, + 0x5065, 0xBDA1, + 0x506C, 0xD9CC, + 0x5076, 0xC5BC, + 0x5077, 0xCDB5, + 0x507B, 0xD9CD, + 0x507E, 0xD9C7, + 0x507F, 0xB3A5, + 0x5080, 0xBFFE, + 0x5085, 0xB8B5, + 0x5088, 0xC0FC, + 0x508D, 0xB0F8, + 0x50A3, 0xB4F6, + 0x50A5, 0xD9CE, + 0x50A7, 0xD9CF, + 0x50A8, 0xB4A2, + 0x50A9, 0xD9D0, + 0x50AC, 0xB4DF, + 0x50B2, 0xB0C1, + 0x50BA, 0xD9D1, + 0x50BB, 0xC9B5, + 0x50CF, 0xCFF1, + 0x50D6, 0xD9D2, + 0x50DA, 0xC1C5, + 0x50E6, 0xD9D6, + 0x50E7, 0xC9AE, + 0x50EC, 0xD9D5, + 0x50ED, 0xD9D4, + 0x50EE, 0xD9D7, + 0x50F3, 0xCBDB, + 0x50F5, 0xBDA9, + 0x50FB, 0xC6A7, + 0x5106, 0xD9D3, + 0x5107, 0xD9D8, + 0x510B, 0xD9D9, + 0x5112, 0xC8E5, + 0x5121, 0xC0DC, + 0x513F, 0xB6F9, + 0x5140, 0xD8A3, + 0x5141, 0xD4CA, + 0x5143, 0xD4AA, + 0x5144, 0xD0D6, + 0x5145, 0xB3E4, + 0x5146, 0xD5D7, + 0x5148, 0xCFC8, + 0x5149, 0xB9E2, + 0x514B, 0xBFCB, + 0x514D, 0xC3E2, + 0x5151, 0xB6D2, + 0x5154, 0xCDC3, + 0x5155, 0xD9EE, + 0x5156, 0xD9F0, + 0x515A, 0xB5B3, + 0x515C, 0xB6B5, + 0x5162, 0xBEA4, + 0x5165, 0xC8EB, + 0x5168, 0xC8AB, + 0x516B, 0xB0CB, + 0x516C, 0xB9AB, + 0x516D, 0xC1F9, + 0x516E, 0xD9E2, + 0x5170, 0xC0BC, + 0x5171, 0xB9B2, + 0x5173, 0xB9D8, + 0x5174, 0xD0CB, + 0x5175, 0xB1F8, + 0x5176, 0xC6E4, + 0x5177, 0xBEDF, + 0x5178, 0xB5E4, + 0x5179, 0xD7C8, + 0x517B, 0xD1F8, + 0x517C, 0xBCE6, + 0x517D, 0xCADE, + 0x5180, 0xBCBD, + 0x5181, 0xD9E6, + 0x5182, 0xD8E7, + 0x5185, 0xC4DA, + 0x5188, 0xB8D4, + 0x5189, 0xC8BD, + 0x518C, 0xB2E1, + 0x518D, 0xD4D9, + 0x5192, 0xC3B0, + 0x5195, 0xC3E1, + 0x5196, 0xDAA2, + 0x5197, 0xC8DF, + 0x5199, 0xD0B4, + 0x519B, 0xBEFC, + 0x519C, 0xC5A9, + 0x51A0, 0xB9DA, + 0x51A2, 0xDAA3, + 0x51A4, 0xD4A9, + 0x51A5, 0xDAA4, + 0x51AB, 0xD9FB, + 0x51AC, 0xB6AC, + 0x51AF, 0xB7EB, + 0x51B0, 0xB1F9, + 0x51B1, 0xD9FC, + 0x51B2, 0xB3E5, + 0x51B3, 0xBEF6, + 0x51B5, 0xBFF6, + 0x51B6, 0xD2B1, + 0x51B7, 0xC0E4, + 0x51BB, 0xB6B3, + 0x51BC, 0xD9FE, + 0x51BD, 0xD9FD, + 0x51C0, 0xBEBB, + 0x51C4, 0xC6E0, + 0x51C6, 0xD7BC, + 0x51C7, 0xDAA1, + 0x51C9, 0xC1B9, + 0x51CB, 0xB5F2, + 0x51CC, 0xC1E8, + 0x51CF, 0xBCF5, + 0x51D1, 0xB4D5, + 0x51DB, 0xC1DD, + 0x51DD, 0xC4FD, + 0x51E0, 0xBCB8, + 0x51E1, 0xB7B2, + 0x51E4, 0xB7EF, + 0x51EB, 0xD9EC, + 0x51ED, 0xC6BE, + 0x51EF, 0xBFAD, + 0x51F0, 0xBBCB, + 0x51F3, 0xB5CA, + 0x51F5, 0xDBC9, + 0x51F6, 0xD0D7, + 0x51F8, 0xCDB9, + 0x51F9, 0xB0BC, + 0x51FA, 0xB3F6, + 0x51FB, 0xBBF7, + 0x51FC, 0xDBCA, + 0x51FD, 0xBAAF, + 0x51FF, 0xD4E4, + 0x5200, 0xB5B6, + 0x5201, 0xB5F3, + 0x5202, 0xD8D6, + 0x5203, 0xC8D0, + 0x5206, 0xB7D6, + 0x5207, 0xC7D0, + 0x5208, 0xD8D7, + 0x520A, 0xBFAF, + 0x520D, 0xDBBB, + 0x520E, 0xD8D8, + 0x5211, 0xD0CC, + 0x5212, 0xBBAE, + 0x5216, 0xEBBE, + 0x5217, 0xC1D0, + 0x5218, 0xC1F5, + 0x5219, 0xD4F2, + 0x521A, 0xB8D5, + 0x521B, 0xB4B4, + 0x521D, 0xB3F5, + 0x5220, 0xC9BE, + 0x5224, 0xC5D0, + 0x5228, 0xC5D9, + 0x5229, 0xC0FB, + 0x522B, 0xB1F0, + 0x522D, 0xD8D9, + 0x522E, 0xB9CE, + 0x5230, 0xB5BD, + 0x5233, 0xD8DA, + 0x5236, 0xD6C6, + 0x5237, 0xCBA2, + 0x5238, 0xC8AF, + 0x5239, 0xC9B2, + 0x523A, 0xB4CC, + 0x523B, 0xBFCC, + 0x523D, 0xB9F4, + 0x523F, 0xD8DB, + 0x5240, 0xD8DC, + 0x5241, 0xB6E7, + 0x5242, 0xBCC1, + 0x5243, 0xCCEA, + 0x524A, 0xCFF7, + 0x524C, 0xD8DD, + 0x524D, 0xC7B0, + 0x5250, 0xB9D0, + 0x5251, 0xBDA3, + 0x5254, 0xCCDE, + 0x5256, 0xC6CA, + 0x525C, 0xD8E0, + 0x525E, 0xD8DE, + 0x5261, 0xD8DF, + 0x5265, 0xB0FE, + 0x5267, 0xBEE7, + 0x5269, 0xCAA3, + 0x526A, 0xBCF4, + 0x526F, 0xB8B1, + 0x5272, 0xB8EE, + 0x527D, 0xD8E2, + 0x527F, 0xBDCB, + 0x5281, 0xD8E4, + 0x5282, 0xD8E3, + 0x5288, 0xC5FC, + 0x5290, 0xD8E5, + 0x5293, 0xD8E6, + 0x529B, 0xC1A6, + 0x529D, 0xC8B0, + 0x529E, 0xB0EC, + 0x529F, 0xB9A6, + 0x52A0, 0xBCD3, + 0x52A1, 0xCEF1, + 0x52A2, 0xDBBD, + 0x52A3, 0xC1D3, + 0x52A8, 0xB6AF, + 0x52A9, 0xD6FA, + 0x52AA, 0xC5AC, + 0x52AB, 0xBDD9, + 0x52AC, 0xDBBE, + 0x52AD, 0xDBBF, + 0x52B1, 0xC0F8, + 0x52B2, 0xBEA2, + 0x52B3, 0xC0CD, + 0x52BE, 0xDBC0, + 0x52BF, 0xCAC6, + 0x52C3, 0xB2AA, + 0x52C7, 0xD3C2, + 0x52C9, 0xC3E3, + 0x52CB, 0xD1AB, + 0x52D0, 0xDBC2, + 0x52D2, 0xC0D5, + 0x52D6, 0xDBC3, + 0x52D8, 0xBFB1, + 0x52DF, 0xC4BC, + 0x52E4, 0xC7DA, + 0x52F0, 0xDBC4, + 0x52F9, 0xD9E8, + 0x52FA, 0xC9D7, + 0x52FE, 0xB9B4, + 0x52FF, 0xCEF0, + 0x5300, 0xD4C8, + 0x5305, 0xB0FC, + 0x5306, 0xB4D2, + 0x5308, 0xD0D9, + 0x530D, 0xD9E9, + 0x530F, 0xDECB, + 0x5310, 0xD9EB, + 0x5315, 0xD8B0, + 0x5316, 0xBBAF, + 0x5317, 0xB1B1, + 0x5319, 0xB3D7, + 0x531A, 0xD8CE, + 0x531D, 0xD4D1, + 0x5320, 0xBDB3, + 0x5321, 0xBFEF, + 0x5323, 0xCFBB, + 0x5326, 0xD8D0, + 0x532A, 0xB7CB, + 0x532E, 0xD8D1, + 0x5339, 0xC6A5, + 0x533A, 0xC7F8, + 0x533B, 0xD2BD, + 0x533E, 0xD8D2, + 0x533F, 0xC4E4, + 0x5341, 0xCAAE, + 0x5343, 0xC7A7, + 0x5345, 0xD8A6, + 0x5347, 0xC9FD, + 0x5348, 0xCEE7, + 0x5349, 0xBBDC, + 0x534A, 0xB0EB, + 0x534E, 0xBBAA, + 0x534F, 0xD0AD, + 0x5351, 0xB1B0, + 0x5352, 0xD7E4, + 0x5353, 0xD7BF, + 0x5355, 0xB5A5, + 0x5356, 0xC2F4, + 0x5357, 0xC4CF, + 0x535A, 0xB2A9, + 0x535C, 0xB2B7, + 0x535E, 0xB1E5, + 0x535F, 0xDFB2, + 0x5360, 0xD5BC, + 0x5361, 0xBFA8, + 0x5362, 0xC2AC, + 0x5363, 0xD8D5, + 0x5364, 0xC2B1, + 0x5366, 0xD8D4, + 0x5367, 0xCED4, + 0x5369, 0xDAE0, + 0x536B, 0xCEC0, + 0x536E, 0xD8B4, + 0x536F, 0xC3AE, + 0x5370, 0xD3A1, + 0x5371, 0xCEA3, + 0x5373, 0xBCB4, + 0x5374, 0xC8B4, + 0x5375, 0xC2D1, + 0x5377, 0xBEED, + 0x5378, 0xD0B6, + 0x537A, 0xDAE1, + 0x537F, 0xC7E4, + 0x5382, 0xB3A7, + 0x5384, 0xB6F2, + 0x5385, 0xCCFC, + 0x5386, 0xC0FA, + 0x5389, 0xC0F7, + 0x538B, 0xD1B9, + 0x538C, 0xD1E1, + 0x538D, 0xD8C7, + 0x5395, 0xB2DE, + 0x5398, 0xC0E5, + 0x539A, 0xBAF1, + 0x539D, 0xD8C8, + 0x539F, 0xD4AD, + 0x53A2, 0xCFE1, + 0x53A3, 0xD8C9, + 0x53A5, 0xD8CA, + 0x53A6, 0xCFC3, + 0x53A8, 0xB3F8, + 0x53A9, 0xBEC7, + 0x53AE, 0xD8CB, + 0x53B6, 0xDBCC, + 0x53BB, 0xC8A5, + 0x53BF, 0xCFD8, + 0x53C1, 0xC8FE, + 0x53C2, 0xB2CE, + 0x53C8, 0xD3D6, + 0x53C9, 0xB2E6, + 0x53CA, 0xBCB0, + 0x53CB, 0xD3D1, + 0x53CC, 0xCBAB, + 0x53CD, 0xB7B4, + 0x53D1, 0xB7A2, + 0x53D4, 0xCAE5, + 0x53D6, 0xC8A1, + 0x53D7, 0xCADC, + 0x53D8, 0xB1E4, + 0x53D9, 0xD0F0, + 0x53DB, 0xC5D1, + 0x53DF, 0xDBC5, + 0x53E0, 0xB5FE, + 0x53E3, 0xBFDA, + 0x53E4, 0xB9C5, + 0x53E5, 0xBEE4, + 0x53E6, 0xC1ED, + 0x53E8, 0xDFB6, + 0x53E9, 0xDFB5, + 0x53EA, 0xD6BB, + 0x53EB, 0xBDD0, + 0x53EC, 0xD5D9, + 0x53ED, 0xB0C8, + 0x53EE, 0xB6A3, + 0x53EF, 0xBFC9, + 0x53F0, 0xCCA8, + 0x53F1, 0xDFB3, + 0x53F2, 0xCAB7, + 0x53F3, 0xD3D2, + 0x53F5, 0xD8CF, + 0x53F6, 0xD2B6, + 0x53F7, 0xBAC5, + 0x53F8, 0xCBBE, + 0x53F9, 0xCCBE, + 0x53FB, 0xDFB7, + 0x53FC, 0xB5F0, + 0x53FD, 0xDFB4, + 0x5401, 0xD3F5, + 0x5403, 0xB3D4, + 0x5404, 0xB8F7, + 0x5406, 0xDFBA, + 0x5408, 0xBACF, + 0x5409, 0xBCAA, + 0x540A, 0xB5F5, + 0x540C, 0xCDAC, + 0x540D, 0xC3FB, + 0x540E, 0xBAF3, + 0x540F, 0xC0F4, + 0x5410, 0xCDC2, + 0x5411, 0xCFF2, + 0x5412, 0xDFB8, + 0x5413, 0xCFC5, + 0x5415, 0xC2C0, + 0x5416, 0xDFB9, + 0x5417, 0xC2F0, + 0x541B, 0xBEFD, + 0x541D, 0xC1DF, + 0x541E, 0xCDCC, + 0x541F, 0xD2F7, + 0x5420, 0xB7CD, + 0x5421, 0xDFC1, + 0x5423, 0xDFC4, + 0x5426, 0xB7F1, + 0x5427, 0xB0C9, + 0x5428, 0xB6D6, + 0x5429, 0xB7D4, + 0x542B, 0xBAAC, + 0x542C, 0xCCFD, + 0x542D, 0xBFD4, + 0x542E, 0xCBB1, + 0x542F, 0xC6F4, + 0x5431, 0xD6A8, + 0x5432, 0xDFC5, + 0x5434, 0xCEE2, + 0x5435, 0xB3B3, + 0x5438, 0xCEFC, + 0x5439, 0xB4B5, + 0x543B, 0xCEC7, + 0x543C, 0xBAF0, + 0x543E, 0xCEE1, + 0x5440, 0xD1BD, + 0x5443, 0xDFC0, + 0x5446, 0xB4F4, + 0x5448, 0xB3CA, + 0x544A, 0xB8E6, + 0x544B, 0xDFBB, + 0x5450, 0xC4C5, + 0x5452, 0xDFBC, + 0x5453, 0xDFBD, + 0x5454, 0xDFBE, + 0x5455, 0xC5BB, + 0x5456, 0xDFBF, + 0x5457, 0xDFC2, + 0x5458, 0xD4B1, + 0x5459, 0xDFC3, + 0x545B, 0xC7BA, + 0x545C, 0xCED8, + 0x5462, 0xC4D8, + 0x5464, 0xDFCA, + 0x5466, 0xDFCF, + 0x5468, 0xD6DC, + 0x5471, 0xDFC9, + 0x5472, 0xDFDA, + 0x5473, 0xCEB6, + 0x5475, 0xBAC7, + 0x5476, 0xDFCE, + 0x5477, 0xDFC8, + 0x5478, 0xC5DE, + 0x547B, 0xC9EB, + 0x547C, 0xBAF4, + 0x547D, 0xC3FC, + 0x5480, 0xBED7, + 0x5482, 0xDFC6, + 0x5484, 0xDFCD, + 0x5486, 0xC5D8, + 0x548B, 0xD5A6, + 0x548C, 0xBACD, + 0x548E, 0xBECC, + 0x548F, 0xD3BD, + 0x5490, 0xB8C0, + 0x5492, 0xD6E4, + 0x5494, 0xDFC7, + 0x5495, 0xB9BE, + 0x5496, 0xBFA7, + 0x5499, 0xC1FC, + 0x549A, 0xDFCB, + 0x549B, 0xDFCC, + 0x549D, 0xDFD0, + 0x54A3, 0xDFDB, + 0x54A4, 0xDFE5, + 0x54A6, 0xDFD7, + 0x54A7, 0xDFD6, + 0x54A8, 0xD7C9, + 0x54A9, 0xDFE3, + 0x54AA, 0xDFE4, + 0x54AB, 0xE5EB, + 0x54AC, 0xD2A7, + 0x54AD, 0xDFD2, + 0x54AF, 0xBFA9, + 0x54B1, 0xD4DB, + 0x54B3, 0xBFC8, + 0x54B4, 0xDFD4, + 0x54B8, 0xCFCC, + 0x54BB, 0xDFDD, + 0x54BD, 0xD1CA, + 0x54BF, 0xDFDE, + 0x54C0, 0xB0A7, + 0x54C1, 0xC6B7, + 0x54C2, 0xDFD3, + 0x54C4, 0xBAE5, + 0x54C6, 0xB6DF, + 0x54C7, 0xCDDB, + 0x54C8, 0xB9FE, + 0x54C9, 0xD4D5, + 0x54CC, 0xDFDF, + 0x54CD, 0xCFEC, + 0x54CE, 0xB0A5, + 0x54CF, 0xDFE7, + 0x54D0, 0xDFD1, + 0x54D1, 0xD1C6, + 0x54D2, 0xDFD5, + 0x54D3, 0xDFD8, + 0x54D4, 0xDFD9, + 0x54D5, 0xDFDC, + 0x54D7, 0xBBA9, + 0x54D9, 0xDFE0, + 0x54DA, 0xDFE1, + 0x54DC, 0xDFE2, + 0x54DD, 0xDFE6, + 0x54DE, 0xDFE8, + 0x54DF, 0xD3B4, + 0x54E5, 0xB8E7, + 0x54E6, 0xC5B6, + 0x54E7, 0xDFEA, + 0x54E8, 0xC9DA, + 0x54E9, 0xC1A8, + 0x54EA, 0xC4C4, + 0x54ED, 0xBFDE, + 0x54EE, 0xCFF8, + 0x54F2, 0xD5DC, + 0x54F3, 0xDFEE, + 0x54FA, 0xB2B8, + 0x54FC, 0xBADF, + 0x54FD, 0xDFEC, + 0x54FF, 0xDBC1, + 0x5501, 0xD1E4, + 0x5506, 0xCBF4, + 0x5507, 0xB4BD, + 0x5509, 0xB0A6, + 0x550F, 0xDFF1, + 0x5510, 0xCCC6, + 0x5511, 0xDFF2, + 0x5514, 0xDFED, + 0x551B, 0xDFE9, + 0x5520, 0xDFEB, + 0x5522, 0xDFEF, + 0x5523, 0xDFF0, + 0x5524, 0xBBBD, + 0x5527, 0xDFF3, + 0x552A, 0xDFF4, + 0x552C, 0xBBA3, + 0x552E, 0xCADB, + 0x552F, 0xCEA8, + 0x5530, 0xE0A7, + 0x5531, 0xB3AA, + 0x5533, 0xE0A6, + 0x5537, 0xE0A1, + 0x553C, 0xDFFE, + 0x553E, 0xCDD9, + 0x553F, 0xDFFC, + 0x5541, 0xDFFA, + 0x5543, 0xBFD0, + 0x5544, 0xD7C4, + 0x5546, 0xC9CC, + 0x5549, 0xDFF8, + 0x554A, 0xB0A1, + 0x5550, 0xDFFD, + 0x5555, 0xDFFB, + 0x5556, 0xE0A2, + 0x555C, 0xE0A8, + 0x5561, 0xB7C8, + 0x5564, 0xC6A1, + 0x5565, 0xC9B6, + 0x5566, 0xC0B2, + 0x5567, 0xDFF5, + 0x556A, 0xC5BE, + 0x556C, 0xD8C4, + 0x556D, 0xDFF9, + 0x556E, 0xC4F6, + 0x5575, 0xE0A3, + 0x5576, 0xE0A4, + 0x5577, 0xE0A5, + 0x5578, 0xD0A5, + 0x557B, 0xE0B4, + 0x557C, 0xCCE4, + 0x557E, 0xE0B1, + 0x5580, 0xBFA6, + 0x5581, 0xE0AF, + 0x5582, 0xCEB9, + 0x5583, 0xE0AB, + 0x5584, 0xC9C6, + 0x5587, 0xC0AE, + 0x5588, 0xE0AE, + 0x5589, 0xBAED, + 0x558A, 0xBAB0, + 0x558B, 0xE0A9, + 0x558F, 0xDFF6, + 0x5591, 0xE0B3, + 0x5594, 0xE0B8, + 0x5598, 0xB4AD, + 0x5599, 0xE0B9, + 0x559C, 0xCFB2, + 0x559D, 0xBAC8, + 0x559F, 0xE0B0, + 0x55A7, 0xD0FA, + 0x55B1, 0xE0AC, + 0x55B3, 0xD4FB, + 0x55B5, 0xDFF7, + 0x55B7, 0xC5E7, + 0x55B9, 0xE0AD, + 0x55BB, 0xD3F7, + 0x55BD, 0xE0B6, + 0x55BE, 0xE0B7, + 0x55C4, 0xE0C4, + 0x55C5, 0xD0E1, + 0x55C9, 0xE0BC, + 0x55CC, 0xE0C9, + 0x55CD, 0xE0CA, + 0x55D1, 0xE0BE, + 0x55D2, 0xE0AA, + 0x55D3, 0xC9A4, + 0x55D4, 0xE0C1, + 0x55D6, 0xE0B2, + 0x55DC, 0xCAC8, + 0x55DD, 0xE0C3, + 0x55DF, 0xE0B5, + 0x55E1, 0xCECB, + 0x55E3, 0xCBC3, + 0x55E4, 0xE0CD, + 0x55E5, 0xE0C6, + 0x55E6, 0xE0C2, + 0x55E8, 0xE0CB, + 0x55EA, 0xE0BA, + 0x55EB, 0xE0BF, + 0x55EC, 0xE0C0, + 0x55EF, 0xE0C5, + 0x55F2, 0xE0C7, + 0x55F3, 0xE0C8, + 0x55F5, 0xE0CC, + 0x55F7, 0xE0BB, + 0x55FD, 0xCBD4, + 0x55FE, 0xE0D5, + 0x5600, 0xE0D6, + 0x5601, 0xE0D2, + 0x5608, 0xE0D0, + 0x5609, 0xBCCE, + 0x560C, 0xE0D1, + 0x560E, 0xB8C2, + 0x560F, 0xD8C5, + 0x5618, 0xD0EA, + 0x561B, 0xC2EF, + 0x561E, 0xE0CF, + 0x561F, 0xE0BD, + 0x5623, 0xE0D4, + 0x5624, 0xE0D3, + 0x5627, 0xE0D7, + 0x562C, 0xE0DC, + 0x562D, 0xE0D8, + 0x5631, 0xD6F6, + 0x5632, 0xB3B0, + 0x5634, 0xD7EC, + 0x5636, 0xCBBB, + 0x5639, 0xE0DA, + 0x563B, 0xCEFB, + 0x563F, 0xBAD9, + 0x564C, 0xE0E1, + 0x564D, 0xE0DD, + 0x564E, 0xD2AD, + 0x5654, 0xE0E2, + 0x5657, 0xE0DB, + 0x5658, 0xE0D9, + 0x5659, 0xE0DF, + 0x565C, 0xE0E0, + 0x5662, 0xE0DE, + 0x5664, 0xE0E4, + 0x5668, 0xC6F7, + 0x5669, 0xD8AC, + 0x566A, 0xD4EB, + 0x566B, 0xE0E6, + 0x566C, 0xCAC9, + 0x5671, 0xE0E5, + 0x5676, 0xB8C1, + 0x567B, 0xE0E7, + 0x567C, 0xE0E8, + 0x5685, 0xE0E9, + 0x5686, 0xE0E3, + 0x568E, 0xBABF, + 0x568F, 0xCCE7, + 0x5693, 0xE0EA, + 0x56A3, 0xCFF9, + 0x56AF, 0xE0EB, + 0x56B7, 0xC8C2, + 0x56BC, 0xBDC0, + 0x56CA, 0xC4D2, + 0x56D4, 0xE0EC, + 0x56D7, 0xE0ED, + 0x56DA, 0xC7F4, + 0x56DB, 0xCBC4, + 0x56DD, 0xE0EE, + 0x56DE, 0xBBD8, + 0x56DF, 0xD8B6, + 0x56E0, 0xD2F2, + 0x56E1, 0xE0EF, + 0x56E2, 0xCDC5, + 0x56E4, 0xB6DA, + 0x56EB, 0xE0F1, + 0x56ED, 0xD4B0, + 0x56F0, 0xC0A7, + 0x56F1, 0xB4D1, + 0x56F4, 0xCEA7, + 0x56F5, 0xE0F0, + 0x56F9, 0xE0F2, + 0x56FA, 0xB9CC, + 0x56FD, 0xB9FA, + 0x56FE, 0xCDBC, + 0x56FF, 0xE0F3, + 0x5703, 0xC6D4, + 0x5704, 0xE0F4, + 0x5706, 0xD4B2, + 0x5708, 0xC8A6, + 0x5709, 0xE0F6, + 0x570A, 0xE0F5, + 0x571C, 0xE0F7, + 0x571F, 0xCDC1, + 0x5723, 0xCAA5, + 0x5728, 0xD4DA, + 0x5729, 0xDBD7, + 0x572A, 0xDBD9, + 0x572C, 0xDBD8, + 0x572D, 0xB9E7, + 0x572E, 0xDBDC, + 0x572F, 0xDBDD, + 0x5730, 0xB5D8, + 0x5733, 0xDBDA, + 0x5739, 0xDBDB, + 0x573A, 0xB3A1, + 0x573B, 0xDBDF, + 0x573E, 0xBBF8, + 0x5740, 0xD6B7, + 0x5742, 0xDBE0, + 0x5747, 0xBEF9, + 0x574A, 0xB7BB, + 0x574C, 0xDBD0, + 0x574D, 0xCCAE, + 0x574E, 0xBFB2, + 0x574F, 0xBBB5, + 0x5750, 0xD7F8, + 0x5751, 0xBFD3, + 0x5757, 0xBFE9, + 0x575A, 0xBCE1, + 0x575B, 0xCCB3, + 0x575C, 0xDBDE, + 0x575D, 0xB0D3, + 0x575E, 0xCEEB, + 0x575F, 0xB7D8, + 0x5760, 0xD7B9, + 0x5761, 0xC6C2, + 0x5764, 0xC0A4, + 0x5766, 0xCCB9, + 0x5768, 0xDBE7, + 0x5769, 0xDBE1, + 0x576A, 0xC6BA, + 0x576B, 0xDBE3, + 0x576D, 0xDBE8, + 0x576F, 0xC5F7, + 0x5773, 0xDBEA, + 0x5776, 0xDBE9, + 0x5777, 0xBFC0, + 0x577B, 0xDBE6, + 0x577C, 0xDBE5, + 0x5782, 0xB4B9, + 0x5783, 0xC0AC, + 0x5784, 0xC2A2, + 0x5785, 0xDBE2, + 0x5786, 0xDBE4, + 0x578B, 0xD0CD, + 0x578C, 0xDBED, + 0x5792, 0xC0DD, + 0x5793, 0xDBF2, + 0x579B, 0xB6E2, + 0x57A0, 0xDBF3, + 0x57A1, 0xDBD2, + 0x57A2, 0xB9B8, + 0x57A3, 0xD4AB, + 0x57A4, 0xDBEC, + 0x57A6, 0xBFD1, + 0x57A7, 0xDBF0, + 0x57A9, 0xDBD1, + 0x57AB, 0xB5E6, + 0x57AD, 0xDBEB, + 0x57AE, 0xBFE5, + 0x57B2, 0xDBEE, + 0x57B4, 0xDBF1, + 0x57B8, 0xDBF9, + 0x57C2, 0xB9A1, + 0x57C3, 0xB0A3, + 0x57CB, 0xC2F1, + 0x57CE, 0xB3C7, + 0x57CF, 0xDBEF, + 0x57D2, 0xDBF8, + 0x57D4, 0xC6D2, + 0x57D5, 0xDBF4, + 0x57D8, 0xDBF5, + 0x57D9, 0xDBF7, + 0x57DA, 0xDBF6, + 0x57DD, 0xDBFE, + 0x57DF, 0xD3F2, + 0x57E0, 0xB2BA, + 0x57E4, 0xDBFD, + 0x57ED, 0xDCA4, + 0x57EF, 0xDBFB, + 0x57F4, 0xDBFA, + 0x57F8, 0xDBFC, + 0x57F9, 0xC5E0, + 0x57FA, 0xBBF9, + 0x57FD, 0xDCA3, + 0x5800, 0xDCA5, + 0x5802, 0xCCC3, + 0x5806, 0xB6D1, + 0x5807, 0xDDC0, + 0x580B, 0xDCA1, + 0x580D, 0xDCA2, + 0x5811, 0xC7B5, + 0x5815, 0xB6E9, + 0x5819, 0xDCA7, + 0x581E, 0xDCA6, + 0x5820, 0xDCA9, + 0x5821, 0xB1A4, + 0x5824, 0xB5CC, + 0x582A, 0xBFB0, + 0x5830, 0xD1DF, + 0x5835, 0xB6C2, + 0x5844, 0xDCA8, + 0x584C, 0xCBFA, + 0x584D, 0xEBF3, + 0x5851, 0xCBDC, + 0x5854, 0xCBFE, + 0x5858, 0xCCC1, + 0x585E, 0xC8FB, + 0x5865, 0xDCAA, + 0x586B, 0xCCEE, + 0x586C, 0xDCAB, + 0x587E, 0xDBD3, + 0x5880, 0xDCAF, + 0x5881, 0xDCAC, + 0x5883, 0xBEB3, + 0x5885, 0xCAFB, + 0x5889, 0xDCAD, + 0x5892, 0xC9CA, + 0x5893, 0xC4B9, + 0x5899, 0xC7BD, + 0x589A, 0xDCAE, + 0x589E, 0xD4F6, + 0x589F, 0xD0E6, + 0x58A8, 0xC4AB, + 0x58A9, 0xB6D5, + 0x58BC, 0xDBD4, + 0x58C1, 0xB1DA, + 0x58C5, 0xDBD5, + 0x58D1, 0xDBD6, + 0x58D5, 0xBABE, + 0x58E4, 0xC8C0, + 0x58EB, 0xCABF, + 0x58EC, 0xC8C9, + 0x58EE, 0xD7B3, + 0x58F0, 0xC9F9, + 0x58F3, 0xBFC7, + 0x58F6, 0xBAF8, + 0x58F9, 0xD2BC, + 0x5902, 0xE2BA, + 0x5904, 0xB4A6, + 0x5907, 0xB1B8, + 0x590D, 0xB8B4, + 0x590F, 0xCFC4, + 0x5914, 0xD9E7, + 0x5915, 0xCFA6, + 0x5916, 0xCDE2, + 0x5919, 0xD9ED, + 0x591A, 0xB6E0, + 0x591C, 0xD2B9, + 0x591F, 0xB9BB, + 0x5924, 0xE2B9, + 0x5925, 0xE2B7, + 0x5927, 0xB4F3, + 0x5929, 0xCCEC, + 0x592A, 0xCCAB, + 0x592B, 0xB7F2, + 0x592D, 0xD8B2, + 0x592E, 0xD1EB, + 0x592F, 0xBABB, + 0x5931, 0xCAA7, + 0x5934, 0xCDB7, + 0x5937, 0xD2C4, + 0x5938, 0xBFE4, + 0x5939, 0xBCD0, + 0x593A, 0xB6E1, + 0x593C, 0xDEC5, + 0x5941, 0xDEC6, + 0x5942, 0xDBBC, + 0x5944, 0xD1D9, + 0x5947, 0xC6E6, + 0x5948, 0xC4CE, + 0x5949, 0xB7EE, + 0x594B, 0xB7DC, + 0x594E, 0xBFFC, + 0x594F, 0xD7E0, + 0x5951, 0xC6F5, + 0x5954, 0xB1BC, + 0x5955, 0xDEC8, + 0x5956, 0xBDB1, + 0x5957, 0xCCD7, + 0x5958, 0xDECA, + 0x595A, 0xDEC9, + 0x5960, 0xB5EC, + 0x5962, 0xC9DD, + 0x5965, 0xB0C2, + 0x5973, 0xC5AE, + 0x5974, 0xC5AB, + 0x5976, 0xC4CC, + 0x5978, 0xBCE9, + 0x5979, 0xCBFD, + 0x597D, 0xBAC3, + 0x5981, 0xE5F9, + 0x5982, 0xC8E7, + 0x5983, 0xE5FA, + 0x5984, 0xCDFD, + 0x5986, 0xD7B1, + 0x5987, 0xB8BE, + 0x5988, 0xC2E8, + 0x598A, 0xC8D1, + 0x598D, 0xE5FB, + 0x5992, 0xB6CA, + 0x5993, 0xBCCB, + 0x5996, 0xD1FD, + 0x5997, 0xE6A1, + 0x5999, 0xC3EE, + 0x599E, 0xE6A4, + 0x59A3, 0xE5FE, + 0x59A4, 0xE6A5, + 0x59A5, 0xCDD7, + 0x59A8, 0xB7C1, + 0x59A9, 0xE5FC, + 0x59AA, 0xE5FD, + 0x59AB, 0xE6A3, + 0x59AE, 0xC4DD, + 0x59AF, 0xE6A8, + 0x59B2, 0xE6A7, + 0x59B9, 0xC3C3, + 0x59BB, 0xC6DE, + 0x59BE, 0xE6AA, + 0x59C6, 0xC4B7, + 0x59CA, 0xE6A2, + 0x59CB, 0xCABC, + 0x59D0, 0xBDE3, + 0x59D1, 0xB9C3, + 0x59D2, 0xE6A6, + 0x59D3, 0xD0D5, + 0x59D4, 0xCEAF, + 0x59D7, 0xE6A9, + 0x59D8, 0xE6B0, + 0x59DA, 0xD2A6, + 0x59DC, 0xBDAA, + 0x59DD, 0xE6AD, + 0x59E3, 0xE6AF, + 0x59E5, 0xC0D1, + 0x59E8, 0xD2CC, + 0x59EC, 0xBCA7, + 0x59F9, 0xE6B1, + 0x59FB, 0xD2F6, + 0x59FF, 0xD7CB, + 0x5A01, 0xCDFE, + 0x5A03, 0xCDDE, + 0x5A04, 0xC2A6, + 0x5A05, 0xE6AB, + 0x5A06, 0xE6AC, + 0x5A07, 0xBDBF, + 0x5A08, 0xE6AE, + 0x5A09, 0xE6B3, + 0x5A0C, 0xE6B2, + 0x5A11, 0xE6B6, + 0x5A13, 0xE6B8, + 0x5A18, 0xC4EF, + 0x5A1C, 0xC4C8, + 0x5A1F, 0xBEEA, + 0x5A20, 0xC9EF, + 0x5A23, 0xE6B7, + 0x5A25, 0xB6F0, + 0x5A29, 0xC3E4, + 0x5A31, 0xD3E9, + 0x5A32, 0xE6B4, + 0x5A34, 0xE6B5, + 0x5A36, 0xC8A2, + 0x5A3C, 0xE6BD, + 0x5A40, 0xE6B9, + 0x5A46, 0xC6C5, + 0x5A49, 0xCDF1, + 0x5A4A, 0xE6BB, + 0x5A55, 0xE6BC, + 0x5A5A, 0xBBE9, + 0x5A62, 0xE6BE, + 0x5A67, 0xE6BA, + 0x5A6A, 0xC0B7, + 0x5A74, 0xD3A4, + 0x5A75, 0xE6BF, + 0x5A76, 0xC9F4, + 0x5A77, 0xE6C3, + 0x5A7A, 0xE6C4, + 0x5A7F, 0xD0F6, + 0x5A92, 0xC3BD, + 0x5A9A, 0xC3C4, + 0x5A9B, 0xE6C2, + 0x5AAA, 0xE6C1, + 0x5AB2, 0xE6C7, + 0x5AB3, 0xCFB1, + 0x5AB5, 0xEBF4, + 0x5AB8, 0xE6CA, + 0x5ABE, 0xE6C5, + 0x5AC1, 0xBCDE, + 0x5AC2, 0xC9A9, + 0x5AC9, 0xBCB5, + 0x5ACC, 0xCFD3, + 0x5AD2, 0xE6C8, + 0x5AD4, 0xE6C9, + 0x5AD6, 0xE6CE, + 0x5AD8, 0xE6D0, + 0x5ADC, 0xE6D1, + 0x5AE0, 0xE6CB, + 0x5AE1, 0xB5D5, + 0x5AE3, 0xE6CC, + 0x5AE6, 0xE6CF, + 0x5AE9, 0xC4DB, + 0x5AEB, 0xE6C6, + 0x5AF1, 0xE6CD, + 0x5B09, 0xE6D2, + 0x5B16, 0xE6D4, + 0x5B17, 0xE6D3, + 0x5B32, 0xE6D5, + 0x5B34, 0xD9F8, + 0x5B37, 0xE6D6, + 0x5B40, 0xE6D7, + 0x5B50, 0xD7D3, + 0x5B51, 0xE6DD, + 0x5B53, 0xE6DE, + 0x5B54, 0xBFD7, + 0x5B55, 0xD4D0, + 0x5B57, 0xD7D6, + 0x5B58, 0xB4E6, + 0x5B59, 0xCBEF, + 0x5B5A, 0xE6DA, + 0x5B5B, 0xD8C3, + 0x5B5C, 0xD7CE, + 0x5B5D, 0xD0A2, + 0x5B5F, 0xC3CF, + 0x5B62, 0xE6DF, + 0x5B63, 0xBCBE, + 0x5B64, 0xB9C2, + 0x5B65, 0xE6DB, + 0x5B66, 0xD1A7, + 0x5B69, 0xBAA2, + 0x5B6A, 0xC2CF, + 0x5B6C, 0xD8AB, + 0x5B70, 0xCAEB, + 0x5B71, 0xE5EE, + 0x5B73, 0xE6DC, + 0x5B75, 0xB7F5, + 0x5B7A, 0xC8E6, + 0x5B7D, 0xC4F5, + 0x5B80, 0xE5B2, + 0x5B81, 0xC4FE, + 0x5B83, 0xCBFC, + 0x5B84, 0xE5B3, + 0x5B85, 0xD5AC, + 0x5B87, 0xD3EE, + 0x5B88, 0xCAD8, + 0x5B89, 0xB0B2, + 0x5B8B, 0xCBCE, + 0x5B8C, 0xCDEA, + 0x5B8F, 0xBAEA, + 0x5B93, 0xE5B5, + 0x5B95, 0xE5B4, + 0x5B97, 0xD7DA, + 0x5B98, 0xB9D9, + 0x5B99, 0xD6E6, + 0x5B9A, 0xB6A8, + 0x5B9B, 0xCDF0, + 0x5B9C, 0xD2CB, + 0x5B9D, 0xB1A6, + 0x5B9E, 0xCAB5, + 0x5BA0, 0xB3E8, + 0x5BA1, 0xC9F3, + 0x5BA2, 0xBFCD, + 0x5BA3, 0xD0FB, + 0x5BA4, 0xCAD2, + 0x5BA5, 0xE5B6, + 0x5BA6, 0xBBC2, + 0x5BAA, 0xCFDC, + 0x5BAB, 0xB9AC, + 0x5BB0, 0xD4D7, + 0x5BB3, 0xBAA6, + 0x5BB4, 0xD1E7, + 0x5BB5, 0xCFFC, + 0x5BB6, 0xBCD2, + 0x5BB8, 0xE5B7, + 0x5BB9, 0xC8DD, + 0x5BBD, 0xBFED, + 0x5BBE, 0xB1F6, + 0x5BBF, 0xCBDE, + 0x5BC2, 0xBCC5, + 0x5BC4, 0xBCC4, + 0x5BC5, 0xD2FA, + 0x5BC6, 0xC3DC, + 0x5BC7, 0xBFDC, + 0x5BCC, 0xB8BB, + 0x5BD0, 0xC3C2, + 0x5BD2, 0xBAAE, + 0x5BD3, 0xD4A2, + 0x5BDD, 0xC7DE, + 0x5BDE, 0xC4AF, + 0x5BDF, 0xB2EC, + 0x5BE1, 0xB9D1, + 0x5BE4, 0xE5BB, + 0x5BE5, 0xC1C8, + 0x5BE8, 0xD5AF, + 0x5BEE, 0xE5BC, + 0x5BF0, 0xE5BE, + 0x5BF8, 0xB4E7, + 0x5BF9, 0xB6D4, + 0x5BFA, 0xCBC2, + 0x5BFB, 0xD1B0, + 0x5BFC, 0xB5BC, + 0x5BFF, 0xCAD9, + 0x5C01, 0xB7E2, + 0x5C04, 0xC9E4, + 0x5C06, 0xBDAB, + 0x5C09, 0xCEBE, + 0x5C0A, 0xD7F0, + 0x5C0F, 0xD0A1, + 0x5C11, 0xC9D9, + 0x5C14, 0xB6FB, + 0x5C15, 0xE6D8, + 0x5C16, 0xBCE2, + 0x5C18, 0xB3BE, + 0x5C1A, 0xC9D0, + 0x5C1C, 0xE6D9, + 0x5C1D, 0xB3A2, + 0x5C22, 0xDECC, + 0x5C24, 0xD3C8, + 0x5C25, 0xDECD, + 0x5C27, 0xD2A2, + 0x5C2C, 0xDECE, + 0x5C31, 0xBECD, + 0x5C34, 0xDECF, + 0x5C38, 0xCAAC, + 0x5C39, 0xD2FC, + 0x5C3A, 0xB3DF, + 0x5C3B, 0xE5EA, + 0x5C3C, 0xC4E1, + 0x5C3D, 0xBEA1, + 0x5C3E, 0xCEB2, + 0x5C3F, 0xC4F2, + 0x5C40, 0xBED6, + 0x5C41, 0xC6A8, + 0x5C42, 0xB2E3, + 0x5C45, 0xBED3, + 0x5C48, 0xC7FC, + 0x5C49, 0xCCEB, + 0x5C4A, 0xBDEC, + 0x5C4B, 0xCEDD, + 0x5C4E, 0xCABA, + 0x5C4F, 0xC6C1, + 0x5C50, 0xE5EC, + 0x5C51, 0xD0BC, + 0x5C55, 0xD5B9, + 0x5C59, 0xE5ED, + 0x5C5E, 0xCAF4, + 0x5C60, 0xCDC0, + 0x5C61, 0xC2C5, + 0x5C63, 0xE5EF, + 0x5C65, 0xC2C4, + 0x5C66, 0xE5F0, + 0x5C6E, 0xE5F8, + 0x5C6F, 0xCDCD, + 0x5C71, 0xC9BD, + 0x5C79, 0xD2D9, + 0x5C7A, 0xE1A8, + 0x5C7F, 0xD3EC, + 0x5C81, 0xCBEA, + 0x5C82, 0xC6F1, + 0x5C88, 0xE1AC, + 0x5C8C, 0xE1A7, + 0x5C8D, 0xE1A9, + 0x5C90, 0xE1AA, + 0x5C91, 0xE1AF, + 0x5C94, 0xB2ED, + 0x5C96, 0xE1AB, + 0x5C97, 0xB8DA, + 0x5C98, 0xE1AD, + 0x5C99, 0xE1AE, + 0x5C9A, 0xE1B0, + 0x5C9B, 0xB5BA, + 0x5C9C, 0xE1B1, + 0x5CA2, 0xE1B3, + 0x5CA3, 0xE1B8, + 0x5CA9, 0xD1D2, + 0x5CAB, 0xE1B6, + 0x5CAC, 0xE1B5, + 0x5CAD, 0xC1EB, + 0x5CB1, 0xE1B7, + 0x5CB3, 0xD4C0, + 0x5CB5, 0xE1B2, + 0x5CB7, 0xE1BA, + 0x5CB8, 0xB0B6, + 0x5CBD, 0xE1B4, + 0x5CBF, 0xBFF9, + 0x5CC1, 0xE1B9, + 0x5CC4, 0xE1BB, + 0x5CCB, 0xE1BE, + 0x5CD2, 0xE1BC, + 0x5CD9, 0xD6C5, + 0x5CE1, 0xCFBF, + 0x5CE4, 0xE1BD, + 0x5CE5, 0xE1BF, + 0x5CE6, 0xC2CD, + 0x5CE8, 0xB6EB, + 0x5CEA, 0xD3F8, + 0x5CED, 0xC7CD, + 0x5CF0, 0xB7E5, + 0x5CFB, 0xBEFE, + 0x5D02, 0xE1C0, + 0x5D03, 0xE1C1, + 0x5D06, 0xE1C7, + 0x5D07, 0xB3E7, + 0x5D0E, 0xC6E9, + 0x5D14, 0xB4DE, + 0x5D16, 0xD1C2, + 0x5D1B, 0xE1C8, + 0x5D1E, 0xE1C6, + 0x5D24, 0xE1C5, + 0x5D26, 0xE1C3, + 0x5D27, 0xE1C2, + 0x5D29, 0xB1C0, + 0x5D2D, 0xD5B8, + 0x5D2E, 0xE1C4, + 0x5D34, 0xE1CB, + 0x5D3D, 0xE1CC, + 0x5D3E, 0xE1CA, + 0x5D47, 0xEFFA, + 0x5D4A, 0xE1D3, + 0x5D4B, 0xE1D2, + 0x5D4C, 0xC7B6, + 0x5D58, 0xE1C9, + 0x5D5B, 0xE1CE, + 0x5D5D, 0xE1D0, + 0x5D69, 0xE1D4, + 0x5D6B, 0xE1D1, + 0x5D6C, 0xE1CD, + 0x5D6F, 0xE1CF, + 0x5D74, 0xE1D5, + 0x5D82, 0xE1D6, + 0x5D99, 0xE1D7, + 0x5D9D, 0xE1D8, + 0x5DB7, 0xE1DA, + 0x5DC5, 0xE1DB, + 0x5DCD, 0xCEA1, + 0x5DDB, 0xE7DD, + 0x5DDD, 0xB4A8, + 0x5DDE, 0xD6DD, + 0x5DE1, 0xD1B2, + 0x5DE2, 0xB3B2, + 0x5DE5, 0xB9A4, + 0x5DE6, 0xD7F3, + 0x5DE7, 0xC7C9, + 0x5DE8, 0xBEDE, + 0x5DE9, 0xB9AE, + 0x5DEB, 0xCED7, + 0x5DEE, 0xB2EE, + 0x5DEF, 0xDBCF, + 0x5DF1, 0xBCBA, + 0x5DF2, 0xD2D1, + 0x5DF3, 0xCBC8, + 0x5DF4, 0xB0CD, + 0x5DF7, 0xCFEF, + 0x5DFD, 0xD9E3, + 0x5DFE, 0xBDED, + 0x5E01, 0xB1D2, + 0x5E02, 0xCAD0, + 0x5E03, 0xB2BC, + 0x5E05, 0xCBA7, + 0x5E06, 0xB7AB, + 0x5E08, 0xCAA6, + 0x5E0C, 0xCFA3, + 0x5E0F, 0xE0F8, + 0x5E10, 0xD5CA, + 0x5E11, 0xE0FB, + 0x5E14, 0xE0FA, + 0x5E15, 0xC5C1, + 0x5E16, 0xCCFB, + 0x5E18, 0xC1B1, + 0x5E19, 0xE0F9, + 0x5E1A, 0xD6E3, + 0x5E1B, 0xB2AF, + 0x5E1C, 0xD6C4, + 0x5E1D, 0xB5DB, + 0x5E26, 0xB4F8, + 0x5E27, 0xD6A1, + 0x5E2D, 0xCFAF, + 0x5E2E, 0xB0EF, + 0x5E31, 0xE0FC, + 0x5E37, 0xE1A1, + 0x5E38, 0xB3A3, + 0x5E3B, 0xE0FD, + 0x5E3C, 0xE0FE, + 0x5E3D, 0xC3B1, + 0x5E42, 0xC3DD, + 0x5E44, 0xE1A2, + 0x5E45, 0xB7F9, + 0x5E4C, 0xBBCF, + 0x5E54, 0xE1A3, + 0x5E55, 0xC4BB, + 0x5E5B, 0xE1A4, + 0x5E5E, 0xE1A5, + 0x5E61, 0xE1A6, + 0x5E62, 0xB4B1, + 0x5E72, 0xB8C9, + 0x5E73, 0xC6BD, + 0x5E74, 0xC4EA, + 0x5E76, 0xB2A2, + 0x5E78, 0xD0D2, + 0x5E7A, 0xE7DB, + 0x5E7B, 0xBBC3, + 0x5E7C, 0xD3D7, + 0x5E7D, 0xD3C4, + 0x5E7F, 0xB9E3, + 0x5E80, 0xE2CF, + 0x5E84, 0xD7AF, + 0x5E86, 0xC7EC, + 0x5E87, 0xB1D3, + 0x5E8A, 0xB4B2, + 0x5E8B, 0xE2D1, + 0x5E8F, 0xD0F2, + 0x5E90, 0xC2AE, + 0x5E91, 0xE2D0, + 0x5E93, 0xBFE2, + 0x5E94, 0xD3A6, + 0x5E95, 0xB5D7, + 0x5E96, 0xE2D2, + 0x5E97, 0xB5EA, + 0x5E99, 0xC3ED, + 0x5E9A, 0xB8FD, + 0x5E9C, 0xB8AE, + 0x5E9E, 0xC5D3, + 0x5E9F, 0xB7CF, + 0x5EA0, 0xE2D4, + 0x5EA5, 0xE2D3, + 0x5EA6, 0xB6C8, + 0x5EA7, 0xD7F9, + 0x5EAD, 0xCDA5, + 0x5EB3, 0xE2D8, + 0x5EB5, 0xE2D6, + 0x5EB6, 0xCAFC, + 0x5EB7, 0xBFB5, + 0x5EB8, 0xD3B9, + 0x5EB9, 0xE2D5, + 0x5EBE, 0xE2D7, + 0x5EC9, 0xC1AE, + 0x5ECA, 0xC0C8, + 0x5ED1, 0xE2DB, + 0x5ED2, 0xE2DA, + 0x5ED3, 0xC0AA, + 0x5ED6, 0xC1CE, + 0x5EDB, 0xE2DC, + 0x5EE8, 0xE2DD, + 0x5EEA, 0xE2DE, + 0x5EF4, 0xDBC8, + 0x5EF6, 0xD1D3, + 0x5EF7, 0xCDA2, + 0x5EFA, 0xBDA8, + 0x5EFE, 0xDEC3, + 0x5EFF, 0xD8A5, + 0x5F00, 0xBFAA, + 0x5F01, 0xDBCD, + 0x5F02, 0xD2EC, + 0x5F03, 0xC6FA, + 0x5F04, 0xC5AA, + 0x5F08, 0xDEC4, + 0x5F0A, 0xB1D7, + 0x5F0B, 0xDFAE, + 0x5F0F, 0xCABD, + 0x5F11, 0xDFB1, + 0x5F13, 0xB9AD, + 0x5F15, 0xD2FD, + 0x5F17, 0xB8A5, + 0x5F18, 0xBAEB, + 0x5F1B, 0xB3DA, + 0x5F1F, 0xB5DC, + 0x5F20, 0xD5C5, + 0x5F25, 0xC3D6, + 0x5F26, 0xCFD2, + 0x5F27, 0xBBA1, + 0x5F29, 0xE5F3, + 0x5F2A, 0xE5F2, + 0x5F2D, 0xE5F4, + 0x5F2F, 0xCDE4, + 0x5F31, 0xC8F5, + 0x5F39, 0xB5AF, + 0x5F3A, 0xC7BF, + 0x5F3C, 0xE5F6, + 0x5F40, 0xECB0, + 0x5F50, 0xE5E6, + 0x5F52, 0xB9E9, + 0x5F53, 0xB5B1, + 0x5F55, 0xC2BC, + 0x5F56, 0xE5E8, + 0x5F57, 0xE5E7, + 0x5F58, 0xE5E9, + 0x5F5D, 0xD2CD, + 0x5F61, 0xE1EA, + 0x5F62, 0xD0CE, + 0x5F64, 0xCDAE, + 0x5F66, 0xD1E5, + 0x5F69, 0xB2CA, + 0x5F6A, 0xB1EB, + 0x5F6C, 0xB1F2, + 0x5F6D, 0xC5ED, + 0x5F70, 0xD5C3, + 0x5F71, 0xD3B0, + 0x5F73, 0xE1DC, + 0x5F77, 0xE1DD, + 0x5F79, 0xD2DB, + 0x5F7B, 0xB3B9, + 0x5F7C, 0xB1CB, + 0x5F80, 0xCDF9, + 0x5F81, 0xD5F7, + 0x5F82, 0xE1DE, + 0x5F84, 0xBEB6, + 0x5F85, 0xB4FD, + 0x5F87, 0xE1DF, + 0x5F88, 0xBADC, + 0x5F89, 0xE1E0, + 0x5F8A, 0xBBB2, + 0x5F8B, 0xC2C9, + 0x5F8C, 0xE1E1, + 0x5F90, 0xD0EC, + 0x5F92, 0xCDBD, + 0x5F95, 0xE1E2, + 0x5F97, 0xB5C3, + 0x5F98, 0xC5C7, + 0x5F99, 0xE1E3, + 0x5F9C, 0xE1E4, + 0x5FA1, 0xD3F9, + 0x5FA8, 0xE1E5, + 0x5FAA, 0xD1AD, + 0x5FAD, 0xE1E6, + 0x5FAE, 0xCEA2, + 0x5FB5, 0xE1E7, + 0x5FB7, 0xB5C2, + 0x5FBC, 0xE1E8, + 0x5FBD, 0xBBD5, + 0x5FC3, 0xD0C4, + 0x5FC4, 0xE2E0, + 0x5FC5, 0xB1D8, + 0x5FC6, 0xD2E4, + 0x5FC9, 0xE2E1, + 0x5FCC, 0xBCC9, + 0x5FCD, 0xC8CC, + 0x5FCF, 0xE2E3, + 0x5FD0, 0xECFE, + 0x5FD1, 0xECFD, + 0x5FD2, 0xDFAF, + 0x5FD6, 0xE2E2, + 0x5FD7, 0xD6BE, + 0x5FD8, 0xCDFC, + 0x5FD9, 0xC3A6, + 0x5FDD, 0xE3C3, + 0x5FE0, 0xD6D2, + 0x5FE1, 0xE2E7, + 0x5FE4, 0xE2E8, + 0x5FE7, 0xD3C7, + 0x5FEA, 0xE2EC, + 0x5FEB, 0xBFEC, + 0x5FED, 0xE2ED, + 0x5FEE, 0xE2E5, + 0x5FF1, 0xB3C0, + 0x5FF5, 0xC4EE, + 0x5FF8, 0xE2EE, + 0x5FFB, 0xD0C3, + 0x5FFD, 0xBAF6, + 0x5FFE, 0xE2E9, + 0x5FFF, 0xB7DE, + 0x6000, 0xBBB3, + 0x6001, 0xCCAC, + 0x6002, 0xCBCB, + 0x6003, 0xE2E4, + 0x6004, 0xE2E6, + 0x6005, 0xE2EA, + 0x6006, 0xE2EB, + 0x600A, 0xE2F7, + 0x600D, 0xE2F4, + 0x600E, 0xD4F5, + 0x600F, 0xE2F3, + 0x6012, 0xC5AD, + 0x6014, 0xD5FA, + 0x6015, 0xC5C2, + 0x6016, 0xB2C0, + 0x6019, 0xE2EF, + 0x601B, 0xE2F2, + 0x601C, 0xC1AF, + 0x601D, 0xCBBC, + 0x6020, 0xB5A1, + 0x6021, 0xE2F9, + 0x6025, 0xBCB1, + 0x6026, 0xE2F1, + 0x6027, 0xD0D4, + 0x6028, 0xD4B9, + 0x6029, 0xE2F5, + 0x602A, 0xB9D6, + 0x602B, 0xE2F6, + 0x602F, 0xC7D3, + 0x6035, 0xE2F0, + 0x603B, 0xD7DC, + 0x603C, 0xEDA1, + 0x603F, 0xE2F8, + 0x6041, 0xEDA5, + 0x6042, 0xE2FE, + 0x6043, 0xCAD1, + 0x604B, 0xC1B5, + 0x604D, 0xBBD0, + 0x6050, 0xBFD6, + 0x6052, 0xBAE3, + 0x6055, 0xCBA1, + 0x6059, 0xEDA6, + 0x605A, 0xEDA3, + 0x605D, 0xEDA2, + 0x6062, 0xBBD6, + 0x6063, 0xEDA7, + 0x6064, 0xD0F4, + 0x6067, 0xEDA4, + 0x6068, 0xBADE, + 0x6069, 0xB6F7, + 0x606A, 0xE3A1, + 0x606B, 0xB6B2, + 0x606C, 0xCCF1, + 0x606D, 0xB9A7, + 0x606F, 0xCFA2, + 0x6070, 0xC7A1, + 0x6073, 0xBFD2, + 0x6076, 0xB6F1, + 0x6078, 0xE2FA, + 0x6079, 0xE2FB, + 0x607A, 0xE2FD, + 0x607B, 0xE2FC, + 0x607C, 0xC4D5, + 0x607D, 0xE3A2, + 0x607F, 0xD3C1, + 0x6083, 0xE3A7, + 0x6084, 0xC7C4, + 0x6089, 0xCFA4, + 0x608C, 0xE3A9, + 0x608D, 0xBAB7, + 0x6092, 0xE3A8, + 0x6094, 0xBBDA, + 0x6096, 0xE3A3, + 0x609A, 0xE3A4, + 0x609B, 0xE3AA, + 0x609D, 0xE3A6, + 0x609F, 0xCEF2, + 0x60A0, 0xD3C6, + 0x60A3, 0xBBBC, + 0x60A6, 0xD4C3, + 0x60A8, 0xC4FA, + 0x60AB, 0xEDA8, + 0x60AC, 0xD0FC, + 0x60AD, 0xE3A5, + 0x60AF, 0xC3F5, + 0x60B1, 0xE3AD, + 0x60B2, 0xB1AF, + 0x60B4, 0xE3B2, + 0x60B8, 0xBCC2, + 0x60BB, 0xE3AC, + 0x60BC, 0xB5BF, + 0x60C5, 0xC7E9, + 0x60C6, 0xE3B0, + 0x60CA, 0xBEAA, + 0x60CB, 0xCDEF, + 0x60D1, 0xBBF3, + 0x60D5, 0xCCE8, + 0x60D8, 0xE3AF, + 0x60DA, 0xE3B1, + 0x60DC, 0xCFA7, + 0x60DD, 0xE3AE, + 0x60DF, 0xCEA9, + 0x60E0, 0xBBDD, + 0x60E6, 0xB5EB, + 0x60E7, 0xBEE5, + 0x60E8, 0xB2D2, + 0x60E9, 0xB3CD, + 0x60EB, 0xB1B9, + 0x60EC, 0xE3AB, + 0x60ED, 0xB2D1, + 0x60EE, 0xB5AC, + 0x60EF, 0xB9DF, + 0x60F0, 0xB6E8, + 0x60F3, 0xCFEB, + 0x60F4, 0xE3B7, + 0x60F6, 0xBBCC, + 0x60F9, 0xC8C7, + 0x60FA, 0xD0CA, + 0x6100, 0xE3B8, + 0x6101, 0xB3EE, + 0x6106, 0xEDA9, + 0x6108, 0xD3FA, + 0x6109, 0xD3E4, + 0x610D, 0xEDAA, + 0x610E, 0xE3B9, + 0x610F, 0xD2E2, + 0x6115, 0xE3B5, + 0x611A, 0xD3DE, + 0x611F, 0xB8D0, + 0x6120, 0xE3B3, + 0x6123, 0xE3B6, + 0x6124, 0xB7DF, + 0x6126, 0xE3B4, + 0x6127, 0xC0A2, + 0x612B, 0xE3BA, + 0x613F, 0xD4B8, + 0x6148, 0xB4C8, + 0x614A, 0xE3BB, + 0x614C, 0xBBC5, + 0x614E, 0xC9F7, + 0x6151, 0xC9E5, + 0x6155, 0xC4BD, + 0x615D, 0xEDAB, + 0x6162, 0xC2FD, + 0x6167, 0xBBDB, + 0x6168, 0xBFAE, + 0x6170, 0xCEBF, + 0x6175, 0xE3BC, + 0x6177, 0xBFB6, + 0x618B, 0xB1EF, + 0x618E, 0xD4F7, + 0x6194, 0xE3BE, + 0x619D, 0xEDAD, + 0x61A7, 0xE3BF, + 0x61A8, 0xBAA9, + 0x61A9, 0xEDAC, + 0x61AC, 0xE3BD, + 0x61B7, 0xE3C0, + 0x61BE, 0xBAB6, + 0x61C2, 0xB6AE, + 0x61C8, 0xD0B8, + 0x61CA, 0xB0C3, + 0x61CB, 0xEDAE, + 0x61D1, 0xEDAF, + 0x61D2, 0xC0C1, + 0x61D4, 0xE3C1, + 0x61E6, 0xC5B3, + 0x61F5, 0xE3C2, + 0x61FF, 0xDCB2, + 0x6206, 0xEDB0, + 0x6208, 0xB8EA, + 0x620A, 0xCEEC, + 0x620B, 0xEAA7, + 0x620C, 0xD0E7, + 0x620D, 0xCAF9, + 0x620E, 0xC8D6, + 0x620F, 0xCFB7, + 0x6210, 0xB3C9, + 0x6211, 0xCED2, + 0x6212, 0xBDE4, + 0x6215, 0xE3DE, + 0x6216, 0xBBF2, + 0x6217, 0xEAA8, + 0x6218, 0xD5BD, + 0x621A, 0xC6DD, + 0x621B, 0xEAA9, + 0x621F, 0xEAAA, + 0x6221, 0xEAAC, + 0x6222, 0xEAAB, + 0x6224, 0xEAAE, + 0x6225, 0xEAAD, + 0x622A, 0xBDD8, + 0x622C, 0xEAAF, + 0x622E, 0xC2BE, + 0x6233, 0xB4C1, + 0x6234, 0xB4F7, + 0x6237, 0xBBA7, + 0x623D, 0xECE6, + 0x623E, 0xECE5, + 0x623F, 0xB7BF, + 0x6240, 0xCBF9, + 0x6241, 0xB1E2, + 0x6243, 0xECE7, + 0x6247, 0xC9C8, + 0x6248, 0xECE8, + 0x6249, 0xECE9, + 0x624B, 0xCAD6, + 0x624C, 0xDED0, + 0x624D, 0xB2C5, + 0x624E, 0xD4FA, + 0x6251, 0xC6CB, + 0x6252, 0xB0C7, + 0x6253, 0xB4F2, + 0x6254, 0xC8D3, + 0x6258, 0xCDD0, + 0x625B, 0xBFB8, + 0x6263, 0xBFDB, + 0x6266, 0xC7A4, + 0x6267, 0xD6B4, + 0x6269, 0xC0A9, + 0x626A, 0xDED1, + 0x626B, 0xC9A8, + 0x626C, 0xD1EF, + 0x626D, 0xC5A4, + 0x626E, 0xB0E7, + 0x626F, 0xB3B6, + 0x6270, 0xC8C5, + 0x6273, 0xB0E2, + 0x6276, 0xB7F6, + 0x6279, 0xC5FA, + 0x627C, 0xB6F3, + 0x627E, 0xD5D2, + 0x627F, 0xB3D0, + 0x6280, 0xBCBC, + 0x6284, 0xB3AD, + 0x6289, 0xBEF1, + 0x628A, 0xB0D1, + 0x6291, 0xD2D6, + 0x6292, 0xCAE3, + 0x6293, 0xD7A5, + 0x6295, 0xCDB6, + 0x6296, 0xB6B6, + 0x6297, 0xBFB9, + 0x6298, 0xD5DB, + 0x629A, 0xB8A7, + 0x629B, 0xC5D7, + 0x629F, 0xDED2, + 0x62A0, 0xBFD9, + 0x62A1, 0xC2D5, + 0x62A2, 0xC7C0, + 0x62A4, 0xBBA4, + 0x62A5, 0xB1A8, + 0x62A8, 0xC5EA, + 0x62AB, 0xC5FB, + 0x62AC, 0xCCA7, + 0x62B1, 0xB1A7, + 0x62B5, 0xB5D6, + 0x62B9, 0xC4A8, + 0x62BB, 0xDED3, + 0x62BC, 0xD1BA, + 0x62BD, 0xB3E9, + 0x62BF, 0xC3F2, + 0x62C2, 0xB7F7, + 0x62C4, 0xD6F4, + 0x62C5, 0xB5A3, + 0x62C6, 0xB2F0, + 0x62C7, 0xC4B4, + 0x62C8, 0xC4E9, + 0x62C9, 0xC0AD, + 0x62CA, 0xDED4, + 0x62CC, 0xB0E8, + 0x62CD, 0xC5C4, + 0x62CE, 0xC1E0, + 0x62D0, 0xB9D5, + 0x62D2, 0xBEDC, + 0x62D3, 0xCDD8, + 0x62D4, 0xB0CE, + 0x62D6, 0xCDCF, + 0x62D7, 0xDED6, + 0x62D8, 0xBED0, + 0x62D9, 0xD7BE, + 0x62DA, 0xDED5, + 0x62DB, 0xD5D0, + 0x62DC, 0xB0DD, + 0x62DF, 0xC4E2, + 0x62E2, 0xC2A3, + 0x62E3, 0xBCF0, + 0x62E5, 0xD3B5, + 0x62E6, 0xC0B9, + 0x62E7, 0xC5A1, + 0x62E8, 0xB2A6, + 0x62E9, 0xD4F1, + 0x62EC, 0xC0A8, + 0x62ED, 0xCAC3, + 0x62EE, 0xDED7, + 0x62EF, 0xD5FC, + 0x62F1, 0xB9B0, + 0x62F3, 0xC8AD, + 0x62F4, 0xCBA9, + 0x62F6, 0xDED9, + 0x62F7, 0xBFBD, + 0x62FC, 0xC6B4, + 0x62FD, 0xD7A7, + 0x62FE, 0xCAB0, + 0x62FF, 0xC4C3, + 0x6301, 0xB3D6, + 0x6302, 0xB9D2, + 0x6307, 0xD6B8, + 0x6308, 0xEAFC, + 0x6309, 0xB0B4, + 0x630E, 0xBFE6, + 0x6311, 0xCCF4, + 0x6316, 0xCDDA, + 0x631A, 0xD6BF, + 0x631B, 0xC2CE, + 0x631D, 0xCECE, + 0x631E, 0xCCA2, + 0x631F, 0xD0AE, + 0x6320, 0xC4D3, + 0x6321, 0xB5B2, + 0x6322, 0xDED8, + 0x6323, 0xD5F5, + 0x6324, 0xBCB7, + 0x6325, 0xBBD3, + 0x6328, 0xB0A4, + 0x632A, 0xC5B2, + 0x632B, 0xB4EC, + 0x632F, 0xD5F1, + 0x6332, 0xEAFD, + 0x6339, 0xDEDA, + 0x633A, 0xCDA6, + 0x633D, 0xCDEC, + 0x6342, 0xCEE6, + 0x6343, 0xDEDC, + 0x6345, 0xCDB1, + 0x6346, 0xC0A6, + 0x6349, 0xD7BD, + 0x634B, 0xDEDB, + 0x634C, 0xB0C6, + 0x634D, 0xBAB4, + 0x634E, 0xC9D3, + 0x634F, 0xC4F3, + 0x6350, 0xBEE8, + 0x6355, 0xB2B6, + 0x635E, 0xC0CC, + 0x635F, 0xCBF0, + 0x6361, 0xBCF1, + 0x6362, 0xBBBB, + 0x6363, 0xB5B7, + 0x6367, 0xC5F5, + 0x6369, 0xDEE6, + 0x636D, 0xDEE3, + 0x636E, 0xBEDD, + 0x6371, 0xDEDF, + 0x6376, 0xB4B7, + 0x6377, 0xBDDD, + 0x637A, 0xDEE0, + 0x637B, 0xC4ED, + 0x6380, 0xCFC6, + 0x6382, 0xB5E0, + 0x6387, 0xB6DE, + 0x6388, 0xCADA, + 0x6389, 0xB5F4, + 0x638A, 0xDEE5, + 0x638C, 0xD5C6, + 0x638E, 0xDEE1, + 0x638F, 0xCCCD, + 0x6390, 0xC6FE, + 0x6392, 0xC5C5, + 0x6396, 0xD2B4, + 0x6398, 0xBEF2, + 0x63A0, 0xC2D3, + 0x63A2, 0xCCBD, + 0x63A3, 0xB3B8, + 0x63A5, 0xBDD3, + 0x63A7, 0xBFD8, + 0x63A8, 0xCDC6, + 0x63A9, 0xD1DA, + 0x63AA, 0xB4EB, + 0x63AC, 0xDEE4, + 0x63AD, 0xDEDD, + 0x63AE, 0xDEE7, + 0x63B0, 0xEAFE, + 0x63B3, 0xC2B0, + 0x63B4, 0xDEE2, + 0x63B7, 0xD6C0, + 0x63B8, 0xB5A7, + 0x63BA, 0xB2F4, + 0x63BC, 0xDEE8, + 0x63BE, 0xDEF2, + 0x63C4, 0xDEED, + 0x63C6, 0xDEF1, + 0x63C9, 0xC8E0, + 0x63CD, 0xD7E1, + 0x63CE, 0xDEEF, + 0x63CF, 0xC3E8, + 0x63D0, 0xCCE1, + 0x63D2, 0xB2E5, + 0x63D6, 0xD2BE, + 0x63DE, 0xDEEE, + 0x63E0, 0xDEEB, + 0x63E1, 0xCED5, + 0x63E3, 0xB4A7, + 0x63E9, 0xBFAB, + 0x63EA, 0xBEBE, + 0x63ED, 0xBDD2, + 0x63F2, 0xDEE9, + 0x63F4, 0xD4AE, + 0x63F6, 0xDEDE, + 0x63F8, 0xDEEA, + 0x63FD, 0xC0BF, + 0x63FF, 0xDEEC, + 0x6400, 0xB2F3, + 0x6401, 0xB8E9, + 0x6402, 0xC2A7, + 0x6405, 0xBDC1, + 0x640B, 0xDEF5, + 0x640C, 0xDEF8, + 0x640F, 0xB2AB, + 0x6410, 0xB4A4, + 0x6413, 0xB4EA, + 0x6414, 0xC9A6, + 0x641B, 0xDEF6, + 0x641C, 0xCBD1, + 0x641E, 0xB8E3, + 0x6420, 0xDEF7, + 0x6421, 0xDEFA, + 0x6426, 0xDEF9, + 0x642A, 0xCCC2, + 0x642C, 0xB0E1, + 0x642D, 0xB4EE, + 0x6434, 0xE5BA, + 0x643A, 0xD0AF, + 0x643D, 0xB2EB, + 0x643F, 0xEBA1, + 0x6441, 0xDEF4, + 0x6444, 0xC9E3, + 0x6445, 0xDEF3, + 0x6446, 0xB0DA, + 0x6447, 0xD2A1, + 0x6448, 0xB1F7, + 0x644A, 0xCCAF, + 0x6452, 0xDEF0, + 0x6454, 0xCBA4, + 0x6458, 0xD5AA, + 0x645E, 0xDEFB, + 0x6467, 0xB4DD, + 0x6469, 0xC4A6, + 0x646D, 0xDEFD, + 0x6478, 0xC3FE, + 0x6479, 0xC4A1, + 0x647A, 0xDFA1, + 0x6482, 0xC1CC, + 0x6484, 0xDEFC, + 0x6485, 0xBEEF, + 0x6487, 0xC6B2, + 0x6491, 0xB3C5, + 0x6492, 0xC8F6, + 0x6495, 0xCBBA, + 0x6496, 0xDEFE, + 0x6499, 0xDFA4, + 0x649E, 0xD7B2, + 0x64A4, 0xB3B7, + 0x64A9, 0xC1C3, + 0x64AC, 0xC7CB, + 0x64AD, 0xB2A5, + 0x64AE, 0xB4E9, + 0x64B0, 0xD7AB, + 0x64B5, 0xC4EC, + 0x64B7, 0xDFA2, + 0x64B8, 0xDFA3, + 0x64BA, 0xDFA5, + 0x64BC, 0xBAB3, + 0x64C0, 0xDFA6, + 0x64C2, 0xC0DE, + 0x64C5, 0xC9C3, + 0x64CD, 0xB2D9, + 0x64CE, 0xC7E6, + 0x64D0, 0xDFA7, + 0x64D2, 0xC7DC, + 0x64D7, 0xDFA8, + 0x64D8, 0xEBA2, + 0x64DE, 0xCBD3, + 0x64E2, 0xDFAA, + 0x64E4, 0xDFA9, + 0x64E6, 0xB2C1, + 0x6500, 0xC5CA, + 0x6509, 0xDFAB, + 0x6512, 0xD4DC, + 0x6518, 0xC8C1, + 0x6525, 0xDFAC, + 0x652B, 0xBEF0, + 0x652E, 0xDFAD, + 0x652F, 0xD6A7, + 0x6534, 0xEAB7, + 0x6535, 0xEBB6, + 0x6536, 0xCAD5, + 0x6538, 0xD8FC, + 0x6539, 0xB8C4, + 0x653B, 0xB9A5, + 0x653E, 0xB7C5, + 0x653F, 0xD5FE, + 0x6545, 0xB9CA, + 0x6548, 0xD0A7, + 0x6549, 0xF4CD, + 0x654C, 0xB5D0, + 0x654F, 0xC3F4, + 0x6551, 0xBEC8, + 0x6555, 0xEBB7, + 0x6556, 0xB0BD, + 0x6559, 0xBDCC, + 0x655B, 0xC1B2, + 0x655D, 0xB1D6, + 0x655E, 0xB3A8, + 0x6562, 0xB8D2, + 0x6563, 0xC9A2, + 0x6566, 0xB6D8, + 0x656B, 0xEBB8, + 0x656C, 0xBEB4, + 0x6570, 0xCAFD, + 0x6572, 0xC7C3, + 0x6574, 0xD5FB, + 0x6577, 0xB7F3, + 0x6587, 0xCEC4, + 0x658B, 0xD5AB, + 0x658C, 0xB1F3, + 0x6590, 0xECB3, + 0x6591, 0xB0DF, + 0x6593, 0xECB5, + 0x6597, 0xB6B7, + 0x6599, 0xC1CF, + 0x659B, 0xF5FA, + 0x659C, 0xD0B1, + 0x659F, 0xD5E5, + 0x65A1, 0xCED3, + 0x65A4, 0xBDEF, + 0x65A5, 0xB3E2, + 0x65A7, 0xB8AB, + 0x65A9, 0xD5B6, + 0x65AB, 0xEDBD, + 0x65AD, 0xB6CF, + 0x65AF, 0xCBB9, + 0x65B0, 0xD0C2, + 0x65B9, 0xB7BD, + 0x65BC, 0xECB6, + 0x65BD, 0xCAA9, + 0x65C1, 0xC5D4, + 0x65C3, 0xECB9, + 0x65C4, 0xECB8, + 0x65C5, 0xC2C3, + 0x65C6, 0xECB7, + 0x65CB, 0xD0FD, + 0x65CC, 0xECBA, + 0x65CE, 0xECBB, + 0x65CF, 0xD7E5, + 0x65D2, 0xECBC, + 0x65D6, 0xECBD, + 0x65D7, 0xC6EC, + 0x65E0, 0xCEDE, + 0x65E2, 0xBCC8, + 0x65E5, 0xC8D5, + 0x65E6, 0xB5A9, + 0x65E7, 0xBEC9, + 0x65E8, 0xD6BC, + 0x65E9, 0xD4E7, + 0x65EC, 0xD1AE, + 0x65ED, 0xD0F1, + 0x65EE, 0xEAB8, + 0x65EF, 0xEAB9, + 0x65F0, 0xEABA, + 0x65F1, 0xBAB5, + 0x65F6, 0xCAB1, + 0x65F7, 0xBFF5, + 0x65FA, 0xCDFA, + 0x6600, 0xEAC0, + 0x6602, 0xB0BA, + 0x6603, 0xEABE, + 0x6606, 0xC0A5, + 0x660A, 0xEABB, + 0x660C, 0xB2FD, + 0x660E, 0xC3F7, + 0x660F, 0xBBE8, + 0x6613, 0xD2D7, + 0x6614, 0xCEF4, + 0x6615, 0xEABF, + 0x6619, 0xEABC, + 0x661D, 0xEAC3, + 0x661F, 0xD0C7, + 0x6620, 0xD3B3, + 0x6625, 0xB4BA, + 0x6627, 0xC3C1, + 0x6628, 0xD7F2, + 0x662D, 0xD5D1, + 0x662F, 0xCAC7, + 0x6631, 0xEAC5, + 0x6634, 0xEAC4, + 0x6635, 0xEAC7, + 0x6636, 0xEAC6, + 0x663C, 0xD6E7, + 0x663E, 0xCFD4, + 0x6641, 0xEACB, + 0x6643, 0xBBCE, + 0x664B, 0xBDFA, + 0x664C, 0xC9CE, + 0x664F, 0xEACC, + 0x6652, 0xC9B9, + 0x6653, 0xCFFE, + 0x6654, 0xEACA, + 0x6655, 0xD4CE, + 0x6656, 0xEACD, + 0x6657, 0xEACF, + 0x665A, 0xCDED, + 0x665F, 0xEAC9, + 0x6661, 0xEACE, + 0x6664, 0xCEEE, + 0x6666, 0xBBDE, + 0x6668, 0xB3BF, + 0x666E, 0xC6D5, + 0x666F, 0xBEB0, + 0x6670, 0xCEFA, + 0x6674, 0xC7E7, + 0x6676, 0xBEA7, + 0x6677, 0xEAD0, + 0x667A, 0xD6C7, + 0x667E, 0xC1C0, + 0x6682, 0xD4DD, + 0x6684, 0xEAD1, + 0x6687, 0xCFBE, + 0x668C, 0xEAD2, + 0x6691, 0xCAEE, + 0x6696, 0xC5AF, + 0x6697, 0xB0B5, + 0x669D, 0xEAD4, + 0x66A7, 0xEAD3, + 0x66A8, 0xF4DF, + 0x66AE, 0xC4BA, + 0x66B4, 0xB1A9, + 0x66B9, 0xE5DF, + 0x66BE, 0xEAD5, + 0x66D9, 0xCAEF, + 0x66DB, 0xEAD6, + 0x66DC, 0xEAD7, + 0x66DD, 0xC6D8, + 0x66E6, 0xEAD8, + 0x66E9, 0xEAD9, + 0x66F0, 0xD4BB, + 0x66F2, 0xC7FA, + 0x66F3, 0xD2B7, + 0x66F4, 0xB8FC, + 0x66F7, 0xEAC2, + 0x66F9, 0xB2DC, + 0x66FC, 0xC2FC, + 0x66FE, 0xD4F8, + 0x66FF, 0xCCE6, + 0x6700, 0xD7EE, + 0x6708, 0xD4C2, + 0x6709, 0xD3D0, + 0x670A, 0xEBC3, + 0x670B, 0xC5F3, + 0x670D, 0xB7FE, + 0x6710, 0xEBD4, + 0x6714, 0xCBB7, + 0x6715, 0xEBDE, + 0x6717, 0xC0CA, + 0x671B, 0xCDFB, + 0x671D, 0xB3AF, + 0x671F, 0xC6DA, + 0x6726, 0xEBFC, + 0x6728, 0xC4BE, + 0x672A, 0xCEB4, + 0x672B, 0xC4A9, + 0x672C, 0xB1BE, + 0x672D, 0xD4FD, + 0x672F, 0xCAF5, + 0x6731, 0xD6EC, + 0x6734, 0xC6D3, + 0x6735, 0xB6E4, + 0x673A, 0xBBFA, + 0x673D, 0xD0E0, + 0x6740, 0xC9B1, + 0x6742, 0xD4D3, + 0x6743, 0xC8A8, + 0x6746, 0xB8CB, + 0x6748, 0xE8BE, + 0x6749, 0xC9BC, + 0x674C, 0xE8BB, + 0x674E, 0xC0EE, + 0x674F, 0xD0D3, + 0x6750, 0xB2C4, + 0x6751, 0xB4E5, + 0x6753, 0xE8BC, + 0x6756, 0xD5C8, + 0x675C, 0xB6C5, + 0x675E, 0xE8BD, + 0x675F, 0xCAF8, + 0x6760, 0xB8DC, + 0x6761, 0xCCF5, + 0x6765, 0xC0B4, + 0x6768, 0xD1EE, + 0x6769, 0xE8BF, + 0x676A, 0xE8C2, + 0x676D, 0xBABC, + 0x676F, 0xB1AD, + 0x6770, 0xBDDC, + 0x6772, 0xEABD, + 0x6773, 0xE8C3, + 0x6775, 0xE8C6, + 0x6777, 0xE8CB, + 0x677C, 0xE8CC, + 0x677E, 0xCBC9, + 0x677F, 0xB0E5, + 0x6781, 0xBCAB, + 0x6784, 0xB9B9, + 0x6787, 0xE8C1, + 0x6789, 0xCDF7, + 0x678B, 0xE8CA, + 0x6790, 0xCEF6, + 0x6795, 0xD5ED, + 0x6797, 0xC1D6, + 0x6798, 0xE8C4, + 0x679A, 0xC3B6, + 0x679C, 0xB9FB, + 0x679D, 0xD6A6, + 0x679E, 0xE8C8, + 0x67A2, 0xCAE0, + 0x67A3, 0xD4E6, + 0x67A5, 0xE8C0, + 0x67A7, 0xE8C5, + 0x67A8, 0xE8C7, + 0x67AA, 0xC7B9, + 0x67AB, 0xB7E3, + 0x67AD, 0xE8C9, + 0x67AF, 0xBFDD, + 0x67B0, 0xE8D2, + 0x67B3, 0xE8D7, + 0x67B5, 0xE8D5, + 0x67B6, 0xBCDC, + 0x67B7, 0xBCCF, + 0x67B8, 0xE8DB, + 0x67C1, 0xE8DE, + 0x67C3, 0xE8DA, + 0x67C4, 0xB1FA, + 0x67CF, 0xB0D8, + 0x67D0, 0xC4B3, + 0x67D1, 0xB8CC, + 0x67D2, 0xC6E2, + 0x67D3, 0xC8BE, + 0x67D4, 0xC8E1, + 0x67D8, 0xE8CF, + 0x67D9, 0xE8D4, + 0x67DA, 0xE8D6, + 0x67DC, 0xB9F1, + 0x67DD, 0xE8D8, + 0x67DE, 0xD7F5, + 0x67E0, 0xC4FB, + 0x67E2, 0xE8DC, + 0x67E5, 0xB2E9, + 0x67E9, 0xE8D1, + 0x67EC, 0xBCED, + 0x67EF, 0xBFC2, + 0x67F0, 0xE8CD, + 0x67F1, 0xD6F9, + 0x67F3, 0xC1F8, + 0x67F4, 0xB2F1, + 0x67FD, 0xE8DF, + 0x67FF, 0xCAC1, + 0x6800, 0xE8D9, + 0x6805, 0xD5A4, + 0x6807, 0xB1EA, + 0x6808, 0xD5BB, + 0x6809, 0xE8CE, + 0x680A, 0xE8D0, + 0x680B, 0xB6B0, + 0x680C, 0xE8D3, + 0x680E, 0xE8DD, + 0x680F, 0xC0B8, + 0x6811, 0xCAF7, + 0x6813, 0xCBA8, + 0x6816, 0xC6DC, + 0x6817, 0xC0F5, + 0x681D, 0xE8E9, + 0x6821, 0xD0A3, + 0x6829, 0xE8F2, + 0x682A, 0xD6EA, + 0x6832, 0xE8E0, + 0x6833, 0xE8E1, + 0x6837, 0xD1F9, + 0x6838, 0xBACB, + 0x6839, 0xB8F9, + 0x683C, 0xB8F1, + 0x683D, 0xD4D4, + 0x683E, 0xE8EF, + 0x6840, 0xE8EE, + 0x6841, 0xE8EC, + 0x6842, 0xB9F0, + 0x6843, 0xCCD2, + 0x6844, 0xE8E6, + 0x6845, 0xCEA6, + 0x6846, 0xBFF2, + 0x6848, 0xB0B8, + 0x6849, 0xE8F1, + 0x684A, 0xE8F0, + 0x684C, 0xD7C0, + 0x684E, 0xE8E4, + 0x6850, 0xCDA9, + 0x6851, 0xC9A3, + 0x6853, 0xBBB8, + 0x6854, 0xBDDB, + 0x6855, 0xE8EA, + 0x6860, 0xE8E2, + 0x6861, 0xE8E3, + 0x6862, 0xE8E5, + 0x6863, 0xB5B5, + 0x6864, 0xE8E7, + 0x6865, 0xC7C5, + 0x6866, 0xE8EB, + 0x6867, 0xE8ED, + 0x6868, 0xBDB0, + 0x6869, 0xD7AE, + 0x686B, 0xE8F8, + 0x6874, 0xE8F5, + 0x6876, 0xCDB0, + 0x6877, 0xE8F6, + 0x6881, 0xC1BA, + 0x6883, 0xE8E8, + 0x6885, 0xC3B7, + 0x6886, 0xB0F0, + 0x688F, 0xE8F4, + 0x6893, 0xE8F7, + 0x6897, 0xB9A3, + 0x68A2, 0xC9D2, + 0x68A6, 0xC3CE, + 0x68A7, 0xCEE0, + 0x68A8, 0xC0E6, + 0x68AD, 0xCBF3, + 0x68AF, 0xCCDD, + 0x68B0, 0xD0B5, + 0x68B3, 0xCAE1, + 0x68B5, 0xE8F3, + 0x68C0, 0xBCEC, + 0x68C2, 0xE8F9, + 0x68C9, 0xC3DE, + 0x68CB, 0xC6E5, + 0x68CD, 0xB9F7, + 0x68D2, 0xB0F4, + 0x68D5, 0xD7D8, + 0x68D8, 0xBCAC, + 0x68DA, 0xC5EF, + 0x68E0, 0xCCC4, + 0x68E3, 0xE9A6, + 0x68EE, 0xC9AD, + 0x68F0, 0xE9A2, + 0x68F1, 0xC0E2, + 0x68F5, 0xBFC3, + 0x68F9, 0xE8FE, + 0x68FA, 0xB9D7, + 0x68FC, 0xE8FB, + 0x6901, 0xE9A4, + 0x6905, 0xD2CE, + 0x690B, 0xE9A3, + 0x690D, 0xD6B2, + 0x690E, 0xD7B5, + 0x6910, 0xE9A7, + 0x6912, 0xBDB7, + 0x691F, 0xE8FC, + 0x6920, 0xE8FD, + 0x6924, 0xE9A1, + 0x692D, 0xCDD6, + 0x6930, 0xD2AC, + 0x6934, 0xE9B2, + 0x6939, 0xE9A9, + 0x693D, 0xB4AA, + 0x693F, 0xB4BB, + 0x6942, 0xE9AB, + 0x6954, 0xD0A8, + 0x6957, 0xE9A5, + 0x695A, 0xB3FE, + 0x695D, 0xE9AC, + 0x695E, 0xC0E3, + 0x6960, 0xE9AA, + 0x6963, 0xE9B9, + 0x6966, 0xE9B8, + 0x696B, 0xE9AE, + 0x696E, 0xE8FA, + 0x6971, 0xE9A8, + 0x6977, 0xBFAC, + 0x6978, 0xE9B1, + 0x6979, 0xE9BA, + 0x697C, 0xC2A5, + 0x6980, 0xE9AF, + 0x6982, 0xB8C5, + 0x6984, 0xE9AD, + 0x6986, 0xD3DC, + 0x6987, 0xE9B4, + 0x6988, 0xE9B5, + 0x6989, 0xE9B7, + 0x698D, 0xE9C7, + 0x6994, 0xC0C6, + 0x6995, 0xE9C5, + 0x6998, 0xE9B0, + 0x699B, 0xE9BB, + 0x699C, 0xB0F1, + 0x69A7, 0xE9BC, + 0x69A8, 0xD5A5, + 0x69AB, 0xE9BE, + 0x69AD, 0xE9BF, + 0x69B1, 0xE9C1, + 0x69B4, 0xC1F1, + 0x69B7, 0xC8B6, + 0x69BB, 0xE9BD, + 0x69C1, 0xE9C2, + 0x69CA, 0xE9C3, + 0x69CC, 0xE9B3, + 0x69CE, 0xE9B6, + 0x69D0, 0xBBB1, + 0x69D4, 0xE9C0, + 0x69DB, 0xBCF7, + 0x69DF, 0xE9C4, + 0x69E0, 0xE9C6, + 0x69ED, 0xE9CA, + 0x69F2, 0xE9CE, + 0x69FD, 0xB2DB, + 0x69FF, 0xE9C8, + 0x6A0A, 0xB7AE, + 0x6A17, 0xE9CB, + 0x6A18, 0xE9CC, + 0x6A1F, 0xD5C1, + 0x6A21, 0xC4A3, + 0x6A28, 0xE9D8, + 0x6A2A, 0xBAE1, + 0x6A2F, 0xE9C9, + 0x6A31, 0xD3A3, + 0x6A35, 0xE9D4, + 0x6A3D, 0xE9D7, + 0x6A3E, 0xE9D0, + 0x6A44, 0xE9CF, + 0x6A47, 0xC7C1, + 0x6A50, 0xE9D2, + 0x6A58, 0xE9D9, + 0x6A59, 0xB3C8, + 0x6A5B, 0xE9D3, + 0x6A61, 0xCFF0, + 0x6A65, 0xE9CD, + 0x6A71, 0xB3F7, + 0x6A79, 0xE9D6, + 0x6A7C, 0xE9DA, + 0x6A80, 0xCCB4, + 0x6A84, 0xCFAD, + 0x6A8E, 0xE9D5, + 0x6A90, 0xE9DC, + 0x6A91, 0xE9DB, + 0x6A97, 0xE9DE, + 0x6AA0, 0xE9D1, + 0x6AA9, 0xE9DD, + 0x6AAB, 0xE9DF, + 0x6AAC, 0xC3CA, + 0x6B20, 0xC7B7, + 0x6B21, 0xB4CE, + 0x6B22, 0xBBB6, + 0x6B23, 0xD0C0, + 0x6B24, 0xECA3, + 0x6B27, 0xC5B7, + 0x6B32, 0xD3FB, + 0x6B37, 0xECA4, + 0x6B39, 0xECA5, + 0x6B3A, 0xC6DB, + 0x6B3E, 0xBFEE, + 0x6B43, 0xECA6, + 0x6B46, 0xECA7, + 0x6B47, 0xD0AA, + 0x6B49, 0xC7B8, + 0x6B4C, 0xB8E8, + 0x6B59, 0xECA8, + 0x6B62, 0xD6B9, + 0x6B63, 0xD5FD, + 0x6B64, 0xB4CB, + 0x6B65, 0xB2BD, + 0x6B66, 0xCEE4, + 0x6B67, 0xC6E7, + 0x6B6A, 0xCDE1, + 0x6B79, 0xB4F5, + 0x6B7B, 0xCBC0, + 0x6B7C, 0xBCDF, + 0x6B81, 0xE9E2, + 0x6B82, 0xE9E3, + 0x6B83, 0xD1EA, + 0x6B84, 0xE9E5, + 0x6B86, 0xB4F9, + 0x6B87, 0xE9E4, + 0x6B89, 0xD1B3, + 0x6B8A, 0xCAE2, + 0x6B8B, 0xB2D0, + 0x6B8D, 0xE9E8, + 0x6B92, 0xE9E6, + 0x6B93, 0xE9E7, + 0x6B96, 0xD6B3, + 0x6B9A, 0xE9E9, + 0x6B9B, 0xE9EA, + 0x6BA1, 0xE9EB, + 0x6BAA, 0xE9EC, + 0x6BB3, 0xECAF, + 0x6BB4, 0xC5B9, + 0x6BB5, 0xB6CE, + 0x6BB7, 0xD2F3, + 0x6BBF, 0xB5EE, + 0x6BC1, 0xBBD9, + 0x6BC2, 0xECB1, + 0x6BC5, 0xD2E3, + 0x6BCB, 0xCEE3, + 0x6BCD, 0xC4B8, + 0x6BCF, 0xC3BF, + 0x6BD2, 0xB6BE, + 0x6BD3, 0xD8B9, + 0x6BD4, 0xB1C8, + 0x6BD5, 0xB1CF, + 0x6BD6, 0xB1D1, + 0x6BD7, 0xC5FE, + 0x6BD9, 0xB1D0, + 0x6BDB, 0xC3AB, + 0x6BE1, 0xD5B1, + 0x6BEA, 0xEBA4, + 0x6BEB, 0xBAC1, + 0x6BEF, 0xCCBA, + 0x6BF3, 0xEBA5, + 0x6BF5, 0xEBA7, + 0x6BF9, 0xEBA8, + 0x6BFD, 0xEBA6, + 0x6C05, 0xEBA9, + 0x6C06, 0xEBAB, + 0x6C07, 0xEBAA, + 0x6C0D, 0xEBAC, + 0x6C0F, 0xCACF, + 0x6C10, 0xD8B5, + 0x6C11, 0xC3F1, + 0x6C13, 0xC3A5, + 0x6C14, 0xC6F8, + 0x6C15, 0xEBAD, + 0x6C16, 0xC4CA, + 0x6C18, 0xEBAE, + 0x6C19, 0xEBAF, + 0x6C1A, 0xEBB0, + 0x6C1B, 0xB7D5, + 0x6C1F, 0xB7FA, + 0x6C21, 0xEBB1, + 0x6C22, 0xC7E2, + 0x6C24, 0xEBB3, + 0x6C26, 0xBAA4, + 0x6C27, 0xD1F5, + 0x6C28, 0xB0B1, + 0x6C29, 0xEBB2, + 0x6C2A, 0xEBB4, + 0x6C2E, 0xB5AA, + 0x6C2F, 0xC2C8, + 0x6C30, 0xC7E8, + 0x6C32, 0xEBB5, + 0x6C34, 0xCBAE, + 0x6C35, 0xE3DF, + 0x6C38, 0xD3C0, + 0x6C3D, 0xD9DB, + 0x6C40, 0xCDA1, + 0x6C41, 0xD6AD, + 0x6C42, 0xC7F3, + 0x6C46, 0xD9E0, + 0x6C47, 0xBBE3, + 0x6C49, 0xBABA, + 0x6C4A, 0xE3E2, + 0x6C50, 0xCFAB, + 0x6C54, 0xE3E0, + 0x6C55, 0xC9C7, + 0x6C57, 0xBAB9, + 0x6C5B, 0xD1B4, + 0x6C5C, 0xE3E1, + 0x6C5D, 0xC8EA, + 0x6C5E, 0xB9AF, + 0x6C5F, 0xBDAD, + 0x6C60, 0xB3D8, + 0x6C61, 0xCEDB, + 0x6C64, 0xCCC0, + 0x6C68, 0xE3E8, + 0x6C69, 0xE3E9, + 0x6C6A, 0xCDF4, + 0x6C70, 0xCCAD, + 0x6C72, 0xBCB3, + 0x6C74, 0xE3EA, + 0x6C76, 0xE3EB, + 0x6C79, 0xD0DA, + 0x6C7D, 0xC6FB, + 0x6C7E, 0xB7DA, + 0x6C81, 0xC7DF, + 0x6C82, 0xD2CA, + 0x6C83, 0xCED6, + 0x6C85, 0xE3E4, + 0x6C86, 0xE3EC, + 0x6C88, 0xC9F2, + 0x6C89, 0xB3C1, + 0x6C8C, 0xE3E7, + 0x6C8F, 0xC6E3, + 0x6C90, 0xE3E5, + 0x6C93, 0xEDB3, + 0x6C94, 0xE3E6, + 0x6C99, 0xC9B3, + 0x6C9B, 0xC5E6, + 0x6C9F, 0xB9B5, + 0x6CA1, 0xC3BB, + 0x6CA3, 0xE3E3, + 0x6CA4, 0xC5BD, + 0x6CA5, 0xC1A4, + 0x6CA6, 0xC2D9, + 0x6CA7, 0xB2D7, + 0x6CA9, 0xE3ED, + 0x6CAA, 0xBBA6, + 0x6CAB, 0xC4AD, + 0x6CAD, 0xE3F0, + 0x6CAE, 0xBEDA, + 0x6CB1, 0xE3FB, + 0x6CB2, 0xE3F5, + 0x6CB3, 0xBAD3, + 0x6CB8, 0xB7D0, + 0x6CB9, 0xD3CD, + 0x6CBB, 0xD6CE, + 0x6CBC, 0xD5D3, + 0x6CBD, 0xB9C1, + 0x6CBE, 0xD5B4, + 0x6CBF, 0xD1D8, + 0x6CC4, 0xD0B9, + 0x6CC5, 0xC7F6, + 0x6CC9, 0xC8AA, + 0x6CCA, 0xB2B4, + 0x6CCC, 0xC3DA, + 0x6CD0, 0xE3EE, + 0x6CD3, 0xE3FC, + 0x6CD4, 0xE3EF, + 0x6CD5, 0xB7A8, + 0x6CD6, 0xE3F7, + 0x6CD7, 0xE3F4, + 0x6CDB, 0xB7BA, + 0x6CDE, 0xC5A2, + 0x6CE0, 0xE3F6, + 0x6CE1, 0xC5DD, + 0x6CE2, 0xB2A8, + 0x6CE3, 0xC6FC, + 0x6CE5, 0xC4E0, + 0x6CE8, 0xD7A2, + 0x6CEA, 0xC0E1, + 0x6CEB, 0xE3F9, + 0x6CEE, 0xE3FA, + 0x6CEF, 0xE3FD, + 0x6CF0, 0xCCA9, + 0x6CF1, 0xE3F3, + 0x6CF3, 0xD3BE, + 0x6CF5, 0xB1C3, + 0x6CF6, 0xEDB4, + 0x6CF7, 0xE3F1, + 0x6CF8, 0xE3F2, + 0x6CFA, 0xE3F8, + 0x6CFB, 0xD0BA, + 0x6CFC, 0xC6C3, + 0x6CFD, 0xD4F3, + 0x6CFE, 0xE3FE, + 0x6D01, 0xBDE0, + 0x6D04, 0xE4A7, + 0x6D07, 0xE4A6, + 0x6D0B, 0xD1F3, + 0x6D0C, 0xE4A3, + 0x6D0E, 0xE4A9, + 0x6D12, 0xC8F7, + 0x6D17, 0xCFB4, + 0x6D19, 0xE4A8, + 0x6D1A, 0xE4AE, + 0x6D1B, 0xC2E5, + 0x6D1E, 0xB6B4, + 0x6D25, 0xBDF2, + 0x6D27, 0xE4A2, + 0x6D2A, 0xBAE9, + 0x6D2B, 0xE4AA, + 0x6D2E, 0xE4AC, + 0x6D31, 0xB6FD, + 0x6D32, 0xD6DE, + 0x6D33, 0xE4B2, + 0x6D35, 0xE4AD, + 0x6D39, 0xE4A1, + 0x6D3B, 0xBBEE, + 0x6D3C, 0xCDDD, + 0x6D3D, 0xC7A2, + 0x6D3E, 0xC5C9, + 0x6D41, 0xC1F7, + 0x6D43, 0xE4A4, + 0x6D45, 0xC7B3, + 0x6D46, 0xBDAC, + 0x6D47, 0xBDBD, + 0x6D48, 0xE4A5, + 0x6D4A, 0xD7C7, + 0x6D4B, 0xB2E2, + 0x6D4D, 0xE4AB, + 0x6D4E, 0xBCC3, + 0x6D4F, 0xE4AF, + 0x6D51, 0xBBEB, + 0x6D52, 0xE4B0, + 0x6D53, 0xC5A8, + 0x6D54, 0xE4B1, + 0x6D59, 0xD5E3, + 0x6D5A, 0xBFA3, + 0x6D5C, 0xE4BA, + 0x6D5E, 0xE4B7, + 0x6D60, 0xE4BB, + 0x6D63, 0xE4BD, + 0x6D66, 0xC6D6, + 0x6D69, 0xBAC6, + 0x6D6A, 0xC0CB, + 0x6D6E, 0xB8A1, + 0x6D6F, 0xE4B4, + 0x6D74, 0xD4A1, + 0x6D77, 0xBAA3, + 0x6D78, 0xBDFE, + 0x6D7C, 0xE4BC, + 0x6D82, 0xCDBF, + 0x6D85, 0xC4F9, + 0x6D88, 0xCFFB, + 0x6D89, 0xC9E6, + 0x6D8C, 0xD3BF, + 0x6D8E, 0xCFD1, + 0x6D91, 0xE4B3, + 0x6D93, 0xE4B8, + 0x6D94, 0xE4B9, + 0x6D95, 0xCCE9, + 0x6D9B, 0xCCCE, + 0x6D9D, 0xC0D4, + 0x6D9E, 0xE4B5, + 0x6D9F, 0xC1B0, + 0x6DA0, 0xE4B6, + 0x6DA1, 0xCED0, + 0x6DA3, 0xBBC1, + 0x6DA4, 0xB5D3, + 0x6DA6, 0xC8F3, + 0x6DA7, 0xBDA7, + 0x6DA8, 0xD5C7, + 0x6DA9, 0xC9AC, + 0x6DAA, 0xB8A2, + 0x6DAB, 0xE4CA, + 0x6DAE, 0xE4CC, + 0x6DAF, 0xD1C4, + 0x6DB2, 0xD2BA, + 0x6DB5, 0xBAAD, + 0x6DB8, 0xBAD4, + 0x6DBF, 0xE4C3, + 0x6DC0, 0xB5ED, + 0x6DC4, 0xD7CD, + 0x6DC5, 0xE4C0, + 0x6DC6, 0xCFFD, + 0x6DC7, 0xE4BF, + 0x6DCB, 0xC1DC, + 0x6DCC, 0xCCCA, + 0x6DD1, 0xCAE7, + 0x6DD6, 0xC4D7, + 0x6DD8, 0xCCD4, + 0x6DD9, 0xE4C8, + 0x6DDD, 0xE4C7, + 0x6DDE, 0xE4C1, + 0x6DE0, 0xE4C4, + 0x6DE1, 0xB5AD, + 0x6DE4, 0xD3D9, + 0x6DE6, 0xE4C6, + 0x6DEB, 0xD2F9, + 0x6DEC, 0xB4E3, + 0x6DEE, 0xBBB4, + 0x6DF1, 0xC9EE, + 0x6DF3, 0xB4BE, + 0x6DF7, 0xBBEC, + 0x6DF9, 0xD1CD, + 0x6DFB, 0xCCED, + 0x6DFC, 0xEDB5, + 0x6E05, 0xC7E5, + 0x6E0A, 0xD4A8, + 0x6E0C, 0xE4CB, + 0x6E0D, 0xD7D5, + 0x6E0E, 0xE4C2, + 0x6E10, 0xBDA5, + 0x6E11, 0xE4C5, + 0x6E14, 0xD3E6, + 0x6E16, 0xE4C9, + 0x6E17, 0xC9F8, + 0x6E1A, 0xE4BE, + 0x6E1D, 0xD3E5, + 0x6E20, 0xC7FE, + 0x6E21, 0xB6C9, + 0x6E23, 0xD4FC, + 0x6E24, 0xB2B3, + 0x6E25, 0xE4D7, + 0x6E29, 0xCEC2, + 0x6E2B, 0xE4CD, + 0x6E2D, 0xCEBC, + 0x6E2F, 0xB8DB, + 0x6E32, 0xE4D6, + 0x6E34, 0xBFCA, + 0x6E38, 0xD3CE, + 0x6E3A, 0xC3EC, + 0x6E43, 0xC5C8, + 0x6E44, 0xE4D8, + 0x6E4D, 0xCDC4, + 0x6E4E, 0xE4CF, + 0x6E53, 0xE4D4, + 0x6E54, 0xE4D5, + 0x6E56, 0xBAFE, + 0x6E58, 0xCFE6, + 0x6E5B, 0xD5BF, + 0x6E5F, 0xE4D2, + 0x6E6B, 0xE4D0, + 0x6E6E, 0xE4CE, + 0x6E7E, 0xCDE5, + 0x6E7F, 0xCAAA, + 0x6E83, 0xC0A3, + 0x6E85, 0xBDA6, + 0x6E86, 0xE4D3, + 0x6E89, 0xB8C8, + 0x6E8F, 0xE4E7, + 0x6E90, 0xD4B4, + 0x6E98, 0xE4DB, + 0x6E9C, 0xC1EF, + 0x6E9F, 0xE4E9, + 0x6EA2, 0xD2E7, + 0x6EA5, 0xE4DF, + 0x6EA7, 0xE4E0, + 0x6EAA, 0xCFAA, + 0x6EAF, 0xCBDD, + 0x6EB1, 0xE4DA, + 0x6EB2, 0xE4D1, + 0x6EB4, 0xE4E5, + 0x6EB6, 0xC8DC, + 0x6EB7, 0xE4E3, + 0x6EBA, 0xC4E7, + 0x6EBB, 0xE4E2, + 0x6EBD, 0xE4E1, + 0x6EC1, 0xB3FC, + 0x6EC2, 0xE4E8, + 0x6EC7, 0xB5E1, + 0x6ECB, 0xD7CC, + 0x6ECF, 0xE4E6, + 0x6ED1, 0xBBAC, + 0x6ED3, 0xD7D2, + 0x6ED4, 0xCCCF, + 0x6ED5, 0xEBF8, + 0x6ED7, 0xE4E4, + 0x6EDA, 0xB9F6, + 0x6EDE, 0xD6CD, + 0x6EDF, 0xE4D9, + 0x6EE0, 0xE4DC, + 0x6EE1, 0xC2FA, + 0x6EE2, 0xE4DE, + 0x6EE4, 0xC2CB, + 0x6EE5, 0xC0C4, + 0x6EE6, 0xC2D0, + 0x6EE8, 0xB1F5, + 0x6EE9, 0xCCB2, + 0x6EF4, 0xB5CE, + 0x6EF9, 0xE4EF, + 0x6F02, 0xC6AF, + 0x6F06, 0xC6E1, + 0x6F09, 0xE4F5, + 0x6F0F, 0xC2A9, + 0x6F13, 0xC0EC, + 0x6F14, 0xD1DD, + 0x6F15, 0xE4EE, + 0x6F20, 0xC4AE, + 0x6F24, 0xE4ED, + 0x6F29, 0xE4F6, + 0x6F2A, 0xE4F4, + 0x6F2B, 0xC2FE, + 0x6F2D, 0xE4DD, + 0x6F2F, 0xE4F0, + 0x6F31, 0xCAFE, + 0x6F33, 0xD5C4, + 0x6F36, 0xE4F1, + 0x6F3E, 0xD1FA, + 0x6F46, 0xE4EB, + 0x6F47, 0xE4EC, + 0x6F4B, 0xE4F2, + 0x6F4D, 0xCEAB, + 0x6F58, 0xC5CB, + 0x6F5C, 0xC7B1, + 0x6F5E, 0xC2BA, + 0x6F62, 0xE4EA, + 0x6F66, 0xC1CA, + 0x6F6D, 0xCCB6, + 0x6F6E, 0xB3B1, + 0x6F72, 0xE4FB, + 0x6F74, 0xE4F3, + 0x6F78, 0xE4FA, + 0x6F7A, 0xE4FD, + 0x6F7C, 0xE4FC, + 0x6F84, 0xB3CE, + 0x6F88, 0xB3BA, + 0x6F89, 0xE4F7, + 0x6F8C, 0xE4F9, + 0x6F8D, 0xE4F8, + 0x6F8E, 0xC5EC, + 0x6F9C, 0xC0BD, + 0x6FA1, 0xD4E8, + 0x6FA7, 0xE5A2, + 0x6FB3, 0xB0C4, + 0x6FB6, 0xE5A4, + 0x6FB9, 0xE5A3, + 0x6FC0, 0xBCA4, + 0x6FC2, 0xE5A5, + 0x6FC9, 0xE5A1, + 0x6FD1, 0xE4FE, + 0x6FD2, 0xB1F4, + 0x6FDE, 0xE5A8, + 0x6FE0, 0xE5A9, + 0x6FE1, 0xE5A6, + 0x6FEE, 0xE5A7, + 0x6FEF, 0xE5AA, + 0x7011, 0xC6D9, + 0x701A, 0xE5AB, + 0x701B, 0xE5AD, + 0x7023, 0xE5AC, + 0x7035, 0xE5AF, + 0x7039, 0xE5AE, + 0x704C, 0xB9E0, + 0x704F, 0xE5B0, + 0x705E, 0xE5B1, + 0x706B, 0xBBF0, + 0x706C, 0xECE1, + 0x706D, 0xC3F0, + 0x706F, 0xB5C6, + 0x7070, 0xBBD2, + 0x7075, 0xC1E9, + 0x7076, 0xD4EE, + 0x7078, 0xBEC4, + 0x707C, 0xD7C6, + 0x707E, 0xD4D6, + 0x707F, 0xB2D3, + 0x7080, 0xECBE, + 0x7085, 0xEAC1, + 0x7089, 0xC2AF, + 0x708A, 0xB4B6, + 0x708E, 0xD1D7, + 0x7092, 0xB3B4, + 0x7094, 0xC8B2, + 0x7095, 0xBFBB, + 0x7096, 0xECC0, + 0x7099, 0xD6CB, + 0x709C, 0xECBF, + 0x709D, 0xECC1, + 0x70AB, 0xECC5, + 0x70AC, 0xBEE6, + 0x70AD, 0xCCBF, + 0x70AE, 0xC5DA, + 0x70AF, 0xBEBC, + 0x70B1, 0xECC6, + 0x70B3, 0xB1FE, + 0x70B7, 0xECC4, + 0x70B8, 0xD5A8, + 0x70B9, 0xB5E3, + 0x70BB, 0xECC2, + 0x70BC, 0xC1B6, + 0x70BD, 0xB3E3, + 0x70C0, 0xECC3, + 0x70C1, 0xCBB8, + 0x70C2, 0xC0C3, + 0x70C3, 0xCCFE, + 0x70C8, 0xC1D2, + 0x70CA, 0xECC8, + 0x70D8, 0xBAE6, + 0x70D9, 0xC0D3, + 0x70DB, 0xD6F2, + 0x70DF, 0xD1CC, + 0x70E4, 0xBFBE, + 0x70E6, 0xB7B3, + 0x70E7, 0xC9D5, + 0x70E8, 0xECC7, + 0x70E9, 0xBBE2, + 0x70EB, 0xCCCC, + 0x70EC, 0xBDFD, + 0x70ED, 0xC8C8, + 0x70EF, 0xCFA9, + 0x70F7, 0xCDE9, + 0x70F9, 0xC5EB, + 0x70FD, 0xB7E9, + 0x7109, 0xD1C9, + 0x710A, 0xBAB8, + 0x7110, 0xECC9, + 0x7113, 0xECCA, + 0x7115, 0xBBC0, + 0x7116, 0xECCB, + 0x7118, 0xECE2, + 0x7119, 0xB1BA, + 0x711A, 0xB7D9, + 0x7126, 0xBDB9, + 0x712F, 0xECCC, + 0x7130, 0xD1E6, + 0x7131, 0xECCD, + 0x7136, 0xC8BB, + 0x7145, 0xECD1, + 0x714A, 0xECD3, + 0x714C, 0xBBCD, + 0x714E, 0xBCE5, + 0x715C, 0xECCF, + 0x715E, 0xC9B7, + 0x7164, 0xC3BA, + 0x7166, 0xECE3, + 0x7167, 0xD5D5, + 0x7168, 0xECD0, + 0x716E, 0xD6F3, + 0x7172, 0xECD2, + 0x7173, 0xECCE, + 0x7178, 0xECD4, + 0x717A, 0xECD5, + 0x717D, 0xC9BF, + 0x7184, 0xCFA8, + 0x718A, 0xD0DC, + 0x718F, 0xD1AC, + 0x7194, 0xC8DB, + 0x7198, 0xECD6, + 0x7199, 0xCEF5, + 0x719F, 0xCAEC, + 0x71A0, 0xECDA, + 0x71A8, 0xECD9, + 0x71AC, 0xB0BE, + 0x71B3, 0xECD7, + 0x71B5, 0xECD8, + 0x71B9, 0xECE4, + 0x71C3, 0xC8BC, + 0x71CE, 0xC1C7, + 0x71D4, 0xECDC, + 0x71D5, 0xD1E0, + 0x71E0, 0xECDB, + 0x71E5, 0xD4EF, + 0x71E7, 0xECDD, + 0x71EE, 0xDBC6, + 0x71F9, 0xECDE, + 0x7206, 0xB1AC, + 0x721D, 0xECDF, + 0x7228, 0xECE0, + 0x722A, 0xD7A6, + 0x722C, 0xC5C0, + 0x7230, 0xEBBC, + 0x7231, 0xB0AE, + 0x7235, 0xBEF4, + 0x7236, 0xB8B8, + 0x7237, 0xD2AF, + 0x7238, 0xB0D6, + 0x7239, 0xB5F9, + 0x723B, 0xD8B3, + 0x723D, 0xCBAC, + 0x723F, 0xE3DD, + 0x7247, 0xC6AC, + 0x7248, 0xB0E6, + 0x724C, 0xC5C6, + 0x724D, 0xEBB9, + 0x7252, 0xEBBA, + 0x7256, 0xEBBB, + 0x7259, 0xD1C0, + 0x725B, 0xC5A3, + 0x725D, 0xEAF2, + 0x725F, 0xC4B2, + 0x7261, 0xC4B5, + 0x7262, 0xC0CE, + 0x7266, 0xEAF3, + 0x7267, 0xC4C1, + 0x7269, 0xCEEF, + 0x726E, 0xEAF0, + 0x726F, 0xEAF4, + 0x7272, 0xC9FC, + 0x7275, 0xC7A3, + 0x7279, 0xCCD8, + 0x727A, 0xCEFE, + 0x727E, 0xEAF5, + 0x727F, 0xEAF6, + 0x7280, 0xCFAC, + 0x7281, 0xC0E7, + 0x7284, 0xEAF7, + 0x728A, 0xB6BF, + 0x728B, 0xEAF8, + 0x728D, 0xEAF9, + 0x728F, 0xEAFA, + 0x7292, 0xEAFB, + 0x729F, 0xEAF1, + 0x72AC, 0xC8AE, + 0x72AD, 0xE1EB, + 0x72AF, 0xB7B8, + 0x72B0, 0xE1EC, + 0x72B4, 0xE1ED, + 0x72B6, 0xD7B4, + 0x72B7, 0xE1EE, + 0x72B8, 0xE1EF, + 0x72B9, 0xD3CC, + 0x72C1, 0xE1F1, + 0x72C2, 0xBFF1, + 0x72C3, 0xE1F0, + 0x72C4, 0xB5D2, + 0x72C8, 0xB1B7, + 0x72CD, 0xE1F3, + 0x72CE, 0xE1F2, + 0x72D0, 0xBAFC, + 0x72D2, 0xE1F4, + 0x72D7, 0xB9B7, + 0x72D9, 0xBED1, + 0x72DE, 0xC4FC, + 0x72E0, 0xBADD, + 0x72E1, 0xBDC6, + 0x72E8, 0xE1F5, + 0x72E9, 0xE1F7, + 0x72EC, 0xB6C0, + 0x72ED, 0xCFC1, + 0x72EE, 0xCAA8, + 0x72EF, 0xE1F6, + 0x72F0, 0xD5F8, + 0x72F1, 0xD3FC, + 0x72F2, 0xE1F8, + 0x72F3, 0xE1FC, + 0x72F4, 0xE1F9, + 0x72F7, 0xE1FA, + 0x72F8, 0xC0EA, + 0x72FA, 0xE1FE, + 0x72FB, 0xE2A1, + 0x72FC, 0xC0C7, + 0x7301, 0xE1FB, + 0x7303, 0xE1FD, + 0x730A, 0xE2A5, + 0x730E, 0xC1D4, + 0x7313, 0xE2A3, + 0x7315, 0xE2A8, + 0x7316, 0xB2FE, + 0x7317, 0xE2A2, + 0x731B, 0xC3CD, + 0x731C, 0xB2C2, + 0x731D, 0xE2A7, + 0x731E, 0xE2A6, + 0x7321, 0xE2A4, + 0x7322, 0xE2A9, + 0x7325, 0xE2AB, + 0x7329, 0xD0C9, + 0x732A, 0xD6ED, + 0x732B, 0xC3A8, + 0x732C, 0xE2AC, + 0x732E, 0xCFD7, + 0x7331, 0xE2AE, + 0x7334, 0xBAEF, + 0x7337, 0xE9E0, + 0x7338, 0xE2AD, + 0x7339, 0xE2AA, + 0x733E, 0xBBAB, + 0x733F, 0xD4B3, + 0x734D, 0xE2B0, + 0x7350, 0xE2AF, + 0x7352, 0xE9E1, + 0x7357, 0xE2B1, + 0x7360, 0xE2B2, + 0x736C, 0xE2B3, + 0x736D, 0xCCA1, + 0x736F, 0xE2B4, + 0x737E, 0xE2B5, + 0x7384, 0xD0FE, + 0x7387, 0xC2CA, + 0x7389, 0xD3F1, + 0x738B, 0xCDF5, + 0x738E, 0xE7E0, + 0x7391, 0xE7E1, + 0x7396, 0xBEC1, + 0x739B, 0xC2EA, + 0x739F, 0xE7E4, + 0x73A2, 0xE7E3, + 0x73A9, 0xCDE6, + 0x73AB, 0xC3B5, + 0x73AE, 0xE7E2, + 0x73AF, 0xBBB7, + 0x73B0, 0xCFD6, + 0x73B2, 0xC1E1, + 0x73B3, 0xE7E9, + 0x73B7, 0xE7E8, + 0x73BA, 0xE7F4, + 0x73BB, 0xB2A3, + 0x73C0, 0xE7EA, + 0x73C2, 0xE7E6, + 0x73C8, 0xE7EC, + 0x73C9, 0xE7EB, + 0x73CA, 0xC9BA, + 0x73CD, 0xD5E4, + 0x73CF, 0xE7E5, + 0x73D0, 0xB7A9, + 0x73D1, 0xE7E7, + 0x73D9, 0xE7EE, + 0x73DE, 0xE7F3, + 0x73E0, 0xD6E9, + 0x73E5, 0xE7ED, + 0x73E7, 0xE7F2, + 0x73E9, 0xE7F1, + 0x73ED, 0xB0E0, + 0x73F2, 0xE7F5, + 0x7403, 0xC7F2, + 0x7405, 0xC0C5, + 0x7406, 0xC0ED, + 0x7409, 0xC1F0, + 0x740A, 0xE7F0, + 0x740F, 0xE7F6, + 0x7410, 0xCBF6, + 0x741A, 0xE8A2, + 0x741B, 0xE8A1, + 0x7422, 0xD7C1, + 0x7425, 0xE7FA, + 0x7426, 0xE7F9, + 0x7428, 0xE7FB, + 0x742A, 0xE7F7, + 0x742C, 0xE7FE, + 0x742E, 0xE7FD, + 0x7430, 0xE7FC, + 0x7433, 0xC1D5, + 0x7434, 0xC7D9, + 0x7435, 0xC5FD, + 0x7436, 0xC5C3, + 0x743C, 0xC7ED, + 0x7441, 0xE8A3, + 0x7455, 0xE8A6, + 0x7457, 0xE8A5, + 0x7459, 0xE8A7, + 0x745A, 0xBAF7, + 0x745B, 0xE7F8, + 0x745C, 0xE8A4, + 0x745E, 0xC8F0, + 0x745F, 0xC9AA, + 0x746D, 0xE8A9, + 0x7470, 0xB9E5, + 0x7476, 0xD1FE, + 0x7477, 0xE8A8, + 0x747E, 0xE8AA, + 0x7480, 0xE8AD, + 0x7481, 0xE8AE, + 0x7483, 0xC1A7, + 0x7487, 0xE8AF, + 0x748B, 0xE8B0, + 0x748E, 0xE8AC, + 0x7490, 0xE8B4, + 0x749C, 0xE8AB, + 0x749E, 0xE8B1, + 0x74A7, 0xE8B5, + 0x74A8, 0xE8B2, + 0x74A9, 0xE8B3, + 0x74BA, 0xE8B7, + 0x74D2, 0xE8B6, + 0x74DC, 0xB9CF, + 0x74DE, 0xF0AC, + 0x74E0, 0xF0AD, + 0x74E2, 0xC6B0, + 0x74E3, 0xB0EA, + 0x74E4, 0xC8BF, + 0x74E6, 0xCDDF, + 0x74EE, 0xCECD, + 0x74EF, 0xEAB1, + 0x74F4, 0xEAB2, + 0x74F6, 0xC6BF, + 0x74F7, 0xB4C9, + 0x74FF, 0xEAB3, + 0x7504, 0xD5E7, + 0x750D, 0xDDF9, + 0x750F, 0xEAB4, + 0x7511, 0xEAB5, + 0x7513, 0xEAB6, + 0x7518, 0xB8CA, + 0x7519, 0xDFB0, + 0x751A, 0xC9F5, + 0x751C, 0xCCF0, + 0x751F, 0xC9FA, + 0x7525, 0xC9FB, + 0x7528, 0xD3C3, + 0x7529, 0xCBA6, + 0x752B, 0xB8A6, + 0x752C, 0xF0AE, + 0x752D, 0xB1C2, + 0x752F, 0xE5B8, + 0x7530, 0xCCEF, + 0x7531, 0xD3C9, + 0x7532, 0xBCD7, + 0x7533, 0xC9EA, + 0x7535, 0xB5E7, + 0x7537, 0xC4D0, + 0x7538, 0xB5E9, + 0x753A, 0xEEAE, + 0x753B, 0xBBAD, + 0x753E, 0xE7DE, + 0x7540, 0xEEAF, + 0x7545, 0xB3A9, + 0x7548, 0xEEB2, + 0x754B, 0xEEB1, + 0x754C, 0xBDE7, + 0x754E, 0xEEB0, + 0x754F, 0xCEB7, + 0x7554, 0xC5CF, + 0x7559, 0xC1F4, + 0x755A, 0xDBCE, + 0x755B, 0xEEB3, + 0x755C, 0xD0F3, + 0x7565, 0xC2D4, + 0x7566, 0xC6E8, + 0x756A, 0xB7AC, + 0x7572, 0xEEB4, + 0x7574, 0xB3EB, + 0x7578, 0xBBFB, + 0x7579, 0xEEB5, + 0x757F, 0xE7DC, + 0x7583, 0xEEB6, + 0x7586, 0xBDAE, + 0x758B, 0xF1E2, + 0x758F, 0xCAE8, + 0x7591, 0xD2C9, + 0x7592, 0xF0DA, + 0x7594, 0xF0DB, + 0x7596, 0xF0DC, + 0x7597, 0xC1C6, + 0x7599, 0xB8ED, + 0x759A, 0xBECE, + 0x759D, 0xF0DE, + 0x759F, 0xC5B1, + 0x75A0, 0xF0DD, + 0x75A1, 0xD1F1, + 0x75A3, 0xF0E0, + 0x75A4, 0xB0CC, + 0x75A5, 0xBDEA, + 0x75AB, 0xD2DF, + 0x75AC, 0xF0DF, + 0x75AE, 0xB4AF, + 0x75AF, 0xB7E8, + 0x75B0, 0xF0E6, + 0x75B1, 0xF0E5, + 0x75B2, 0xC6A3, + 0x75B3, 0xF0E1, + 0x75B4, 0xF0E2, + 0x75B5, 0xB4C3, + 0x75B8, 0xF0E3, + 0x75B9, 0xD5EE, + 0x75BC, 0xCCDB, + 0x75BD, 0xBED2, + 0x75BE, 0xBCB2, + 0x75C2, 0xF0E8, + 0x75C3, 0xF0E7, + 0x75C4, 0xF0E4, + 0x75C5, 0xB2A1, + 0x75C7, 0xD6A2, + 0x75C8, 0xD3B8, + 0x75C9, 0xBEB7, + 0x75CA, 0xC8AC, + 0x75CD, 0xF0EA, + 0x75D2, 0xD1F7, + 0x75D4, 0xD6CC, + 0x75D5, 0xBADB, + 0x75D6, 0xF0E9, + 0x75D8, 0xB6BB, + 0x75DB, 0xCDB4, + 0x75DE, 0xC6A6, + 0x75E2, 0xC1A1, + 0x75E3, 0xF0EB, + 0x75E4, 0xF0EE, + 0x75E6, 0xF0ED, + 0x75E7, 0xF0F0, + 0x75E8, 0xF0EC, + 0x75EA, 0xBBBE, + 0x75EB, 0xF0EF, + 0x75F0, 0xCCB5, + 0x75F1, 0xF0F2, + 0x75F4, 0xB3D5, + 0x75F9, 0xB1D4, + 0x75FC, 0xF0F3, + 0x75FF, 0xF0F4, + 0x7600, 0xF0F6, + 0x7601, 0xB4E1, + 0x7603, 0xF0F1, + 0x7605, 0xF0F7, + 0x760A, 0xF0FA, + 0x760C, 0xF0F8, + 0x7610, 0xF0F5, + 0x7615, 0xF0FD, + 0x7617, 0xF0F9, + 0x7618, 0xF0FC, + 0x7619, 0xF0FE, + 0x761B, 0xF1A1, + 0x761F, 0xCEC1, + 0x7620, 0xF1A4, + 0x7622, 0xF1A3, + 0x7624, 0xC1F6, + 0x7625, 0xF0FB, + 0x7626, 0xCADD, + 0x7629, 0xB4F1, + 0x762A, 0xB1F1, + 0x762B, 0xCCB1, + 0x762D, 0xF1A6, + 0x7630, 0xF1A7, + 0x7633, 0xF1AC, + 0x7634, 0xD5CE, + 0x7635, 0xF1A9, + 0x7638, 0xC8B3, + 0x763C, 0xF1A2, + 0x763E, 0xF1AB, + 0x763F, 0xF1A8, + 0x7640, 0xF1A5, + 0x7643, 0xF1AA, + 0x764C, 0xB0A9, + 0x764D, 0xF1AD, + 0x7654, 0xF1AF, + 0x7656, 0xF1B1, + 0x765C, 0xF1B0, + 0x765E, 0xF1AE, + 0x7663, 0xD1A2, + 0x766B, 0xF1B2, + 0x766F, 0xF1B3, + 0x7678, 0xB9EF, + 0x767B, 0xB5C7, + 0x767D, 0xB0D7, + 0x767E, 0xB0D9, + 0x7682, 0xD4ED, + 0x7684, 0xB5C4, + 0x7686, 0xBDD4, + 0x7687, 0xBBCA, + 0x7688, 0xF0A7, + 0x768B, 0xB8DE, + 0x768E, 0xF0A8, + 0x7691, 0xB0A8, + 0x7693, 0xF0A9, + 0x7696, 0xCDEE, + 0x7699, 0xF0AA, + 0x76A4, 0xF0AB, + 0x76AE, 0xC6A4, + 0x76B1, 0xD6E5, + 0x76B2, 0xF1E4, + 0x76B4, 0xF1E5, + 0x76BF, 0xC3F3, + 0x76C2, 0xD3DB, + 0x76C5, 0xD6D1, + 0x76C6, 0xC5E8, + 0x76C8, 0xD3AF, + 0x76CA, 0xD2E6, + 0x76CD, 0xEEC1, + 0x76CE, 0xB0BB, + 0x76CF, 0xD5B5, + 0x76D0, 0xD1CE, + 0x76D1, 0xBCE0, + 0x76D2, 0xBAD0, + 0x76D4, 0xBFF8, + 0x76D6, 0xB8C7, + 0x76D7, 0xB5C1, + 0x76D8, 0xC5CC, + 0x76DB, 0xCAA2, + 0x76DF, 0xC3CB, + 0x76E5, 0xEEC2, + 0x76EE, 0xC4BF, + 0x76EF, 0xB6A2, + 0x76F1, 0xEDEC, + 0x76F2, 0xC3A4, + 0x76F4, 0xD6B1, + 0x76F8, 0xCFE0, + 0x76F9, 0xEDEF, + 0x76FC, 0xC5CE, + 0x76FE, 0xB6DC, + 0x7701, 0xCAA1, + 0x7704, 0xEDED, + 0x7707, 0xEDF0, + 0x7708, 0xEDF1, + 0x7709, 0xC3BC, + 0x770B, 0xBFB4, + 0x770D, 0xEDEE, + 0x7719, 0xEDF4, + 0x771A, 0xEDF2, + 0x771F, 0xD5E6, + 0x7720, 0xC3DF, + 0x7722, 0xEDF3, + 0x7726, 0xEDF6, + 0x7728, 0xD5A3, + 0x7729, 0xD1A3, + 0x772D, 0xEDF5, + 0x772F, 0xC3D0, + 0x7735, 0xEDF7, + 0x7736, 0xBFF4, + 0x7737, 0xBEEC, + 0x7738, 0xEDF8, + 0x773A, 0xCCF7, + 0x773C, 0xD1DB, + 0x7740, 0xD7C5, + 0x7741, 0xD5F6, + 0x7743, 0xEDFC, + 0x7747, 0xEDFB, + 0x7750, 0xEDF9, + 0x7751, 0xEDFA, + 0x775A, 0xEDFD, + 0x775B, 0xBEA6, + 0x7761, 0xCBAF, + 0x7762, 0xEEA1, + 0x7763, 0xB6BD, + 0x7765, 0xEEA2, + 0x7766, 0xC4C0, + 0x7768, 0xEDFE, + 0x776B, 0xBDDE, + 0x776C, 0xB2C7, + 0x7779, 0xB6C3, + 0x777D, 0xEEA5, + 0x777E, 0xD8BA, + 0x777F, 0xEEA3, + 0x7780, 0xEEA6, + 0x7784, 0xC3E9, + 0x7785, 0xB3F2, + 0x778C, 0xEEA7, + 0x778D, 0xEEA4, + 0x778E, 0xCFB9, + 0x7791, 0xEEA8, + 0x7792, 0xC2F7, + 0x779F, 0xEEA9, + 0x77A0, 0xEEAA, + 0x77A2, 0xDEAB, + 0x77A5, 0xC6B3, + 0x77A7, 0xC7C6, + 0x77A9, 0xD6F5, + 0x77AA, 0xB5C9, + 0x77AC, 0xCBB2, + 0x77B0, 0xEEAB, + 0x77B3, 0xCDAB, + 0x77B5, 0xEEAC, + 0x77BB, 0xD5B0, + 0x77BD, 0xEEAD, + 0x77BF, 0xF6C4, + 0x77CD, 0xDBC7, + 0x77D7, 0xB4A3, + 0x77DB, 0xC3AC, + 0x77DC, 0xF1E6, + 0x77E2, 0xCAB8, + 0x77E3, 0xD2D3, + 0x77E5, 0xD6AA, + 0x77E7, 0xEFF2, + 0x77E9, 0xBED8, + 0x77EB, 0xBDC3, + 0x77EC, 0xEFF3, + 0x77ED, 0xB6CC, + 0x77EE, 0xB0AB, + 0x77F3, 0xCAAF, + 0x77F6, 0xEDB6, + 0x77F8, 0xEDB7, + 0x77FD, 0xCEF9, + 0x77FE, 0xB7AF, + 0x77FF, 0xBFF3, + 0x7800, 0xEDB8, + 0x7801, 0xC2EB, + 0x7802, 0xC9B0, + 0x7809, 0xEDB9, + 0x780C, 0xC6F6, + 0x780D, 0xBFB3, + 0x7811, 0xEDBC, + 0x7812, 0xC5F8, + 0x7814, 0xD1D0, + 0x7816, 0xD7A9, + 0x7817, 0xEDBA, + 0x7818, 0xEDBB, + 0x781A, 0xD1E2, + 0x781C, 0xEDBF, + 0x781D, 0xEDC0, + 0x781F, 0xEDC4, + 0x7823, 0xEDC8, + 0x7825, 0xEDC6, + 0x7826, 0xEDCE, + 0x7827, 0xD5E8, + 0x7829, 0xEDC9, + 0x782C, 0xEDC7, + 0x782D, 0xEDBE, + 0x7830, 0xC5E9, + 0x7834, 0xC6C6, + 0x7837, 0xC9E9, + 0x7838, 0xD4D2, + 0x7839, 0xEDC1, + 0x783A, 0xEDC2, + 0x783B, 0xEDC3, + 0x783C, 0xEDC5, + 0x783E, 0xC0F9, + 0x7840, 0xB4A1, + 0x7845, 0xB9E8, + 0x7847, 0xEDD0, + 0x784C, 0xEDD1, + 0x784E, 0xEDCA, + 0x7850, 0xEDCF, + 0x7852, 0xCEF8, + 0x7855, 0xCBB6, + 0x7856, 0xEDCC, + 0x7857, 0xEDCD, + 0x785D, 0xCFF5, + 0x786A, 0xEDD2, + 0x786B, 0xC1F2, + 0x786C, 0xD3B2, + 0x786D, 0xEDCB, + 0x786E, 0xC8B7, + 0x7877, 0xBCEF, + 0x787C, 0xC5F0, + 0x7887, 0xEDD6, + 0x7889, 0xB5EF, + 0x788C, 0xC2B5, + 0x788D, 0xB0AD, + 0x788E, 0xCBE9, + 0x7891, 0xB1AE, + 0x7893, 0xEDD4, + 0x7897, 0xCDEB, + 0x7898, 0xB5E2, + 0x789A, 0xEDD5, + 0x789B, 0xEDD3, + 0x789C, 0xEDD7, + 0x789F, 0xB5FA, + 0x78A1, 0xEDD8, + 0x78A3, 0xEDD9, + 0x78A5, 0xEDDC, + 0x78A7, 0xB1CC, + 0x78B0, 0xC5F6, + 0x78B1, 0xBCEE, + 0x78B2, 0xEDDA, + 0x78B3, 0xCCBC, + 0x78B4, 0xB2EA, + 0x78B9, 0xEDDB, + 0x78BE, 0xC4EB, + 0x78C1, 0xB4C5, + 0x78C5, 0xB0F5, + 0x78C9, 0xEDDF, + 0x78CA, 0xC0DA, + 0x78CB, 0xB4E8, + 0x78D0, 0xC5CD, + 0x78D4, 0xEDDD, + 0x78D5, 0xBFC4, + 0x78D9, 0xEDDE, + 0x78E8, 0xC4A5, + 0x78EC, 0xEDE0, + 0x78F2, 0xEDE1, + 0x78F4, 0xEDE3, + 0x78F7, 0xC1D7, + 0x78FA, 0xBBC7, + 0x7901, 0xBDB8, + 0x7905, 0xEDE2, + 0x7913, 0xEDE4, + 0x791E, 0xEDE6, + 0x7924, 0xEDE5, + 0x7934, 0xEDE7, + 0x793A, 0xCABE, + 0x793B, 0xECEA, + 0x793C, 0xC0F1, + 0x793E, 0xC9E7, + 0x7940, 0xECEB, + 0x7941, 0xC6EE, + 0x7946, 0xECEC, + 0x7948, 0xC6ED, + 0x7949, 0xECED, + 0x7953, 0xECF0, + 0x7956, 0xD7E6, + 0x7957, 0xECF3, + 0x795A, 0xECF1, + 0x795B, 0xECEE, + 0x795C, 0xECEF, + 0x795D, 0xD7A3, + 0x795E, 0xC9F1, + 0x795F, 0xCBEE, + 0x7960, 0xECF4, + 0x7962, 0xECF2, + 0x7965, 0xCFE9, + 0x7967, 0xECF6, + 0x7968, 0xC6B1, + 0x796D, 0xBCC0, + 0x796F, 0xECF5, + 0x7977, 0xB5BB, + 0x7978, 0xBBF6, + 0x797A, 0xECF7, + 0x7980, 0xD9F7, + 0x7981, 0xBDFB, + 0x7984, 0xC2BB, + 0x7985, 0xECF8, + 0x798A, 0xECF9, + 0x798F, 0xB8A3, + 0x799A, 0xECFA, + 0x79A7, 0xECFB, + 0x79B3, 0xECFC, + 0x79B9, 0xD3ED, + 0x79BA, 0xD8AE, + 0x79BB, 0xC0EB, + 0x79BD, 0xC7DD, + 0x79BE, 0xBACC, + 0x79C0, 0xD0E3, + 0x79C1, 0xCBBD, + 0x79C3, 0xCDBA, + 0x79C6, 0xB8D1, + 0x79C9, 0xB1FC, + 0x79CB, 0xC7EF, + 0x79CD, 0xD6D6, + 0x79D1, 0xBFC6, + 0x79D2, 0xC3EB, + 0x79D5, 0xEFF5, + 0x79D8, 0xC3D8, + 0x79DF, 0xD7E2, + 0x79E3, 0xEFF7, + 0x79E4, 0xB3D3, + 0x79E6, 0xC7D8, + 0x79E7, 0xD1ED, + 0x79E9, 0xD6C8, + 0x79EB, 0xEFF8, + 0x79ED, 0xEFF6, + 0x79EF, 0xBBFD, + 0x79F0, 0xB3C6, + 0x79F8, 0xBDD5, + 0x79FB, 0xD2C6, + 0x79FD, 0xBBE0, + 0x7A00, 0xCFA1, + 0x7A02, 0xEFFC, + 0x7A03, 0xEFFB, + 0x7A06, 0xEFF9, + 0x7A0B, 0xB3CC, + 0x7A0D, 0xC9D4, + 0x7A0E, 0xCBB0, + 0x7A14, 0xEFFE, + 0x7A17, 0xB0DE, + 0x7A1A, 0xD6C9, + 0x7A1E, 0xEFFD, + 0x7A20, 0xB3ED, + 0x7A23, 0xF6D5, + 0x7A33, 0xCEC8, + 0x7A37, 0xF0A2, + 0x7A39, 0xF0A1, + 0x7A3B, 0xB5BE, + 0x7A3C, 0xBCDA, + 0x7A3D, 0xBBFC, + 0x7A3F, 0xB8E5, + 0x7A46, 0xC4C2, + 0x7A51, 0xF0A3, + 0x7A57, 0xCBEB, + 0x7A70, 0xF0A6, + 0x7A74, 0xD1A8, + 0x7A76, 0xBEBF, + 0x7A77, 0xC7EE, + 0x7A78, 0xF1B6, + 0x7A79, 0xF1B7, + 0x7A7A, 0xBFD5, + 0x7A7F, 0xB4A9, + 0x7A80, 0xF1B8, + 0x7A81, 0xCDBB, + 0x7A83, 0xC7D4, + 0x7A84, 0xD5AD, + 0x7A86, 0xF1B9, + 0x7A88, 0xF1BA, + 0x7A8D, 0xC7CF, + 0x7A91, 0xD2A4, + 0x7A92, 0xD6CF, + 0x7A95, 0xF1BB, + 0x7A96, 0xBDD1, + 0x7A97, 0xB4B0, + 0x7A98, 0xBEBD, + 0x7A9C, 0xB4DC, + 0x7A9D, 0xCED1, + 0x7A9F, 0xBFDF, + 0x7AA0, 0xF1BD, + 0x7AA5, 0xBFFA, + 0x7AA6, 0xF1BC, + 0x7AA8, 0xF1BF, + 0x7AAC, 0xF1BE, + 0x7AAD, 0xF1C0, + 0x7AB3, 0xF1C1, + 0x7ABF, 0xC1FE, + 0x7ACB, 0xC1A2, + 0x7AD6, 0xCAFA, + 0x7AD9, 0xD5BE, + 0x7ADE, 0xBEBA, + 0x7ADF, 0xBEB9, + 0x7AE0, 0xD5C2, + 0x7AE3, 0xBFA2, + 0x7AE5, 0xCDAF, + 0x7AE6, 0xF1B5, + 0x7AED, 0xBDDF, + 0x7AEF, 0xB6CB, + 0x7AF9, 0xD6F1, + 0x7AFA, 0xF3C3, + 0x7AFD, 0xF3C4, + 0x7AFF, 0xB8CD, + 0x7B03, 0xF3C6, + 0x7B04, 0xF3C7, + 0x7B06, 0xB0CA, + 0x7B08, 0xF3C5, + 0x7B0A, 0xF3C9, + 0x7B0B, 0xCBF1, + 0x7B0F, 0xF3CB, + 0x7B11, 0xD0A6, + 0x7B14, 0xB1CA, + 0x7B15, 0xF3C8, + 0x7B19, 0xF3CF, + 0x7B1B, 0xB5D1, + 0x7B1E, 0xF3D7, + 0x7B20, 0xF3D2, + 0x7B24, 0xF3D4, + 0x7B25, 0xF3D3, + 0x7B26, 0xB7FB, + 0x7B28, 0xB1BF, + 0x7B2A, 0xF3CE, + 0x7B2B, 0xF3CA, + 0x7B2C, 0xB5DA, + 0x7B2E, 0xF3D0, + 0x7B31, 0xF3D1, + 0x7B33, 0xF3D5, + 0x7B38, 0xF3CD, + 0x7B3A, 0xBCE3, + 0x7B3C, 0xC1FD, + 0x7B3E, 0xF3D6, + 0x7B45, 0xF3DA, + 0x7B47, 0xF3CC, + 0x7B49, 0xB5C8, + 0x7B4B, 0xBDEE, + 0x7B4C, 0xF3DC, + 0x7B4F, 0xB7A4, + 0x7B50, 0xBFF0, + 0x7B51, 0xD6FE, + 0x7B52, 0xCDB2, + 0x7B54, 0xB4F0, + 0x7B56, 0xB2DF, + 0x7B58, 0xF3D8, + 0x7B5A, 0xF3D9, + 0x7B5B, 0xC9B8, + 0x7B5D, 0xF3DD, + 0x7B60, 0xF3DE, + 0x7B62, 0xF3E1, + 0x7B6E, 0xF3DF, + 0x7B71, 0xF3E3, + 0x7B72, 0xF3E2, + 0x7B75, 0xF3DB, + 0x7B77, 0xBFEA, + 0x7B79, 0xB3EF, + 0x7B7B, 0xF3E0, + 0x7B7E, 0xC7A9, + 0x7B80, 0xBCF2, + 0x7B85, 0xF3EB, + 0x7B8D, 0xB9BF, + 0x7B90, 0xF3E4, + 0x7B94, 0xB2AD, + 0x7B95, 0xBBFE, + 0x7B97, 0xCBE3, + 0x7B9C, 0xF3ED, + 0x7B9D, 0xF3E9, + 0x7BA1, 0xB9DC, + 0x7BA2, 0xF3EE, + 0x7BA6, 0xF3E5, + 0x7BA7, 0xF3E6, + 0x7BA8, 0xF3EA, + 0x7BA9, 0xC2E1, + 0x7BAA, 0xF3EC, + 0x7BAB, 0xF3EF, + 0x7BAC, 0xF3E8, + 0x7BAD, 0xBCFD, + 0x7BB1, 0xCFE4, + 0x7BB4, 0xF3F0, + 0x7BB8, 0xF3E7, + 0x7BC1, 0xF3F2, + 0x7BC6, 0xD7AD, + 0x7BC7, 0xC6AA, + 0x7BCC, 0xF3F3, + 0x7BD1, 0xF3F1, + 0x7BD3, 0xC2A8, + 0x7BD9, 0xB8DD, + 0x7BDA, 0xF3F5, + 0x7BDD, 0xF3F4, + 0x7BE1, 0xB4DB, + 0x7BE5, 0xF3F6, + 0x7BE6, 0xF3F7, + 0x7BEA, 0xF3F8, + 0x7BEE, 0xC0BA, + 0x7BF1, 0xC0E9, + 0x7BF7, 0xC5F1, + 0x7BFC, 0xF3FB, + 0x7BFE, 0xF3FA, + 0x7C07, 0xB4D8, + 0x7C0B, 0xF3FE, + 0x7C0C, 0xF3F9, + 0x7C0F, 0xF3FC, + 0x7C16, 0xF3FD, + 0x7C1F, 0xF4A1, + 0x7C26, 0xF4A3, + 0x7C27, 0xBBC9, + 0x7C2A, 0xF4A2, + 0x7C38, 0xF4A4, + 0x7C3F, 0xB2BE, + 0x7C40, 0xF4A6, + 0x7C41, 0xF4A5, + 0x7C4D, 0xBCAE, + 0x7C73, 0xC3D7, + 0x7C74, 0xD9E1, + 0x7C7B, 0xC0E0, + 0x7C7C, 0xF4CC, + 0x7C7D, 0xD7D1, + 0x7C89, 0xB7DB, + 0x7C91, 0xF4CE, + 0x7C92, 0xC1A3, + 0x7C95, 0xC6C9, + 0x7C97, 0xB4D6, + 0x7C98, 0xD5B3, + 0x7C9C, 0xF4D0, + 0x7C9D, 0xF4CF, + 0x7C9E, 0xF4D1, + 0x7C9F, 0xCBDA, + 0x7CA2, 0xF4D2, + 0x7CA4, 0xD4C1, + 0x7CA5, 0xD6E0, + 0x7CAA, 0xB7E0, + 0x7CAE, 0xC1B8, + 0x7CB1, 0xC1BB, + 0x7CB2, 0xF4D3, + 0x7CB3, 0xBEAC, + 0x7CB9, 0xB4E2, + 0x7CBC, 0xF4D4, + 0x7CBD, 0xF4D5, + 0x7CBE, 0xBEAB, + 0x7CC1, 0xF4D6, + 0x7CC5, 0xF4DB, + 0x7CC7, 0xF4D7, + 0x7CC8, 0xF4DA, + 0x7CCA, 0xBAFD, + 0x7CCC, 0xF4D8, + 0x7CCD, 0xF4D9, + 0x7CD5, 0xB8E2, + 0x7CD6, 0xCCC7, + 0x7CD7, 0xF4DC, + 0x7CD9, 0xB2DA, + 0x7CDC, 0xC3D3, + 0x7CDF, 0xD4E3, + 0x7CE0, 0xBFB7, + 0x7CE8, 0xF4DD, + 0x7CEF, 0xC5B4, + 0x7CF8, 0xF4E9, + 0x7CFB, 0xCFB5, + 0x7D0A, 0xCEC9, + 0x7D20, 0xCBD8, + 0x7D22, 0xCBF7, + 0x7D27, 0xBDF4, + 0x7D2B, 0xD7CF, + 0x7D2F, 0xC0DB, + 0x7D6E, 0xD0F5, + 0x7D77, 0xF4EA, + 0x7DA6, 0xF4EB, + 0x7DAE, 0xF4EC, + 0x7E3B, 0xF7E3, + 0x7E41, 0xB7B1, + 0x7E47, 0xF4ED, + 0x7E82, 0xD7EB, + 0x7E9B, 0xF4EE, + 0x7E9F, 0xE6F9, + 0x7EA0, 0xBEC0, + 0x7EA1, 0xE6FA, + 0x7EA2, 0xBAEC, + 0x7EA3, 0xE6FB, + 0x7EA4, 0xCFCB, + 0x7EA5, 0xE6FC, + 0x7EA6, 0xD4BC, + 0x7EA7, 0xBCB6, + 0x7EA8, 0xE6FD, + 0x7EA9, 0xE6FE, + 0x7EAA, 0xBCCD, + 0x7EAB, 0xC8D2, + 0x7EAC, 0xCEB3, + 0x7EAD, 0xE7A1, + 0x7EAF, 0xB4BF, + 0x7EB0, 0xE7A2, + 0x7EB1, 0xC9B4, + 0x7EB2, 0xB8D9, + 0x7EB3, 0xC4C9, + 0x7EB5, 0xD7DD, + 0x7EB6, 0xC2DA, + 0x7EB7, 0xB7D7, + 0x7EB8, 0xD6BD, + 0x7EB9, 0xCEC6, + 0x7EBA, 0xB7C4, + 0x7EBD, 0xC5A6, + 0x7EBE, 0xE7A3, + 0x7EBF, 0xCFDF, + 0x7EC0, 0xE7A4, + 0x7EC1, 0xE7A5, + 0x7EC2, 0xE7A6, + 0x7EC3, 0xC1B7, + 0x7EC4, 0xD7E9, + 0x7EC5, 0xC9F0, + 0x7EC6, 0xCFB8, + 0x7EC7, 0xD6AF, + 0x7EC8, 0xD6D5, + 0x7EC9, 0xE7A7, + 0x7ECA, 0xB0ED, + 0x7ECB, 0xE7A8, + 0x7ECC, 0xE7A9, + 0x7ECD, 0xC9DC, + 0x7ECE, 0xD2EF, + 0x7ECF, 0xBEAD, + 0x7ED0, 0xE7AA, + 0x7ED1, 0xB0F3, + 0x7ED2, 0xC8DE, + 0x7ED3, 0xBDE1, + 0x7ED4, 0xE7AB, + 0x7ED5, 0xC8C6, + 0x7ED7, 0xE7AC, + 0x7ED8, 0xBBE6, + 0x7ED9, 0xB8F8, + 0x7EDA, 0xD1A4, + 0x7EDB, 0xE7AD, + 0x7EDC, 0xC2E7, + 0x7EDD, 0xBEF8, + 0x7EDE, 0xBDCA, + 0x7EDF, 0xCDB3, + 0x7EE0, 0xE7AE, + 0x7EE1, 0xE7AF, + 0x7EE2, 0xBEEE, + 0x7EE3, 0xD0E5, + 0x7EE5, 0xCBE7, + 0x7EE6, 0xCCD0, + 0x7EE7, 0xBCCC, + 0x7EE8, 0xE7B0, + 0x7EE9, 0xBCA8, + 0x7EEA, 0xD0F7, + 0x7EEB, 0xE7B1, + 0x7EED, 0xD0F8, + 0x7EEE, 0xE7B2, + 0x7EEF, 0xE7B3, + 0x7EF0, 0xB4C2, + 0x7EF1, 0xE7B4, + 0x7EF2, 0xE7B5, + 0x7EF3, 0xC9FE, + 0x7EF4, 0xCEAC, + 0x7EF5, 0xC3E0, + 0x7EF6, 0xE7B7, + 0x7EF7, 0xB1C1, + 0x7EF8, 0xB3F1, + 0x7EFA, 0xE7B8, + 0x7EFB, 0xE7B9, + 0x7EFC, 0xD7DB, + 0x7EFD, 0xD5C0, + 0x7EFE, 0xE7BA, + 0x7EFF, 0xC2CC, + 0x7F00, 0xD7BA, + 0x7F01, 0xE7BB, + 0x7F02, 0xE7BC, + 0x7F03, 0xE7BD, + 0x7F04, 0xBCEA, + 0x7F05, 0xC3E5, + 0x7F06, 0xC0C2, + 0x7F07, 0xE7BE, + 0x7F08, 0xE7BF, + 0x7F09, 0xBCA9, + 0x7F0B, 0xE7C0, + 0x7F0C, 0xE7C1, + 0x7F0D, 0xE7B6, + 0x7F0E, 0xB6D0, + 0x7F0F, 0xE7C2, + 0x7F11, 0xE7C3, + 0x7F12, 0xE7C4, + 0x7F13, 0xBBBA, + 0x7F14, 0xB5DE, + 0x7F15, 0xC2C6, + 0x7F16, 0xB1E0, + 0x7F17, 0xE7C5, + 0x7F18, 0xD4B5, + 0x7F19, 0xE7C6, + 0x7F1A, 0xB8BF, + 0x7F1B, 0xE7C8, + 0x7F1C, 0xE7C7, + 0x7F1D, 0xB7EC, + 0x7F1F, 0xE7C9, + 0x7F20, 0xB2F8, + 0x7F21, 0xE7CA, + 0x7F22, 0xE7CB, + 0x7F23, 0xE7CC, + 0x7F24, 0xE7CD, + 0x7F25, 0xE7CE, + 0x7F26, 0xE7CF, + 0x7F27, 0xE7D0, + 0x7F28, 0xD3A7, + 0x7F29, 0xCBF5, + 0x7F2A, 0xE7D1, + 0x7F2B, 0xE7D2, + 0x7F2C, 0xE7D3, + 0x7F2D, 0xE7D4, + 0x7F2E, 0xC9C9, + 0x7F2F, 0xE7D5, + 0x7F30, 0xE7D6, + 0x7F31, 0xE7D7, + 0x7F32, 0xE7D8, + 0x7F33, 0xE7D9, + 0x7F34, 0xBDC9, + 0x7F35, 0xE7DA, + 0x7F36, 0xF3BE, + 0x7F38, 0xB8D7, + 0x7F3A, 0xC8B1, + 0x7F42, 0xF3BF, + 0x7F44, 0xF3C0, + 0x7F45, 0xF3C1, + 0x7F50, 0xB9DE, + 0x7F51, 0xCDF8, + 0x7F54, 0xD8E8, + 0x7F55, 0xBAB1, + 0x7F57, 0xC2DE, + 0x7F58, 0xEEB7, + 0x7F5A, 0xB7A3, + 0x7F5F, 0xEEB9, + 0x7F61, 0xEEB8, + 0x7F62, 0xB0D5, + 0x7F68, 0xEEBB, + 0x7F69, 0xD5D6, + 0x7F6A, 0xD7EF, + 0x7F6E, 0xD6C3, + 0x7F71, 0xEEBD, + 0x7F72, 0xCAF0, + 0x7F74, 0xEEBC, + 0x7F79, 0xEEBE, + 0x7F7E, 0xEEC0, + 0x7F81, 0xEEBF, + 0x7F8A, 0xD1F2, + 0x7F8C, 0xC7BC, + 0x7F8E, 0xC3C0, + 0x7F94, 0xB8E1, + 0x7F9A, 0xC1E7, + 0x7F9D, 0xF4C6, + 0x7F9E, 0xD0DF, + 0x7F9F, 0xF4C7, + 0x7FA1, 0xCFDB, + 0x7FA4, 0xC8BA, + 0x7FA7, 0xF4C8, + 0x7FAF, 0xF4C9, + 0x7FB0, 0xF4CA, + 0x7FB2, 0xF4CB, + 0x7FB8, 0xD9FA, + 0x7FB9, 0xB8FE, + 0x7FBC, 0xE5F1, + 0x7FBD, 0xD3F0, + 0x7FBF, 0xF4E0, + 0x7FC1, 0xCECC, + 0x7FC5, 0xB3E1, + 0x7FCA, 0xF1B4, + 0x7FCC, 0xD2EE, + 0x7FCE, 0xF4E1, + 0x7FD4, 0xCFE8, + 0x7FD5, 0xF4E2, + 0x7FD8, 0xC7CC, + 0x7FDF, 0xB5D4, + 0x7FE0, 0xB4E4, + 0x7FE1, 0xF4E4, + 0x7FE5, 0xF4E3, + 0x7FE6, 0xF4E5, + 0x7FE9, 0xF4E6, + 0x7FEE, 0xF4E7, + 0x7FF0, 0xBAB2, + 0x7FF1, 0xB0BF, + 0x7FF3, 0xF4E8, + 0x7FFB, 0xB7AD, + 0x7FFC, 0xD2ED, + 0x8000, 0xD2AB, + 0x8001, 0xC0CF, + 0x8003, 0xBFBC, + 0x8004, 0xEBA3, + 0x8005, 0xD5DF, + 0x8006, 0xEAC8, + 0x800B, 0xF1F3, + 0x800C, 0xB6F8, + 0x800D, 0xCBA3, + 0x8010, 0xC4CD, + 0x8012, 0xF1E7, + 0x8014, 0xF1E8, + 0x8015, 0xB8FB, + 0x8016, 0xF1E9, + 0x8017, 0xBAC4, + 0x8018, 0xD4C5, + 0x8019, 0xB0D2, + 0x801C, 0xF1EA, + 0x8020, 0xF1EB, + 0x8022, 0xF1EC, + 0x8025, 0xF1ED, + 0x8026, 0xF1EE, + 0x8027, 0xF1EF, + 0x8028, 0xF1F1, + 0x8029, 0xF1F0, + 0x802A, 0xC5D5, + 0x8031, 0xF1F2, + 0x8033, 0xB6FA, + 0x8035, 0xF1F4, + 0x8036, 0xD2AE, + 0x8037, 0xDEC7, + 0x8038, 0xCBCA, + 0x803B, 0xB3DC, + 0x803D, 0xB5A2, + 0x803F, 0xB9A2, + 0x8042, 0xC4F4, + 0x8043, 0xF1F5, + 0x8046, 0xF1F6, + 0x804A, 0xC1C4, + 0x804B, 0xC1FB, + 0x804C, 0xD6B0, + 0x804D, 0xF1F7, + 0x8052, 0xF1F8, + 0x8054, 0xC1AA, + 0x8058, 0xC6B8, + 0x805A, 0xBEDB, + 0x8069, 0xF1F9, + 0x806A, 0xB4CF, + 0x8071, 0xF1FA, + 0x807F, 0xEDB2, + 0x8080, 0xEDB1, + 0x8083, 0xCBE0, + 0x8084, 0xD2DE, + 0x8086, 0xCBC1, + 0x8087, 0xD5D8, + 0x8089, 0xC8E2, + 0x808B, 0xC0DF, + 0x808C, 0xBCA1, + 0x8093, 0xEBC1, + 0x8096, 0xD0A4, + 0x8098, 0xD6E2, + 0x809A, 0xB6C7, + 0x809B, 0xB8D8, + 0x809C, 0xEBC0, + 0x809D, 0xB8CE, + 0x809F, 0xEBBF, + 0x80A0, 0xB3A6, + 0x80A1, 0xB9C9, + 0x80A2, 0xD6AB, + 0x80A4, 0xB7F4, + 0x80A5, 0xB7CA, + 0x80A9, 0xBCE7, + 0x80AA, 0xB7BE, + 0x80AB, 0xEBC6, + 0x80AD, 0xEBC7, + 0x80AE, 0xB0B9, + 0x80AF, 0xBFCF, + 0x80B1, 0xEBC5, + 0x80B2, 0xD3FD, + 0x80B4, 0xEBC8, + 0x80B7, 0xEBC9, + 0x80BA, 0xB7CE, + 0x80BC, 0xEBC2, + 0x80BD, 0xEBC4, + 0x80BE, 0xC9F6, + 0x80BF, 0xD6D7, + 0x80C0, 0xD5CD, + 0x80C1, 0xD0B2, + 0x80C2, 0xEBCF, + 0x80C3, 0xCEB8, + 0x80C4, 0xEBD0, + 0x80C6, 0xB5A8, + 0x80CC, 0xB1B3, + 0x80CD, 0xEBD2, + 0x80CE, 0xCCA5, + 0x80D6, 0xC5D6, + 0x80D7, 0xEBD3, + 0x80D9, 0xEBD1, + 0x80DA, 0xC5DF, + 0x80DB, 0xEBCE, + 0x80DC, 0xCAA4, + 0x80DD, 0xEBD5, + 0x80DE, 0xB0FB, + 0x80E1, 0xBAFA, + 0x80E4, 0xD8B7, + 0x80E5, 0xF1E3, + 0x80E7, 0xEBCA, + 0x80E8, 0xEBCB, + 0x80E9, 0xEBCC, + 0x80EA, 0xEBCD, + 0x80EB, 0xEBD6, + 0x80EC, 0xE6C0, + 0x80ED, 0xEBD9, + 0x80EF, 0xBFE8, + 0x80F0, 0xD2C8, + 0x80F1, 0xEBD7, + 0x80F2, 0xEBDC, + 0x80F3, 0xB8EC, + 0x80F4, 0xEBD8, + 0x80F6, 0xBDBA, + 0x80F8, 0xD0D8, + 0x80FA, 0xB0B7, + 0x80FC, 0xEBDD, + 0x80FD, 0xC4DC, + 0x8102, 0xD6AC, + 0x8106, 0xB4E0, + 0x8109, 0xC2F6, + 0x810A, 0xBCB9, + 0x810D, 0xEBDA, + 0x810E, 0xEBDB, + 0x810F, 0xD4E0, + 0x8110, 0xC6EA, + 0x8111, 0xC4D4, + 0x8112, 0xEBDF, + 0x8113, 0xC5A7, + 0x8114, 0xD9F5, + 0x8116, 0xB2B1, + 0x8118, 0xEBE4, + 0x811A, 0xBDC5, + 0x811E, 0xEBE2, + 0x812C, 0xEBE3, + 0x812F, 0xB8AC, + 0x8131, 0xCDD1, + 0x8132, 0xEBE5, + 0x8136, 0xEBE1, + 0x8138, 0xC1B3, + 0x813E, 0xC6A2, + 0x8146, 0xCCF3, + 0x8148, 0xEBE6, + 0x814A, 0xC0B0, + 0x814B, 0xD2B8, + 0x814C, 0xEBE7, + 0x8150, 0xB8AF, + 0x8151, 0xB8AD, + 0x8153, 0xEBE8, + 0x8154, 0xC7BB, + 0x8155, 0xCDF3, + 0x8159, 0xEBEA, + 0x815A, 0xEBEB, + 0x8160, 0xEBED, + 0x8165, 0xD0C8, + 0x8167, 0xEBF2, + 0x8169, 0xEBEE, + 0x816D, 0xEBF1, + 0x816E, 0xC8F9, + 0x8170, 0xD1FC, + 0x8171, 0xEBEC, + 0x8174, 0xEBE9, + 0x8179, 0xB8B9, + 0x817A, 0xCFD9, + 0x817B, 0xC4E5, + 0x817C, 0xEBEF, + 0x817D, 0xEBF0, + 0x817E, 0xCCDA, + 0x817F, 0xCDC8, + 0x8180, 0xB0F2, + 0x8182, 0xEBF6, + 0x8188, 0xEBF5, + 0x818A, 0xB2B2, + 0x818F, 0xB8E0, + 0x8191, 0xEBF7, + 0x8198, 0xB1EC, + 0x819B, 0xCCC5, + 0x819C, 0xC4A4, + 0x819D, 0xCFA5, + 0x81A3, 0xEBF9, + 0x81A6, 0xECA2, + 0x81A8, 0xC5F2, + 0x81AA, 0xEBFA, + 0x81B3, 0xC9C5, + 0x81BA, 0xE2DF, + 0x81BB, 0xEBFE, + 0x81C0, 0xCDCE, + 0x81C1, 0xECA1, + 0x81C2, 0xB1DB, + 0x81C3, 0xD3B7, + 0x81C6, 0xD2DC, + 0x81CA, 0xEBFD, + 0x81CC, 0xEBFB, + 0x81E3, 0xB3BC, + 0x81E7, 0xEAB0, + 0x81EA, 0xD7D4, + 0x81EC, 0xF4AB, + 0x81ED, 0xB3F4, + 0x81F3, 0xD6C1, + 0x81F4, 0xD6C2, + 0x81FB, 0xD5E9, + 0x81FC, 0xBECA, + 0x81FE, 0xF4A7, + 0x8200, 0xD2A8, + 0x8201, 0xF4A8, + 0x8202, 0xF4A9, + 0x8204, 0xF4AA, + 0x8205, 0xBECB, + 0x8206, 0xD3DF, + 0x820C, 0xC9E0, + 0x820D, 0xC9E1, + 0x8210, 0xF3C2, + 0x8212, 0xCAE6, + 0x8214, 0xCCF2, + 0x821B, 0xE2B6, + 0x821C, 0xCBB4, + 0x821E, 0xCEE8, + 0x821F, 0xD6DB, + 0x8221, 0xF4AD, + 0x8222, 0xF4AE, + 0x8223, 0xF4AF, + 0x8228, 0xF4B2, + 0x822A, 0xBABD, + 0x822B, 0xF4B3, + 0x822C, 0xB0E3, + 0x822D, 0xF4B0, + 0x822F, 0xF4B1, + 0x8230, 0xBDA2, + 0x8231, 0xB2D5, + 0x8233, 0xF4B6, + 0x8234, 0xF4B7, + 0x8235, 0xB6E6, + 0x8236, 0xB2B0, + 0x8237, 0xCFCF, + 0x8238, 0xF4B4, + 0x8239, 0xB4AC, + 0x823B, 0xF4B5, + 0x823E, 0xF4B8, + 0x8244, 0xF4B9, + 0x8247, 0xCDA7, + 0x8249, 0xF4BA, + 0x824B, 0xF4BB, + 0x824F, 0xF4BC, + 0x8258, 0xCBD2, + 0x825A, 0xF4BD, + 0x825F, 0xF4BE, + 0x8268, 0xF4BF, + 0x826E, 0xF4DE, + 0x826F, 0xC1BC, + 0x8270, 0xBCE8, + 0x8272, 0xC9AB, + 0x8273, 0xD1DE, + 0x8274, 0xE5F5, + 0x8279, 0xDCB3, + 0x827A, 0xD2D5, + 0x827D, 0xDCB4, + 0x827E, 0xB0AC, + 0x827F, 0xDCB5, + 0x8282, 0xBDDA, + 0x8284, 0xDCB9, + 0x8288, 0xD8C2, + 0x828A, 0xDCB7, + 0x828B, 0xD3F3, + 0x828D, 0xC9D6, + 0x828E, 0xDCBA, + 0x828F, 0xDCB6, + 0x8291, 0xDCBB, + 0x8292, 0xC3A2, + 0x8297, 0xDCBC, + 0x8298, 0xDCC5, + 0x8299, 0xDCBD, + 0x829C, 0xCEDF, + 0x829D, 0xD6A5, + 0x829F, 0xDCCF, + 0x82A1, 0xDCCD, + 0x82A4, 0xDCD2, + 0x82A5, 0xBDE6, + 0x82A6, 0xC2AB, + 0x82A8, 0xDCB8, + 0x82A9, 0xDCCB, + 0x82AA, 0xDCCE, + 0x82AB, 0xDCBE, + 0x82AC, 0xB7D2, + 0x82AD, 0xB0C5, + 0x82AE, 0xDCC7, + 0x82AF, 0xD0BE, + 0x82B0, 0xDCC1, + 0x82B1, 0xBBA8, + 0x82B3, 0xB7BC, + 0x82B4, 0xDCCC, + 0x82B7, 0xDCC6, + 0x82B8, 0xDCBF, + 0x82B9, 0xC7DB, + 0x82BD, 0xD1BF, + 0x82BE, 0xDCC0, + 0x82C1, 0xDCCA, + 0x82C4, 0xDCD0, + 0x82C7, 0xCEAD, + 0x82C8, 0xDCC2, + 0x82CA, 0xDCC3, + 0x82CB, 0xDCC8, + 0x82CC, 0xDCC9, + 0x82CD, 0xB2D4, + 0x82CE, 0xDCD1, + 0x82CF, 0xCBD5, + 0x82D1, 0xD4B7, + 0x82D2, 0xDCDB, + 0x82D3, 0xDCDF, + 0x82D4, 0xCCA6, + 0x82D5, 0xDCE6, + 0x82D7, 0xC3E7, + 0x82D8, 0xDCDC, + 0x82DB, 0xBFC1, + 0x82DC, 0xDCD9, + 0x82DE, 0xB0FA, + 0x82DF, 0xB9B6, + 0x82E0, 0xDCE5, + 0x82E1, 0xDCD3, + 0x82E3, 0xDCC4, + 0x82E4, 0xDCD6, + 0x82E5, 0xC8F4, + 0x82E6, 0xBFE0, + 0x82EB, 0xC9BB, + 0x82EF, 0xB1BD, + 0x82F1, 0xD3A2, + 0x82F4, 0xDCDA, + 0x82F7, 0xDCD5, + 0x82F9, 0xC6BB, + 0x82FB, 0xDCDE, + 0x8301, 0xD7C2, + 0x8302, 0xC3AF, + 0x8303, 0xB7B6, + 0x8304, 0xC7D1, + 0x8305, 0xC3A9, + 0x8306, 0xDCE2, + 0x8307, 0xDCD8, + 0x8308, 0xDCEB, + 0x8309, 0xDCD4, + 0x830C, 0xDCDD, + 0x830E, 0xBEA5, + 0x830F, 0xDCD7, + 0x8311, 0xDCE0, + 0x8314, 0xDCE3, + 0x8315, 0xDCE4, + 0x8317, 0xDCF8, + 0x831A, 0xDCE1, + 0x831B, 0xDDA2, + 0x831C, 0xDCE7, + 0x8327, 0xBCEB, + 0x8328, 0xB4C4, + 0x832B, 0xC3A3, + 0x832C, 0xB2E7, + 0x832D, 0xDCFA, + 0x832F, 0xDCF2, + 0x8331, 0xDCEF, + 0x8333, 0xDCFC, + 0x8334, 0xDCEE, + 0x8335, 0xD2F0, + 0x8336, 0xB2E8, + 0x8338, 0xC8D7, + 0x8339, 0xC8E3, + 0x833A, 0xDCFB, + 0x833C, 0xDCED, + 0x8340, 0xDCF7, + 0x8343, 0xDCF5, + 0x8346, 0xBEA3, + 0x8347, 0xDCF4, + 0x8349, 0xB2DD, + 0x834F, 0xDCF3, + 0x8350, 0xBCF6, + 0x8351, 0xDCE8, + 0x8352, 0xBBC4, + 0x8354, 0xC0F3, + 0x835A, 0xBCD4, + 0x835B, 0xDCE9, + 0x835C, 0xDCEA, + 0x835E, 0xDCF1, + 0x835F, 0xDCF6, + 0x8360, 0xDCF9, + 0x8361, 0xB5B4, + 0x8363, 0xC8D9, + 0x8364, 0xBBE7, + 0x8365, 0xDCFE, + 0x8366, 0xDCFD, + 0x8367, 0xD3AB, + 0x8368, 0xDDA1, + 0x8369, 0xDDA3, + 0x836A, 0xDDA5, + 0x836B, 0xD2F1, + 0x836C, 0xDDA4, + 0x836D, 0xDDA6, + 0x836E, 0xDDA7, + 0x836F, 0xD2A9, + 0x8377, 0xBAC9, + 0x8378, 0xDDA9, + 0x837B, 0xDDB6, + 0x837C, 0xDDB1, + 0x837D, 0xDDB4, + 0x8385, 0xDDB0, + 0x8386, 0xC6CE, + 0x8389, 0xC0F2, + 0x838E, 0xC9AF, + 0x8392, 0xDCEC, + 0x8393, 0xDDAE, + 0x8398, 0xDDB7, + 0x839B, 0xDCF0, + 0x839C, 0xDDAF, + 0x839E, 0xDDB8, + 0x83A0, 0xDDAC, + 0x83A8, 0xDDB9, + 0x83A9, 0xDDB3, + 0x83AA, 0xDDAD, + 0x83AB, 0xC4AA, + 0x83B0, 0xDDA8, + 0x83B1, 0xC0B3, + 0x83B2, 0xC1AB, + 0x83B3, 0xDDAA, + 0x83B4, 0xDDAB, + 0x83B6, 0xDDB2, + 0x83B7, 0xBBF1, + 0x83B8, 0xDDB5, + 0x83B9, 0xD3A8, + 0x83BA, 0xDDBA, + 0x83BC, 0xDDBB, + 0x83BD, 0xC3A7, + 0x83C0, 0xDDD2, + 0x83C1, 0xDDBC, + 0x83C5, 0xDDD1, + 0x83C7, 0xB9BD, + 0x83CA, 0xBED5, + 0x83CC, 0xBEFA, + 0x83CF, 0xBACA, + 0x83D4, 0xDDCA, + 0x83D6, 0xDDC5, + 0x83D8, 0xDDBF, + 0x83DC, 0xB2CB, + 0x83DD, 0xDDC3, + 0x83DF, 0xDDCB, + 0x83E0, 0xB2A4, + 0x83E1, 0xDDD5, + 0x83E5, 0xDDBE, + 0x83E9, 0xC6D0, + 0x83EA, 0xDDD0, + 0x83F0, 0xDDD4, + 0x83F1, 0xC1E2, + 0x83F2, 0xB7C6, + 0x83F8, 0xDDCE, + 0x83F9, 0xDDCF, + 0x83FD, 0xDDC4, + 0x8401, 0xDDBD, + 0x8403, 0xDDCD, + 0x8404, 0xCCD1, + 0x8406, 0xDDC9, + 0x840B, 0xDDC2, + 0x840C, 0xC3C8, + 0x840D, 0xC6BC, + 0x840E, 0xCEAE, + 0x840F, 0xDDCC, + 0x8411, 0xDDC8, + 0x8418, 0xDDC1, + 0x841C, 0xDDC6, + 0x841D, 0xC2DC, + 0x8424, 0xD3A9, + 0x8425, 0xD3AA, + 0x8426, 0xDDD3, + 0x8427, 0xCFF4, + 0x8428, 0xC8F8, + 0x8431, 0xDDE6, + 0x8438, 0xDDC7, + 0x843C, 0xDDE0, + 0x843D, 0xC2E4, + 0x8446, 0xDDE1, + 0x8451, 0xDDD7, + 0x8457, 0xD6F8, + 0x8459, 0xDDD9, + 0x845A, 0xDDD8, + 0x845B, 0xB8F0, + 0x845C, 0xDDD6, + 0x8461, 0xC6CF, + 0x8463, 0xB6AD, + 0x8469, 0xDDE2, + 0x846B, 0xBAF9, + 0x846C, 0xD4E1, + 0x846D, 0xDDE7, + 0x8471, 0xB4D0, + 0x8473, 0xDDDA, + 0x8475, 0xBFFB, + 0x8476, 0xDDE3, + 0x8478, 0xDDDF, + 0x847A, 0xDDDD, + 0x8482, 0xB5D9, + 0x8487, 0xDDDB, + 0x8488, 0xDDDC, + 0x8489, 0xDDDE, + 0x848B, 0xBDAF, + 0x848C, 0xDDE4, + 0x848E, 0xDDE5, + 0x8497, 0xDDF5, + 0x8499, 0xC3C9, + 0x849C, 0xCBE2, + 0x84A1, 0xDDF2, + 0x84AF, 0xD8E1, + 0x84B2, 0xC6D1, + 0x84B4, 0xDDF4, + 0x84B8, 0xD5F4, + 0x84B9, 0xDDF3, + 0x84BA, 0xDDF0, + 0x84BD, 0xDDEC, + 0x84BF, 0xDDEF, + 0x84C1, 0xDDE8, + 0x84C4, 0xD0EE, + 0x84C9, 0xC8D8, + 0x84CA, 0xDDEE, + 0x84CD, 0xDDE9, + 0x84D0, 0xDDEA, + 0x84D1, 0xCBF2, + 0x84D3, 0xDDED, + 0x84D6, 0xB1CD, + 0x84DD, 0xC0B6, + 0x84DF, 0xBCBB, + 0x84E0, 0xDDF1, + 0x84E3, 0xDDF7, + 0x84E5, 0xDDF6, + 0x84E6, 0xDDEB, + 0x84EC, 0xC5EE, + 0x84F0, 0xDDFB, + 0x84FC, 0xDEA4, + 0x84FF, 0xDEA3, + 0x850C, 0xDDF8, + 0x8511, 0xC3EF, + 0x8513, 0xC2FB, + 0x8517, 0xD5E1, + 0x851A, 0xCEB5, + 0x851F, 0xDDFD, + 0x8521, 0xB2CC, + 0x852B, 0xC4E8, + 0x852C, 0xCADF, + 0x8537, 0xC7BE, + 0x8538, 0xDDFA, + 0x8539, 0xDDFC, + 0x853A, 0xDDFE, + 0x853B, 0xDEA2, + 0x853C, 0xB0AA, + 0x853D, 0xB1CE, + 0x8543, 0xDEAC, + 0x8548, 0xDEA6, + 0x8549, 0xBDB6, + 0x854A, 0xC8EF, + 0x8556, 0xDEA1, + 0x8559, 0xDEA5, + 0x855E, 0xDEA9, + 0x8564, 0xDEA8, + 0x8568, 0xDEA7, + 0x8572, 0xDEAD, + 0x8574, 0xD4CC, + 0x8579, 0xDEB3, + 0x857A, 0xDEAA, + 0x857B, 0xDEAE, + 0x857E, 0xC0D9, + 0x8584, 0xB1A1, + 0x8585, 0xDEB6, + 0x8587, 0xDEB1, + 0x858F, 0xDEB2, + 0x859B, 0xD1A6, + 0x859C, 0xDEB5, + 0x85A4, 0xDEAF, + 0x85A8, 0xDEB0, + 0x85AA, 0xD0BD, + 0x85AE, 0xDEB4, + 0x85AF, 0xCAED, + 0x85B0, 0xDEB9, + 0x85B7, 0xDEB8, + 0x85B9, 0xDEB7, + 0x85C1, 0xDEBB, + 0x85C9, 0xBDE5, + 0x85CF, 0xB2D8, + 0x85D0, 0xC3EA, + 0x85D3, 0xDEBA, + 0x85D5, 0xC5BA, + 0x85DC, 0xDEBC, + 0x85E4, 0xCCD9, + 0x85E9, 0xB7AA, + 0x85FB, 0xD4E5, + 0x85FF, 0xDEBD, + 0x8605, 0xDEBF, + 0x8611, 0xC4A2, + 0x8616, 0xDEC1, + 0x8627, 0xDEBE, + 0x8629, 0xDEC0, + 0x8638, 0xD5BA, + 0x863C, 0xDEC2, + 0x864D, 0xF2AE, + 0x864E, 0xBBA2, + 0x864F, 0xC2B2, + 0x8650, 0xC5B0, + 0x8651, 0xC2C7, + 0x8654, 0xF2AF, + 0x865A, 0xD0E9, + 0x865E, 0xD3DD, + 0x8662, 0xEBBD, + 0x866B, 0xB3E6, + 0x866C, 0xF2B0, + 0x866E, 0xF2B1, + 0x8671, 0xCAAD, + 0x8679, 0xBAE7, + 0x867A, 0xF2B3, + 0x867B, 0xF2B5, + 0x867C, 0xF2B4, + 0x867D, 0xCBE4, + 0x867E, 0xCFBA, + 0x867F, 0xF2B2, + 0x8680, 0xCAB4, + 0x8681, 0xD2CF, + 0x8682, 0xC2EC, + 0x868A, 0xCEC3, + 0x868B, 0xF2B8, + 0x868C, 0xB0F6, + 0x868D, 0xF2B7, + 0x8693, 0xF2BE, + 0x8695, 0xB2CF, + 0x869C, 0xD1C1, + 0x869D, 0xF2BA, + 0x86A3, 0xF2BC, + 0x86A4, 0xD4E9, + 0x86A7, 0xF2BB, + 0x86A8, 0xF2B6, + 0x86A9, 0xF2BF, + 0x86AA, 0xF2BD, + 0x86AC, 0xF2B9, + 0x86AF, 0xF2C7, + 0x86B0, 0xF2C4, + 0x86B1, 0xF2C6, + 0x86B4, 0xF2CA, + 0x86B5, 0xF2C2, + 0x86B6, 0xF2C0, + 0x86BA, 0xF2C5, + 0x86C0, 0xD6FB, + 0x86C4, 0xF2C1, + 0x86C6, 0xC7F9, + 0x86C7, 0xC9DF, + 0x86C9, 0xF2C8, + 0x86CA, 0xB9C6, + 0x86CB, 0xB5B0, + 0x86CE, 0xF2C3, + 0x86CF, 0xF2C9, + 0x86D0, 0xF2D0, + 0x86D1, 0xF2D6, + 0x86D4, 0xBBD7, + 0x86D8, 0xF2D5, + 0x86D9, 0xCDDC, + 0x86DB, 0xD6EB, + 0x86DE, 0xF2D2, + 0x86DF, 0xF2D4, + 0x86E4, 0xB8F2, + 0x86E9, 0xF2CB, + 0x86ED, 0xF2CE, + 0x86EE, 0xC2F9, + 0x86F0, 0xD5DD, + 0x86F1, 0xF2CC, + 0x86F2, 0xF2CD, + 0x86F3, 0xF2CF, + 0x86F4, 0xF2D3, + 0x86F8, 0xF2D9, + 0x86F9, 0xD3BC, + 0x86FE, 0xB6EA, + 0x8700, 0xCAF1, + 0x8702, 0xB7E4, + 0x8703, 0xF2D7, + 0x8707, 0xF2D8, + 0x8708, 0xF2DA, + 0x8709, 0xF2DD, + 0x870A, 0xF2DB, + 0x870D, 0xF2DC, + 0x8712, 0xD1D1, + 0x8713, 0xF2D1, + 0x8715, 0xCDC9, + 0x8717, 0xCECF, + 0x8718, 0xD6A9, + 0x871A, 0xF2E3, + 0x871C, 0xC3DB, + 0x871E, 0xF2E0, + 0x8721, 0xC0AF, + 0x8722, 0xF2EC, + 0x8723, 0xF2DE, + 0x8725, 0xF2E1, + 0x8729, 0xF2E8, + 0x872E, 0xF2E2, + 0x8731, 0xF2E7, + 0x8734, 0xF2E6, + 0x8737, 0xF2E9, + 0x873B, 0xF2DF, + 0x873E, 0xF2E4, + 0x873F, 0xF2EA, + 0x8747, 0xD3AC, + 0x8748, 0xF2E5, + 0x8749, 0xB2F5, + 0x874C, 0xF2F2, + 0x874E, 0xD0AB, + 0x8753, 0xF2F5, + 0x8757, 0xBBC8, + 0x8759, 0xF2F9, + 0x8760, 0xF2F0, + 0x8763, 0xF2F6, + 0x8764, 0xF2F8, + 0x8765, 0xF2FA, + 0x876E, 0xF2F3, + 0x8770, 0xF2F1, + 0x8774, 0xBAFB, + 0x8776, 0xB5FB, + 0x877B, 0xF2EF, + 0x877C, 0xF2F7, + 0x877D, 0xF2ED, + 0x877E, 0xF2EE, + 0x8782, 0xF2EB, + 0x8783, 0xF3A6, + 0x8785, 0xF3A3, + 0x8788, 0xF3A2, + 0x878B, 0xF2F4, + 0x878D, 0xC8DA, + 0x8793, 0xF2FB, + 0x8797, 0xF3A5, + 0x879F, 0xC3F8, + 0x87A8, 0xF2FD, + 0x87AB, 0xF3A7, + 0x87AC, 0xF3A9, + 0x87AD, 0xF3A4, + 0x87AF, 0xF2FC, + 0x87B3, 0xF3AB, + 0x87B5, 0xF3AA, + 0x87BA, 0xC2DD, + 0x87BD, 0xF3AE, + 0x87C0, 0xF3B0, + 0x87C6, 0xF3A1, + 0x87CA, 0xF3B1, + 0x87CB, 0xF3AC, + 0x87D1, 0xF3AF, + 0x87D2, 0xF2FE, + 0x87D3, 0xF3AD, + 0x87DB, 0xF3B2, + 0x87E0, 0xF3B4, + 0x87E5, 0xF3A8, + 0x87EA, 0xF3B3, + 0x87EE, 0xF3B5, + 0x87F9, 0xD0B7, + 0x87FE, 0xF3B8, + 0x8803, 0xD9F9, + 0x880A, 0xF3B9, + 0x8813, 0xF3B7, + 0x8815, 0xC8E4, + 0x8816, 0xF3B6, + 0x881B, 0xF3BA, + 0x8821, 0xF3BB, + 0x8822, 0xB4C0, + 0x8832, 0xEEC3, + 0x8839, 0xF3BC, + 0x883C, 0xF3BD, + 0x8840, 0xD1AA, + 0x8844, 0xF4AC, + 0x8845, 0xD0C6, + 0x884C, 0xD0D0, + 0x884D, 0xD1DC, + 0x8854, 0xCFCE, + 0x8857, 0xBDD6, + 0x8859, 0xD1C3, + 0x8861, 0xBAE2, + 0x8862, 0xE1E9, + 0x8863, 0xD2C2, + 0x8864, 0xF1C2, + 0x8865, 0xB2B9, + 0x8868, 0xB1ED, + 0x8869, 0xF1C3, + 0x886B, 0xC9C0, + 0x886C, 0xB3C4, + 0x886E, 0xD9F2, + 0x8870, 0xCBA5, + 0x8872, 0xF1C4, + 0x8877, 0xD6D4, + 0x887D, 0xF1C5, + 0x887E, 0xF4C0, + 0x887F, 0xF1C6, + 0x8881, 0xD4AC, + 0x8882, 0xF1C7, + 0x8884, 0xB0C0, + 0x8885, 0xF4C1, + 0x8888, 0xF4C2, + 0x888B, 0xB4FC, + 0x888D, 0xC5DB, + 0x8892, 0xCCBB, + 0x8896, 0xD0E4, + 0x889C, 0xCDE0, + 0x88A2, 0xF1C8, + 0x88A4, 0xD9F3, + 0x88AB, 0xB1BB, + 0x88AD, 0xCFAE, + 0x88B1, 0xB8A4, + 0x88B7, 0xF1CA, + 0x88BC, 0xF1CB, + 0x88C1, 0xB2C3, + 0x88C2, 0xC1D1, + 0x88C5, 0xD7B0, + 0x88C6, 0xF1C9, + 0x88C9, 0xF1CC, + 0x88CE, 0xF1CE, + 0x88D2, 0xD9F6, + 0x88D4, 0xD2E1, + 0x88D5, 0xD4A3, + 0x88D8, 0xF4C3, + 0x88D9, 0xC8B9, + 0x88DF, 0xF4C4, + 0x88E2, 0xF1CD, + 0x88E3, 0xF1CF, + 0x88E4, 0xBFE3, + 0x88E5, 0xF1D0, + 0x88E8, 0xF1D4, + 0x88F0, 0xF1D6, + 0x88F1, 0xF1D1, + 0x88F3, 0xC9D1, + 0x88F4, 0xC5E1, + 0x88F8, 0xC2E3, + 0x88F9, 0xB9FC, + 0x88FC, 0xF1D3, + 0x88FE, 0xF1D5, + 0x8902, 0xB9D3, + 0x890A, 0xF1DB, + 0x8910, 0xBAD6, + 0x8912, 0xB0FD, + 0x8913, 0xF1D9, + 0x8919, 0xF1D8, + 0x891A, 0xF1D2, + 0x891B, 0xF1DA, + 0x8921, 0xF1D7, + 0x8925, 0xC8EC, + 0x892A, 0xCDCA, + 0x892B, 0xF1DD, + 0x8930, 0xE5BD, + 0x8934, 0xF1DC, + 0x8936, 0xF1DE, + 0x8941, 0xF1DF, + 0x8944, 0xCFE5, + 0x895E, 0xF4C5, + 0x895F, 0xBDF3, + 0x8966, 0xF1E0, + 0x897B, 0xF1E1, + 0x897F, 0xCEF7, + 0x8981, 0xD2AA, + 0x8983, 0xF1FB, + 0x8986, 0xB8B2, + 0x89C1, 0xBCFB, + 0x89C2, 0xB9DB, + 0x89C4, 0xB9E6, + 0x89C5, 0xC3D9, + 0x89C6, 0xCAD3, + 0x89C7, 0xEAE8, + 0x89C8, 0xC0C0, + 0x89C9, 0xBEF5, + 0x89CA, 0xEAE9, + 0x89CB, 0xEAEA, + 0x89CC, 0xEAEB, + 0x89CE, 0xEAEC, + 0x89CF, 0xEAED, + 0x89D0, 0xEAEE, + 0x89D1, 0xEAEF, + 0x89D2, 0xBDC7, + 0x89D6, 0xF5FB, + 0x89DA, 0xF5FD, + 0x89DC, 0xF5FE, + 0x89DE, 0xF5FC, + 0x89E3, 0xBDE2, + 0x89E5, 0xF6A1, + 0x89E6, 0xB4A5, + 0x89EB, 0xF6A2, + 0x89EF, 0xF6A3, + 0x89F3, 0xECB2, + 0x8A00, 0xD1D4, + 0x8A07, 0xD9EA, + 0x8A3E, 0xF6A4, + 0x8A48, 0xEEBA, + 0x8A79, 0xD5B2, + 0x8A89, 0xD3FE, + 0x8A8A, 0xCCDC, + 0x8A93, 0xCAC4, + 0x8B07, 0xE5C0, + 0x8B26, 0xF6A5, + 0x8B66, 0xBEAF, + 0x8B6C, 0xC6A9, + 0x8BA0, 0xDAA5, + 0x8BA1, 0xBCC6, + 0x8BA2, 0xB6A9, + 0x8BA3, 0xB8BC, + 0x8BA4, 0xC8CF, + 0x8BA5, 0xBCA5, + 0x8BA6, 0xDAA6, + 0x8BA7, 0xDAA7, + 0x8BA8, 0xCCD6, + 0x8BA9, 0xC8C3, + 0x8BAA, 0xDAA8, + 0x8BAB, 0xC6FD, + 0x8BAD, 0xD1B5, + 0x8BAE, 0xD2E9, + 0x8BAF, 0xD1B6, + 0x8BB0, 0xBCC7, + 0x8BB2, 0xBDB2, + 0x8BB3, 0xBBE4, + 0x8BB4, 0xDAA9, + 0x8BB5, 0xDAAA, + 0x8BB6, 0xD1C8, + 0x8BB7, 0xDAAB, + 0x8BB8, 0xD0ED, + 0x8BB9, 0xB6EF, + 0x8BBA, 0xC2DB, + 0x8BBC, 0xCBCF, + 0x8BBD, 0xB7ED, + 0x8BBE, 0xC9E8, + 0x8BBF, 0xB7C3, + 0x8BC0, 0xBEF7, + 0x8BC1, 0xD6A4, + 0x8BC2, 0xDAAC, + 0x8BC3, 0xDAAD, + 0x8BC4, 0xC6C0, + 0x8BC5, 0xD7E7, + 0x8BC6, 0xCAB6, + 0x8BC8, 0xD5A9, + 0x8BC9, 0xCBDF, + 0x8BCA, 0xD5EF, + 0x8BCB, 0xDAAE, + 0x8BCC, 0xD6DF, + 0x8BCD, 0xB4CA, + 0x8BCE, 0xDAB0, + 0x8BCF, 0xDAAF, + 0x8BD1, 0xD2EB, + 0x8BD2, 0xDAB1, + 0x8BD3, 0xDAB2, + 0x8BD4, 0xDAB3, + 0x8BD5, 0xCAD4, + 0x8BD6, 0xDAB4, + 0x8BD7, 0xCAAB, + 0x8BD8, 0xDAB5, + 0x8BD9, 0xDAB6, + 0x8BDA, 0xB3CF, + 0x8BDB, 0xD6EF, + 0x8BDC, 0xDAB7, + 0x8BDD, 0xBBB0, + 0x8BDE, 0xB5AE, + 0x8BDF, 0xDAB8, + 0x8BE0, 0xDAB9, + 0x8BE1, 0xB9EE, + 0x8BE2, 0xD1AF, + 0x8BE3, 0xD2E8, + 0x8BE4, 0xDABA, + 0x8BE5, 0xB8C3, + 0x8BE6, 0xCFEA, + 0x8BE7, 0xB2EF, + 0x8BE8, 0xDABB, + 0x8BE9, 0xDABC, + 0x8BEB, 0xBDEB, + 0x8BEC, 0xCEDC, + 0x8BED, 0xD3EF, + 0x8BEE, 0xDABD, + 0x8BEF, 0xCEF3, + 0x8BF0, 0xDABE, + 0x8BF1, 0xD3D5, + 0x8BF2, 0xBBE5, + 0x8BF3, 0xDABF, + 0x8BF4, 0xCBB5, + 0x8BF5, 0xCBD0, + 0x8BF6, 0xDAC0, + 0x8BF7, 0xC7EB, + 0x8BF8, 0xD6EE, + 0x8BF9, 0xDAC1, + 0x8BFA, 0xC5B5, + 0x8BFB, 0xB6C1, + 0x8BFC, 0xDAC2, + 0x8BFD, 0xB7CC, + 0x8BFE, 0xBFCE, + 0x8BFF, 0xDAC3, + 0x8C00, 0xDAC4, + 0x8C01, 0xCBAD, + 0x8C02, 0xDAC5, + 0x8C03, 0xB5F7, + 0x8C04, 0xDAC6, + 0x8C05, 0xC1C2, + 0x8C06, 0xD7BB, + 0x8C07, 0xDAC7, + 0x8C08, 0xCCB8, + 0x8C0A, 0xD2EA, + 0x8C0B, 0xC4B1, + 0x8C0C, 0xDAC8, + 0x8C0D, 0xB5FD, + 0x8C0E, 0xBBD1, + 0x8C0F, 0xDAC9, + 0x8C10, 0xD0B3, + 0x8C11, 0xDACA, + 0x8C12, 0xDACB, + 0x8C13, 0xCEBD, + 0x8C14, 0xDACC, + 0x8C15, 0xDACD, + 0x8C16, 0xDACE, + 0x8C17, 0xB2F7, + 0x8C18, 0xDAD1, + 0x8C19, 0xDACF, + 0x8C1A, 0xD1E8, + 0x8C1B, 0xDAD0, + 0x8C1C, 0xC3D5, + 0x8C1D, 0xDAD2, + 0x8C1F, 0xDAD3, + 0x8C20, 0xDAD4, + 0x8C21, 0xDAD5, + 0x8C22, 0xD0BB, + 0x8C23, 0xD2A5, + 0x8C24, 0xB0F9, + 0x8C25, 0xDAD6, + 0x8C26, 0xC7AB, + 0x8C27, 0xDAD7, + 0x8C28, 0xBDF7, + 0x8C29, 0xC3A1, + 0x8C2A, 0xDAD8, + 0x8C2B, 0xDAD9, + 0x8C2C, 0xC3FD, + 0x8C2D, 0xCCB7, + 0x8C2E, 0xDADA, + 0x8C2F, 0xDADB, + 0x8C30, 0xC0BE, + 0x8C31, 0xC6D7, + 0x8C32, 0xDADC, + 0x8C33, 0xDADD, + 0x8C34, 0xC7B4, + 0x8C35, 0xDADE, + 0x8C36, 0xDADF, + 0x8C37, 0xB9C8, + 0x8C41, 0xBBED, + 0x8C46, 0xB6B9, + 0x8C47, 0xF4F8, + 0x8C49, 0xF4F9, + 0x8C4C, 0xCDE3, + 0x8C55, 0xF5B9, + 0x8C5A, 0xEBE0, + 0x8C61, 0xCFF3, + 0x8C62, 0xBBBF, + 0x8C6A, 0xBAC0, + 0x8C6B, 0xD4A5, + 0x8C73, 0xE1D9, + 0x8C78, 0xF5F4, + 0x8C79, 0xB1AA, + 0x8C7A, 0xB2F2, + 0x8C82, 0xF5F5, + 0x8C85, 0xF5F7, + 0x8C89, 0xBAD1, + 0x8C8A, 0xF5F6, + 0x8C8C, 0xC3B2, + 0x8C94, 0xF5F9, + 0x8C98, 0xF5F8, + 0x8D1D, 0xB1B4, + 0x8D1E, 0xD5EA, + 0x8D1F, 0xB8BA, + 0x8D21, 0xB9B1, + 0x8D22, 0xB2C6, + 0x8D23, 0xD4F0, + 0x8D24, 0xCFCD, + 0x8D25, 0xB0DC, + 0x8D26, 0xD5CB, + 0x8D27, 0xBBF5, + 0x8D28, 0xD6CA, + 0x8D29, 0xB7B7, + 0x8D2A, 0xCCB0, + 0x8D2B, 0xC6B6, + 0x8D2C, 0xB1E1, + 0x8D2D, 0xB9BA, + 0x8D2E, 0xD6FC, + 0x8D2F, 0xB9E1, + 0x8D30, 0xB7A1, + 0x8D31, 0xBCFA, + 0x8D32, 0xEADA, + 0x8D33, 0xEADB, + 0x8D34, 0xCCF9, + 0x8D35, 0xB9F3, + 0x8D36, 0xEADC, + 0x8D37, 0xB4FB, + 0x8D38, 0xC3B3, + 0x8D39, 0xB7D1, + 0x8D3A, 0xBAD8, + 0x8D3B, 0xEADD, + 0x8D3C, 0xD4F4, + 0x8D3D, 0xEADE, + 0x8D3E, 0xBCD6, + 0x8D3F, 0xBBDF, + 0x8D40, 0xEADF, + 0x8D41, 0xC1DE, + 0x8D42, 0xC2B8, + 0x8D43, 0xD4DF, + 0x8D44, 0xD7CA, + 0x8D45, 0xEAE0, + 0x8D46, 0xEAE1, + 0x8D47, 0xEAE4, + 0x8D48, 0xEAE2, + 0x8D49, 0xEAE3, + 0x8D4A, 0xC9DE, + 0x8D4B, 0xB8B3, + 0x8D4C, 0xB6C4, + 0x8D4D, 0xEAE5, + 0x8D4E, 0xCAEA, + 0x8D4F, 0xC9CD, + 0x8D50, 0xB4CD, + 0x8D53, 0xE2D9, + 0x8D54, 0xC5E2, + 0x8D55, 0xEAE6, + 0x8D56, 0xC0B5, + 0x8D58, 0xD7B8, + 0x8D59, 0xEAE7, + 0x8D5A, 0xD7AC, + 0x8D5B, 0xC8FC, + 0x8D5C, 0xD8D3, + 0x8D5D, 0xD8CD, + 0x8D5E, 0xD4DE, + 0x8D60, 0xD4F9, + 0x8D61, 0xC9C4, + 0x8D62, 0xD3AE, + 0x8D63, 0xB8D3, + 0x8D64, 0xB3E0, + 0x8D66, 0xC9E2, + 0x8D67, 0xF4F6, + 0x8D6B, 0xBAD5, + 0x8D6D, 0xF4F7, + 0x8D70, 0xD7DF, + 0x8D73, 0xF4F1, + 0x8D74, 0xB8B0, + 0x8D75, 0xD5D4, + 0x8D76, 0xB8CF, + 0x8D77, 0xC6F0, + 0x8D81, 0xB3C3, + 0x8D84, 0xF4F2, + 0x8D85, 0xB3AC, + 0x8D8A, 0xD4BD, + 0x8D8B, 0xC7F7, + 0x8D91, 0xF4F4, + 0x8D94, 0xF4F3, + 0x8D9F, 0xCCCB, + 0x8DA3, 0xC8A4, + 0x8DB1, 0xF4F5, + 0x8DB3, 0xD7E3, + 0x8DB4, 0xC5BF, + 0x8DB5, 0xF5C0, + 0x8DB8, 0xF5BB, + 0x8DBA, 0xF5C3, + 0x8DBC, 0xF5C2, + 0x8DBE, 0xD6BA, + 0x8DBF, 0xF5C1, + 0x8DC3, 0xD4BE, + 0x8DC4, 0xF5C4, + 0x8DC6, 0xF5CC, + 0x8DCB, 0xB0CF, + 0x8DCC, 0xB5F8, + 0x8DCE, 0xF5C9, + 0x8DCF, 0xF5CA, + 0x8DD1, 0xC5DC, + 0x8DD6, 0xF5C5, + 0x8DD7, 0xF5C6, + 0x8DDA, 0xF5C7, + 0x8DDB, 0xF5CB, + 0x8DDD, 0xBEE0, + 0x8DDE, 0xF5C8, + 0x8DDF, 0xB8FA, + 0x8DE3, 0xF5D0, + 0x8DE4, 0xF5D3, + 0x8DE8, 0xBFE7, + 0x8DEA, 0xB9F2, + 0x8DEB, 0xF5BC, + 0x8DEC, 0xF5CD, + 0x8DEF, 0xC2B7, + 0x8DF3, 0xCCF8, + 0x8DF5, 0xBCF9, + 0x8DF7, 0xF5CE, + 0x8DF8, 0xF5CF, + 0x8DF9, 0xF5D1, + 0x8DFA, 0xB6E5, + 0x8DFB, 0xF5D2, + 0x8DFD, 0xF5D5, + 0x8E05, 0xF5BD, + 0x8E09, 0xF5D4, + 0x8E0A, 0xD3BB, + 0x8E0C, 0xB3EC, + 0x8E0F, 0xCCA4, + 0x8E14, 0xF5D6, + 0x8E1D, 0xF5D7, + 0x8E1E, 0xBEE1, + 0x8E1F, 0xF5D8, + 0x8E22, 0xCCDF, + 0x8E23, 0xF5DB, + 0x8E29, 0xB2C8, + 0x8E2A, 0xD7D9, + 0x8E2C, 0xF5D9, + 0x8E2E, 0xF5DA, + 0x8E2F, 0xF5DC, + 0x8E31, 0xF5E2, + 0x8E35, 0xF5E0, + 0x8E39, 0xF5DF, + 0x8E3A, 0xF5DD, + 0x8E3D, 0xF5E1, + 0x8E40, 0xF5DE, + 0x8E41, 0xF5E4, + 0x8E42, 0xF5E5, + 0x8E44, 0xCCE3, + 0x8E47, 0xE5BF, + 0x8E48, 0xB5B8, + 0x8E49, 0xF5E3, + 0x8E4A, 0xF5E8, + 0x8E4B, 0xCCA3, + 0x8E51, 0xF5E6, + 0x8E52, 0xF5E7, + 0x8E59, 0xF5BE, + 0x8E66, 0xB1C4, + 0x8E69, 0xF5BF, + 0x8E6C, 0xB5C5, + 0x8E6D, 0xB2E4, + 0x8E6F, 0xF5EC, + 0x8E70, 0xF5E9, + 0x8E72, 0xB6D7, + 0x8E74, 0xF5ED, + 0x8E76, 0xF5EA, + 0x8E7C, 0xF5EB, + 0x8E7F, 0xB4DA, + 0x8E81, 0xD4EA, + 0x8E85, 0xF5EE, + 0x8E87, 0xB3F9, + 0x8E8F, 0xF5EF, + 0x8E90, 0xF5F1, + 0x8E94, 0xF5F0, + 0x8E9C, 0xF5F2, + 0x8E9E, 0xF5F3, + 0x8EAB, 0xC9ED, + 0x8EAC, 0xB9AA, + 0x8EAF, 0xC7FB, + 0x8EB2, 0xB6E3, + 0x8EBA, 0xCCC9, + 0x8ECE, 0xEAA6, + 0x8F66, 0xB3B5, + 0x8F67, 0xD4FE, + 0x8F68, 0xB9EC, + 0x8F69, 0xD0F9, + 0x8F6B, 0xE9ED, + 0x8F6C, 0xD7AA, + 0x8F6D, 0xE9EE, + 0x8F6E, 0xC2D6, + 0x8F6F, 0xC8ED, + 0x8F70, 0xBAE4, + 0x8F71, 0xE9EF, + 0x8F72, 0xE9F0, + 0x8F73, 0xE9F1, + 0x8F74, 0xD6E1, + 0x8F75, 0xE9F2, + 0x8F76, 0xE9F3, + 0x8F77, 0xE9F5, + 0x8F78, 0xE9F4, + 0x8F79, 0xE9F6, + 0x8F7A, 0xE9F7, + 0x8F7B, 0xC7E1, + 0x8F7C, 0xE9F8, + 0x8F7D, 0xD4D8, + 0x8F7E, 0xE9F9, + 0x8F7F, 0xBDCE, + 0x8F81, 0xE9FA, + 0x8F82, 0xE9FB, + 0x8F83, 0xBDCF, + 0x8F84, 0xE9FC, + 0x8F85, 0xB8A8, + 0x8F86, 0xC1BE, + 0x8F87, 0xE9FD, + 0x8F88, 0xB1B2, + 0x8F89, 0xBBD4, + 0x8F8A, 0xB9F5, + 0x8F8B, 0xE9FE, + 0x8F8D, 0xEAA1, + 0x8F8E, 0xEAA2, + 0x8F8F, 0xEAA3, + 0x8F90, 0xB7F8, + 0x8F91, 0xBCAD, + 0x8F93, 0xCAE4, + 0x8F94, 0xE0CE, + 0x8F95, 0xD4AF, + 0x8F96, 0xCFBD, + 0x8F97, 0xD5B7, + 0x8F98, 0xEAA4, + 0x8F99, 0xD5DE, + 0x8F9A, 0xEAA5, + 0x8F9B, 0xD0C1, + 0x8F9C, 0xB9BC, + 0x8F9E, 0xB4C7, + 0x8F9F, 0xB1D9, + 0x8FA3, 0xC0B1, + 0x8FA8, 0xB1E6, + 0x8FA9, 0xB1E7, + 0x8FAB, 0xB1E8, + 0x8FB0, 0xB3BD, + 0x8FB1, 0xC8E8, + 0x8FB6, 0xE5C1, + 0x8FB9, 0xB1DF, + 0x8FBD, 0xC1C9, + 0x8FBE, 0xB4EF, + 0x8FC1, 0xC7A8, + 0x8FC2, 0xD3D8, + 0x8FC4, 0xC6F9, + 0x8FC5, 0xD1B8, + 0x8FC7, 0xB9FD, + 0x8FC8, 0xC2F5, + 0x8FCE, 0xD3AD, + 0x8FD0, 0xD4CB, + 0x8FD1, 0xBDFC, + 0x8FD3, 0xE5C2, + 0x8FD4, 0xB7B5, + 0x8FD5, 0xE5C3, + 0x8FD8, 0xBBB9, + 0x8FD9, 0xD5E2, + 0x8FDB, 0xBDF8, + 0x8FDC, 0xD4B6, + 0x8FDD, 0xCEA5, + 0x8FDE, 0xC1AC, + 0x8FDF, 0xB3D9, + 0x8FE2, 0xCCF6, + 0x8FE4, 0xE5C6, + 0x8FE5, 0xE5C4, + 0x8FE6, 0xE5C8, + 0x8FE8, 0xE5CA, + 0x8FE9, 0xE5C7, + 0x8FEA, 0xB5CF, + 0x8FEB, 0xC6C8, + 0x8FED, 0xB5FC, + 0x8FEE, 0xE5C5, + 0x8FF0, 0xCAF6, + 0x8FF3, 0xE5C9, + 0x8FF7, 0xC3D4, + 0x8FF8, 0xB1C5, + 0x8FF9, 0xBCA3, + 0x8FFD, 0xD7B7, + 0x9000, 0xCDCB, + 0x9001, 0xCBCD, + 0x9002, 0xCACA, + 0x9003, 0xCCD3, + 0x9004, 0xE5CC, + 0x9005, 0xE5CB, + 0x9006, 0xC4E6, + 0x9009, 0xD1A1, + 0x900A, 0xD1B7, + 0x900B, 0xE5CD, + 0x900D, 0xE5D0, + 0x900F, 0xCDB8, + 0x9010, 0xD6F0, + 0x9011, 0xE5CF, + 0x9012, 0xB5DD, + 0x9014, 0xCDBE, + 0x9016, 0xE5D1, + 0x9017, 0xB6BA, + 0x901A, 0xCDA8, + 0x901B, 0xB9E4, + 0x901D, 0xCAC5, + 0x901E, 0xB3D1, + 0x901F, 0xCBD9, + 0x9020, 0xD4EC, + 0x9021, 0xE5D2, + 0x9022, 0xB7EA, + 0x9026, 0xE5CE, + 0x902D, 0xE5D5, + 0x902E, 0xB4FE, + 0x902F, 0xE5D6, + 0x9035, 0xE5D3, + 0x9036, 0xE5D4, + 0x9038, 0xD2DD, + 0x903B, 0xC2DF, + 0x903C, 0xB1C6, + 0x903E, 0xD3E2, + 0x9041, 0xB6DD, + 0x9042, 0xCBEC, + 0x9044, 0xE5D7, + 0x9047, 0xD3F6, + 0x904D, 0xB1E9, + 0x904F, 0xB6F4, + 0x9050, 0xE5DA, + 0x9051, 0xE5D8, + 0x9052, 0xE5D9, + 0x9053, 0xB5C0, + 0x9057, 0xD2C5, + 0x9058, 0xE5DC, + 0x905B, 0xE5DE, + 0x9062, 0xE5DD, + 0x9063, 0xC7B2, + 0x9065, 0xD2A3, + 0x9068, 0xE5DB, + 0x906D, 0xD4E2, + 0x906E, 0xD5DA, + 0x9074, 0xE5E0, + 0x9075, 0xD7F1, + 0x907D, 0xE5E1, + 0x907F, 0xB1DC, + 0x9080, 0xD1FB, + 0x9082, 0xE5E2, + 0x9083, 0xE5E4, + 0x9088, 0xE5E3, + 0x908B, 0xE5E5, + 0x9091, 0xD2D8, + 0x9093, 0xB5CB, + 0x9095, 0xE7DF, + 0x9097, 0xDAF5, + 0x9099, 0xDAF8, + 0x909B, 0xDAF6, + 0x909D, 0xDAF7, + 0x90A1, 0xDAFA, + 0x90A2, 0xD0CF, + 0x90A3, 0xC4C7, + 0x90A6, 0xB0EE, + 0x90AA, 0xD0B0, + 0x90AC, 0xDAF9, + 0x90AE, 0xD3CA, + 0x90AF, 0xBAAA, + 0x90B0, 0xDBA2, + 0x90B1, 0xC7F1, + 0x90B3, 0xDAFC, + 0x90B4, 0xDAFB, + 0x90B5, 0xC9DB, + 0x90B6, 0xDAFD, + 0x90B8, 0xDBA1, + 0x90B9, 0xD7DE, + 0x90BA, 0xDAFE, + 0x90BB, 0xC1DA, + 0x90BE, 0xDBA5, + 0x90C1, 0xD3F4, + 0x90C4, 0xDBA7, + 0x90C5, 0xDBA4, + 0x90C7, 0xDBA8, + 0x90CA, 0xBDBC, + 0x90CE, 0xC0C9, + 0x90CF, 0xDBA3, + 0x90D0, 0xDBA6, + 0x90D1, 0xD6A3, + 0x90D3, 0xDBA9, + 0x90D7, 0xDBAD, + 0x90DB, 0xDBAE, + 0x90DC, 0xDBAC, + 0x90DD, 0xBAC2, + 0x90E1, 0xBFA4, + 0x90E2, 0xDBAB, + 0x90E6, 0xDBAA, + 0x90E7, 0xD4C7, + 0x90E8, 0xB2BF, + 0x90EB, 0xDBAF, + 0x90ED, 0xB9F9, + 0x90EF, 0xDBB0, + 0x90F4, 0xB3BB, + 0x90F8, 0xB5A6, + 0x90FD, 0xB6BC, + 0x90FE, 0xDBB1, + 0x9102, 0xB6F5, + 0x9104, 0xDBB2, + 0x9119, 0xB1C9, + 0x911E, 0xDBB4, + 0x9122, 0xDBB3, + 0x9123, 0xDBB5, + 0x912F, 0xDBB7, + 0x9131, 0xDBB6, + 0x9139, 0xDBB8, + 0x9143, 0xDBB9, + 0x9146, 0xDBBA, + 0x9149, 0xD3CF, + 0x914A, 0xF4FA, + 0x914B, 0xC7F5, + 0x914C, 0xD7C3, + 0x914D, 0xC5E4, + 0x914E, 0xF4FC, + 0x914F, 0xF4FD, + 0x9150, 0xF4FB, + 0x9152, 0xBEC6, + 0x9157, 0xD0EF, + 0x915A, 0xB7D3, + 0x915D, 0xD4CD, + 0x915E, 0xCCAA, + 0x9161, 0xF5A2, + 0x9162, 0xF5A1, + 0x9163, 0xBAA8, + 0x9164, 0xF4FE, + 0x9165, 0xCBD6, + 0x9169, 0xF5A4, + 0x916A, 0xC0D2, + 0x916C, 0xB3EA, + 0x916E, 0xCDAA, + 0x916F, 0xF5A5, + 0x9170, 0xF5A3, + 0x9171, 0xBDB4, + 0x9172, 0xF5A8, + 0x9174, 0xF5A9, + 0x9175, 0xBDCD, + 0x9176, 0xC3B8, + 0x9177, 0xBFE1, + 0x9178, 0xCBE1, + 0x9179, 0xF5AA, + 0x917D, 0xF5A6, + 0x917E, 0xF5A7, + 0x917F, 0xC4F0, + 0x9185, 0xF5AC, + 0x9187, 0xB4BC, + 0x9189, 0xD7ED, + 0x918B, 0xB4D7, + 0x918C, 0xF5AB, + 0x918D, 0xF5AE, + 0x9190, 0xF5AD, + 0x9191, 0xF5AF, + 0x9192, 0xD0D1, + 0x919A, 0xC3D1, + 0x919B, 0xC8A9, + 0x91A2, 0xF5B0, + 0x91A3, 0xF5B1, + 0x91AA, 0xF5B2, + 0x91AD, 0xF5B3, + 0x91AE, 0xF5B4, + 0x91AF, 0xF5B5, + 0x91B4, 0xF5B7, + 0x91B5, 0xF5B6, + 0x91BA, 0xF5B8, + 0x91C7, 0xB2C9, + 0x91C9, 0xD3D4, + 0x91CA, 0xCACD, + 0x91CC, 0xC0EF, + 0x91CD, 0xD6D8, + 0x91CE, 0xD2B0, + 0x91CF, 0xC1BF, + 0x91D1, 0xBDF0, + 0x91DC, 0xB8AA, + 0x9274, 0xBCF8, + 0x928E, 0xF6C6, + 0x92AE, 0xF6C7, + 0x92C8, 0xF6C8, + 0x933E, 0xF6C9, + 0x936A, 0xF6CA, + 0x938F, 0xF6CC, + 0x93CA, 0xF6CB, + 0x93D6, 0xF7E9, + 0x943E, 0xF6CD, + 0x946B, 0xF6CE, + 0x9485, 0xEEC4, + 0x9486, 0xEEC5, + 0x9487, 0xEEC6, + 0x9488, 0xD5EB, + 0x9489, 0xB6A4, + 0x948A, 0xEEC8, + 0x948B, 0xEEC7, + 0x948C, 0xEEC9, + 0x948D, 0xEECA, + 0x948E, 0xC7A5, + 0x948F, 0xEECB, + 0x9490, 0xEECC, + 0x9492, 0xB7B0, + 0x9493, 0xB5F6, + 0x9494, 0xEECD, + 0x9495, 0xEECF, + 0x9497, 0xEECE, + 0x9499, 0xB8C6, + 0x949A, 0xEED0, + 0x949B, 0xEED1, + 0x949C, 0xEED2, + 0x949D, 0xB6DB, + 0x949E, 0xB3AE, + 0x949F, 0xD6D3, + 0x94A0, 0xC4C6, + 0x94A1, 0xB1B5, + 0x94A2, 0xB8D6, + 0x94A3, 0xEED3, + 0x94A4, 0xEED4, + 0x94A5, 0xD4BF, + 0x94A6, 0xC7D5, + 0x94A7, 0xBEFB, + 0x94A8, 0xCED9, + 0x94A9, 0xB9B3, + 0x94AA, 0xEED6, + 0x94AB, 0xEED5, + 0x94AC, 0xEED8, + 0x94AD, 0xEED7, + 0x94AE, 0xC5A5, + 0x94AF, 0xEED9, + 0x94B0, 0xEEDA, + 0x94B1, 0xC7AE, + 0x94B2, 0xEEDB, + 0x94B3, 0xC7AF, + 0x94B4, 0xEEDC, + 0x94B5, 0xB2A7, + 0x94B6, 0xEEDD, + 0x94B7, 0xEEDE, + 0x94B8, 0xEEDF, + 0x94B9, 0xEEE0, + 0x94BA, 0xEEE1, + 0x94BB, 0xD7EA, + 0x94BC, 0xEEE2, + 0x94BD, 0xEEE3, + 0x94BE, 0xBCD8, + 0x94BF, 0xEEE4, + 0x94C0, 0xD3CB, + 0x94C1, 0xCCFA, + 0x94C2, 0xB2AC, + 0x94C3, 0xC1E5, + 0x94C4, 0xEEE5, + 0x94C5, 0xC7A6, + 0x94C6, 0xC3AD, + 0x94C8, 0xEEE6, + 0x94C9, 0xEEE7, + 0x94CA, 0xEEE8, + 0x94CB, 0xEEE9, + 0x94CC, 0xEEEA, + 0x94CD, 0xEEEB, + 0x94CE, 0xEEEC, + 0x94D0, 0xEEED, + 0x94D1, 0xEEEE, + 0x94D2, 0xEEEF, + 0x94D5, 0xEEF0, + 0x94D6, 0xEEF1, + 0x94D7, 0xEEF2, + 0x94D8, 0xEEF4, + 0x94D9, 0xEEF3, + 0x94DB, 0xEEF5, + 0x94DC, 0xCDAD, + 0x94DD, 0xC2C1, + 0x94DE, 0xEEF6, + 0x94DF, 0xEEF7, + 0x94E0, 0xEEF8, + 0x94E1, 0xD5A1, + 0x94E2, 0xEEF9, + 0x94E3, 0xCFB3, + 0x94E4, 0xEEFA, + 0x94E5, 0xEEFB, + 0x94E7, 0xEEFC, + 0x94E8, 0xEEFD, + 0x94E9, 0xEFA1, + 0x94EA, 0xEEFE, + 0x94EB, 0xEFA2, + 0x94EC, 0xB8F5, + 0x94ED, 0xC3FA, + 0x94EE, 0xEFA3, + 0x94EF, 0xEFA4, + 0x94F0, 0xBDC2, + 0x94F1, 0xD2BF, + 0x94F2, 0xB2F9, + 0x94F3, 0xEFA5, + 0x94F4, 0xEFA6, + 0x94F5, 0xEFA7, + 0x94F6, 0xD2F8, + 0x94F7, 0xEFA8, + 0x94F8, 0xD6FD, + 0x94F9, 0xEFA9, + 0x94FA, 0xC6CC, + 0x94FC, 0xEFAA, + 0x94FD, 0xEFAB, + 0x94FE, 0xC1B4, + 0x94FF, 0xEFAC, + 0x9500, 0xCFFA, + 0x9501, 0xCBF8, + 0x9502, 0xEFAE, + 0x9503, 0xEFAD, + 0x9504, 0xB3FA, + 0x9505, 0xB9F8, + 0x9506, 0xEFAF, + 0x9507, 0xEFB0, + 0x9508, 0xD0E2, + 0x9509, 0xEFB1, + 0x950A, 0xEFB2, + 0x950B, 0xB7E6, + 0x950C, 0xD0BF, + 0x950D, 0xEFB3, + 0x950E, 0xEFB4, + 0x950F, 0xEFB5, + 0x9510, 0xC8F1, + 0x9511, 0xCCE0, + 0x9512, 0xEFB6, + 0x9513, 0xEFB7, + 0x9514, 0xEFB8, + 0x9515, 0xEFB9, + 0x9516, 0xEFBA, + 0x9517, 0xD5E0, + 0x9518, 0xEFBB, + 0x9519, 0xB4ED, + 0x951A, 0xC3AA, + 0x951B, 0xEFBC, + 0x951D, 0xEFBD, + 0x951E, 0xEFBE, + 0x951F, 0xEFBF, + 0x9521, 0xCEFD, + 0x9522, 0xEFC0, + 0x9523, 0xC2E0, + 0x9524, 0xB4B8, + 0x9525, 0xD7B6, + 0x9526, 0xBDF5, + 0x9528, 0xCFC7, + 0x9529, 0xEFC3, + 0x952A, 0xEFC1, + 0x952B, 0xEFC2, + 0x952C, 0xEFC4, + 0x952D, 0xB6A7, + 0x952E, 0xBCFC, + 0x952F, 0xBEE2, + 0x9530, 0xC3CC, + 0x9531, 0xEFC5, + 0x9532, 0xEFC6, + 0x9534, 0xEFC7, + 0x9535, 0xEFCF, + 0x9536, 0xEFC8, + 0x9537, 0xEFC9, + 0x9538, 0xEFCA, + 0x9539, 0xC7C2, + 0x953A, 0xEFF1, + 0x953B, 0xB6CD, + 0x953C, 0xEFCB, + 0x953E, 0xEFCC, + 0x953F, 0xEFCD, + 0x9540, 0xB6C6, + 0x9541, 0xC3BE, + 0x9542, 0xEFCE, + 0x9544, 0xEFD0, + 0x9545, 0xEFD1, + 0x9546, 0xEFD2, + 0x9547, 0xD5F2, + 0x9549, 0xEFD3, + 0x954A, 0xC4F7, + 0x954C, 0xEFD4, + 0x954D, 0xC4F8, + 0x954E, 0xEFD5, + 0x954F, 0xEFD6, + 0x9550, 0xB8E4, + 0x9551, 0xB0F7, + 0x9552, 0xEFD7, + 0x9553, 0xEFD8, + 0x9554, 0xEFD9, + 0x9556, 0xEFDA, + 0x9557, 0xEFDB, + 0x9558, 0xEFDC, + 0x9559, 0xEFDD, + 0x955B, 0xEFDE, + 0x955C, 0xBEB5, + 0x955D, 0xEFE1, + 0x955E, 0xEFDF, + 0x955F, 0xEFE0, + 0x9561, 0xEFE2, + 0x9562, 0xEFE3, + 0x9563, 0xC1CD, + 0x9564, 0xEFE4, + 0x9565, 0xEFE5, + 0x9566, 0xEFE6, + 0x9567, 0xEFE7, + 0x9568, 0xEFE8, + 0x9569, 0xEFE9, + 0x956A, 0xEFEA, + 0x956B, 0xEFEB, + 0x956C, 0xEFEC, + 0x956D, 0xC0D8, + 0x956F, 0xEFED, + 0x9570, 0xC1AD, + 0x9571, 0xEFEE, + 0x9572, 0xEFEF, + 0x9573, 0xEFF0, + 0x9576, 0xCFE2, + 0x957F, 0xB3A4, + 0x95E8, 0xC3C5, + 0x95E9, 0xE3C5, + 0x95EA, 0xC9C1, + 0x95EB, 0xE3C6, + 0x95ED, 0xB1D5, + 0x95EE, 0xCECA, + 0x95EF, 0xB4B3, + 0x95F0, 0xC8F2, + 0x95F1, 0xE3C7, + 0x95F2, 0xCFD0, + 0x95F3, 0xE3C8, + 0x95F4, 0xBCE4, + 0x95F5, 0xE3C9, + 0x95F6, 0xE3CA, + 0x95F7, 0xC3C6, + 0x95F8, 0xD5A2, + 0x95F9, 0xC4D6, + 0x95FA, 0xB9EB, + 0x95FB, 0xCEC5, + 0x95FC, 0xE3CB, + 0x95FD, 0xC3F6, + 0x95FE, 0xE3CC, + 0x9600, 0xB7A7, + 0x9601, 0xB8F3, + 0x9602, 0xBAD2, + 0x9603, 0xE3CD, + 0x9604, 0xE3CE, + 0x9605, 0xD4C4, + 0x9606, 0xE3CF, + 0x9608, 0xE3D0, + 0x9609, 0xD1CB, + 0x960A, 0xE3D1, + 0x960B, 0xE3D2, + 0x960C, 0xE3D3, + 0x960D, 0xE3D4, + 0x960E, 0xD1D6, + 0x960F, 0xE3D5, + 0x9610, 0xB2FB, + 0x9611, 0xC0BB, + 0x9612, 0xE3D6, + 0x9614, 0xC0AB, + 0x9615, 0xE3D7, + 0x9616, 0xE3D8, + 0x9617, 0xE3D9, + 0x9619, 0xE3DA, + 0x961A, 0xE3DB, + 0x961C, 0xB8B7, + 0x961D, 0xDAE2, + 0x961F, 0xB6D3, + 0x9621, 0xDAE4, + 0x9622, 0xDAE3, + 0x962A, 0xDAE6, + 0x962E, 0xC8EE, + 0x9631, 0xDAE5, + 0x9632, 0xB7C0, + 0x9633, 0xD1F4, + 0x9634, 0xD2F5, + 0x9635, 0xD5F3, + 0x9636, 0xBDD7, + 0x963B, 0xD7E8, + 0x963C, 0xDAE8, + 0x963D, 0xDAE7, + 0x963F, 0xB0A2, + 0x9640, 0xCDD3, + 0x9642, 0xDAE9, + 0x9644, 0xB8BD, + 0x9645, 0xBCCA, + 0x9646, 0xC2BD, + 0x9647, 0xC2A4, + 0x9648, 0xB3C2, + 0x9649, 0xDAEA, + 0x964B, 0xC2AA, + 0x964C, 0xC4B0, + 0x964D, 0xBDB5, + 0x9650, 0xCFDE, + 0x9654, 0xDAEB, + 0x9655, 0xC9C2, + 0x965B, 0xB1DD, + 0x965F, 0xDAEC, + 0x9661, 0xB6B8, + 0x9662, 0xD4BA, + 0x9664, 0xB3FD, + 0x9667, 0xDAED, + 0x9668, 0xD4C9, + 0x9669, 0xCFD5, + 0x966A, 0xC5E3, + 0x966C, 0xDAEE, + 0x9672, 0xDAEF, + 0x9674, 0xDAF0, + 0x9675, 0xC1EA, + 0x9676, 0xCCD5, + 0x9677, 0xCFDD, + 0x9685, 0xD3E7, + 0x9686, 0xC2A1, + 0x9688, 0xDAF1, + 0x968B, 0xCBE5, + 0x968D, 0xDAF2, + 0x968F, 0xCBE6, + 0x9690, 0xD2FE, + 0x9694, 0xB8F4, + 0x9697, 0xDAF3, + 0x9698, 0xB0AF, + 0x9699, 0xCFB6, + 0x969C, 0xD5CF, + 0x96A7, 0xCBED, + 0x96B0, 0xDAF4, + 0x96B3, 0xE3C4, + 0x96B6, 0xC1A5, + 0x96B9, 0xF6BF, + 0x96BC, 0xF6C0, + 0x96BD, 0xF6C1, + 0x96BE, 0xC4D1, + 0x96C0, 0xC8B8, + 0x96C1, 0xD1E3, + 0x96C4, 0xD0DB, + 0x96C5, 0xD1C5, + 0x96C6, 0xBCAF, + 0x96C7, 0xB9CD, + 0x96C9, 0xEFF4, + 0x96CC, 0xB4C6, + 0x96CD, 0xD3BA, + 0x96CE, 0xF6C2, + 0x96CF, 0xB3FB, + 0x96D2, 0xF6C3, + 0x96D5, 0xB5F1, + 0x96E0, 0xF6C5, + 0x96E8, 0xD3EA, + 0x96E9, 0xF6A7, + 0x96EA, 0xD1A9, + 0x96EF, 0xF6A9, + 0x96F3, 0xF6A8, + 0x96F6, 0xC1E3, + 0x96F7, 0xC0D7, + 0x96F9, 0xB1A2, + 0x96FE, 0xCEED, + 0x9700, 0xD0E8, + 0x9701, 0xF6AB, + 0x9704, 0xCFF6, + 0x9706, 0xF6AA, + 0x9707, 0xD5F0, + 0x9708, 0xF6AC, + 0x9709, 0xC3B9, + 0x970D, 0xBBF4, + 0x970E, 0xF6AE, + 0x970F, 0xF6AD, + 0x9713, 0xC4DE, + 0x9716, 0xC1D8, + 0x971C, 0xCBAA, + 0x971E, 0xCFBC, + 0x972A, 0xF6AF, + 0x972D, 0xF6B0, + 0x9730, 0xF6B1, + 0x9732, 0xC2B6, + 0x9738, 0xB0D4, + 0x9739, 0xC5F9, + 0x973E, 0xF6B2, + 0x9752, 0xC7E0, + 0x9753, 0xF6A6, + 0x9756, 0xBEB8, + 0x9759, 0xBEB2, + 0x975B, 0xB5E5, + 0x975E, 0xB7C7, + 0x9760, 0xBFBF, + 0x9761, 0xC3D2, + 0x9762, 0xC3E6, + 0x9765, 0xD8CC, + 0x9769, 0xB8EF, + 0x9773, 0xBDF9, + 0x9774, 0xD1A5, + 0x9776, 0xB0D0, + 0x977C, 0xF7B0, + 0x9785, 0xF7B1, + 0x978B, 0xD0AC, + 0x978D, 0xB0B0, + 0x9791, 0xF7B2, + 0x9792, 0xF7B3, + 0x9794, 0xF7B4, + 0x9798, 0xC7CA, + 0x97A0, 0xBECF, + 0x97A3, 0xF7B7, + 0x97AB, 0xF7B6, + 0x97AD, 0xB1DE, + 0x97AF, 0xF7B5, + 0x97B2, 0xF7B8, + 0x97B4, 0xF7B9, + 0x97E6, 0xCEA4, + 0x97E7, 0xC8CD, + 0x97E9, 0xBAAB, + 0x97EA, 0xE8B8, + 0x97EB, 0xE8B9, + 0x97EC, 0xE8BA, + 0x97ED, 0xBEC2, + 0x97F3, 0xD2F4, + 0x97F5, 0xD4CF, + 0x97F6, 0xC9D8, + 0x9875, 0xD2B3, + 0x9876, 0xB6A5, + 0x9877, 0xC7EA, + 0x9878, 0xF1FC, + 0x9879, 0xCFEE, + 0x987A, 0xCBB3, + 0x987B, 0xD0EB, + 0x987C, 0xE7EF, + 0x987D, 0xCDE7, + 0x987E, 0xB9CB, + 0x987F, 0xB6D9, + 0x9880, 0xF1FD, + 0x9881, 0xB0E4, + 0x9882, 0xCBCC, + 0x9883, 0xF1FE, + 0x9884, 0xD4A4, + 0x9885, 0xC2AD, + 0x9886, 0xC1EC, + 0x9887, 0xC6C4, + 0x9888, 0xBEB1, + 0x9889, 0xF2A1, + 0x988A, 0xBCD5, + 0x988C, 0xF2A2, + 0x988D, 0xF2A3, + 0x988F, 0xF2A4, + 0x9890, 0xD2C3, + 0x9891, 0xC6B5, + 0x9893, 0xCDC7, + 0x9894, 0xF2A5, + 0x9896, 0xD3B1, + 0x9897, 0xBFC5, + 0x9898, 0xCCE2, + 0x989A, 0xF2A6, + 0x989B, 0xF2A7, + 0x989C, 0xD1D5, + 0x989D, 0xB6EE, + 0x989E, 0xF2A8, + 0x989F, 0xF2A9, + 0x98A0, 0xB5DF, + 0x98A1, 0xF2AA, + 0x98A2, 0xF2AB, + 0x98A4, 0xB2FC, + 0x98A5, 0xF2AC, + 0x98A6, 0xF2AD, + 0x98A7, 0xC8A7, + 0x98CE, 0xB7E7, + 0x98D1, 0xECA9, + 0x98D2, 0xECAA, + 0x98D3, 0xECAB, + 0x98D5, 0xECAC, + 0x98D8, 0xC6AE, + 0x98D9, 0xECAD, + 0x98DA, 0xECAE, + 0x98DE, 0xB7C9, + 0x98DF, 0xCAB3, + 0x98E7, 0xE2B8, + 0x98E8, 0xF7CF, + 0x990D, 0xF7D0, + 0x9910, 0xB2CD, + 0x992E, 0xF7D1, + 0x9954, 0xF7D3, + 0x9955, 0xF7D2, + 0x9963, 0xE2BB, + 0x9965, 0xBCA2, + 0x9967, 0xE2BC, + 0x9968, 0xE2BD, + 0x9969, 0xE2BE, + 0x996A, 0xE2BF, + 0x996B, 0xE2C0, + 0x996C, 0xE2C1, + 0x996D, 0xB7B9, + 0x996E, 0xD2FB, + 0x996F, 0xBDA4, + 0x9970, 0xCACE, + 0x9971, 0xB1A5, + 0x9972, 0xCBC7, + 0x9974, 0xE2C2, + 0x9975, 0xB6FC, + 0x9976, 0xC8C4, + 0x9977, 0xE2C3, + 0x997A, 0xBDC8, + 0x997C, 0xB1FD, + 0x997D, 0xE2C4, + 0x997F, 0xB6F6, + 0x9980, 0xE2C5, + 0x9981, 0xC4D9, + 0x9984, 0xE2C6, + 0x9985, 0xCFDA, + 0x9986, 0xB9DD, + 0x9987, 0xE2C7, + 0x9988, 0xC0A1, + 0x998A, 0xE2C8, + 0x998B, 0xB2F6, + 0x998D, 0xE2C9, + 0x998F, 0xC1F3, + 0x9990, 0xE2CA, + 0x9991, 0xE2CB, + 0x9992, 0xC2F8, + 0x9993, 0xE2CC, + 0x9994, 0xE2CD, + 0x9995, 0xE2CE, + 0x9996, 0xCAD7, + 0x9997, 0xD8B8, + 0x9998, 0xD9E5, + 0x9999, 0xCFE3, + 0x99A5, 0xF0A5, + 0x99A8, 0xDCB0, + 0x9A6C, 0xC2ED, + 0x9A6D, 0xD4A6, + 0x9A6E, 0xCDD4, + 0x9A6F, 0xD1B1, + 0x9A70, 0xB3DB, + 0x9A71, 0xC7FD, + 0x9A73, 0xB2B5, + 0x9A74, 0xC2BF, + 0x9A75, 0xE6E0, + 0x9A76, 0xCABB, + 0x9A77, 0xE6E1, + 0x9A78, 0xE6E2, + 0x9A79, 0xBED4, + 0x9A7A, 0xE6E3, + 0x9A7B, 0xD7A4, + 0x9A7C, 0xCDD5, + 0x9A7D, 0xE6E5, + 0x9A7E, 0xBCDD, + 0x9A7F, 0xE6E4, + 0x9A80, 0xE6E6, + 0x9A81, 0xE6E7, + 0x9A82, 0xC2EE, + 0x9A84, 0xBDBE, + 0x9A85, 0xE6E8, + 0x9A86, 0xC2E6, + 0x9A87, 0xBAA7, + 0x9A88, 0xE6E9, + 0x9A8A, 0xE6EA, + 0x9A8B, 0xB3D2, + 0x9A8C, 0xD1E9, + 0x9A8F, 0xBFA5, + 0x9A90, 0xE6EB, + 0x9A91, 0xC6EF, + 0x9A92, 0xE6EC, + 0x9A93, 0xE6ED, + 0x9A96, 0xE6EE, + 0x9A97, 0xC6AD, + 0x9A98, 0xE6EF, + 0x9A9A, 0xC9A7, + 0x9A9B, 0xE6F0, + 0x9A9C, 0xE6F1, + 0x9A9D, 0xE6F2, + 0x9A9E, 0xE5B9, + 0x9A9F, 0xE6F3, + 0x9AA0, 0xE6F4, + 0x9AA1, 0xC2E2, + 0x9AA2, 0xE6F5, + 0x9AA3, 0xE6F6, + 0x9AA4, 0xD6E8, + 0x9AA5, 0xE6F7, + 0x9AA7, 0xE6F8, + 0x9AA8, 0xB9C7, + 0x9AB0, 0xF7BB, + 0x9AB1, 0xF7BA, + 0x9AB6, 0xF7BE, + 0x9AB7, 0xF7BC, + 0x9AB8, 0xBAA1, + 0x9ABA, 0xF7BF, + 0x9ABC, 0xF7C0, + 0x9AC0, 0xF7C2, + 0x9AC1, 0xF7C1, + 0x9AC2, 0xF7C4, + 0x9AC5, 0xF7C3, + 0x9ACB, 0xF7C5, + 0x9ACC, 0xF7C6, + 0x9AD1, 0xF7C7, + 0x9AD3, 0xCBE8, + 0x9AD8, 0xB8DF, + 0x9ADF, 0xF7D4, + 0x9AE1, 0xF7D5, + 0x9AE6, 0xF7D6, + 0x9AEB, 0xF7D8, + 0x9AED, 0xF7DA, + 0x9AEF, 0xF7D7, + 0x9AF9, 0xF7DB, + 0x9AFB, 0xF7D9, + 0x9B03, 0xD7D7, + 0x9B08, 0xF7DC, + 0x9B0F, 0xF7DD, + 0x9B13, 0xF7DE, + 0x9B1F, 0xF7DF, + 0x9B23, 0xF7E0, + 0x9B2F, 0xDBCB, + 0x9B32, 0xD8AA, + 0x9B3B, 0xE5F7, + 0x9B3C, 0xB9ED, + 0x9B41, 0xBFFD, + 0x9B42, 0xBBEA, + 0x9B43, 0xF7C9, + 0x9B44, 0xC6C7, + 0x9B45, 0xF7C8, + 0x9B47, 0xF7CA, + 0x9B48, 0xF7CC, + 0x9B49, 0xF7CB, + 0x9B4D, 0xF7CD, + 0x9B4F, 0xCEBA, + 0x9B51, 0xF7CE, + 0x9B54, 0xC4A7, + 0x9C7C, 0xD3E3, + 0x9C7F, 0xF6CF, + 0x9C81, 0xC2B3, + 0x9C82, 0xF6D0, + 0x9C85, 0xF6D1, + 0x9C86, 0xF6D2, + 0x9C87, 0xF6D3, + 0x9C88, 0xF6D4, + 0x9C8B, 0xF6D6, + 0x9C8D, 0xB1AB, + 0x9C8E, 0xF6D7, + 0x9C90, 0xF6D8, + 0x9C91, 0xF6D9, + 0x9C92, 0xF6DA, + 0x9C94, 0xF6DB, + 0x9C95, 0xF6DC, + 0x9C9A, 0xF6DD, + 0x9C9B, 0xF6DE, + 0x9C9C, 0xCFCA, + 0x9C9E, 0xF6DF, + 0x9C9F, 0xF6E0, + 0x9CA0, 0xF6E1, + 0x9CA1, 0xF6E2, + 0x9CA2, 0xF6E3, + 0x9CA3, 0xF6E4, + 0x9CA4, 0xC0F0, + 0x9CA5, 0xF6E5, + 0x9CA6, 0xF6E6, + 0x9CA7, 0xF6E7, + 0x9CA8, 0xF6E8, + 0x9CA9, 0xF6E9, + 0x9CAB, 0xF6EA, + 0x9CAD, 0xF6EB, + 0x9CAE, 0xF6EC, + 0x9CB0, 0xF6ED, + 0x9CB1, 0xF6EE, + 0x9CB2, 0xF6EF, + 0x9CB3, 0xF6F0, + 0x9CB4, 0xF6F1, + 0x9CB5, 0xF6F2, + 0x9CB6, 0xF6F3, + 0x9CB7, 0xF6F4, + 0x9CB8, 0xBEA8, + 0x9CBA, 0xF6F5, + 0x9CBB, 0xF6F6, + 0x9CBC, 0xF6F7, + 0x9CBD, 0xF6F8, + 0x9CC3, 0xC8FA, + 0x9CC4, 0xF6F9, + 0x9CC5, 0xF6FA, + 0x9CC6, 0xF6FB, + 0x9CC7, 0xF6FC, + 0x9CCA, 0xF6FD, + 0x9CCB, 0xF6FE, + 0x9CCC, 0xF7A1, + 0x9CCD, 0xF7A2, + 0x9CCE, 0xF7A3, + 0x9CCF, 0xF7A4, + 0x9CD0, 0xF7A5, + 0x9CD3, 0xF7A6, + 0x9CD4, 0xF7A7, + 0x9CD5, 0xF7A8, + 0x9CD6, 0xB1EE, + 0x9CD7, 0xF7A9, + 0x9CD8, 0xF7AA, + 0x9CD9, 0xF7AB, + 0x9CDC, 0xF7AC, + 0x9CDD, 0xF7AD, + 0x9CDE, 0xC1DB, + 0x9CDF, 0xF7AE, + 0x9CE2, 0xF7AF, + 0x9E1F, 0xC4F1, + 0x9E20, 0xF0AF, + 0x9E21, 0xBCA6, + 0x9E22, 0xF0B0, + 0x9E23, 0xC3F9, + 0x9E25, 0xC5B8, + 0x9E26, 0xD1BB, + 0x9E28, 0xF0B1, + 0x9E29, 0xF0B2, + 0x9E2A, 0xF0B3, + 0x9E2B, 0xF0B4, + 0x9E2C, 0xF0B5, + 0x9E2D, 0xD1BC, + 0x9E2F, 0xD1EC, + 0x9E31, 0xF0B7, + 0x9E32, 0xF0B6, + 0x9E33, 0xD4A7, + 0x9E35, 0xCDD2, + 0x9E36, 0xF0B8, + 0x9E37, 0xF0BA, + 0x9E38, 0xF0B9, + 0x9E39, 0xF0BB, + 0x9E3A, 0xF0BC, + 0x9E3D, 0xB8EB, + 0x9E3E, 0xF0BD, + 0x9E3F, 0xBAE8, + 0x9E41, 0xF0BE, + 0x9E42, 0xF0BF, + 0x9E43, 0xBEE9, + 0x9E44, 0xF0C0, + 0x9E45, 0xB6EC, + 0x9E46, 0xF0C1, + 0x9E47, 0xF0C2, + 0x9E48, 0xF0C3, + 0x9E49, 0xF0C4, + 0x9E4A, 0xC8B5, + 0x9E4B, 0xF0C5, + 0x9E4C, 0xF0C6, + 0x9E4E, 0xF0C7, + 0x9E4F, 0xC5F4, + 0x9E51, 0xF0C8, + 0x9E55, 0xF0C9, + 0x9E57, 0xF0CA, + 0x9E58, 0xF7BD, + 0x9E5A, 0xF0CB, + 0x9E5B, 0xF0CC, + 0x9E5C, 0xF0CD, + 0x9E5E, 0xF0CE, + 0x9E63, 0xF0CF, + 0x9E64, 0xBAD7, + 0x9E66, 0xF0D0, + 0x9E67, 0xF0D1, + 0x9E68, 0xF0D2, + 0x9E69, 0xF0D3, + 0x9E6A, 0xF0D4, + 0x9E6B, 0xF0D5, + 0x9E6C, 0xF0D6, + 0x9E6D, 0xF0D8, + 0x9E70, 0xD3A5, + 0x9E71, 0xF0D7, + 0x9E73, 0xF0D9, + 0x9E7E, 0xF5BA, + 0x9E7F, 0xC2B9, + 0x9E82, 0xF7E4, + 0x9E87, 0xF7E5, + 0x9E88, 0xF7E6, + 0x9E8B, 0xF7E7, + 0x9E92, 0xF7E8, + 0x9E93, 0xC2B4, + 0x9E9D, 0xF7EA, + 0x9E9F, 0xF7EB, + 0x9EA6, 0xC2F3, + 0x9EB4, 0xF4F0, + 0x9EB8, 0xF4EF, + 0x9EBB, 0xC2E9, + 0x9EBD, 0xF7E1, + 0x9EBE, 0xF7E2, + 0x9EC4, 0xBBC6, + 0x9EC9, 0xD9E4, + 0x9ECD, 0xCAF2, + 0x9ECE, 0xC0E8, + 0x9ECF, 0xF0A4, + 0x9ED1, 0xBADA, + 0x9ED4, 0xC7AD, + 0x9ED8, 0xC4AC, + 0x9EDB, 0xF7EC, + 0x9EDC, 0xF7ED, + 0x9EDD, 0xF7EE, + 0x9EDF, 0xF7F0, + 0x9EE0, 0xF7EF, + 0x9EE2, 0xF7F1, + 0x9EE5, 0xF7F4, + 0x9EE7, 0xF7F3, + 0x9EE9, 0xF7F2, + 0x9EEA, 0xF7F5, + 0x9EEF, 0xF7F6, + 0x9EF9, 0xEDE9, + 0x9EFB, 0xEDEA, + 0x9EFC, 0xEDEB, + 0x9EFE, 0xF6BC, + 0x9F0B, 0xF6BD, + 0x9F0D, 0xF6BE, + 0x9F0E, 0xB6A6, + 0x9F10, 0xD8BE, + 0x9F13, 0xB9C4, + 0x9F17, 0xD8BB, + 0x9F19, 0xDCB1, + 0x9F20, 0xCAF3, + 0x9F22, 0xF7F7, + 0x9F2C, 0xF7F8, + 0x9F2F, 0xF7F9, + 0x9F37, 0xF7FB, + 0x9F39, 0xF7FA, + 0x9F3B, 0xB1C7, + 0x9F3D, 0xF7FC, + 0x9F3E, 0xF7FD, + 0x9F44, 0xF7FE, + 0x9F50, 0xC6EB, + 0x9F51, 0xECB4, + 0x9F7F, 0xB3DD, + 0x9F80, 0xF6B3, + 0x9F83, 0xF6B4, + 0x9F84, 0xC1E4, + 0x9F85, 0xF6B5, + 0x9F86, 0xF6B6, + 0x9F87, 0xF6B7, + 0x9F88, 0xF6B8, + 0x9F89, 0xF6B9, + 0x9F8A, 0xF6BA, + 0x9F8B, 0xC8A3, + 0x9F8C, 0xF6BB, + 0x9F99, 0xC1FA, + 0x9F9A, 0xB9A8, + 0x9F9B, 0xEDE8, + 0x9F9F, 0xB9EA, + 0x9FA0, 0xD9DF, + 0xFF01, 0xA3A1, + 0xFF02, 0xA3A2, + 0xFF03, 0xA3A3, + 0xFF04, 0xA1E7, + 0xFF05, 0xA3A5, + 0xFF06, 0xA3A6, + 0xFF07, 0xA3A7, + 0xFF08, 0xA3A8, + 0xFF09, 0xA3A9, + 0xFF0A, 0xA3AA, + 0xFF0B, 0xA3AB, + 0xFF0C, 0xA3AC, + 0xFF0D, 0xA3AD, + 0xFF0E, 0xA3AE, + 0xFF0F, 0xA3AF, + 0xFF10, 0xA3B0, + 0xFF11, 0xA3B1, + 0xFF12, 0xA3B2, + 0xFF13, 0xA3B3, + 0xFF14, 0xA3B4, + 0xFF15, 0xA3B5, + 0xFF16, 0xA3B6, + 0xFF17, 0xA3B7, + 0xFF18, 0xA3B8, + 0xFF19, 0xA3B9, + 0xFF1A, 0xA3BA, + 0xFF1B, 0xA3BB, + 0xFF1C, 0xA3BC, + 0xFF1D, 0xA3BD, + 0xFF1E, 0xA3BE, + 0xFF1F, 0xA3BF, + 0xFF20, 0xA3C0, + 0xFF21, 0xA3C1, + 0xFF22, 0xA3C2, + 0xFF23, 0xA3C3, + 0xFF24, 0xA3C4, + 0xFF25, 0xA3C5, + 0xFF26, 0xA3C6, + 0xFF27, 0xA3C7, + 0xFF28, 0xA3C8, + 0xFF29, 0xA3C9, + 0xFF2A, 0xA3CA, + 0xFF2B, 0xA3CB, + 0xFF2C, 0xA3CC, + 0xFF2D, 0xA3CD, + 0xFF2E, 0xA3CE, + 0xFF2F, 0xA3CF, + 0xFF30, 0xA3D0, + 0xFF31, 0xA3D1, + 0xFF32, 0xA3D2, + 0xFF33, 0xA3D3, + 0xFF34, 0xA3D4, + 0xFF35, 0xA3D5, + 0xFF36, 0xA3D6, + 0xFF37, 0xA3D7, + 0xFF38, 0xA3D8, + 0xFF39, 0xA3D9, + 0xFF3A, 0xA3DA, + 0xFF3B, 0xA3DB, + 0xFF3C, 0xA3DC, + 0xFF3D, 0xA3DD, + 0xFF3E, 0xA3DE, + 0xFF3F, 0xA3DF, + 0xFF40, 0xA3E0, + 0xFF41, 0xA3E1, + 0xFF42, 0xA3E2, + 0xFF43, 0xA3E3, + 0xFF44, 0xA3E4, + 0xFF45, 0xA3E5, + 0xFF46, 0xA3E6, + 0xFF47, 0xA3E7, + 0xFF48, 0xA3E8, + 0xFF49, 0xA3E9, + 0xFF4A, 0xA3EA, + 0xFF4B, 0xA3EB, + 0xFF4C, 0xA3EC, + 0xFF4D, 0xA3ED, + 0xFF4E, 0xA3EE, + 0xFF4F, 0xA3EF, + 0xFF50, 0xA3F0, + 0xFF51, 0xA3F1, + 0xFF52, 0xA3F2, + 0xFF53, 0xA3F3, + 0xFF54, 0xA3F4, + 0xFF55, 0xA3F5, + 0xFF56, 0xA3F6, + 0xFF57, 0xA3F7, + 0xFF58, 0xA3F8, + 0xFF59, 0xA3F9, + 0xFF5A, 0xA3FA, + 0xFF5B, 0xA3FB, + 0xFF5C, 0xA3FC, + 0xFF5D, 0xA3FD, + 0xFF5E, 0xA1AB, + 0xFFE0, 0xA1E9, + 0xFFE1, 0xA1EA, + 0xFFE3, 0xA3FE, + 0xFFE5, 0xA3A4 +}; diff --git a/3rdparty/zint-2.6.1/backend/gif.c b/3rdparty/zint-2.6.1/backend/gif.c new file mode 100644 index 0000000..99aabf9 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gif.c @@ -0,0 +1,402 @@ +/* gif.c - Handles output to gif file */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" +#include +#ifdef _MSC_VER +#include +#include +#include +#endif + +#define SSET "0123456789ABCDEF" + +/* Index of transparent color, -1 for no transparent color + * This might be set into a variable if transparency is activated as an option + */ +#define TRANSPARENT_INDEX (-1) + +/* Used bit depth, may be changed for bigger pallet in future */ +#define DESTINATION_IMAGE_BITS 1 +#include + +typedef struct s_statestruct { + unsigned char * pOut; + unsigned char *pIn; + unsigned int InLen; + unsigned int OutLength; + unsigned int OutPosCur; + unsigned int OutByteCountPos; + unsigned short ClearCode; + unsigned short FreeCode; + char fByteCountByteSet; + unsigned char OutBitsFree; + unsigned short NodeAxon[4096]; + unsigned short NodeNext[4096]; + unsigned char NodePix[4096]; +} statestruct; + +static char BufferNextByte(statestruct *pState) { + (pState->OutPosCur)++; + /* Check if this position is a byte count position + * fg_f_bytecountbyte_set indicates, if byte count position bytes should be + * inserted in general. + * If this is true, and the distance to the last byte count position is 256 + * (e.g. 255 bytes in between), a byte count byte is inserted, and the value + * of the last one is set to 255. + * */ + if (pState->fByteCountByteSet && (pState->OutByteCountPos + 256 == pState->OutPosCur)) { + (pState->pOut)[pState->OutByteCountPos] = 255; + pState->OutByteCountPos = pState->OutPosCur; + (pState->OutPosCur)++; + } + if (pState->OutPosCur >= pState->OutLength) + return 1; + (pState->pOut)[pState->OutPosCur] = 0x00; + return 0; +} + +static char AddCodeToBuffer(statestruct *pState, unsigned short CodeIn, unsigned char CodeBits) { + /* Check, if we may fill up the current byte completely */ + if (CodeBits >= pState->OutBitsFree) { + (pState->pOut)[pState->OutPosCur] |= (unsigned char) + (CodeIn << (8 - pState->OutBitsFree)); + if (BufferNextByte(pState)) + return -1; + CodeIn = (unsigned short) (CodeIn >> pState->OutBitsFree); + CodeBits -= pState->OutBitsFree; + pState->OutBitsFree = 8; + /* Write a full byte if there are at least 8 code bits left */ + if (CodeBits >= pState->OutBitsFree) { + (pState->pOut)[pState->OutPosCur] = (unsigned char) CodeIn; + if (BufferNextByte(pState)) + return -1; + CodeIn = (unsigned short) (CodeIn >> 8); + CodeBits -= 8; + } + } + /* The remaining bits of CodeIn fit in the current byte. */ + if (CodeBits > 0) { + (pState->pOut)[pState->OutPosCur] |= (unsigned char) + (CodeIn << (8 - pState->OutBitsFree)); + pState->OutBitsFree -= CodeBits; + } + return 0; +} + +static void FlushStringTable(statestruct *pState) { + unsigned short Pos; + for (Pos = 0; Pos < pState->ClearCode; Pos++) { + (pState->NodeAxon)[Pos] = 0; + } +} + +unsigned short FindPixelOutlet(statestruct *pState, unsigned short HeadNode, unsigned char Byte) { + unsigned short Outlet; + + Outlet = (pState->NodeAxon)[HeadNode]; + while (Outlet) { + if ((pState->NodePix)[Outlet] == Byte) + return Outlet; + Outlet = (pState->NodeNext)[Outlet]; + } + return 0; +} + +static char NextCode(statestruct *pState, unsigned char * pPixelValueCur, unsigned char CodeBits) { + unsigned short UpNode; + unsigned short DownNode; + /* start with the root node for last pixel chain */ + UpNode = *pPixelValueCur; + if ((pState->InLen) == 0) + return AddCodeToBuffer(pState, UpNode, CodeBits); + + *pPixelValueCur = (*(pState->pIn)) - '0'; + (pState->pIn)++; + (pState->InLen)--; + /* Follow the string table and the data stream to the end of the longest string that has a code */ + while (0 != (DownNode = FindPixelOutlet(pState, UpNode, *pPixelValueCur))) { + UpNode = DownNode; + if ((pState->InLen) == 0) + return AddCodeToBuffer(pState, UpNode, CodeBits); + + *pPixelValueCur = (*(pState->pIn)) - '0'; + (pState->pIn)++; + (pState->InLen)--; + } + /* Submit 'UpNode' which is the code of the longest string */ + if (AddCodeToBuffer(pState, UpNode, CodeBits)) + return -1; + /* ... and extend the string by appending 'PixelValueCur' */ + /* Create a successor node for 'PixelValueCur' whose code is 'freecode' */ + (pState->NodePix)[pState->FreeCode] = *pPixelValueCur; + (pState->NodeAxon)[pState->FreeCode] = (pState->NodeNext)[pState->FreeCode] = 0; + /* ...and link it to the end of the chain emanating from fg_axon[UpNode]. */ + DownNode = (pState->NodeAxon)[UpNode]; + if (!DownNode) { + (pState->NodeAxon)[UpNode] = pState->FreeCode; + } else { + while ((pState->NodeNext)[DownNode]) { + DownNode = (pState->NodeNext)[DownNode]; + } + (pState->NodeNext)[DownNode] = pState->FreeCode; + } + return 1; +} + +int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int InLen) { + unsigned char PixelValueCur; + unsigned char CodeBits; + unsigned short Pos; + statestruct State; + + State.pIn = pIn; + State.InLen = InLen; + State.pOut = pOut; + State.OutLength = OutLength; + // > Get first data byte + if (State.InLen == 0) + return 0; + + PixelValueCur = (unsigned char) ((*(State.pIn)) - '0'); + (State.pIn)++; + (State.InLen)--; + CodeBits = 3; + State.ClearCode = 4; + State.FreeCode = 6; + State.OutBitsFree = 8; + State.OutPosCur = -1; + State.fByteCountByteSet = 0; + + if (BufferNextByte(&State)) + return 0; + + for (Pos = 0; Pos < State.ClearCode; Pos++) + State.NodePix[Pos] = (unsigned char) Pos; + + FlushStringTable(&State); + + /* Write what the GIF specification calls the "code size". */ + (State.pOut)[State.OutPosCur] = 2; + /* Reserve first bytecount byte */ + if (BufferNextByte(&State)) + return 0; + State.OutByteCountPos = State.OutPosCur; + if (BufferNextByte(&State)) + return 0; + State.fByteCountByteSet = 1; + /* Submit one 'ClearCode' as the first code */ + if (AddCodeToBuffer(&State, State.ClearCode, CodeBits)) + return 0; + + for (;;) { + char Res; + /* generate and save the next code, which may consist of multiple input pixels. */ + Res = NextCode(&State, &PixelValueCur, CodeBits); + if (Res < 0) + return 0; + //* Check for end of data stream */ + if (!Res) { + /* submit 'eoi' as the last item of the code stream */ + if (AddCodeToBuffer(&State, (unsigned short) (State.ClearCode + 1), CodeBits)) + return 0; + State.fByteCountByteSet = 0; + if (State.OutBitsFree < 8) { + if (BufferNextByte(&State)) + return 0; + } + // > Update last bytecount byte; + if (State.OutByteCountPos < State.OutPosCur) { + (State.pOut)[State.OutByteCountPos] = (unsigned char) (State.OutPosCur - State.OutByteCountPos - 1); + } + State.OutPosCur++; + return State.OutPosCur; + } + /* Check for currently last code */ + if (State.FreeCode == (1U << CodeBits)) + CodeBits++; + State.FreeCode++; + /* Check for full stringtable */ + if (State.FreeCode == 0xfff) { + FlushStringTable(&State); + if (AddCodeToBuffer(&State, State.ClearCode, CodeBits)) + return 0; + + CodeBits = (unsigned char) (1 + 2); + State.FreeCode = (unsigned short) (State.ClearCode + 2); + } + } +} + +int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { + char outbuf[10]; + FILE *gif_file; + unsigned short usTemp; + int byte_out; +#ifdef _MSC_VER + char * lzwoutbuf; +#endif + +#ifndef _MSC_VER + char lzwoutbuf[symbol->bitmap_height * symbol->bitmap_width]; +#else + lzwoutbuf = (char *) _alloca((symbol->bitmap_height * symbol->bitmap_width) * sizeof (char)); +#endif /* _MSC_VER */ + + /* Open output file in binary mode */ + if ((symbol->output_options & BARCODE_STDOUT) != 0) { +#ifdef _MSC_VER + if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { + strcpy(symbol->errtxt, "610: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } +#endif + gif_file = stdout; + } else { + if (!(gif_file = fopen(symbol->outfile, "wb"))) { + strcpy(symbol->errtxt, "611: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + } + /*ImageWidth = 2; + ImageHeight = 2; + rotated_bitmap[0] = 1; + rotated_bitmap[1] = 1; + rotated_bitmap[2] = 0; + rotated_bitmap[3] = 0; + */ + + /* GIF signature (6) */ + memcpy(outbuf, "GIF87a", 6); + if (TRANSPARENT_INDEX != -1) + outbuf[4] = '9'; + fwrite(outbuf, 6, 1, gif_file); + /* Screen Descriptor (7) */ + /* Screen Width */ + usTemp = (unsigned short) symbol->bitmap_width; + outbuf[0] = (unsigned char) (0xff & usTemp); + outbuf[1] = (unsigned char) ((0xff00 & usTemp) / 0x100); + /* Screen Height */ + usTemp = (unsigned short) symbol->bitmap_height; + outbuf[2] = (unsigned char) (0xff & usTemp); + outbuf[3] = (unsigned char) ((0xff00 & usTemp) / 0x100); + /* write ImageBits-1 to the three least significant bits of byte 5 of + * the Screen Descriptor + */ + outbuf[4] = (unsigned char) (0xf0 | (0x7 & (DESTINATION_IMAGE_BITS - 1))); + /* Background color = colortable index 0 */ + outbuf[5] = 0x00; + /* Byte 7 must be 0x00 */ + outbuf[6] = 0x00; + fwrite(outbuf, 7, 1, gif_file); + /* Global Color Table (6) */ + /* RGB 0 color */ + outbuf[0] = (unsigned char) (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + outbuf[1] = (unsigned char) (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + outbuf[2] = (unsigned char) (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + /* RGB 1 color */ + outbuf[3] = (unsigned char) (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + outbuf[4] = (unsigned char) (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + outbuf[5] = (unsigned char) (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + fwrite(outbuf, 6, 1, gif_file); + + /* Graphic control extension (8) */ + /* A graphic control extension block is used for overlay gifs. + * This is necessary to define a transparent color. + */ + if (TRANSPARENT_INDEX != -1) { + /* Extension Introducer = '!' */ + outbuf[0] = '\x21'; + /* Graphic Control Label */ + outbuf[1] = '\xf9'; + /* Block Size */ + outbuf[2] = 4; + /* Packet fields: + * 3 Reserved + * 3 Disposal Method: 0 No Action, 1 No Dispose, 2: Background, 3: Prev. + * 1 User Input Flag: 0: no user input, 1: user input + * 1 Transparent Color Flag: 0: No Transparency, 1: Transparency index + */ + outbuf[3] = 1; + /* Delay Time */ + outbuf[4] = 0; + outbuf[5] = 0; + /* Transparent Color Index */ + outbuf[6] = (unsigned char) TRANSPARENT_INDEX; + /* Block Terminator */ + outbuf[7] = 0; + fwrite(outbuf, 8, 1, gif_file); + } + /* Image Descriptor */ + /* Image separator character = ',' */ + outbuf[0] = 0x2c; + /* "Image Left" */ + outbuf[1] = 0x00; + outbuf[2] = 0x00; + /* "Image Top" */ + outbuf[3] = 0x00; + outbuf[4] = 0x00; + /* Image Width (low byte first) */ + outbuf[5] = (unsigned char) (0xff & symbol->bitmap_width); + outbuf[6] = (unsigned char) ((0xff00 & symbol->bitmap_width) / 0x100); + /* Image Height */ + outbuf[7] = (unsigned char) (0xff & symbol->bitmap_height); + outbuf[8] = (unsigned char) ((0xff00 & symbol->bitmap_height) / 0x100); + + /* Byte 10 contains the interlaced flag and + * information on the local color table. + * There is no local color table if its most significant bit is reset. + */ + outbuf[9] = (unsigned char) (0 | (0x7 & (DESTINATION_IMAGE_BITS - 1))); + fwrite(outbuf, 10, 1, gif_file); + + /* call lzw encoding */ + byte_out = gif_lzw( + (unsigned char *) lzwoutbuf, + symbol->bitmap_height * symbol->bitmap_width, + (unsigned char *) pixelbuf, + symbol->bitmap_height * symbol->bitmap_width); + if (byte_out <= 0) { + fclose(gif_file); + return ZINT_ERROR_MEMORY; + } + fwrite(lzwoutbuf, byte_out, 1, gif_file); + + /* GIF terminator */ + fputc('\x3b', gif_file); + fclose(gif_file); + + return 0; +} \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/gridmtx.c b/3rdparty/zint-2.6.1/backend/gridmtx.c new file mode 100644 index 0000000..b77a05b --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gridmtx.c @@ -0,0 +1,1208 @@ +/* gridmtx.c - Grid Matrix + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* This file impliments Grid Matrix as specified in + AIM Global Document Number AIMD014 Rev. 1.63 Revised 9 Dec 2008 */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "reedsol.h" +#include "gridmtx.h" +#include "gb2312.h" + +int number_lat(int gbdata[], const size_t length, const size_t position) { + /* Attempt to calculate the 'cost' of using numeric mode from a given position in number of bits */ + /* Also ensures that numeric mode is not selected when it cannot be used: for example in + a string which has "2.2.0" (cannot have more than one non-numeric character for each + block of three numeric characters) */ + size_t sp; + int numb = 0, nonum = 0, done; + int tally = 0; + + sp = position; + + do { + done = 0; + + if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + numb++; + done = 1; + } + switch (gbdata[sp]) { + case ' ': + case '+': + case '-': + case '.': + case ',': + nonum++; + done = 1; + } + if ((sp + 1) < length) { + if ((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + nonum++; + done = 1; + sp++; + } + } + + if (done == 0) { + tally += 80; + } else { + if (numb == 3) { + if (nonum == 0) { + tally += 10; + } + if (nonum == 1) { + tally += 20; + } + if (nonum > 1) { + tally += 80; + } + numb = 0; + nonum = 0; + } + } + + sp++; + } while ((sp < length) && (sp <= (position + 8))); + + if (numb == 0) { + tally += 80; + } + + if (numb > 1) { + if (nonum == 0) { + tally += 10; + } + if (nonum == 1) { + tally += 20; + } + if (nonum > 1) { + tally += 80; + } + } + + return tally; +} + +static int seek_forward(int gbdata[], const size_t length, const size_t position, int current_mode) { + /* In complete contrast to the method recommended in Annex D of the ANSI standard this + code uses a look-ahead test in the same manner as Data Matrix. This decision was made + because the "official" algorithm does not provide clear methods for dealing with all + possible combinations of input data */ + + int number_count, byte_count, mixed_count, upper_count, lower_count, chinese_count; + int best_mode, done; + size_t sp; + int best_count, last = -1; + int debug = 0; + + if (gbdata[position] > 0xff) { + return GM_CHINESE; + } + + switch (current_mode) { + case GM_CHINESE: + number_count = 13; + byte_count = 13; + mixed_count = 13; + upper_count = 13; + lower_count = 13; + chinese_count = 0; + break; + case GM_NUMBER: + number_count = 0; + byte_count = 10; + mixed_count = 10; + upper_count = 10; + lower_count = 10; + chinese_count = 10; + break; + case GM_LOWER: + number_count = 5; + byte_count = 7; + mixed_count = 7; + upper_count = 5; + lower_count = 0; + chinese_count = 5; + break; + case GM_UPPER: + number_count = 5; + byte_count = 7; + mixed_count = 7; + upper_count = 0; + lower_count = 5; + chinese_count = 5; + break; + case GM_MIXED: + number_count = 10; + byte_count = 10; + mixed_count = 0; + upper_count = 10; + lower_count = 10; + chinese_count = 10; + break; + case GM_BYTE: + number_count = 4; + byte_count = 0; + mixed_count = 4; + upper_count = 4; + lower_count = 4; + chinese_count = 4; + break; + default: /* Start of symbol */ + number_count = 4; + byte_count = 4; + mixed_count = 4; + upper_count = 4; + lower_count = 4; + chinese_count = 4; + } + + for (sp = position; (sp < length) && (sp <= (position + 8)); sp++) { + + done = 0; + + if (gbdata[sp] >= 0xff) { + byte_count += 17; + mixed_count += 23; + upper_count += 18; + lower_count += 18; + chinese_count += 13; + done = 1; + } + + if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { + byte_count += 8; + mixed_count += 6; + upper_count += 10; + lower_count += 5; + chinese_count += 13; + done = 1; + } + + if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { + byte_count += 8; + mixed_count += 6; + upper_count += 5; + lower_count += 10; + chinese_count += 13; + done = 1; + } + + if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + byte_count += 8; + mixed_count += 6; + upper_count += 8; + lower_count += 8; + chinese_count += 13; + done = 1; + } + + if (gbdata[sp] == ' ') { + byte_count += 8; + mixed_count += 6; + upper_count += 5; + lower_count += 5; + chinese_count += 13; + done = 1; + } + + if (done == 0) { + /* Control character */ + byte_count += 8; + mixed_count += 16; + upper_count += 13; + lower_count += 13; + chinese_count += 13; + } + + if (gbdata[sp] >= 0x7f) { + mixed_count += 20; + upper_count += 20; + lower_count += 20; + } + } + + /* Adjust for */ + for (sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { + if ((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + chinese_count -= 13; + } + } + + /* Adjust for double digits */ + for (sp = position; (sp < (length - 1)) && (sp <= (position + 7)); sp++) { + if (sp != last) { + if (((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { + chinese_count -= 13; + last = (int)(sp + 1); + } + } + } + + /* Numeric mode is more complex */ + number_count += number_lat(gbdata, length, position); + + if (debug) { + printf("C %d / B %d / M %d / U %d / L %d / N %d\n", chinese_count, byte_count, mixed_count, upper_count, lower_count, number_count); + } + + best_count = chinese_count; + best_mode = GM_CHINESE; + + if (byte_count <= best_count) { + best_count = byte_count; + best_mode = GM_BYTE; + } + + if (mixed_count <= best_count) { + best_count = mixed_count; + best_mode = GM_MIXED; + } + + if (upper_count <= best_count) { + best_count = upper_count; + best_mode = GM_UPPER; + } + + if (lower_count <= best_count) { + best_count = lower_count; + best_mode = GM_LOWER; + } + + if (number_count <= best_count) { + best_count = number_count; + best_mode = GM_NUMBER; + } + + return best_mode; +} + +/* Add the length indicator for byte encoded blocks */ +static void add_byte_count(char binary[], const size_t byte_count_posn, const int byte_count) { + int p; + + for (p = 0; p < 8; p++) { + if (byte_count & (0x100 >> p)) { + binary[byte_count_posn + p] = '0'; + } else { + binary[byte_count_posn + p] = '1'; + } + } +} + +/* Add a control character to the data stream */ +void add_shift_char(char binary[], int shifty) { + int i, debug = 0; + int glyph = 0; + + for (i = 0; i < 64; i++) { + if (shift_set[i] == shifty) { + glyph = i; + } + } + + if (debug) { + printf("SHIFT [%d] ", glyph); + } + + bin_append(glyph, 6, binary); +} + +static int gm_encode(int gbdata[], const size_t length, char binary[],const int reader,const int eci, int debug) { + /* Create a binary stream representation of the input data. + 7 sets are defined - Chinese characters, Numerals, Lower case letters, Upper case letters, + Mixed numerals and latters, Control characters and 8-bit binary data */ + int sp, current_mode, next_mode, last_mode, glyph = 0; + int c1, c2, done; + int p = 0, ppos; + int numbuf[3], punt = 0; + size_t number_pad_posn, byte_count_posn = 0; + int byte_count = 0; + int shift; + + strcpy(binary, ""); + + sp = 0; + current_mode = 0; + last_mode = 0; + number_pad_posn = 0; + + if (reader) { + bin_append(10, 4, binary); /* FNC3 - Reader Initialisation */ + } + + if (eci != 3) { + /* ECI assignment according to Table 8 */ + bin_append(12, 4, binary); /* ECI */ + if (eci <= 1023) { + bin_append(eci, 11, binary); + } + if ((eci >= 1024) && (eci <= 32767)) { + strcat(binary, "10"); + bin_append(eci, 15, binary); + } + if (eci >= 32768) { + strcat(binary, "11"); + bin_append(eci, 20, binary); + } + } + + do { + next_mode = seek_forward(gbdata, length, sp, current_mode); + + if (next_mode != current_mode) { + switch (current_mode) { + case 0: + switch (next_mode) { + case GM_CHINESE: bin_append(1, 4, binary); + break; + case GM_NUMBER: bin_append(2, 4, binary); + break; + case GM_LOWER: bin_append(3, 4, binary); + break; + case GM_UPPER: bin_append(4, 4, binary); + break; + case GM_MIXED: bin_append(5, 4, binary); + break; + case GM_BYTE: bin_append(6, 4, binary); + break; + } + break; + case GM_CHINESE: + switch (next_mode) { + case GM_NUMBER: bin_append(8161, 13, binary); + break; + case GM_LOWER: bin_append(8162, 13, binary); + break; + case GM_UPPER: bin_append(8163, 13, binary); + break; + case GM_MIXED: bin_append(8164, 13, binary); + break; + case GM_BYTE: bin_append(8165, 13, binary); + break; + } + break; + case GM_NUMBER: + /* add numeric block padding value */ + switch (p) { + case 1: binary[number_pad_posn] = '1'; + binary[number_pad_posn + 1] = '0'; + break; // 2 pad digits + case 2: binary[number_pad_posn] = '0'; + binary[number_pad_posn + 1] = '1'; + break; // 1 pad digits + case 3: binary[number_pad_posn] = '0'; + binary[number_pad_posn + 1] = '0'; + break; // 0 pad digits + } + switch (next_mode) { + case GM_CHINESE: bin_append(1019, 10, binary); + break; + case GM_LOWER: bin_append(1020, 10, binary); + break; + case GM_UPPER: bin_append(1021, 10, binary); + break; + case GM_MIXED: bin_append(1022, 10, binary); + break; + case GM_BYTE: bin_append(1023, 10, binary); + break; + } + break; + case GM_LOWER: + case GM_UPPER: + switch (next_mode) { + case GM_CHINESE: bin_append(28, 5, binary); + break; + case GM_NUMBER: bin_append(29, 5, binary); + break; + case GM_LOWER: + case GM_UPPER: bin_append(30, 5, binary); + break; + case GM_MIXED: bin_append(124, 7, binary); + break; + case GM_BYTE: bin_append(126, 7, binary); + break; + } + break; + case GM_MIXED: + switch (next_mode) { + case GM_CHINESE: bin_append(1009, 10, binary); + break; + case GM_NUMBER: bin_append(1010, 10, binary); + break; + case GM_LOWER: bin_append(1011, 10, binary); + break; + case GM_UPPER: bin_append(1012, 10, binary); + break; + case GM_BYTE: bin_append(1015, 10, binary); + break; + } + break; + case GM_BYTE: + /* add byte block length indicator */ + add_byte_count(binary, byte_count_posn, byte_count); + byte_count = 0; + switch (next_mode) { + case GM_CHINESE: bin_append(1, 4, binary); + break; + case GM_NUMBER: bin_append(2, 4, binary); + break; + case GM_LOWER: bin_append(3, 4, binary); + break; + case GM_UPPER: bin_append(4, 4, binary); + break; + case GM_MIXED: bin_append(5, 4, binary); + break; + } + break; + } + if (debug) { + switch (next_mode) { + case GM_CHINESE: printf("CHIN "); + break; + case GM_NUMBER: printf("NUMB "); + break; + case GM_LOWER: printf("LOWR "); + break; + case GM_UPPER: printf("UPPR "); + break; + case GM_MIXED: printf("MIXD "); + break; + case GM_BYTE: printf("BYTE "); + break; + } + } + } + last_mode = current_mode; + current_mode = next_mode; + + switch (current_mode) { + case GM_CHINESE: + done = 0; + if (gbdata[sp] > 0xff) { + /* GB2312 character */ + c1 = (gbdata[sp] & 0xff00) >> 8; + c2 = gbdata[sp] & 0xff; + + if ((c1 >= 0xa0) && (c1 <= 0xa9)) { + glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0); + } + if ((c1 >= 0xb0) && (c1 <= 0xf7)) { + glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2 - 0xa0); + } + done = 1; + } + if (!(done)) { + if (sp != (length - 1)) { + if ((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + /* End of Line */ + glyph = 7776; + sp++; + } + done = 1; + } + } + if (!(done)) { + if (sp != (length - 1)) { + if (((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) && + ((gbdata[sp + 1] >= '0') && (gbdata[sp + 1] <= '9'))) { + /* Two digits */ + glyph = 8033 + (10 * (gbdata[sp] - '0')) + (gbdata[sp + 1] - '0'); + sp++; + } + } + } + if (!(done)) { + /* Byte value */ + glyph = 7777 + gbdata[sp]; + } + + if (debug) { + printf("[%d] ", glyph); + } + + bin_append(glyph, 13, binary); + sp++; + break; + + case GM_NUMBER: + if (last_mode != current_mode) { + /* Reserve a space for numeric digit padding value (2 bits) */ + number_pad_posn = strlen(binary); + strcat(binary, "XX"); + } + p = 0; + ppos = -1; + + /* Numeric compression can also include certain combinations of + non-numeric character */ + + numbuf[0] = '0'; + numbuf[1] = '0'; + numbuf[2] = '0'; + do { + if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + numbuf[p] = gbdata[sp]; + sp++; + p++; + } + switch (gbdata[sp]) { + case ' ': + case '+': + case '-': + case '.': + case ',': + punt = gbdata[sp]; + sp++; + ppos = p; + break; + } + if (sp < (length - 1)) { + if ((gbdata[sp] == 0x13) && (gbdata[sp + 1] == 0x10)) { + /* */ + punt = gbdata[sp]; + sp += 2; + ppos = p; + } + } + } while ((p < 3) && (sp < length)); + + if (ppos != -1) { + switch (punt) { + case ' ': glyph = 0; + break; + case '+': glyph = 3; + break; + case '-': glyph = 6; + break; + case '.': glyph = 9; + break; + case ',': glyph = 12; + break; + case 0x13: glyph = 15; + break; + } + glyph += ppos; + glyph += 1000; + + if (debug) { + printf("[%d] ", glyph); + } + + bin_append(glyph, 10, binary); + } + + glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0'); + if (debug) { + printf("[%d] ", glyph); + } + + bin_append(glyph, 10, binary); + break; + + case GM_BYTE: + if (last_mode != current_mode) { + /* Reserve space for byte block length indicator (9 bits) */ + byte_count_posn = strlen(binary); + strcat(binary, "LLLLLLLLL"); + } + if (byte_count == 512) { + /* Maximum byte block size is 512 bytes. If longer is needed then start a new block */ + add_byte_count(binary, byte_count_posn, byte_count); + bin_append(7, 4, binary); + byte_count_posn = strlen(binary); + strcat(binary, "LLLLLLLLL"); + byte_count = 0; + } + + glyph = gbdata[sp]; + if (debug) { + printf("[%d] ", glyph); + } + bin_append(glyph, 8, binary); + sp++; + byte_count++; + break; + + case GM_MIXED: + shift = 1; + if ((gbdata[sp] >= '0') && (gbdata[sp] <= '9')) { + shift = 0; + } + if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { + shift = 0; + } + if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { + shift = 0; + } + if (gbdata[sp] == ' ') { + shift = 0; + } + + if (shift == 0) { + /* Mixed Mode character */ + glyph = posn(EUROPIUM, gbdata[sp]); + if (debug) { + printf("[%d] ", glyph); + } + + bin_append(glyph, 6, binary); + } else { + /* Shift Mode character */ + bin_append(1014, 10, binary); /* shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + + case GM_UPPER: + shift = 1; + if ((gbdata[sp] >= 'A') && (gbdata[sp] <= 'Z')) { + shift = 0; + } + if (gbdata[sp] == ' ') { + shift = 0; + } + + if (shift == 0) { + /* Upper Case character */ + glyph = posn("ABCDEFGHIJKLMNOPQRSTUVWXYZ ", gbdata[sp]); + if (debug) { + printf("[%d] ", glyph); + } + + bin_append(glyph, 5, binary); + } else { + /* Shift Mode character */ + bin_append(125, 7, binary); /* shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + + case GM_LOWER: + shift = 1; + if ((gbdata[sp] >= 'a') && (gbdata[sp] <= 'z')) { + shift = 0; + } + if (gbdata[sp] == ' ') { + shift = 0; + } + + if (shift == 0) { + /* Lower Case character */ + glyph = posn("abcdefghijklmnopqrstuvwxyz ", gbdata[sp]); + if (debug) { + printf("[%d] ", glyph); + } + + bin_append(glyph, 5, binary); + } else { + /* Shift Mode character */ + bin_append(125, 7, binary); /* shift indicator */ + add_shift_char(binary, gbdata[sp]); + } + + sp++; + break; + } + if (strlen(binary) > 9191) { + return ZINT_ERROR_TOO_LONG; + } + + } while (sp < length); + + if (current_mode == GM_NUMBER) { + /* add numeric block padding value */ + switch (p) { + case 1: binary[number_pad_posn] = '1'; + binary[number_pad_posn + 1] = '0'; + break; // 2 pad digits + case 2: binary[number_pad_posn] = '0'; + binary[number_pad_posn + 1] = '1'; + break; // 1 pad digit + case 3: binary[number_pad_posn] = '0'; + binary[number_pad_posn + 1] = '0'; + break; // 0 pad digits + } + } + + if (current_mode == GM_BYTE) { + /* Add byte block length indicator */ + add_byte_count(binary, byte_count_posn, byte_count); + } + + /* Add "end of data" character */ + switch (current_mode) { + case GM_CHINESE: bin_append(8160, 13, binary); + break; + case GM_NUMBER: bin_append(1018, 10, binary); + break; + case GM_LOWER: + case GM_UPPER: bin_append(27, 5, binary); + break; + case GM_MIXED: bin_append(1008, 10, binary); + break; + case GM_BYTE: bin_append(0, 4, binary); + break; + } + + /* Add padding bits if required */ + p = 7 - (strlen(binary) % 7); + if (p == 7) { + p = 0; + } + bin_append(0, p, binary); + + if (strlen(binary) > 9191) { + return ZINT_ERROR_TOO_LONG; + } + return 0; +} + +static void gm_add_ecc(const char binary[], const size_t data_posn, const int layers, const int ecc_level, int word[]) { + int data_cw, i, j, wp, p; + int n1, b1, n2, b2, e1, b3, e2; + int block_size, data_size, ecc_size; + int data[1320], block[130]; + unsigned char data_block[115], ecc_block[70]; + + data_cw = gm_data_codewords[((layers - 1) * 5) + (ecc_level - 1)]; + + for (i = 0; i < 1320; i++) { + data[i] = 0; + } + + /* Convert from binary sream to 7-bit codewords */ + for (i = 0; i < data_posn; i++) { + for (p = 0; p < 7; p++) { + if (binary[i * 7 + p] == '1') { + data[i] += (0x40 >> p); + } + } + } + + /* Add padding codewords */ + data[data_posn] = 0x00; + for (i = (int) (data_posn + 1); i < data_cw; i++) { + if (i & 1) { + data[i] = 0x7e; + } else { + data[i] = 0x00; + } + } + + /* Get block sizes */ + n1 = gm_n1[(layers - 1)]; + b1 = gm_b1[(layers - 1)]; + n2 = n1 - 1; + b2 = gm_b2[(layers - 1)]; + e1 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4)]; + b3 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 1]; + e2 = gm_ebeb[((layers - 1) * 20) + ((ecc_level - 1) * 4) + 2]; + + /* Split the data into blocks */ + wp = 0; + for (i = 0; i < (b1 + b2); i++) { + if (i < b1) { + block_size = n1; + } else { + block_size = n2; + } + if (i < b3) { + ecc_size = e1; + } else { + ecc_size = e2; + } + data_size = block_size - ecc_size; + + /* printf("block %d/%d: data %d / ecc %d\n", i + 1, (b1 + b2), data_size, ecc_size);*/ + + for (j = 0; j < data_size; j++) { + data_block[j] = data[wp]; + wp++; + } + + /* Calculate ECC data for this block */ + rs_init_gf(0x89); + rs_init_code(ecc_size, 1); + rs_encode(data_size, data_block, ecc_block); + rs_free(); + + /* Correct error correction data but in reverse order */ + for (j = 0; j < data_size; j++) { + block[j] = data_block[j]; + } + for (j = 0; j < ecc_size; j++) { + block[(j + data_size)] = ecc_block[ecc_size - j - 1]; + } + + for (j = 0; j < n2; j++) { + word[((b1 + b2) * j) + i] = block[j]; + } + if (block_size == n1) { + word[((b1 + b2) * (n1 - 1)) + i] = block[(n1 - 1)]; + } + } +} + +void place_macromodule(char grid[], int x, int y, int word1, int word2, int size) { + int i, j; + + i = (x * 6) + 1; + j = (y * 6) + 1; + + if (word2 & 0x40) { + grid[(j * size) + i + 2] = '1'; + } + if (word2 & 0x20) { + grid[(j * size) + i + 3] = '1'; + } + if (word2 & 0x10) { + grid[((j + 1) * size) + i] = '1'; + } + if (word2 & 0x08) { + grid[((j + 1) * size) + i + 1] = '1'; + } + if (word2 & 0x04) { + grid[((j + 1) * size) + i + 2] = '1'; + } + if (word2 & 0x02) { + grid[((j + 1) * size) + i + 3] = '1'; + } + if (word2 & 0x01) { + grid[((j + 2) * size) + i] = '1'; + } + if (word1 & 0x40) { + grid[((j + 2) * size) + i + 1] = '1'; + } + if (word1 & 0x20) { + grid[((j + 2) * size) + i + 2] = '1'; + } + if (word1 & 0x10) { + grid[((j + 2) * size) + i + 3] = '1'; + } + if (word1 & 0x08) { + grid[((j + 3) * size) + i] = '1'; + } + if (word1 & 0x04) { + grid[((j + 3) * size) + i + 1] = '1'; + } + if (word1 & 0x02) { + grid[((j + 3) * size) + i + 2] = '1'; + } + if (word1 & 0x01) { + grid[((j + 3) * size) + i + 3] = '1'; + } +} + +void place_data_in_grid(int word[], char grid[], int modules, int size) { + int x, y, macromodule, offset; + + offset = 13 - ((modules - 1) / 2); + for (y = 0; y < modules; y++) { + for (x = 0; x < modules; x++) { + macromodule = gm_macro_matrix[((y + offset) * 27) + (x + offset)]; + place_macromodule(grid, x, y, word[macromodule * 2], word[(macromodule * 2) + 1], size); + } + } +} + +/* Place the layer ID into each macromodule */ +void place_layer_id(char* grid, int size, int layers, int modules, int ecc_level) { + int i, j, layer, start, stop; + +#ifndef _MSC_VER + int layerid[layers + 1]; + int id[modules * modules]; +#else + int* layerid = (int *) _alloca((layers + 1) * sizeof (int)); + int* id = (int *) _alloca((modules * modules) * sizeof (int)); +#endif + + /* Calculate Layer IDs */ + for (i = 0; i <= layers; i++) { + if (ecc_level == 1) { + layerid[i] = 3 - (i % 4); + } else { + layerid[i] = (i + 5 - ecc_level) % 4; + } + } + + for (i = 0; i < modules; i++) { + for (j = 0; j < modules; j++) { + id[(i * modules) + j] = 0; + } + } + + /* Calculate which value goes in each macromodule */ + start = modules / 2; + stop = modules / 2; + for (layer = 0; layer <= layers; layer++) { + for (i = start; i <= stop; i++) { + id[(start * modules) + i] = layerid[layer]; + id[(i * modules) + start] = layerid[layer]; + id[((modules - start - 1) * modules) + i] = layerid[layer]; + id[(i * modules) + (modules - start - 1)] = layerid[layer]; + } + start--; + stop++; + } + + /* Place the data in the grid */ + for (i = 0; i < modules; i++) { + for (j = 0; j < modules; j++) { + if (id[(i * modules) + j] & 0x02) { + grid[(((i * 6) + 1) * size) + (j * 6) + 1] = '1'; + } + if (id[(i * modules) + j] & 0x01) { + grid[(((i * 6) + 1) * size) + (j * 6) + 2] = '1'; + } + } + } +} + +int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], size_t length) { + int size, modules, dark, error_number; + int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level; + int x, y, i, j, glyph; + char binary[9300]; + int data_cw, input_latch = 0; + int word[1460], data_max, reader = 0; + +#ifndef _MSC_VER + int utfdata[length + 1]; + int gbdata[length + 1]; +#else + char* grid; + int* utfdata = (int *) _alloca((length + 1) * sizeof (int)); + int* gbdata = (int *) _alloca((length + 1) * sizeof (int)); +#endif + + for (i = 0; i < 1460; i++) { + word[i] = 0; + } + + if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) { + for (i = 0; i < length; i++) { + gbdata[i] = (int) source[i]; + } + } else { + /* Convert Unicode input to GB-2312 */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if (error_number != 0) { + return error_number; + } + + for (i = 0; i < length; i++) { + if (utfdata[i] <= 0xff) { + gbdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if (gb2312_lookup[j * 2] == utfdata[i]) { + glyph = gb2312_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 7445) && (glyph == 0)); + if (glyph == 0) { + strcpy(symbol->errtxt, "530: Invalid character in input data"); + return ZINT_ERROR_INVALID_DATA; + } + gbdata[i] = glyph; + } + } + } + + if (symbol->output_options & READER_INIT) reader = 1; + + if (symbol->eci > 811799) { + strcpy(symbol->errtxt, "533: Invalid ECI"); + return ZINT_ERROR_INVALID_OPTION; + } + + error_number = gm_encode(gbdata, length, binary, reader, symbol->eci, symbol->debug); + if (error_number != 0) { + strcpy(symbol->errtxt, "531: Input data too long"); + return error_number; + } + + /* Determine the size of the symbol */ + data_cw = (int)strlen(binary) / 7; + + auto_layers = 13; + for (i = 12; i > 0; i--) { + if (gm_recommend_cw[(i - 1)] >= data_cw) { + auto_layers = i; + } + } + min_layers = 13; + for (i = 12; i > 0; i--) { + if (gm_max_cw[(i - 1)] >= data_cw) { + min_layers = i; + } + } + layers = auto_layers; + auto_ecc_level = 3; + if (layers == 1) { + auto_ecc_level = 5; + } + if ((layers == 2) || (layers == 3)) { + auto_ecc_level = 4; + } + min_ecc_level = 1; + if (layers == 1) { + min_ecc_level = 4; + } + if ((layers == 2) || (layers == 3)) { + min_ecc_level = 2; + } + ecc_level = auto_ecc_level; + + if ((symbol->option_2 >= 1) && (symbol->option_2 <= 13)) { + input_latch = 1; + if (symbol->option_2 > min_layers) { + layers = symbol->option_2; + } else { + strcpy(symbol->errtxt, "534: Input data too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + } + + if (input_latch == 1) { + auto_ecc_level = 3; + if (layers == 1) { + auto_ecc_level = 5; + } + if ((layers == 2) || (layers == 3)) { + auto_ecc_level = 4; + } + ecc_level = auto_ecc_level; + if (data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { + layers++; + } + } + + if (input_latch == 0) { + if ((symbol->option_1 >= 1) && (symbol->option_1 <= 5)) { + if (symbol->option_1 > min_ecc_level) { + ecc_level = symbol->option_1; + } else { + ecc_level = min_ecc_level; + } + } + if (data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { + do { + layers++; + } while ((data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) && (layers <= 13)); + } + } + + data_max = 1313; + switch (ecc_level) { + case 2: data_max = 1167; + break; + case 3: data_max = 1021; + break; + case 4: data_max = 875; + break; + case 5: data_max = 729; + break; + } + + if (data_cw > data_max) { + strcpy(symbol->errtxt, "532: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + gm_add_ecc(binary, data_cw, layers, ecc_level, word); + size = 6 + (layers * 12); + modules = 1 + (layers * 2); + +#ifndef _MSC_VER + char grid[size * size]; +#else + grid = (char *) _alloca((size * size) * sizeof (char)); +#endif + + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + grid[(y * size) + x] = '0'; + } + } + + place_data_in_grid(word, grid, modules, size); + place_layer_id(grid, size, layers, modules, ecc_level); + + /* Add macromodule frames */ + for (x = 0; x < modules; x++) { + dark = 1 - (x & 1); + for (y = 0; y < modules; y++) { + if (dark == 1) { + for (i = 0; i < 5; i++) { + grid[((y * 6) * size) + (x * 6) + i] = '1'; + grid[(((y * 6) + 5) * size) + (x * 6) + i] = '1'; + grid[(((y * 6) + i) * size) + (x * 6)] = '1'; + grid[(((y * 6) + i) * size) + (x * 6) + 5] = '1'; + } + grid[(((y * 6) + 5) * size) + (x * 6) + 5] = '1'; + dark = 0; + } else { + dark = 1; + } + } + } + + /* Copy values to symbol */ + symbol->width = size; + symbol->rows = size; + + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (grid[(y * size) + x] == '1') { + set_module(symbol, y, x); + } + } + symbol->row_height[x] = 1; + } + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/gridmtx.h b/3rdparty/zint-2.6.1/backend/gridmtx.h new file mode 100644 index 0000000..5153488 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gridmtx.h @@ -0,0 +1,184 @@ +/* gridmtx.h - definitions for Grid Matrix + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define GM_NUMBER 1 +#define GM_LOWER 2 +#define GM_UPPER 3 +#define GM_MIXED 4 +#define GM_CONTROL 5 +#define GM_BYTE 6 +#define GM_CHINESE 7 + +#define EUROPIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " + +static const char shift_set[] = { + /* From Table 7 - Encoding of control characters */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* NULL -> SI */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* DLE -> US */ + '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', + ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' +}; + +static const unsigned short int gm_recommend_cw[] = { + 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021 +}; + +static const unsigned short int gm_max_cw[] = { + 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313 +}; + +static const unsigned short int gm_data_codewords[] = { + 0, 15, 13, 11, 9, + 45, 40, 35, 30, 25, + 89, 79, 69, 59, 49, + 146, 130, 114, 98, 81, + 218, 194, 170, 146, 121, + 305, 271, 237, 203, 169, + 405, 360, 315, 270, 225, + 521, 463, 405, 347, 289, + 650, 578, 506, 434, 361, + 794, 706, 618, 530, 441, + 953, 847, 741, 635, 529, + 1125, 1000, 875, 750, 625, + 1313, 1167, 1021, 875, 729 +}; + +static const char gm_n1[] = { + 18, 50, 98, 81, 121, 113, 113, 116, 121, 126, 118, 125, 122 +}; + +static const char gm_b1[] = { + 1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6 +}; + +static const char gm_b2[] = { + 0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6 +}; + +/* Values from table A.1 */ +static const char gm_ebeb[] = { + /* E1 B3 E2 B4 */ + 0, 0, 0, 0, // version 1 + 3, 1, 0, 0, + 5, 1, 0, 0, + 7, 1, 0, 0, + 9, 1, 0, 0, + 5, 1, 0, 0, // version 2 + 10, 1, 0, 0, + 15, 1, 0, 0, + 20, 1, 0, 0, + 25, 1, 0, 0, + 9, 1, 0, 0, // version 3 + 19, 1, 0, 0, + 29, 1, 0, 0, + 39, 1, 0, 0, + 49, 1, 0, 0, + 8, 2, 0, 0, // version 4 + 16, 2, 0, 0, + 24, 2, 0, 0, + 32, 2, 0, 0, + 41, 1, 40, 1, + 12, 2, 0, 0, // version 5 + 24, 2, 0, 0, + 36, 2, 0, 0, + 48, 2, 0, 0, + 61, 1, 60, 1, + 11, 3, 0, 0, // version 6 + 23, 1, 22, 2, + 34, 2, 33, 1, + 45, 3, 0, 0, + 57, 1, 56, 2, + 12, 1, 11, 3, // version 7 + 23, 2, 22, 2, + 34, 3, 33, 1, + 45, 4, 0, 0, + 57, 1, 56, 3, + 12, 2, 11, 3, // version 8 + 23, 5, 0, 0, + 35, 3, 34, 2, + 47, 1, 46, 4, + 58, 4, 57, 1, + 12, 6, 0, 0, // version 9 + 24, 6, 0, 0, + 36, 6, 0, 0, + 48, 6, 0, 0, + 61, 1, 60, 5, + 13, 4, 12, 3, // version 10 + 26, 1, 25, 6, + 38, 5, 37, 2, + 51, 2, 50, 5, + 63, 7, 0, 0, + 12, 6, 11, 3, // version 11 + 24, 4, 23, 5, + 36, 2, 35, 7, + 47, 9, 0, 0, + 59, 7, 58, 2, + 13, 5, 12, 5, // version 12 + 25, 10, 0, 0, + 38, 5, 37, 5, + 50, 10, 0, 0, + 63, 5, 62, 5, + 13, 1, 12, 11, //version 13 + 25, 3, 24, 9, + 37, 5, 36, 7, + 49, 7, 48, 5, + 61, 9, 60, 3 +}; + +static const unsigned short int gm_macro_matrix[] = { + 728, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 727, 624, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 651, + 726, 623, 528, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 553, 652, + 725, 622, 527, 440, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 463, 554, 653, + 724, 621, 526, 439, 360, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 381, 464, 555, 654, + 723, 620, 525, 438, 359, 288, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 307, 382, 465, 556, 655, + 722, 619, 524, 437, 358, 287, 224, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 241, 308, 383, 466, 557, 656, + 721, 618, 523, 436, 357, 286, 223, 168, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 183, 242, 309, 384, 467, 558, 657, + 720, 617, 522, 435, 356, 285, 222, 167, 120, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 133, 184, 243, 310, 385, 468, 559, 658, + 719, 616, 521, 434, 355, 284, 221, 166, 119, 80, 49, 50, 51, 52, 53, 54, 55, 56, 91, 134, 185, 244, 311, 386, 469, 560, 659, + 718, 615, 520, 433, 354, 283, 220, 165, 118, 79, 48, 25, 26, 27, 28, 29, 30, 57, 92, 135, 186, 245, 312, 387, 470, 561, 660, + 717, 614, 519, 432, 353, 282, 219, 164, 117, 78, 47, 24, 9, 10, 11, 12, 31, 58, 93, 136, 187, 246, 313, 388, 471, 562, 661, + 716, 613, 518, 431, 352, 281, 218, 163, 116, 77, 46, 23, 8, 1, 2, 13, 32, 59, 94, 137, 188, 247, 314, 389, 472, 563, 662, + 715, 612, 517, 430, 351, 280, 217, 162, 115, 76, 45, 22, 7, 0, 3, 14, 33, 60, 95, 138, 189, 248, 315, 390, 473, 564, 663, + 714, 611, 516, 429, 350, 279, 216, 161, 114, 75, 44, 21, 6, 5, 4, 15, 34, 61, 96, 139, 190, 249, 316, 391, 474, 565, 664, + 713, 610, 515, 428, 349, 278, 215, 160, 113, 74, 43, 20, 19, 18, 17, 16, 35, 62, 97, 140, 191, 250, 317, 392, 475, 566, 665, + 712, 609, 514, 427, 348, 277, 214, 159, 112, 73, 42, 41, 40, 39, 38, 37, 36, 63, 98, 141, 192, 251, 318, 393, 476, 567, 666, + 711, 608, 513, 426, 347, 276, 213, 158, 111, 72, 71, 70, 69, 68, 67, 66, 65, 64, 99, 142, 193, 252, 319, 394, 477, 568, 667, + 710, 607, 512, 425, 346, 275, 212, 157, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 143, 194, 253, 320, 395, 478, 569, 668, + 709, 606, 511, 424, 345, 274, 211, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 195, 254, 321, 396, 479, 570, 669, + 708, 605, 510, 423, 344, 273, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 255, 322, 397, 480, 571, 670, + 707, 604, 509, 422, 343, 272, 271, 270, 269, 268, 267, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 323, 398, 481, 572, 671, + 706, 603, 508, 421, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 399, 482, 573, 672, + 705, 602, 507, 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 483, 574, 673, + 704, 601, 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 575, 674, + 703, 600, 599, 598, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, 675, + 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676, +}; diff --git a/3rdparty/zint-2.6.1/backend/gs1.c b/3rdparty/zint-2.6.1/backend/gs1.c new file mode 100644 index 0000000..547fba4 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gs1.c @@ -0,0 +1,358 @@ +/* gs1.c - Verifies GS1 data */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +/* This code does some checks on the integrity of GS1 data. It is not intended + to be bulletproof, nor does it report very accurately what problem was found + or where, but should prevent some of the more common encoding errors */ + +void itostr(char ai_string[], int ai_value) { + int thou, hund, ten, unit; + char temp[2]; + + strcpy(ai_string, "("); + thou = ai_value / 1000; + hund = (ai_value - (1000 * thou)) / 100; + ten = (ai_value - ((1000 * thou) + (100 * hund))) / 10; + unit = ai_value - ((1000 * thou) + (100 * hund) + (10 * ten)); + + temp[1] = '\0'; + if (ai_value >= 1000) { + temp[0] = itoc(thou); + strcat(ai_string, temp); + } + if (ai_value >= 100) { + temp[0] = itoc(hund); + strcat(ai_string, temp); + } + temp[0] = itoc(ten); + strcat(ai_string, temp); + temp[0] = itoc(unit); + strcat(ai_string, temp); + strcat(ai_string, ")"); +} + +int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]) { + int i, j, last_ai, ai_latch; + char ai_string[6]; + int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length; + int ai_value[100], ai_location[100], ai_count, data_location[100], data_length[100]; + int error_latch; + + /* Detect extended ASCII characters */ + for (i = 0; i < src_len; i++) { + if (source[i] >= 128) { + strcpy(symbol->errtxt, "250: Extended ASCII characters are not supported by GS1"); + return ZINT_ERROR_INVALID_DATA; + } + if (source[i] < 32) { + strcpy(symbol->errtxt, "251: Control characters are not supported by GS1 "); + return ZINT_ERROR_INVALID_DATA; + } + } + + if (source[0] != '[') { + strcpy(symbol->errtxt, "252: Data does not start with an AI"); + return ZINT_ERROR_INVALID_DATA; + } + + /* Check the position of the brackets */ + bracket_level = 0; + max_bracket_level = 0; + ai_length = 0; + max_ai_length = 0; + min_ai_length = 5; + j = 0; + ai_latch = 0; + for (i = 0; i < src_len; i++) { + ai_length += j; + if (((j == 1) && (source[i] != ']')) && ((source[i] < '0') || (source[i] > '9'))) { + ai_latch = 1; + } + if (source[i] == '[') { + bracket_level++; + j = 1; + } + if (source[i] == ']') { + bracket_level--; + if (ai_length < min_ai_length) { + min_ai_length = ai_length; + } + j = 0; + ai_length = 0; + } + if (bracket_level > max_bracket_level) { + max_bracket_level = bracket_level; + } + if (ai_length > max_ai_length) { + max_ai_length = ai_length; + } + } + min_ai_length--; + + if (bracket_level != 0) { + /* Not all brackets are closed */ + strcpy(symbol->errtxt, "253: Malformed AI in input data (brackets don\'t match)"); + return ZINT_ERROR_INVALID_DATA; + } + + if (max_bracket_level > 1) { + /* Nested brackets */ + strcpy(symbol->errtxt, "254: Found nested brackets in input data"); + return ZINT_ERROR_INVALID_DATA; + } + + if (max_ai_length > 4) { + /* AI is too long */ + strcpy(symbol->errtxt, "255: Invalid AI in input data (AI too long)"); + return ZINT_ERROR_INVALID_DATA; + } + + if (min_ai_length <= 1) { + /* AI is too short */ + strcpy(symbol->errtxt, "256: Invalid AI in input data (AI too short)"); + return ZINT_ERROR_INVALID_DATA; + } + + if (ai_latch == 1) { + /* Non-numeric data in AI */ + strcpy(symbol->errtxt, "257: Invalid AI in input data (non-numeric characters in AI)"); + return ZINT_ERROR_INVALID_DATA; + } + + ai_count = 0; + for (i = 1; i < src_len; i++) { + if (source[i - 1] == '[') { + ai_location[ai_count] = i; + j = 0; + do { + ai_string[j] = source[i + j]; + j++; + } while (ai_string[j - 1] != ']'); + ai_string[j - 1] = '\0'; + ai_value[ai_count] = atoi(ai_string); + ai_count++; + } + } + + for (i = 0; i < ai_count; i++) { + data_location[i] = ai_location[i] + 3; + if (ai_value[i] >= 100) { + data_location[i]++; + } + if (ai_value[i] >= 1000) { + data_location[i]++; + } + data_length[i] = 0; + do { + data_length[i]++; + } while ((source[data_location[i] + data_length[i] - 1] != '[') && (data_location[i] + data_length[i] <= src_len)); + data_length[i]--; + } + + for (i = 0; i < ai_count; i++) { + if (data_length[i] == 0) { + /* No data for given AI */ + strcpy(symbol->errtxt, "258: Empty data field in input data"); + return ZINT_ERROR_INVALID_DATA; + } + } + + error_latch = 0; + strcpy(ai_string, ""); + for (i = 0; i < ai_count; i++) { + switch (ai_value[i]) { + case 0: if (data_length[i] != 18) { + error_latch = 1; + } + break; + case 1: + case 2: + case 3: if (data_length[i] != 14) { + error_latch = 1; + } + break; + case 4: if (data_length[i] != 16) { + error_latch = 1; + } + break; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: if (data_length[i] != 6) { + error_latch = 1; + } + break; + case 20: if (data_length[i] != 2) { + error_latch = 1; + } + break; + case 23: + case 24: + case 25: + case 39: + case 40: + case 41: + case 42: + case 70: + case 80: + case 81: error_latch = 2; + break; + } + if ( + ((ai_value[i] >= 100) && (ai_value[i] <= 179)) + || ((ai_value[i] >= 1000) && (ai_value[i] <= 1799)) + || ((ai_value[i] >= 200) && (ai_value[i] <= 229)) + || ((ai_value[i] >= 2000) && (ai_value[i] <= 2299)) + || ((ai_value[i] >= 300) && (ai_value[i] <= 309)) + || ((ai_value[i] >= 3000) && (ai_value[i] <= 3099)) + || ((ai_value[i] >= 31) && (ai_value[i] <= 36)) + || ((ai_value[i] >= 310) && (ai_value[i] <= 369)) + ) { + error_latch = 2; + } + if ((ai_value[i] >= 3100) && (ai_value[i] <= 3699)) { + if (data_length[i] != 6) { + error_latch = 1; + } + } + if ( + ((ai_value[i] >= 370) && (ai_value[i] <= 379)) + || ((ai_value[i] >= 3700) && (ai_value[i] <= 3799)) + ) { + error_latch = 2; + } + if ((ai_value[i] >= 410) && (ai_value[i] <= 415)) { + if (data_length[i] != 13) { + error_latch = 1; + } + } + if ( + ((ai_value[i] >= 4100) && (ai_value[i] <= 4199)) + || ((ai_value[i] >= 700) && (ai_value[i] <= 703)) + || ((ai_value[i] >= 800) && (ai_value[i] <= 810)) + || ((ai_value[i] >= 900) && (ai_value[i] <= 999)) + || ((ai_value[i] >= 9000) && (ai_value[i] <= 9999)) + ) { + error_latch = 2; + } + if ((error_latch < 4) && (error_latch > 0)) { + /* error has just been detected: capture AI */ + itostr(ai_string, ai_value[i]); + error_latch += 4; + } + } + + if (error_latch == 5) { + strcpy(symbol->errtxt, "259: Invalid data length for AI "); + strcat(symbol->errtxt, ai_string); + return ZINT_ERROR_INVALID_DATA; + } + + if (error_latch == 6) { + strcpy(symbol->errtxt, "260: Invalid AI value"); + strcat(symbol->errtxt, ai_string); + return ZINT_ERROR_INVALID_DATA; + } + + /* Resolve AI data - put resulting string in 'reduced' */ + j = 0; + last_ai = 0; + ai_latch = 1; + for (i = 0; i < src_len; i++) { + if ((source[i] != '[') && (source[i] != ']')) { + reduced[j++] = source[i]; + } + if (source[i] == '[') { + /* Start of an AI string */ + if (ai_latch == 0) { + reduced[j++] = '['; + } + ai_string[0] = source[i + 1]; + ai_string[1] = source[i + 2]; + ai_string[2] = '\0'; + last_ai = atoi(ai_string); + ai_latch = 0; + /* The following values from "GS-1 General Specification version 8.0 issue 2, May 2008" + figure 5.4.8.2.1 - 1 "Element Strings with Pre-Defined Length Using Application Identifiers" */ + if ( + ((last_ai >= 0) && (last_ai <= 4)) + || ((last_ai >= 11) && (last_ai <= 20)) + || (last_ai == 23) /* legacy support - see 5.3.8.2.2 */ + || ((last_ai >= 31) && (last_ai <= 36)) + || (last_ai == 41) + ) { + ai_latch = 1; + } + } + /* The ']' character is simply dropped from the input */ + } + reduced[j] = '\0'; + + /* the character '[' in the reduced string refers to the FNC1 character */ + return 0; +} + +int ugs1_verify(struct zint_symbol *symbol, const unsigned char source[], const unsigned int src_len, unsigned char reduced[]) { + /* Only to keep the compiler happy */ +#ifndef _MSC_VER + char temp[src_len + 5]; +#else + char* temp = (char*) _alloca(src_len + 5); +#endif + int error_number; + + error_number = gs1_verify(symbol, source, src_len, temp); + if (error_number != 0) { + return error_number; + } + + if (strlen(temp) < src_len + 5) { + ustrcpy(reduced, (unsigned char*) temp); + return 0; + } + strcpy(symbol->errtxt, "261: ugs1_verify overflow"); + return ZINT_ERROR_INVALID_DATA; +} diff --git a/3rdparty/zint-2.6.1/backend/gs1.h b/3rdparty/zint-2.6.1/backend/gs1.h new file mode 100644 index 0000000..0dba084 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/gs1.h @@ -0,0 +1,46 @@ +/* gs1.h - Verifies GS1 data */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ +#ifndef __GS1_H +#define __GS1_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + extern int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]); + extern int ugs1_verify(struct zint_symbol *symbol, const unsigned char source[], const unsigned int src_len, unsigned char reduced[]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GS1_H */ \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/hanxin.c b/3rdparty/zint-2.6.1/backend/hanxin.c new file mode 100644 index 0000000..2b99650 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/hanxin.c @@ -0,0 +1,1576 @@ +/* hanxin.c - Han Xin Code + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* This code attempts to implement Han Xin Code according to AIMD-015:2010 (Rev 0.8) */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "reedsol.h" +#include "hanxin.h" +#include "gb2312.h" +#include "gb18030.h" +#include "assert.h" + +/* Find which submode to use for a text character */ +int getsubmode(char input) { + int submode = 2; + + if ((input >= '0') && (input <= '9')) { + submode = 1; + } + + if ((input >= 'A') && (input <= 'Z')) { + submode = 1; + } + + if ((input >= 'a') && (input <= 'z')) { + submode = 1; + } + + return submode; +} + +/* Calculate the approximate length of the binary string */ +static int calculate_binlength(char mode[], int source[], const size_t length, int eci) { + size_t i; + char lastmode = 't'; + int est_binlen = 0; + int submode = 1; + + if (eci != 3) { + est_binlen += 12; + } + + i = 0; + do { + switch (mode[i]) { + case 'n': + if (lastmode != 'n') { + est_binlen += 14; + lastmode = 'n'; + } + est_binlen += 4; + break; + case 't': + if (lastmode != 't') { + est_binlen += 10; + lastmode = 't'; + submode = 1; + } + if (getsubmode((char) source[i]) != submode) { + est_binlen += 6; + submode = getsubmode((char) source[i]); + } + est_binlen += 6; + break; + case 'b': + if (lastmode != 'b') { + est_binlen += 17; + lastmode = 'b'; + } + est_binlen += 8; + break; + case '1': + if (lastmode != '1') { + est_binlen += 16; + lastmode = '1'; + } + est_binlen += 12; + break; + case '2': + if (lastmode != '2') { + est_binlen += 16; + lastmode = '2'; + } + est_binlen += 12; + break; + case 'd': + if (lastmode != 'd') { + est_binlen += 16; + lastmode = 'd'; + } + est_binlen += 15; + break; + case 'f': + if (lastmode != 'f') { + est_binlen += 4; + lastmode = 'f'; + } + est_binlen += 21; + i++; + break; + } + i++; + } while (i < length); + + return est_binlen; +} + +int isRegion1(int glyph) { + int first_byte, second_byte; + int valid = 0; + + first_byte = (glyph & 0xff00) >> 8; + second_byte = glyph & 0xff; + + if ((first_byte >= 0xb0) && (first_byte <= 0xd7)) { + if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) { + valid = 1; + } + } + + if ((first_byte >= 0xa1) && (first_byte <= 0xa3)) { + if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) { + valid = 1; + } + } + + if ((glyph >= 0xa8a1) && (glyph <= 0xa8c0)) { + valid = 1; + } + + return valid; +} + +int isRegion2(int glyph) { + int first_byte, second_byte; + int valid = 0; + + first_byte = (glyph & 0xff00) >> 8; + second_byte = glyph & 0xff; + + if ((first_byte >= 0xd8) && (first_byte <= 0xf7)) { + if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) { + valid = 1; + } + } + + return valid; +} + +int isDoubleByte(int glyph) { + int first_byte, second_byte; + int valid = 0; + + first_byte = (glyph & 0xff00) >> 8; + second_byte = glyph & 0xff; + + if ((first_byte >= 0x81) && (first_byte <= 0xfe)) { + if ((second_byte >= 0x40) && (second_byte <= 0x7e)) { + valid = 1; + } + + if ((second_byte >= 0x80) && (second_byte <= 0xfe)) { + valid = 1; + } + } + + return valid; +} + +int isFourByte(int glyph, int glyph2) { + int first_byte, second_byte; + int third_byte, fourth_byte; + int valid = 0; + + first_byte = (glyph & 0xff00) >> 8; + second_byte = glyph & 0xff; + third_byte = (glyph2 & 0xff00) >> 8; + fourth_byte = glyph2 & 0xff; + + if ((first_byte >= 0x81) && (first_byte <= 0xfe)) { + if ((second_byte >= 0x30) && (second_byte <= 0x39)) { + if ((third_byte >= 0x81) && (third_byte <= 0xfe)) { + if ((fourth_byte >= 0x30) && (fourth_byte <= 0x39)) { + valid = 1; + } + } + } + } + + return valid; +} + +/* Calculate mode switching */ +static void hx_define_mode(char mode[], int source[], const size_t length) { + size_t i; + char lastmode = 't'; + int done; + + i = 0; + do { + done = 0; + + if (isRegion1(source[i])) { + mode[i] = '1'; + done = 1; + i++; + } + + if ((done == 0) && (isRegion2(source[i]))) { + mode[i] = '2'; + done = 1; + i++; + } + + if ((done == 0) && (isDoubleByte(source[i]))) { + mode[i] = 'd'; + done = 1; + i++; + } + + if ((done == 0) && (i < length - 1)) { + if (isFourByte(source[i], source[i + 1])) { + mode[i] = 'f'; + mode[i + 1] = 'f'; + done = 1; + i += 2; + } + } + + if (done == 0) { + if ((source[i] >= '0') && (source[i] <= '9')) { + mode[i] = 'n'; + if (lastmode != 'n') { + lastmode = 'n'; + } + } else { + if ((source[i] <= 127) && ((source[i] <= 27) || (source[i] >= 32))) { + mode[i] = 't'; + if (lastmode != 't') { + lastmode = 't'; + } + } else { + mode[i] = 'b'; + if (lastmode != 'b') { + lastmode = 'b'; + } + } + } + i++; + } + } while (i < length); + mode[length] = '\0'; +} + +/* Convert Text 1 sub-mode character to encoding value, as given in table 3 */ +int lookup_text1(char input) { + int encoding_value = 0; + + if ((input >= '0') && (input <= '9')) { + encoding_value = input - '0'; + } + + if ((input >= 'A') && (input <= 'Z')) { + encoding_value = input - 'A' + 10; + } + + if ((input >= 'a') && (input <= 'z')) { + encoding_value = input - 'a' + 36; + } + + return encoding_value; +} + +/* Convert Text 2 sub-mode character to encoding value, as given in table 4 */ +int lookup_text2(char input) { + int encoding_value = 0; + + if ((input >= 0) && (input <= 27)) { + encoding_value = input; + } + + if ((input >= ' ') && (input <= '/')) { + encoding_value = input - ' ' + 28; + } + + if ((input >= '[') && (input <= 96)) { + encoding_value = input - '[' + 51; + } + + if ((input >= '{') && (input <= 127)) { + encoding_value = input - '{' + 57; + } + + return encoding_value; +} + +/* Convert input data to binary stream */ +static void calculate_binary(char binary[], char mode[], int source[], const size_t length, const int eci, int debug) { + int block_length; + int position = 0; + int i, count, encoding_value; + int first_byte, second_byte; + int third_byte, fourth_byte; + int glyph; + int submode; + + if (eci != 3) { + /* Encoding ECI assignment number, according to Table 5 */ + bin_append(8, 4, binary); // ECI + if (eci <= 127) { + bin_append(eci, 8, binary); + } + if ((eci >= 128) && (eci <= 16383)) { + strcat(binary, "10"); + bin_append(eci, 14, binary); + } + if (eci >= 16384) { + strcat(binary, "110"); + bin_append(eci, 21, binary); + } + } + + do { + block_length = 0; + do { + block_length++; + } while (mode[position + block_length] == mode[position]); + + switch (mode[position]) { + case 'n': + /* Numeric mode */ + /* Mode indicator */ + bin_append(1, 4, binary); + + if (debug) { + printf("Numeric\n"); + } + + i = 0; + + while (i < block_length) { + int first = 0, second = 0, third = 0; + + first = posn(NEON, (char) source[position + i]); + count = 1; + encoding_value = first; + + if (i + 1 < block_length && mode[position + i + 1] == 'n') { + second = posn(NEON, (char) source[position + i + 1]); + count = 2; + encoding_value = (encoding_value * 10) + second; + + if (i + 2 < block_length && mode[position + i + 2] == 'n') { + third = posn(NEON, (char) source[position + i + 2]); + count = 3; + encoding_value = (encoding_value * 10) + third; + } + } + + bin_append(encoding_value, 10, binary); + + if (debug) { + printf("0x%4x (%d)", encoding_value, encoding_value); + } + + i += count; + } + + /* Mode terminator depends on number of characters in last group (Table 2) */ + switch (count) { + case 1: + bin_append(1021, 10, binary); + break; + case 2: + bin_append(1022, 10, binary); + break; + case 3: + bin_append(1023, 10, binary); + break; + } + + if (debug) { + printf(" (TERM %d)\n", count); + } + + break; + case 't': + /* Text mode */ + if (position != 0) { + /* Mode indicator */ + bin_append(2, 4, binary); + + if (debug) { + printf("Text\n"); + } + } + + submode = 1; + + i = 0; + + while (i < block_length) { + + if (getsubmode((char) source[i + position]) != submode) { + /* Change submode */ + bin_append(62, 6, binary); + submode = getsubmode((char) source[i + position]); + if (debug) { + printf("SWITCH "); + } + } + + if (submode == 1) { + encoding_value = lookup_text1((char) source[i + position]); + } else { + encoding_value = lookup_text2((char) source[i + position]); + } + + bin_append(encoding_value, 6, binary); + + if (debug) { + printf("%c (%d) ", (char) source[i], encoding_value); + } + i++; + } + + /* Terminator */ + bin_append(63, 6, binary); + + if (debug) { + printf("\n"); + } + break; + case 'b': + /* Binary Mode */ + /* Mode indicator */ + bin_append(3, 4, binary); + + /* Count indicator */ + bin_append(block_length, 13, binary); + + if (debug) { + printf("Binary (length %d)\n", block_length); + } + + i = 0; + + while (i < block_length) { + + /* 8-bit bytes with no conversion */ + bin_append(source[i + position], 8, binary); + + if (debug) { + printf("%d ", source[i + position]); + } + + i++; + } + + if (debug) { + printf("\n"); + } + break; + case '1': + /* Region 1 encoding */ + /* Mode indicator */ + bin_append(4, 4, binary); + + if (debug) { + printf("Region 1\n"); + } + + i = 0; + + while (i < block_length) { + first_byte = (source[i + position] & 0xff00) >> 8; + second_byte = source[i + position] & 0xff; + + /* Subset 1 */ + glyph = (0x5e * (first_byte - 0xb0)) + (second_byte - 0xa1); + + /* Subset 2 */ + if ((first_byte >= 0xa1) && (first_byte <= 0xa3)) { + if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) { + glyph = (0x5e * first_byte - 0xa1) + (second_byte - 0xa1) + 0xeb0; + } + } + + /* Subset 3 */ + if ((source[i + position] >= 0xa8a1) && (source[i + position] <= 0xa8c0)) { + glyph = (second_byte - 0xa1) + 0xfca; + } + + if (debug) { + printf("%d ", glyph); + } + + bin_append(glyph, 12, binary); + i++; + } + + /* Terminator */ + bin_append(4095, 12, binary); + + if (debug) { + printf("\n"); + } + + break; + case '2': + /* Region 2 encoding */ + /* Mode indicator */ + bin_append(5, 4, binary); + + if (debug) { + printf("Region 2\n"); + } + + i = 0; + + while (i < block_length) { + first_byte = (source[i + position] & 0xff00) >> 8; + second_byte = source[i + position] & 0xff; + + glyph = (0x5e * (first_byte - 0xd8)) + (second_byte - 0xa1); + + if (debug) { + printf("%d ", glyph); + } + + bin_append(glyph, 12, binary); + i++; + } + + /* Terminator */ + bin_append(4095, 12, binary); + + if (debug) { + printf("\n"); + } + break; + case 'd': + /* Double byte encoding */ + /* Mode indicator */ + bin_append(6, 4, binary); + + if (debug) { + printf("Double byte\n"); + } + + i = 0; + + while (i < block_length) { + first_byte = (source[i + position] & 0xff00) >> 8; + second_byte = source[i + position] & 0xff; + + if (second_byte <= 0x7e) { + glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x40); + } else { + glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x41); + } + + if (debug) { + printf("%d ", glyph); + } + + bin_append(glyph, 15, binary); + i++; + } + + /* Terminator */ + bin_append(32767, 15, binary); + /* Terminator sequence of length 12 is a mistake + - confirmed by Wang Yi */ + + if (debug) { + printf("\n"); + } + break; + case 'f': + /* Four-byte encoding */ + if (debug) { + printf("Four byte\n"); + } + + i = 0; + + while (i < block_length) { + + /* Mode indicator */ + bin_append(7, 4, binary); + + first_byte = (source[i + position] & 0xff00) >> 8; + second_byte = source[i + position] & 0xff; + third_byte = (source[i + position + 1] & 0xff00) >> 8; + fourth_byte = source[i + position + 1] & 0xff; + + glyph = (0x3138 * (first_byte - 0x81)) + (0x04ec * (second_byte - 0x30)) + + (0x0a * (third_byte - 0x81)) + (fourth_byte - 0x30); + + if (debug) { + printf("%d ", glyph); + } + + bin_append(glyph, 15, binary); + i += 2; + } + + /* No terminator */ + + if (debug) { + printf("\n"); + } + break; + + } + + position += block_length; + + } while (position < length); +} + +/* Finder pattern for top left of symbol */ +void hx_place_finder_top_left(unsigned char* grid, int size) { + int xp, yp; + int x = 0, y = 0; + char finder[] = {0x7F, 0x40, 0x5F, 0x50, 0x57, 0x57, 0x57}; + + for (xp = 0; xp < 7; xp++) { + for (yp = 0; yp < 7; yp++) { + if (finder[yp] & 0x40 >> xp) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +/* Finder pattern for top right and bottom left of symbol */ +void hx_place_finder(unsigned char* grid, int size, int x, int y) { + int xp, yp; + char finder[] = {0x7F, 0x01, 0x7D, 0x05, 0x75, 0x75, 0x75}; + + for (xp = 0; xp < 7; xp++) { + for (yp = 0; yp < 7; yp++) { + if (finder[yp] & 0x40 >> xp) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +/* Finder pattern for bottom right of symbol */ +void hx_place_finder_bottom_right(unsigned char* grid, int size) { + int xp, yp; + int x = size - 7, y = size - 7; + char finder[] = {0x75, 0x75, 0x75, 0x05, 0x7D, 0x01, 0x7F}; + + for (xp = 0; xp < 7; xp++) { + for (yp = 0; yp < 7; yp++) { + if (finder[yp] & 0x40 >> xp) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +/* Avoid plotting outside symbol or over finder patterns */ +void hx_safe_plot(unsigned char *grid, int size, int x, int y, int value) { + if ((x >= 0) && (x < size)) { + if ((y >= 0) && (y < size)) { + if (grid[(y * size) + x] == 0) { + grid[(y * size) + x] = value; + } + } + } +} + +/* Plot an alignment pattern around top and right of a module */ +void hx_plot_alignment(unsigned char *grid, int size, int x, int y, int w, int h) { + int i; + hx_safe_plot(grid, size, x, y, 0x11); + hx_safe_plot(grid, size, x - 1, y + 1, 0x10); + + for (i = 1; i <= w; i++) { + /* Top */ + hx_safe_plot(grid, size, x - i, y, 0x11); + hx_safe_plot(grid, size, x - i - 1, y + 1, 0x10); + } + + for (i = 1; i < h; i++) { + /* Right */ + hx_safe_plot(grid, size, x, y + i, 0x11); + hx_safe_plot(grid, size, x - 1, y + i + 1, 0x10); + } +} + +/* Plot assistant alignment patterns */ +void hx_plot_assistant(unsigned char *grid, int size, int x, int y) { + hx_safe_plot(grid, size, x - 1, y - 1, 0x10); + hx_safe_plot(grid, size, x, y - 1, 0x10); + hx_safe_plot(grid, size, x + 1, y - 1, 0x10); + hx_safe_plot(grid, size, x - 1, y, 0x10); + hx_safe_plot(grid, size, x, y, 0x11); + hx_safe_plot(grid, size, x + 1, y, 0x10); + hx_safe_plot(grid, size, x - 1, y + 1, 0x10); + hx_safe_plot(grid, size, x, y + 1, 0x10); + hx_safe_plot(grid, size, x + 1, y + 1, 0x10); +} + +/* Put static elements in the grid */ +void hx_setup_grid(unsigned char* grid, int size, int version) { + int i, j; + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + grid[(i * size) + j] = 0; + } + } + + /* Add finder patterns */ + hx_place_finder_top_left(grid, size); + hx_place_finder(grid, size, 0, size - 7); + hx_place_finder(grid, size, size - 7, 0); + hx_place_finder_bottom_right(grid, size); + + /* Add finder pattern separator region */ + for (i = 0; i < 8; i++) { + /* Top left */ + grid[(7 * size) + i] = 0x10; + grid[(i * size) + 7] = 0x10; + + /* Top right */ + grid[(7 * size) + (size - i - 1)] = 0x10; + grid[((size - i - 1) * size) + 7] = 0x10; + + /* Bottom left */ + grid[(i * size) + (size - 8)] = 0x10; + grid[((size - 8) * size) + i] = 0x10; + + /* Bottom right */ + grid[((size - 8) * size) + (size - i - 1)] = 0x10; + grid[((size - i - 1) * size) + (size - 8)] = 0x10; + } + + /* Reserve function information region */ + for (i = 0; i < 9; i++) { + /* Top left */ + grid[(8 * size) + i] = 0x10; + grid[(i * size) + 8] = 0x10; + + /* Top right */ + grid[(8 * size) + (size - i - 1)] = 0x10; + grid[((size - i - 1) * size) + 8] = 0x10; + + /* Bottom left */ + grid[(i * size) + (size - 9)] = 0x10; + grid[((size - 9) * size) + i] = 0x10; + + /* Bottom right */ + grid[((size - 9) * size) + (size - i - 1)] = 0x10; + grid[((size - i - 1) * size) + (size - 9)] = 0x10; + } + + if (version > 3) { + int k = hx_module_k[version - 1]; + int r = hx_module_r[version - 1]; + int m = hx_module_m[version - 1]; + int x, y, row_switch, column_switch; + int module_height, module_width; + int mod_x, mod_y; + + /* Add assistant alignment patterns to left and right */ + y = 0; + mod_y = 0; + do { + if (mod_y < m) { + module_height = k; + } else { + module_height = r - 1; + } + + if ((mod_y % 2) == 0) { + if ((m % 2) == 1) { + hx_plot_assistant(grid, size, 0, y); + } + } else { + if ((m % 2) == 0) { + hx_plot_assistant(grid, size, 0, y); + } + hx_plot_assistant(grid, size, size - 1, y); + } + + mod_y++; + y += module_height; + } while (y < size); + + /* Add assistant alignment patterns to top and bottom */ + x = (size - 1); + mod_x = 0; + do { + if (mod_x < m) { + module_width = k; + } else { + module_width = r - 1; + } + + if ((mod_x % 2) == 0) { + if ((m % 2) == 1) { + hx_plot_assistant(grid, size, x, (size - 1)); + } + } else { + if ((m % 2) == 0) { + hx_plot_assistant(grid, size, x, (size - 1)); + } + hx_plot_assistant(grid, size, x, 0); + } + + mod_x++; + x -= module_width; + } while (x >= 0); + + /* Add alignment pattern */ + column_switch = 1; + y = 0; + mod_y = 0; + do { + if (mod_y < m) { + module_height = k; + } else { + module_height = r - 1; + } + + if (column_switch == 1) { + row_switch = 1; + column_switch = 0; + } else { + row_switch = 0; + column_switch = 1; + } + + x = (size - 1); + mod_x = 0; + do { + if (mod_x < m) { + module_width = k; + } else { + module_width = r - 1; + } + + if (row_switch == 1) { + if (!(y == 0 && x == (size - 1))) { + hx_plot_alignment(grid, size, x, y, module_width, module_height); + } + row_switch = 0; + } else { + row_switch = 1; + } + mod_x++; + x -= module_width; + } while (x >= 0); + + mod_y++; + y += module_height; + } while (y < size); + } +} + +/* Calculate error correction codes */ +void hx_add_ecc(unsigned char fullstream[], unsigned char datastream[], int version, int ecc_level) { + unsigned char data_block[180]; + unsigned char ecc_block[36]; + int i, j, block; + int batch_size, data_length, ecc_length; + int input_position = -1; + int output_position = -1; + int table_d1_pos = ((version - 1) * 36) + ((ecc_level - 1) * 9); + + for (i = 0; i < 3; i++) { + batch_size = hx_table_d1[table_d1_pos + (3 * i)]; + data_length = hx_table_d1[table_d1_pos + (3 * i) + 1]; + ecc_length = hx_table_d1[table_d1_pos + (3 * i) + 2]; + + for (block = 0; block < batch_size; block++) { + for (j = 0; j < data_length; j++) { + input_position++; + output_position++; + data_block[j] = datastream[input_position]; + fullstream[output_position] = datastream[input_position]; + } + + rs_init_gf(0x163); // x^8 + x^6 + x^5 + x + 1 = 0 + rs_init_code(ecc_length, 1); + rs_encode(data_length, data_block, ecc_block); + rs_free(); + + for (j = 0; j < ecc_length; j++) { + output_position++; + fullstream[output_position] = ecc_block[ecc_length - j - 1]; + } + } + } +} + +/* Rearrange data in batches of 13 codewords (section 5.8.2) */ +void make_picket_fence(unsigned char fullstream[], unsigned char picket_fence[], int streamsize) { + int i, start; + int output_position = 0; + + for (start = 0; start < 13; start++) { + for (i = start; i < streamsize; i += 13) { + if (i < streamsize) { + picket_fence[output_position] = fullstream[i]; + output_position++; + } + } + } +} + +/* Evaluate a bitmask according to table 9 */ +int hx_evaluate(unsigned char *eval, int size, int pattern) { + int x, y, block, weight; + int result = 0; + char state; + int p; + int a, b, afterCount, beforeCount; +#ifndef _MSC_VER + char local[size * size]; +#else + char* local = (char *) _alloca((size * size) * sizeof (char)); +#endif + + /* all four bitmask variants have been encoded in the 4 bits of the bytes + * that make up the grid array. select them for evaluation according to the + * desired pattern.*/ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if ((eval[(y * size) + x] & (0x01 << pattern)) != 0) { + local[(y * size) + x] = '1'; + } else { + local[(y * size) + x] = '0'; + } + } + } + + /* Test 1: 1:1:1:1:3 or 3:1:1:1:1 ratio pattern in row/column */ + /* Vertical */ + for (x = 0; x < size; x++) { + for (y = 0; y < (size - 7); y++) { + p = 0; + for (weight = 0; weight < 7; weight++) { + if (local[((y + weight) * size) + x] == '1') { + p += (0x40 >> weight); + } + } + if ((p == 0x57) || (p == 0x75)) { + /* Pattern found, check before and after */ + beforeCount = 0; + for (b = (y - 3); b < y; b++) { + if (b < 0) { + beforeCount++; + } else { + if (local[(b * size) + x] == '0') { + beforeCount++; + } else { + beforeCount = 0; + } + } + } + + afterCount = 0; + for (a = (y + 7); a <= (y + 9); a++) { + if (a >= size) { + afterCount++; + } else { + if (local[(a * size) + x] == '0') { + afterCount++; + } else { + afterCount = 0; + } + } + } + + if ((beforeCount == 3) || (afterCount == 3)) { + /* Pattern is preceeded or followed by light area + 3 modules wide */ + result += 50; + } + } + } + } + + /* Horizontal */ + for (y = 0; y < size; y++) { + for (x = 0; x < (size - 7); x++) { + p = 0; + for (weight = 0; weight < 7; weight++) { + if (local[(y * size) + x + weight] == '1') { + p += (0x40 >> weight); + } + } + if ((p == 0x57) || (p == 0x75)) { + /* Pattern found, check before and after */ + beforeCount = 0; + for (b = (x - 3); b < x; b++) { + if (b < 0) { + beforeCount++; + } else { + if (local[(y * size) + b] == '0') { + beforeCount++; + } else { + beforeCount = 0; + } + } + } + + afterCount = 0; + for (a = (x + 7); a <= (x + 9); a++) { + if (a >= size) { + afterCount++; + } else { + if (local[(y * size) + a] == '0') { + afterCount++; + } else { + afterCount = 0; + } + } + } + + if ((beforeCount == 3) || (afterCount == 3)) { + /* Pattern is preceeded or followed by light area + 3 modules wide */ + result += 50; + } + } + } + } + + /* Test 2: Adjacent modules in row/column in same colour */ + /* In AIMD-15 section 5.8.3.2 it is stated... “In Table 9 below, i refers to the row + * position of the module.” - however i being the length of the run of the + * same colour (i.e. "block" below) in the same fashion as ISO/IEC 18004 + * makes more sense. -- Confirmed by Wang Yi */ + + /* Vertical */ + for (x = 0; x < size; x++) { + state = local[x]; + block = 0; + for (y = 0; y < size; y++) { + if (local[(y * size) + x] == state) { + block++; + } else { + if (block > 3) { + result += (3 + block) * 4; + } + block = 0; + state = local[(y * size) + x]; + } + } + if (block > 3) { + result += (3 + block) * 4; + } + } + + /* Horizontal */ + for (y = 0; y < size; y++) { + state = local[y * size]; + block = 0; + for (x = 0; x < size; x++) { + if (local[(y * size) + x] == state) { + block++; + } else { + if (block > 3) { + result += (3 + block) * 4; + } + block = 0; + state = local[(y * size) + x]; + } + } + if (block > 3) { + result += (3 + block) * 4; + } + } + + return result; +} + +/* Apply the four possible bitmasks for evaluation */ +int hx_apply_bitmask(unsigned char *grid, int size) { + int x, y; + int i, j; + int pattern, penalty[4]; + int best_pattern, best_val; + int bit; + unsigned char p; + +#ifndef _MSC_VER + unsigned char mask[size * size]; + unsigned char eval[size * size]; +#else + unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); + unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + /* Perform data masking */ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + mask[(y * size) + x] = 0x00; + j = x + 1; + i = y + 1; + + if (!(grid[(y * size) + x] & 0xf0)) { + if ((i + j) % 2 == 0) { + mask[(y * size) + x] += 0x02; + } + if ((((i + j) % 3) + (j % 3)) % 2 == 0) { + mask[(y * size) + x] += 0x04; + } + if (((i % j) + (j % i) + (i % 3) + (j % 3)) % 2 == 0) { + mask[(y * size) + x] += 0x08; + } + } + } + } + + // apply data masks to grid, result in eval + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (grid[(y * size) + x] & 0x01) { + p = 0xff; + } else { + p = 0x00; + } + + eval[(y * size) + x] = mask[(y * size) + x] ^ p; + } + } + + /* Evaluate result */ + for (pattern = 0; pattern < 4; pattern++) { + penalty[pattern] = hx_evaluate(eval, size, pattern); + } + + best_pattern = 0; + best_val = penalty[0]; + for (pattern = 1; pattern < 4; pattern++) { + if (penalty[pattern] < best_val) { + best_pattern = pattern; + best_val = penalty[pattern]; + } + } + + /* Apply mask */ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + bit = 0; + switch (best_pattern) { + case 0: if (mask[(y * size) + x] & 0x01) { + bit = 1; + } + break; + case 1: if (mask[(y * size) + x] & 0x02) { + bit = 1; + } + break; + case 2: if (mask[(y * size) + x] & 0x04) { + bit = 1; + } + break; + case 3: if (mask[(y * size) + x] & 0x08) { + bit = 1; + } + break; + } + if (bit == 1) { + if (grid[(y * size) + x] & 0x01) { + grid[(y * size) + x] = 0x00; + } else { + grid[(y * size) + x] = 0x01; + } + } + } + } + + return best_pattern; +} + +/* Han Xin Code - main */ +int han_xin(struct zint_symbol *symbol, const unsigned char source[], size_t length) { + int est_binlen; + int ecc_level = symbol->option_1; + int i, j, version, posn = 0; + int data_codewords = 0, size; + int codewords; + int bitmask; + int error_number; + int bin_len; + int done; + char function_information[36]; + unsigned char fi_cw[3] = {0, 0, 0}; + unsigned char fi_ecc[4]; + +#ifndef _MSC_VER + int utfdata[length + 1]; + int gbdata[(length + 1) * 2]; + char mode[length + 1]; +#else + int* utfdata = (int *) _alloca((length + 1) * sizeof (int)); + int* gbdata = (int *) _alloca(((length + 1) * 2) * sizeof (int)); + char* mode = (char *) _alloca((length + 1) * sizeof (char)); + char* binary; + unsigned char *datastream; + unsigned char *fullstream; + unsigned char *picket_fence; + unsigned char *grid; +#endif + + if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) { + for (i = 0; i < length; i++) { + gbdata[i] = (int) source[i]; + } + } else { + /* Convert Unicode input to GB-18030 */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if (error_number != 0) { + return error_number; + } + + posn = 0; + for (i = 0; i < length; i++) { + done = 0; + gbdata[posn] = 0; + + /* Single byte characters in range U+0000 -> U+007F */ + if (utfdata[i] <= 0x7f) { + gbdata[posn] = utfdata[i]; + posn++; + done = 1; + } + + /* Two bytes characters in GB-2312 */ + if (done == 0) { + j = 0; + do { + if (gb2312_lookup[j * 2] == utfdata[i]) { + gbdata[posn] = gb2312_lookup[(j * 2) + 1]; + posn++; + done = 1; + } + j++; + } while ((j < 7445) && (done == 0)); + } + + /* Two byte characters in GB-18030 */ + if (done == 0) { + j = 0; + do { + if (gb18030_twobyte_lookup[j * 2] == utfdata[i]) { + gbdata[posn] = gb18030_twobyte_lookup[(j * 2) + 1]; + posn++; + done = 1; + } + j++; + } while ((j < 16495) && (done == 0)); + } + + /* Four byte characters in range U+0080 -> U+FFFF */ + if (done == 0) { + j = 0; + do { + if (gb18030_fourbyte_lookup[j * 3] == utfdata[i]) { + gbdata[posn] = gb18030_fourbyte_lookup[(j * 3) + 1]; + gbdata[posn + 1] = gb18030_fourbyte_lookup[(j * 3) + 2]; + posn += 2; + done = 1; + } + j++; + } while ((j < 6793) && (done == 0)); + } + + /* Supplementary planes U+10000 -> U+1FFFF */ + if (done == 0) { + if (utfdata[i] >= 0x10000 && utfdata[i] < 0x110000) { + /* algorithm from libiconv-1.15\lib\gb18030.h */ + int j, r3, r2, r1, r0; + + j = utfdata[i] - 0x10000; + r3 = (j % 10) + 0x30; j = j / 10; + r2 = (j % 126) + 0x81; j = j / 126; + r1 = (j % 10) + 0x30; j = j / 10; + r0 = j + 0x90; + gbdata[posn] = (r0 << 8) + r1; + gbdata[posn + 1] = (r2 << 8) + r3; + posn += 2; + done = 1; + } + } + + /* Character not found */ + if (done == 0) { + strcpy(symbol->errtxt, "540: Unknown character in input data"); + return ZINT_ERROR_INVALID_DATA; + } + } + length = posn; + } + + hx_define_mode(mode, gbdata, length); + + est_binlen = calculate_binlength(mode, gbdata, length, symbol->eci); + +#ifndef _MSC_VER + char binary[est_binlen + 10]; +#else + binary = (char *) _alloca((est_binlen + 10) * sizeof (char)); +#endif + memset(binary, 0, (est_binlen + 1) * sizeof (char)); + + if ((ecc_level <= 0) || (ecc_level >= 5)) { + ecc_level = 1; + } + + calculate_binary(binary, mode, gbdata, length, symbol->eci, symbol->debug); + bin_len = strlen(binary); + codewords = bin_len / 8; + if (bin_len % 8 != 0) { + codewords++; + } + + version = 85; + for (i = 84; i > 0; i--) { + switch (ecc_level) { + case 1: + if (hx_data_codewords_L1[i - 1] > codewords) { + version = i; + data_codewords = hx_data_codewords_L1[i - 1]; + } + break; + case 2: + if (hx_data_codewords_L2[i - 1] > codewords) { + version = i; + data_codewords = hx_data_codewords_L2[i - 1]; + } + break; + case 3: + if (hx_data_codewords_L3[i - 1] > codewords) { + version = i; + data_codewords = hx_data_codewords_L3[i - 1]; + } + break; + case 4: + if (hx_data_codewords_L4[i - 1] > codewords) { + version = i; + data_codewords = hx_data_codewords_L4[i - 1]; + } + break; + default: + assert(0); + break; + } + } + + if (version == 85) { + strcpy(symbol->errtxt, "541: Input too long for selected error correction level"); + return ZINT_ERROR_TOO_LONG; + } + + if ((symbol->option_2 < 0) || (symbol->option_2 > 84)) { + symbol->option_2 = 0; + } + + if (symbol->option_2 > version) { + version = symbol->option_2; + } + + if ((symbol->option_2 != 0) && (symbol->option_2 < version)) { + strcpy(symbol->errtxt, "542: Input too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + + /* If there is spare capacity, increase the level of ECC */ + + if ((ecc_level == 1) && (codewords < hx_data_codewords_L2[version - 1])) { + ecc_level = 2; + data_codewords = hx_data_codewords_L2[version - 1]; + } + + if ((ecc_level == 2) && (codewords < hx_data_codewords_L3[version - 1])) { + ecc_level = 3; + data_codewords = hx_data_codewords_L3[version - 1]; + } + + if ((ecc_level == 3) && (codewords < hx_data_codewords_L4[version - 1])) { + ecc_level = 4; + data_codewords = hx_data_codewords_L4[version - 1]; + } + + //printf("Version %d, ECC %d\n", version, ecc_level); + + size = (version * 2) + 21; + +#ifndef _MSC_VER + unsigned char datastream[data_codewords]; + unsigned char fullstream[hx_total_codewords[version - 1]]; + unsigned char picket_fence[hx_total_codewords[version - 1]]; + unsigned char grid[size * size]; +#else + datastream = (unsigned char *) _alloca((data_codewords) * sizeof (unsigned char)); + fullstream = (unsigned char *) _alloca((hx_total_codewords[version - 1]) * sizeof (unsigned char)); + picket_fence = (unsigned char *) _alloca((hx_total_codewords[version - 1]) * sizeof (unsigned char)); + grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + for (i = 0; i < data_codewords; i++) { + datastream[i] = 0; + } + + for (i = 0; i < bin_len; i++) { + if (binary[i] == '1') { + datastream[i / 8] += 0x80 >> (i % 8); + } + } + + hx_setup_grid(grid, size, version); + + hx_add_ecc(fullstream, datastream, version, ecc_level); + + make_picket_fence(fullstream, picket_fence, hx_total_codewords[version - 1]); + + /* Populate grid */ + j = 0; + for (i = 0; i < (size * size); i++) { + if (grid[i] == 0x00) { + if (j < (hx_total_codewords[version - 1] * 8)) { + if (picket_fence[(j / 8)] & (0x80 >> (j % 8))) { + grid[i] = 0x01; + } + j++; + } + } + } + + bitmask = hx_apply_bitmask(grid, size); + + /* Form function information string */ + for (i = 0; i < 34; i++) { + if (i % 2) { + function_information[i] = '1'; + } else { + function_information[i] = '0'; + } + } + function_information[34] = '\0'; + + for (i = 0; i < 8; i++) { + if ((version + 20) & (0x80 >> i)) { + function_information[i] = '1'; + } else { + function_information[i] = '0'; + } + } + + for (i = 0; i < 2; i++) { + if ((ecc_level - 1) & (0x02 >> i)) { + function_information[i + 8] = '1'; + } else { + function_information[i + 8] = '0'; + } + } + + for (i = 0; i < 2; i++) { + if (bitmask & (0x02 >> i)) { + function_information[i + 10] = '1'; + } else { + function_information[i + 10] = '0'; + } + } + + + + for (i = 0; i < 3; i++) { + for (j = 0; j < 4; j++) { + if (function_information[(i * 4) + j] == '1') { + fi_cw[i] += (0x08 >> j); + } + } + } + + rs_init_gf(0x13); + rs_init_code(4, 1); + rs_encode(3, fi_cw, fi_ecc); + rs_free(); + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + if (fi_ecc[3 - i] & (0x08 >> j)) { + function_information[(i * 4) + j + 12] = '1'; + } else { + function_information[(i * 4) + j + 12] = '0'; + } + } + } + + /* Add function information to symbol */ + for (i = 0; i < 9; i++) { + if (function_information[i] == '1') { + grid[(8 * size) + i] = 0x01; + grid[((size - 8 - 1) * size) + (size - i - 1)] = 0x01; + } + if (function_information[i + 8] == '1') { + grid[((8 - i) * size) + 8] = 0x01; + grid[((size - 8 - 1 + i) * size) + (size - 8 - 1)] = 0x01; + } + if (function_information[i + 17] == '1') { + grid[(i * size) + (size - 1 - 8)] = 0x01; + grid[((size - 1 - i) * size) + 8] = 0x01; + } + if (function_information[i + 25] == '1') { + grid[(8 * size) + (size - 1 - 8 + i)] = 0x01; + grid[((size - 1 - 8) * size) + (8 - i)] = 0x01; + } + } + + symbol->width = size; + symbol->rows = size; + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + if (grid[(i * size) + j] & 0x01) { + set_module(symbol, i, j); + } + } + symbol->row_height[i] = 1; + } + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/hanxin.h b/3rdparty/zint-2.6.1/backend/hanxin.h new file mode 100644 index 0000000..1ad4685 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/hanxin.h @@ -0,0 +1,460 @@ +/* hanxin.h - definitions for Han Xin code + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + Copyright (C) 2016 Zoe Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* Data from table B1: Data capacity of Han Xin Code */ +static const unsigned short int hx_total_codewords[] = { + 25, 37, 50, 54, 69, 84, 100, 117, 136, 155, 161, 181, 203, 225, 249, + 273, 299, 325, 353, 381, 411, 422, 453, 485, 518, 552, 587, 623, 660, + 698, 737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105, 1126, 1175, + 1224, 1275, 1327, 1380, 1434, 1489, 1513, 1569, 1628, 1686, 1745, 1805, + 1867, 1929, 1992, 2021, 2086, 2151, 2218, 2286, 2355, 2425, 2496, 2528, + 2600, 2673, 2749, 2824, 2900, 2977, 3056, 3135, 3171, 3252, 3334, 3416, + 3500, 3585, 3671, 3758, 3798, 3886 +}; + +static const unsigned short int hx_data_codewords_L1[] = { + 21, 31, 42, 46, 57, 70, 84, 99, 114, 131, 135, 153, 171, 189, 209, 229, + 251, 273, 297, 321, 345, 354, 381, 407, 436, 464, 493, 523, 554, 586, 619, + 634, 666, 702, 738, 774, 812, 849, 888, 929, 946, 987, 1028, 1071, 1115, + 1160, 1204, 1251, 1271, 1317, 1368, 1416, 1465, 1517, 1569, 1621, 1674, + 1697, 1752, 1807, 1864, 1920, 1979, 2037, 2096, 2124, 2184, 2245, 2309, + 2372, 2436, 2501, 2568, 2633, 2663, 2732, 2800, 2870, 2940, 3011, + 3083, 3156, 3190, 3264 +}; + +static const unsigned short int hx_data_codewords_L2[] = { + 17, 25, 34, 38, 49, 58, 70, 81, 96, 109, 113, 127, 143, 157, 175, 191, 209, + 227, 247, 267, 287, 296, 317, 339, 362, 386, 411, 437, 462, 488, 515, 528, + 556, 586, 614, 646, 676, 707, 740, 773, 788, 823, 856, 893, 929, 966, 1004, + 1043, 1059, 1099, 1140, 1180, 1221, 1263, 1307, 1351, 1394, 1415, 1460, + 1505, 1552, 1600, 1649, 1697, 1748, 1770, 1820, 1871, 1925, 1976, 2030, + 2083, 2140, 2195, 2219, 2276, 2334, 2392, 2450, 2509, 2569, 2630, 2658, + 2720 +}; + +static const unsigned short int hx_data_codewords_L3[] = { + 13, 19, 26, 30, 37, 46, 54, 63, 74, 83, 87, 97, 109, 121, 135, 147, 161, + 175, 191, 205, 221, 228, 245, 261, 280, 298, 317, 337, 358, 376, 397, 408, + 428, 452, 474, 498, 522, 545, 572, 597, 608, 635, 660, 689, 717, 746, 774, + 805, 817, 847, 880, 910, 943, 975, 1009, 1041, 1076, 1091, 1126, 1161, 1198, + 1234, 1271, 1309, 1348, 1366, 1404, 1443, 1485, 1524, 1566, 1607, 1650, 1693, + 1713, 1756, 1800, 1844, 1890, 1935, 1983, 2030, 2050, 2098 +}; + +static const unsigned short int hx_data_codewords_L4[] = { + 9, 15, 20, 22, 27, 34, 40, 47, 54, 61, 65, 73, 81, 89, 99, 109, 119, 129, + 141, 153, 165, 168, 181, 195, 208, 220, 235, 251, 264, 280, 295, 302, 318, + 334, 352, 368, 386, 405, 424, 441, 450, 469, 490, 509, 531, 552, 574, 595, 605, + 627, 652, 674, 697, 721, 747, 771, 796, 809, 834, 861, 892, 914, 941, 969, 998, + 1012, 1040, 1069, 1099, 1130, 1160, 1191, 1222, 1253, 1269, 1300, 1334, + 1366, 1400, 1433, 1469, 1504, 1520, 1554 +}; + +/* Value 'k' from Annex A */ +static const char hx_module_k[] = { + 0, 0, 0, 14, 16, 16, 17, 18, 19, 20, + 14, 15, 16, 16, 17, 17, 18, 19, 20, 20, + 21, 16, 17, 17, 18, 18, 19, 19, 20, 20, + 21, 17, 17, 18, 18, 19, 19, 19, 20, 20, + 17, 17, 18, 18, 18, 19, 19, 19, 17, 17, + 18, 18, 18, 18, 19, 19, 19, 17, 17, 18, + 18, 18, 18, 19, 19, 17, 17, 17, 18, 18, + 18, 18, 19, 19, 17, 17, 17, 18, 18, 18, + 18, 18, 17, 17 +}; + +/* Value 'r' from Annex A */ +static const char hx_module_r[] = { + 0, 0, 0, 15, 15, 17, 18, 19, 20, 21, + 15, 15, 15, 17, 17, 19, 19, 19, 19, 21, + 21, 17, 16, 18, 17, 19, 18, 20, 19, 21, + 20, 17, 19, 17, 19, 17, 19, 21, 19, 21, + 18, 20, 17, 19, 21, 18, 20, 22, 17, 19, + 15, 17, 19, 21, 17, 19, 21, 18, 20, 15, + 17, 19, 21, 16, 18, 17, 19, 21, 15, 17, + 19, 21, 15, 17, 18, 20, 22, 15, 17, 19, + 21, 23, 17, 19 +}; + +/* Value of 'm' from Annex A */ +static const char hx_module_m[] = { + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 10, 10 +}; + +/* Error correction block sizes from Table D1 */ +static const unsigned short int hx_table_d1[] = { + /* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */ + 1, 21, 4, 0, 0, 0, 0, 0, 0, // version 1 + 1, 17, 8, 0, 0, 0, 0, 0, 0, + 1, 13, 12, 0, 0, 0, 0, 0, 0, + 1, 9, 16, 0, 0, 0, 0, 0, 0, + 1, 31, 6, 0, 0, 0, 0, 0, 0, // version 2 + 1, 25, 12, 0, 0, 0, 0, 0, 0, + 1, 19, 18, 0, 0, 0, 0, 0, 0, + 1, 15, 22, 0, 0, 0, 0, 0, 0, + 1, 42, 8, 0, 0, 0, 0, 0, 0, // version 3 + 1, 34, 16, 0, 0, 0, 0, 0, 0, + 1, 26, 24, 0, 0, 0, 0, 0, 0, + 1, 20, 30, 0, 0, 0, 0, 0, 0, + 1, 46, 8, 0, 0, 0, 0, 0, 0, // version 4 + 1, 38, 16, 0, 0, 0, 0, 0, 0, + 1, 30, 24, 0, 0, 0, 0, 0, 0, + 1, 22, 32, 0, 0, 0, 0, 0, 0, + 1, 57, 12, 0, 0, 0, 0, 0, 0, // version 5 + 1, 49, 20, 0, 0, 0, 0, 0, 0, + 1, 37, 32, 0, 0, 0, 0, 0, 0, + 1, 14, 20, 1, 13, 22, 0, 0, 0, + 1, 70, 14, 0, 0, 0, 0, 0, 0, // version 6 + 1, 58, 26, 0, 0, 0, 0, 0, 0, + 1, 24, 20, 1, 22, 18, 0, 0, 0, + 1, 16, 24, 1, 18, 26, 0, 0, 0, + 1, 84, 16, 0, 0, 0, 0, 0, 0, // version 7 + 1, 70, 30, 0, 0, 0, 0, 0, 0, + 1, 26, 22, 1, 28, 24, 0, 0, 0, + 2, 14, 20, 1, 12, 20, 0, 0, 0, + 1, 99, 18, 0, 0, 0, 0, 0, 0, // version 8 + 1, 40, 18, 1, 41, 18, 0, 0, 0, + 1, 31, 26, 1, 32, 28, 0, 0, 0, + 2, 16, 24, 1, 15, 22, 0, 0, 0, + 1, 114, 22, 0, 0, 0, 0, 0, 0, // version 9 + 2, 48, 20, 0, 0, 0, 0, 0, 0, + 2, 24, 20, 1, 26, 22, 0, 0, 0, + 2, 18, 28, 1, 18, 26, 0, 0, 0, + 1, 131, 24, 0, 0, 0, 0, 0, 0, // version 10 + 1, 52, 22, 1, 57, 24, 0, 0, 0, + 2, 27, 24, 1, 29, 24, 0, 0, 0, + 2, 21, 32, 1, 19, 30, 0, 0, 0, + 1, 135, 26, 0, 0, 0, 0, 0, 0, // version 11 + 1, 56, 24, 1, 57, 24, 0, 0, 0, + 2, 28, 24, 1, 31, 26, 0, 0, 0, + 2, 22, 32, 1, 21, 32, 0, 0, 0, + 1, 153, 28, 0, 0, 0, 0, 0, 0, // version 12 + 1, 62, 26, 1, 65, 28, 0, 0, 0, + 2, 32, 28, 1, 33, 28, 0, 0, 0, + 3, 17, 26, 1, 22, 30, 0, 0, 0, + 1, 86, 16, 1, 85, 16, 0, 0, 0, // version 13 + 1, 71, 30, 1, 72, 30, 0, 0, 0, + 2, 37, 32, 1, 35, 30, 0, 0, 0, + 3, 20, 30, 1, 21, 32, 0, 0, 0, + 1, 94, 18, 1, 95, 18, 0, 0, 0, // version 14 + 2, 51, 22, 1, 55, 24, 0, 0, 0, + 3, 30, 26, 1, 31, 26, 0, 0, 0, + 4, 18, 28, 1, 17, 24, 0, 0, 0, + 1, 104, 20, 1, 105, 20, 0, 0, 0, // version 15 + 2, 57, 24, 1, 61, 26, 0, 0, 0, + 3, 33, 28, 1, 36, 30, 0, 0, 0, + 4, 20, 30, 1, 19, 30, 0, 0, 0, + 1, 115, 22, 1, 114, 22, 0, 0, 0, // version 16 + 2, 65, 28, 1, 61, 26, 0, 0, 0, + 3, 38, 32, 1, 33, 30, 0, 0, 0, + 5, 19, 28, 1, 14, 24, 0, 0, 0, + 1, 126, 24, 1, 125, 24, 0, 0, 0, // version 17 + 2, 70, 30, 1, 69, 30, 0, 0, 0, + 4, 33, 28, 1, 29, 26, 0, 0, 0, + 5, 20, 30, 1, 19, 30, 0, 0, 0, + 1, 136, 26, 1, 137, 26, 0, 0, 0, //version 18 + 3, 56, 24, 1, 59, 26, 0, 0, 0, + 5, 35, 30, 0, 0, 0, 0, 0, 0, + 6, 18, 28, 1, 21, 28, 0, 0, 0, + 1, 148, 28, 1, 149, 28, 0, 0, 0, // version 19 + 3, 61, 26, 1, 64, 28, 0, 0, 0, + 7, 24, 20, 1, 23, 22, 0, 0, 0, + 6, 20, 30, 1, 21, 32, 0, 0, 0, + 3, 107, 20, 0, 0, 0, 0, 0, 0, // version 20 + 3, 65, 28, 1, 72, 30, 0, 0, 0, + 7, 26, 22, 1, 23, 22, 0, 0, 0, + 7, 19, 28, 1, 20, 32, 0, 0, 0, + 3, 115, 22, 0, 0, 0, 0, 0, 0, // version 21 + 4, 56, 24, 1, 63, 28, 0, 0, 0, + 7, 28, 24, 1, 25, 22, 0, 0, 0, + 8, 18, 28, 1, 21, 22, 0, 0, 0, + 2, 116, 22, 1, 122, 24, 0, 0, 0, // version 22 + 4, 56, 24, 1, 72, 30, 0, 0, 0, + 7, 28, 24, 1, 32, 26, 0, 0, 0, + 8, 18, 28, 1, 24, 30, 0, 0, 0, + 3, 127, 24, 0, 0, 0, 0, 0, 0, // version 23 + 5, 51, 22, 1, 62, 26, 0, 0, 0, + 7, 30, 26, 1, 35, 26, 0, 0, 0, + 8, 20, 30, 1, 21, 32, 0, 0, 0, + 2, 135, 26, 1, 137, 26, 0, 0, 0, // version 24 + 5, 56, 24, 1, 59, 26, 0, 0, 0, + 7, 33, 28, 1, 30, 28, 0, 0, 0, + 11, 16, 24, 1, 19, 26, 0, 0, 0, + 3, 105, 20, 1, 121, 22, 0, 0, 0, // version 25 + 5, 61, 26, 1, 57, 26, 0, 0, 0, + 9, 28, 24, 1, 28, 22, 0, 0, 0, + 10, 19, 28, 1, 18, 30, 0, 0, 0, + 2, 157, 30, 1, 150, 28, 0, 0, 0, // version 26 + 5, 65, 28, 1, 61, 26, 0, 0, 0, + 8, 33, 28, 1, 34, 30, 0, 0, 0, + 10, 19, 28, 2, 15, 26, 0, 0, 0, + 3, 126, 24, 1, 115, 22, 0, 0, 0, // version 27 + 7, 51, 22, 1, 54, 22, 0, 0, 0, + 8, 35, 30, 1, 37, 30, 0, 0, 0, + 15, 15, 22, 1, 10, 22, 0, 0, 0, + 4, 105, 20, 1, 103, 20, 0, 0, 0, // version 28 + 7, 56, 24, 1, 45, 18, 0, 0, 0, + 10, 31, 26, 1, 27, 26, 0, 0, 0, + 10, 17, 26, 3, 20, 28, 1, 21, 28, + 3, 139, 26, 1, 137, 28, 0, 0, 0, // version 29 + 6, 66, 28, 1, 66, 30, 0, 0, 0, + 9, 36, 30, 1, 34, 32, 0, 0, 0, + 13, 19, 28, 1, 17, 32, 0, 0, 0, + 6, 84, 16, 1, 82, 16, 0, 0, 0, // version 30 + 6, 70, 30, 1, 68, 30, 0, 0, 0, + 7, 35, 30, 3, 33, 28, 1, 32, 28, + 13, 20, 30, 1, 20, 28, 0, 0, 0, + 5, 105, 20, 1, 94, 18, 0, 0, 0, // version 31 + 6, 74, 32, 1, 71, 30, 0, 0, 0, + 11, 33, 28, 1, 34, 32, 0, 0, 0, + 13, 19, 28, 3, 16, 26, 0, 0, 0, + 4, 127, 24, 1, 126, 24, 0, 0, 0, // version 32 + 7, 66, 28, 1, 66, 30, 0, 0, 0, + 12, 30, 24, 1, 24, 28, 1, 24, 30, + 15, 19, 28, 1, 17, 32, 0, 0, 0, + 7, 84, 16, 1, 78, 16, 0, 0, 0, // version 33 + 7, 70, 30, 1, 66, 28, 0, 0, 0, + 12, 33, 28, 1, 32, 30, 0, 0, 0, + 14, 21, 32, 1, 24, 28, 0, 0, 0, + 5, 117, 22, 1, 117, 24, 0, 0, 0, // version 34 + 8, 66, 28, 1, 58, 26, 0, 0, 0, + 11, 38, 32, 1, 34, 32, 0, 0, 0, + 15, 20, 30, 2, 17, 26, 0, 0, 0, + 4, 148, 28, 1, 146, 28, 0, 0, 0, // version 35 + 8, 68, 30, 1, 70, 24, 0, 0, 0, + 10, 36, 32, 3, 38, 28, 0, 0, 0, + 16, 19, 28, 3, 16, 26, 0, 0, 0, + 4, 126, 24, 2, 135, 26, 0, 0, 0, // version 36 + 8, 70, 28, 2, 43, 26, 0, 0, 0, + 13, 32, 28, 2, 41, 30, 0, 0, 0, + 17, 19, 28, 3, 15, 26, 0, 0, 0, + 5, 136, 26, 1, 132, 24, 0, 0, 0, // version 37 + 5, 67, 30, 4, 68, 28, 1, 69, 28, + 14, 35, 30, 1, 32, 24, 0, 0, 0, + 18, 18, 26, 3, 16, 28, 1, 14, 28, + 3, 142, 26, 3, 141, 28, 0, 0, 0, // version 38 + 8, 70, 30, 1, 73, 32, 1, 74, 32, + 12, 34, 30, 3, 34, 26, 1, 35, 28, + 18, 21, 32, 1, 27, 30, 0, 0, 0, + 5, 116, 22, 2, 103, 20, 1, 102, 20, // version 39 + 9, 74, 32, 1, 74, 30, 0, 0, 0, + 14, 34, 28, 2, 32, 32, 1, 32, 30, + 19, 21, 32, 1, 25, 26, 0, 0, 0, + 7, 116, 22, 1, 117, 22, 0, 0, 0, // version 40 + 11, 65, 28, 1, 58, 24, 0, 0, 0, + 15, 38, 32, 1, 27, 28, 0, 0, 0, + 20, 20, 30, 1, 20, 32, 1, 21, 32, + 6, 136, 26, 1, 130, 24, 0, 0, 0, // version 41 + 11, 66, 28, 1, 62, 30, 0, 0, 0, + 14, 34, 28, 3, 34, 32, 1, 30, 30, + 18, 20, 30, 3, 20, 28, 2, 15, 26, + 5, 105, 20, 2, 115, 22, 2, 116, 22, // version 42 + 10, 75, 32, 1, 73, 32, 0, 0, 0, + 16, 38, 32, 1, 27, 28, 0, 0, 0, + 22, 19, 28, 2, 16, 30, 1, 19, 30, + 6, 147, 28, 1, 146, 28, 0, 0, 0, // version 43 + 11, 66, 28, 2, 65, 30, 0, 0, 0, + 18, 33, 28, 2, 33, 30, 0, 0, 0, + 22, 21, 32, 1, 28, 30, 0, 0, 0, + 6, 116, 22, 3, 125, 24, 0, 0, 0, // version 44 + 11, 75, 32, 1, 68, 30, 0, 0, 0, + 13, 35, 28, 6, 34, 32, 1, 30, 30, + 23, 21, 32, 1, 26, 30, 0, 0, 0, + 7, 105, 20, 4, 95, 18, 0, 0, 0, // version 45 + 12, 67, 28, 1, 63, 30, 1, 62, 32, + 21, 31, 26, 2, 33, 32, 0, 0, 0, + 23, 21, 32, 2, 24, 30, 0, 0, 0, + 10, 116, 22, 0, 0, 0, 0, 0, 0, // version 46 + 12, 74, 32, 1, 78, 30, 0, 0, 0, + 18, 37, 32, 1, 39, 30, 1, 41, 28, + 25, 21, 32, 1, 27, 28, 0, 0, 0, + 5, 126, 24, 4, 115, 22, 1, 114, 22, // version 47 + 12, 67, 28, 2, 66, 32, 1, 68, 30, + 21, 35, 30, 1, 39, 30, 0, 0, 0, + 26, 21, 32, 1, 28, 28, 0, 0, 0, + 9, 126, 24, 1, 117, 22, 0, 0, 0, // version 48 + 13, 75, 32, 1, 68, 30, 0, 0, 0, + 20, 35, 30, 3, 35, 28, 0, 0, 0, + 27, 21, 32, 1, 28, 30, 0, 0, 0, + 9, 126, 24, 1, 137, 26, 0, 0, 0, // version 49 + 13, 71, 30, 2, 68, 32, 0, 0, 0, + 20, 37, 32, 1, 39, 28, 1, 38, 28, + 24, 20, 32, 5, 25, 28, 0, 0, 0, + 8, 147, 28, 1, 141, 28, 0, 0, 0, // version 50 + 10, 73, 32, 4, 74, 30, 1, 73, 30, + 16, 36, 32, 6, 39, 30, 1, 37, 30, + 27, 21, 32, 3, 20, 26, 0, 0, 0, + 9, 137, 26, 1, 135, 26, 0, 0, 0, // version 51 + 12, 70, 30, 4, 75, 32, 0, 0, 0, + 24, 35, 30, 1, 40, 28, 0, 0, 0, + 23, 20, 32, 8, 24, 30, 0, 0, 0, + 14, 95, 18, 1, 86, 18, 0, 0, 0, // version 52 + 13, 73, 32, 3, 77, 30, 0, 0, 0, + 24, 35, 30, 2, 35, 28, 0, 0, 0, + 26, 21, 32, 5, 21, 30, 1, 23, 30, + 9, 147, 28, 1, 142, 28, 0, 0, 0, // version 53 + 10, 73, 30, 6, 70, 32, 1, 71, 32, + 25, 35, 30, 2, 34, 26, 0, 0, 0, + 29, 21, 32, 4, 22, 30, 0, 0, 0, + 11, 126, 24, 1, 131, 24, 0, 0, 0, // version 54 + 16, 74, 32, 1, 79, 30, 0, 0, 0, + 25, 38, 32, 1, 25, 30, 0, 0, 0, + 33, 21, 32, 1, 28, 28, 0, 0, 0, + 14, 105, 20, 1, 99, 18, 0, 0, 0, // version 55 + 19, 65, 28, 1, 72, 28, 0, 0, 0, + 24, 37, 32, 2, 40, 30, 1, 41, 30, + 31, 21, 32, 4, 24, 32, 0, 0, 0, + 10, 147, 28, 1, 151, 28, 0, 0, 0, // version 56 + 15, 71, 30, 3, 71, 32, 1, 73, 32, + 24, 37, 32, 3, 38, 30, 1, 39, 30, + 36, 19, 30, 3, 29, 26, 0, 0, 0, + 15, 105, 20, 1, 99, 18, 0, 0, 0, // version 57 + 19, 70, 30, 1, 64, 28, 0, 0, 0, + 27, 38, 32, 2, 25, 26, 0, 0, 0, + 38, 20, 30, 2, 18, 28, 0, 0, 0, + 14, 105, 20, 1, 113, 22, 1, 114, 22, // version 58 + 17, 67, 30, 3, 92, 32, 0, 0, 0, + 30, 35, 30, 1, 41, 30, 0, 0, 0, + 36, 21, 32, 1, 26, 30, 1, 27, 30, + 11, 146, 28, 1, 146, 26, 0, 0, 0, // version 59 + 20, 70, 30, 1, 60, 26, 0, 0, 0, + 29, 38, 32, 1, 24, 32, 0, 0, 0, + 40, 20, 30, 2, 17, 26, 0, 0, 0, + 3, 137, 26, 1, 136, 26, 10, 126, 24, // version 60 + 22, 65, 28, 1, 75, 30, 0, 0, 0, + 30, 37, 32, 1, 51, 30, 0, 0, 0, + 42, 20, 30, 1, 21, 30, 0, 0, 0, + 12, 126, 24, 2, 118, 22, 1, 116, 22, // version 61 + 19, 74, 32, 1, 74, 30, 1, 72, 28, + 30, 38, 32, 2, 29, 30, 0, 0, 0, + 39, 20, 32, 2, 37, 26, 1, 38, 26, + 12, 126, 24, 3, 136, 26, 0, 0, 0, // version 62 + 21, 70, 30, 2, 65, 28, 0, 0, 0, + 34, 35, 30, 1, 44, 32, 0, 0, 0, + 42, 20, 30, 2, 19, 28, 2, 18, 28, + 12, 126, 24, 3, 117, 22, 1, 116, 22, // version 63 + 25, 61, 26, 2, 62, 28, 0, 0, 0, + 34, 35, 30, 1, 40, 32, 1, 41, 32, + 45, 20, 30, 1, 20, 32, 1, 21, 32, + 15, 105, 20, 2, 115, 22, 2, 116, 22, // version 64 + 25, 65, 28, 1, 72, 28, 0, 0, 0, + 18, 35, 30, 17, 37, 32, 1, 50, 32, + 42, 20, 30, 6, 19, 28, 1, 15, 28, + 19, 105, 20, 1, 101, 20, 0, 0, 0, // version 65 + 33, 51, 22, 1, 65, 22, 0, 0, 0, + 40, 33, 28, 1, 28, 28, 0, 0, 0, + 49, 20, 30, 1, 18, 28, 0, 0, 0, + 18, 105, 20, 2, 117, 22, 0, 0, 0, // version 66 + 26, 65, 28, 1, 80, 30, 0, 0, 0, + 35, 35, 30, 3, 35, 28, 1, 36, 28, + 52, 18, 28, 2, 38, 30, 0, 0, 0, + 26, 84, 16, 0, 0, 0, 0, 0, 0, // version 67 + 26, 70, 30, 0, 0, 0, 0, 0, 0, + 45, 31, 26, 1, 9, 26, 0, 0, 0, + 52, 20, 30, 0, 0, 0, 0, 0, 0, + 16, 126, 24, 1, 114, 22, 1, 115, 22, // version 68 + 23, 70, 30, 3, 65, 28, 1, 66, 28, + 40, 35, 30, 1, 43, 30, 0, 0, 0, + 46, 20, 30, 7, 19, 28, 1, 16, 28, + 19, 116, 22, 1, 105, 22, 0, 0, 0, // version 69 + 20, 70, 30, 7, 66, 28, 1, 63, 28, + 40, 35, 30, 1, 42, 32, 1, 43, 32, + 54, 20, 30, 1, 19, 30, 0, 0, 0, + 17, 126, 24, 2, 115, 22, 0, 0, 0, // version 70 + 24, 70, 30, 4, 74, 32, 0, 0, 0, + 48, 31, 26, 2, 18, 26, 0, 0, 0, + 54, 19, 28, 6, 15, 26, 1, 14, 26, + 29, 84, 16, 0, 0, 0, 0, 0, 0, // version 71 + 29, 70, 30, 0, 0, 0, 0, 0, 0, + 6, 34, 30, 3, 36, 30, 38, 33, 28, + 58, 20, 30, 0, 0, 0, 0, 0, 0, + 16, 147, 28, 1, 149, 28, 0, 0, 0, // version 72 + 31, 66, 28, 1, 37, 26, 0, 0, 0, + 48, 33, 28, 1, 23, 26, 0, 0, 0, + 53, 20, 30, 6, 19, 28, 1, 17, 28, + 20, 115, 22, 2, 134, 24, 0, 0, 0, // verdion 73 + 29, 66, 28, 2, 56, 26, 2, 57, 26, + 45, 36, 30, 2, 15, 28, 0, 0, 0, + 59, 20, 30, 2, 21, 32, 0, 0, 0, + 17, 147, 28, 1, 134, 26, 0, 0, 0, // version 74 + 26, 70, 30, 5, 75, 32, 0, 0, 0, + 47, 35, 30, 1, 48, 32, 0, 0, 0, + 64, 18, 28, 2, 33, 30, 1, 35, 30, + 22, 115, 22, 1, 133, 24, 0, 0, 0, // version 75 + 33, 65, 28, 1, 74, 28, 0, 0, 0, + 43, 36, 30, 5, 27, 28, 1, 30, 28, + 57, 20, 30, 5, 21, 32, 1, 24, 32, + 18, 136, 26, 2, 142, 26, 0, 0, 0, // version 76 + 33, 66, 28, 2, 49, 26, 0, 0, 0, + 48, 35, 30, 2, 38, 28, 0, 0, 0, + 64, 20, 30, 1, 20, 32, 0, 0, 0, + 19, 126, 24, 2, 135, 26, 1, 136, 26, // version 77 + 32, 66, 28, 2, 55, 26, 2, 56, 26, + 49, 36, 30, 2, 18, 32, 0, 0, 0, + 65, 18, 28, 5, 27, 30, 1, 29, 30, + 20, 137, 26, 1, 130, 26, 0, 0, 0, // version 78 + 30, 75, 32, 2, 71, 32, 0, 0, 0, + 46, 35, 30, 6, 39, 32, 0, 0, 0, + 3, 12, 30, 70, 19, 28, 0, 0, 0, + 20, 147, 28, 0, 0, 0, 0, 0, 0, // version 79 + 35, 70, 30, 0, 0, 0, 0, 0, 0, + 49, 35, 30, 5, 35, 28, 0, 0, 0, + 70, 20, 30, 0, 0, 0, 0, 0, 0, + 21, 136, 26, 1, 155, 28, 0, 0, 0, // version 80 + 34, 70, 30, 1, 64, 28, 1, 65, 28, + 54, 35, 30, 1, 45, 30, 0, 0, 0, + 68, 20, 30, 3, 18, 28, 1, 19, 28, + 19, 126, 24, 5, 115, 22, 1, 114, 22, // version 81 + 33, 70, 30, 3, 65, 28, 1, 64, 28, + 52, 35, 30, 3, 41, 32, 1, 40, 32, + 67, 20, 30, 5, 21, 32, 1, 24, 32, + 2, 150, 28, 21, 136, 26, 0, 0, 0, // version 82 + 32, 70, 30, 6, 65, 28, 0, 0, 0, + 52, 38, 32, 2, 27, 32, 0, 0, 0, + 73, 20, 30, 2, 22, 32, 0, 0, 0, + 21, 126, 24, 4, 136, 26, 0, 0, 0, // version 83 + 30, 74, 32, 6, 73, 30, 0, 0, 0, + 54, 35, 30, 4, 40, 32, 0, 0, 0, + 75, 20, 30, 1, 20, 28, 0, 0, 0, + 30, 105, 20, 1, 114, 22, 0, 0, 0, // version 84 + 3, 45, 22, 55, 47, 20, 0, 0, 0, + 2, 26, 26, 62, 33, 28, 0, 0, 0, + 79, 18, 28, 4, 33, 30, 0, 0, 0 +}; \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/imail.c b/3rdparty/zint-2.6.1/backend/imail.c new file mode 100644 index 0000000..5489282 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/imail.c @@ -0,0 +1,605 @@ +/* imail.c - Handles Intelligent Mail (aka OneCode) for USPS */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence" + is Copyright (C) 2006 United States Postal Service */ + +#include +#include +#include +#include "common.h" +#include "large.h" + +#define SODIUM "0123456789-" + +/* The following lookup tables were generated using the code in Appendix C */ + +static const unsigned short AppxD_I[1287] = { + /* Appendix D Table 1 - 5 of 13 characters */ + 0x001F, 0x1F00, 0x002F, 0x1E80, 0x0037, 0x1D80, 0x003B, 0x1B80, 0x003D, 0x1780, + 0x003E, 0x0F80, 0x004F, 0x1E40, 0x0057, 0x1D40, 0x005B, 0x1B40, 0x005D, 0x1740, + 0x005E, 0x0F40, 0x0067, 0x1CC0, 0x006B, 0x1AC0, 0x006D, 0x16C0, 0x006E, 0x0EC0, + 0x0073, 0x19C0, 0x0075, 0x15C0, 0x0076, 0x0DC0, 0x0079, 0x13C0, 0x007A, 0x0BC0, + 0x007C, 0x07C0, 0x008F, 0x1E20, 0x0097, 0x1D20, 0x009B, 0x1B20, 0x009D, 0x1720, + 0x009E, 0x0F20, 0x00A7, 0x1CA0, 0x00AB, 0x1AA0, 0x00AD, 0x16A0, 0x00AE, 0x0EA0, + 0x00B3, 0x19A0, 0x00B5, 0x15A0, 0x00B6, 0x0DA0, 0x00B9, 0x13A0, 0x00BA, 0x0BA0, + 0x00BC, 0x07A0, 0x00C7, 0x1C60, 0x00CB, 0x1A60, 0x00CD, 0x1660, 0x00CE, 0x0E60, + 0x00D3, 0x1960, 0x00D5, 0x1560, 0x00D6, 0x0D60, 0x00D9, 0x1360, 0x00DA, 0x0B60, + 0x00DC, 0x0760, 0x00E3, 0x18E0, 0x00E5, 0x14E0, 0x00E6, 0x0CE0, 0x00E9, 0x12E0, + 0x00EA, 0x0AE0, 0x00EC, 0x06E0, 0x00F1, 0x11E0, 0x00F2, 0x09E0, 0x00F4, 0x05E0, + 0x00F8, 0x03E0, 0x010F, 0x1E10, 0x0117, 0x1D10, 0x011B, 0x1B10, 0x011D, 0x1710, + 0x011E, 0x0F10, 0x0127, 0x1C90, 0x012B, 0x1A90, 0x012D, 0x1690, 0x012E, 0x0E90, + 0x0133, 0x1990, 0x0135, 0x1590, 0x0136, 0x0D90, 0x0139, 0x1390, 0x013A, 0x0B90, + 0x013C, 0x0790, 0x0147, 0x1C50, 0x014B, 0x1A50, 0x014D, 0x1650, 0x014E, 0x0E50, + 0x0153, 0x1950, 0x0155, 0x1550, 0x0156, 0x0D50, 0x0159, 0x1350, 0x015A, 0x0B50, + 0x015C, 0x0750, 0x0163, 0x18D0, 0x0165, 0x14D0, 0x0166, 0x0CD0, 0x0169, 0x12D0, + 0x016A, 0x0AD0, 0x016C, 0x06D0, 0x0171, 0x11D0, 0x0172, 0x09D0, 0x0174, 0x05D0, + 0x0178, 0x03D0, 0x0187, 0x1C30, 0x018B, 0x1A30, 0x018D, 0x1630, 0x018E, 0x0E30, + 0x0193, 0x1930, 0x0195, 0x1530, 0x0196, 0x0D30, 0x0199, 0x1330, 0x019A, 0x0B30, + 0x019C, 0x0730, 0x01A3, 0x18B0, 0x01A5, 0x14B0, 0x01A6, 0x0CB0, 0x01A9, 0x12B0, + 0x01AA, 0x0AB0, 0x01AC, 0x06B0, 0x01B1, 0x11B0, 0x01B2, 0x09B0, 0x01B4, 0x05B0, + 0x01B8, 0x03B0, 0x01C3, 0x1870, 0x01C5, 0x1470, 0x01C6, 0x0C70, 0x01C9, 0x1270, + 0x01CA, 0x0A70, 0x01CC, 0x0670, 0x01D1, 0x1170, 0x01D2, 0x0970, 0x01D4, 0x0570, + 0x01D8, 0x0370, 0x01E1, 0x10F0, 0x01E2, 0x08F0, 0x01E4, 0x04F0, 0x01E8, 0x02F0, + 0x020F, 0x1E08, 0x0217, 0x1D08, 0x021B, 0x1B08, 0x021D, 0x1708, 0x021E, 0x0F08, + 0x0227, 0x1C88, 0x022B, 0x1A88, 0x022D, 0x1688, 0x022E, 0x0E88, 0x0233, 0x1988, + 0x0235, 0x1588, 0x0236, 0x0D88, 0x0239, 0x1388, 0x023A, 0x0B88, 0x023C, 0x0788, + 0x0247, 0x1C48, 0x024B, 0x1A48, 0x024D, 0x1648, 0x024E, 0x0E48, 0x0253, 0x1948, + 0x0255, 0x1548, 0x0256, 0x0D48, 0x0259, 0x1348, 0x025A, 0x0B48, 0x025C, 0x0748, + 0x0263, 0x18C8, 0x0265, 0x14C8, 0x0266, 0x0CC8, 0x0269, 0x12C8, 0x026A, 0x0AC8, + 0x026C, 0x06C8, 0x0271, 0x11C8, 0x0272, 0x09C8, 0x0274, 0x05C8, 0x0278, 0x03C8, + 0x0287, 0x1C28, 0x028B, 0x1A28, 0x028D, 0x1628, 0x028E, 0x0E28, 0x0293, 0x1928, + 0x0295, 0x1528, 0x0296, 0x0D28, 0x0299, 0x1328, 0x029A, 0x0B28, 0x029C, 0x0728, + 0x02A3, 0x18A8, 0x02A5, 0x14A8, 0x02A6, 0x0CA8, 0x02A9, 0x12A8, 0x02AA, 0x0AA8, + 0x02AC, 0x06A8, 0x02B1, 0x11A8, 0x02B2, 0x09A8, 0x02B4, 0x05A8, 0x02B8, 0x03A8, + 0x02C3, 0x1868, 0x02C5, 0x1468, 0x02C6, 0x0C68, 0x02C9, 0x1268, 0x02CA, 0x0A68, + 0x02CC, 0x0668, 0x02D1, 0x1168, 0x02D2, 0x0968, 0x02D4, 0x0568, 0x02D8, 0x0368, + 0x02E1, 0x10E8, 0x02E2, 0x08E8, 0x02E4, 0x04E8, 0x0307, 0x1C18, 0x030B, 0x1A18, + 0x030D, 0x1618, 0x030E, 0x0E18, 0x0313, 0x1918, 0x0315, 0x1518, 0x0316, 0x0D18, + 0x0319, 0x1318, 0x031A, 0x0B18, 0x031C, 0x0718, 0x0323, 0x1898, 0x0325, 0x1498, + 0x0326, 0x0C98, 0x0329, 0x1298, 0x032A, 0x0A98, 0x032C, 0x0698, 0x0331, 0x1198, + 0x0332, 0x0998, 0x0334, 0x0598, 0x0338, 0x0398, 0x0343, 0x1858, 0x0345, 0x1458, + 0x0346, 0x0C58, 0x0349, 0x1258, 0x034A, 0x0A58, 0x034C, 0x0658, 0x0351, 0x1158, + 0x0352, 0x0958, 0x0354, 0x0558, 0x0361, 0x10D8, 0x0362, 0x08D8, 0x0364, 0x04D8, + 0x0383, 0x1838, 0x0385, 0x1438, 0x0386, 0x0C38, 0x0389, 0x1238, 0x038A, 0x0A38, + 0x038C, 0x0638, 0x0391, 0x1138, 0x0392, 0x0938, 0x0394, 0x0538, 0x03A1, 0x10B8, + 0x03A2, 0x08B8, 0x03A4, 0x04B8, 0x03C1, 0x1078, 0x03C2, 0x0878, 0x03C4, 0x0478, + 0x040F, 0x1E04, 0x0417, 0x1D04, 0x041B, 0x1B04, 0x041D, 0x1704, 0x041E, 0x0F04, + 0x0427, 0x1C84, 0x042B, 0x1A84, 0x042D, 0x1684, 0x042E, 0x0E84, 0x0433, 0x1984, + 0x0435, 0x1584, 0x0436, 0x0D84, 0x0439, 0x1384, 0x043A, 0x0B84, 0x043C, 0x0784, + 0x0447, 0x1C44, 0x044B, 0x1A44, 0x044D, 0x1644, 0x044E, 0x0E44, 0x0453, 0x1944, + 0x0455, 0x1544, 0x0456, 0x0D44, 0x0459, 0x1344, 0x045A, 0x0B44, 0x045C, 0x0744, + 0x0463, 0x18C4, 0x0465, 0x14C4, 0x0466, 0x0CC4, 0x0469, 0x12C4, 0x046A, 0x0AC4, + 0x046C, 0x06C4, 0x0471, 0x11C4, 0x0472, 0x09C4, 0x0474, 0x05C4, 0x0487, 0x1C24, + 0x048B, 0x1A24, 0x048D, 0x1624, 0x048E, 0x0E24, 0x0493, 0x1924, 0x0495, 0x1524, + 0x0496, 0x0D24, 0x0499, 0x1324, 0x049A, 0x0B24, 0x049C, 0x0724, 0x04A3, 0x18A4, + 0x04A5, 0x14A4, 0x04A6, 0x0CA4, 0x04A9, 0x12A4, 0x04AA, 0x0AA4, 0x04AC, 0x06A4, + 0x04B1, 0x11A4, 0x04B2, 0x09A4, 0x04B4, 0x05A4, 0x04C3, 0x1864, 0x04C5, 0x1464, + 0x04C6, 0x0C64, 0x04C9, 0x1264, 0x04CA, 0x0A64, 0x04CC, 0x0664, 0x04D1, 0x1164, + 0x04D2, 0x0964, 0x04D4, 0x0564, 0x04E1, 0x10E4, 0x04E2, 0x08E4, 0x0507, 0x1C14, + 0x050B, 0x1A14, 0x050D, 0x1614, 0x050E, 0x0E14, 0x0513, 0x1914, 0x0515, 0x1514, + 0x0516, 0x0D14, 0x0519, 0x1314, 0x051A, 0x0B14, 0x051C, 0x0714, 0x0523, 0x1894, + 0x0525, 0x1494, 0x0526, 0x0C94, 0x0529, 0x1294, 0x052A, 0x0A94, 0x052C, 0x0694, + 0x0531, 0x1194, 0x0532, 0x0994, 0x0534, 0x0594, 0x0543, 0x1854, 0x0545, 0x1454, + 0x0546, 0x0C54, 0x0549, 0x1254, 0x054A, 0x0A54, 0x054C, 0x0654, 0x0551, 0x1154, + 0x0552, 0x0954, 0x0561, 0x10D4, 0x0562, 0x08D4, 0x0583, 0x1834, 0x0585, 0x1434, + 0x0586, 0x0C34, 0x0589, 0x1234, 0x058A, 0x0A34, 0x058C, 0x0634, 0x0591, 0x1134, + 0x0592, 0x0934, 0x05A1, 0x10B4, 0x05A2, 0x08B4, 0x05C1, 0x1074, 0x05C2, 0x0874, + 0x0607, 0x1C0C, 0x060B, 0x1A0C, 0x060D, 0x160C, 0x060E, 0x0E0C, 0x0613, 0x190C, + 0x0615, 0x150C, 0x0616, 0x0D0C, 0x0619, 0x130C, 0x061A, 0x0B0C, 0x061C, 0x070C, + 0x0623, 0x188C, 0x0625, 0x148C, 0x0626, 0x0C8C, 0x0629, 0x128C, 0x062A, 0x0A8C, + 0x062C, 0x068C, 0x0631, 0x118C, 0x0632, 0x098C, 0x0643, 0x184C, 0x0645, 0x144C, + 0x0646, 0x0C4C, 0x0649, 0x124C, 0x064A, 0x0A4C, 0x0651, 0x114C, 0x0652, 0x094C, + 0x0661, 0x10CC, 0x0662, 0x08CC, 0x0683, 0x182C, 0x0685, 0x142C, 0x0686, 0x0C2C, + 0x0689, 0x122C, 0x068A, 0x0A2C, 0x0691, 0x112C, 0x0692, 0x092C, 0x06A1, 0x10AC, + 0x06A2, 0x08AC, 0x06C1, 0x106C, 0x06C2, 0x086C, 0x0703, 0x181C, 0x0705, 0x141C, + 0x0706, 0x0C1C, 0x0709, 0x121C, 0x070A, 0x0A1C, 0x0711, 0x111C, 0x0712, 0x091C, + 0x0721, 0x109C, 0x0722, 0x089C, 0x0741, 0x105C, 0x0742, 0x085C, 0x0781, 0x103C, + 0x0782, 0x083C, 0x080F, 0x1E02, 0x0817, 0x1D02, 0x081B, 0x1B02, 0x081D, 0x1702, + 0x081E, 0x0F02, 0x0827, 0x1C82, 0x082B, 0x1A82, 0x082D, 0x1682, 0x082E, 0x0E82, + 0x0833, 0x1982, 0x0835, 0x1582, 0x0836, 0x0D82, 0x0839, 0x1382, 0x083A, 0x0B82, + 0x0847, 0x1C42, 0x084B, 0x1A42, 0x084D, 0x1642, 0x084E, 0x0E42, 0x0853, 0x1942, + 0x0855, 0x1542, 0x0856, 0x0D42, 0x0859, 0x1342, 0x085A, 0x0B42, 0x0863, 0x18C2, + 0x0865, 0x14C2, 0x0866, 0x0CC2, 0x0869, 0x12C2, 0x086A, 0x0AC2, 0x0871, 0x11C2, + 0x0872, 0x09C2, 0x0887, 0x1C22, 0x088B, 0x1A22, 0x088D, 0x1622, 0x088E, 0x0E22, + 0x0893, 0x1922, 0x0895, 0x1522, 0x0896, 0x0D22, 0x0899, 0x1322, 0x089A, 0x0B22, + 0x08A3, 0x18A2, 0x08A5, 0x14A2, 0x08A6, 0x0CA2, 0x08A9, 0x12A2, 0x08AA, 0x0AA2, + 0x08B1, 0x11A2, 0x08B2, 0x09A2, 0x08C3, 0x1862, 0x08C5, 0x1462, 0x08C6, 0x0C62, + 0x08C9, 0x1262, 0x08CA, 0x0A62, 0x08D1, 0x1162, 0x08D2, 0x0962, 0x08E1, 0x10E2, + 0x0907, 0x1C12, 0x090B, 0x1A12, 0x090D, 0x1612, 0x090E, 0x0E12, 0x0913, 0x1912, + 0x0915, 0x1512, 0x0916, 0x0D12, 0x0919, 0x1312, 0x091A, 0x0B12, 0x0923, 0x1892, + 0x0925, 0x1492, 0x0926, 0x0C92, 0x0929, 0x1292, 0x092A, 0x0A92, 0x0931, 0x1192, + 0x0932, 0x0992, 0x0943, 0x1852, 0x0945, 0x1452, 0x0946, 0x0C52, 0x0949, 0x1252, + 0x094A, 0x0A52, 0x0951, 0x1152, 0x0961, 0x10D2, 0x0983, 0x1832, 0x0985, 0x1432, + 0x0986, 0x0C32, 0x0989, 0x1232, 0x098A, 0x0A32, 0x0991, 0x1132, 0x09A1, 0x10B2, + 0x09C1, 0x1072, 0x0A07, 0x1C0A, 0x0A0B, 0x1A0A, 0x0A0D, 0x160A, 0x0A0E, 0x0E0A, + 0x0A13, 0x190A, 0x0A15, 0x150A, 0x0A16, 0x0D0A, 0x0A19, 0x130A, 0x0A1A, 0x0B0A, + 0x0A23, 0x188A, 0x0A25, 0x148A, 0x0A26, 0x0C8A, 0x0A29, 0x128A, 0x0A2A, 0x0A8A, + 0x0A31, 0x118A, 0x0A43, 0x184A, 0x0A45, 0x144A, 0x0A46, 0x0C4A, 0x0A49, 0x124A, + 0x0A51, 0x114A, 0x0A61, 0x10CA, 0x0A83, 0x182A, 0x0A85, 0x142A, 0x0A86, 0x0C2A, + 0x0A89, 0x122A, 0x0A91, 0x112A, 0x0AA1, 0x10AA, 0x0AC1, 0x106A, 0x0B03, 0x181A, + 0x0B05, 0x141A, 0x0B06, 0x0C1A, 0x0B09, 0x121A, 0x0B11, 0x111A, 0x0B21, 0x109A, + 0x0B41, 0x105A, 0x0B81, 0x103A, 0x0C07, 0x1C06, 0x0C0B, 0x1A06, 0x0C0D, 0x1606, + 0x0C0E, 0x0E06, 0x0C13, 0x1906, 0x0C15, 0x1506, 0x0C16, 0x0D06, 0x0C19, 0x1306, + 0x0C23, 0x1886, 0x0C25, 0x1486, 0x0C26, 0x0C86, 0x0C29, 0x1286, 0x0C31, 0x1186, + 0x0C43, 0x1846, 0x0C45, 0x1446, 0x0C49, 0x1246, 0x0C51, 0x1146, 0x0C61, 0x10C6, + 0x0C83, 0x1826, 0x0C85, 0x1426, 0x0C89, 0x1226, 0x0C91, 0x1126, 0x0CA1, 0x10A6, + 0x0CC1, 0x1066, 0x0D03, 0x1816, 0x0D05, 0x1416, 0x0D09, 0x1216, 0x0D11, 0x1116, + 0x0D21, 0x1096, 0x0D41, 0x1056, 0x0D81, 0x1036, 0x0E03, 0x180E, 0x0E05, 0x140E, + 0x0E09, 0x120E, 0x0E11, 0x110E, 0x0E21, 0x108E, 0x0E41, 0x104E, 0x0E81, 0x102E, + 0x0F01, 0x101E, 0x100F, 0x1E01, 0x1017, 0x1D01, 0x101B, 0x1B01, 0x101D, 0x1701, + 0x1027, 0x1C81, 0x102B, 0x1A81, 0x102D, 0x1681, 0x1033, 0x1981, 0x1035, 0x1581, + 0x1039, 0x1381, 0x1047, 0x1C41, 0x104B, 0x1A41, 0x104D, 0x1641, 0x1053, 0x1941, + 0x1055, 0x1541, 0x1059, 0x1341, 0x1063, 0x18C1, 0x1065, 0x14C1, 0x1069, 0x12C1, + 0x1071, 0x11C1, 0x1087, 0x1C21, 0x108B, 0x1A21, 0x108D, 0x1621, 0x1093, 0x1921, + 0x1095, 0x1521, 0x1099, 0x1321, 0x10A3, 0x18A1, 0x10A5, 0x14A1, 0x10A9, 0x12A1, + 0x10B1, 0x11A1, 0x10C3, 0x1861, 0x10C5, 0x1461, 0x10C9, 0x1261, 0x10D1, 0x1161, + 0x1107, 0x1C11, 0x110B, 0x1A11, 0x110D, 0x1611, 0x1113, 0x1911, 0x1115, 0x1511, + 0x1119, 0x1311, 0x1123, 0x1891, 0x1125, 0x1491, 0x1129, 0x1291, 0x1131, 0x1191, + 0x1143, 0x1851, 0x1145, 0x1451, 0x1149, 0x1251, 0x1183, 0x1831, 0x1185, 0x1431, + 0x1189, 0x1231, 0x1207, 0x1C09, 0x120B, 0x1A09, 0x120D, 0x1609, 0x1213, 0x1909, + 0x1215, 0x1509, 0x1219, 0x1309, 0x1223, 0x1889, 0x1225, 0x1489, 0x1229, 0x1289, + 0x1243, 0x1849, 0x1245, 0x1449, 0x1283, 0x1829, 0x1285, 0x1429, 0x1303, 0x1819, + 0x1305, 0x1419, 0x1407, 0x1C05, 0x140B, 0x1A05, 0x140D, 0x1605, 0x1413, 0x1905, + 0x1415, 0x1505, 0x1423, 0x1885, 0x1425, 0x1485, 0x1443, 0x1845, 0x1483, 0x1825, + 0x1503, 0x1815, 0x1603, 0x180D, 0x1807, 0x1C03, 0x180B, 0x1A03, 0x1813, 0x1903, + 0x1823, 0x1883, 0x1843, 0x1445, 0x1249, 0x1151, 0x10E1, 0x0C46, 0x0A4A, 0x0952, + 0x08E2, 0x064C, 0x0554, 0x04E4, 0x0358, 0x02E8, 0x01F0 +}; + +static const unsigned short AppxD_II[78] = { + /* Appendix D Table II - 2 of 13 characters */ + 0x0003, 0x1800, 0x0005, 0x1400, 0x0006, 0x0C00, 0x0009, 0x1200, 0x000A, 0x0A00, + 0x000C, 0x0600, 0x0011, 0x1100, 0x0012, 0x0900, 0x0014, 0x0500, 0x0018, 0x0300, + 0x0021, 0x1080, 0x0022, 0x0880, 0x0024, 0x0480, 0x0028, 0x0280, 0x0030, 0x0180, + 0x0041, 0x1040, 0x0042, 0x0840, 0x0044, 0x0440, 0x0048, 0x0240, 0x0050, 0x0140, + 0x0060, 0x00C0, 0x0081, 0x1020, 0x0082, 0x0820, 0x0084, 0x0420, 0x0088, 0x0220, + 0x0090, 0x0120, 0x0101, 0x1010, 0x0102, 0x0810, 0x0104, 0x0410, 0x0108, 0x0210, + 0x0201, 0x1008, 0x0202, 0x0808, 0x0204, 0x0408, 0x0401, 0x1004, 0x0402, 0x0804, + 0x0801, 0x1002, 0x1001, 0x0802, 0x0404, 0x0208, 0x0110, 0x00A0 +}; + +static const unsigned short int AppxD_IV[130] = { + /* Appendix D Table IV - Bar-to-Character Mapping (reverse lookup) */ + 67, 6, 78, 16, 86, 95, 34, 40, 45, 113, 117, 121, 62, 87, 18, 104, 41, 76, 57, 119, 115, 72, 97, + 2, 127, 26, 105, 35, 122, 52, 114, 7, 24, 82, 68, 63, 94, 44, 77, 112, 70, 100, 39, 30, 107, + 15, 125, 85, 10, 65, 54, 88, 20, 106, 46, 66, 8, 116, 29, 61, 99, 80, 90, 37, 123, 51, 25, 84, + 129, 56, 4, 109, 96, 28, 36, 47, 11, 71, 33, 102, 21, 9, 17, 49, 124, 79, 64, 91, 42, 69, 53, + 60, 14, 1, 27, 103, 126, 75, 89, 50, 120, 19, 32, 110, 92, 111, 130, 59, 31, 12, 81, 43, 55, + 5, 74, 22, 101, 128, 58, 118, 48, 108, 38, 98, 93, 23, 83, 13, 73, 3 +}; + +/*************************************************************************** + ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence + ** + ** Inputs: + ** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which + ** are right justified - ie: the leftmost 2 bits of the first byte do not + ** hold data and must be set to zero. + ** + ** Outputs: + ** return unsigned short - 11 bit Frame Check Sequence (right justified) + ***************************************************************************/ +extern unsigned short USPS_MSB_Math_CRC11GenerateFrameCheckSequence(unsigned char *ByteArrayPtr) { + unsigned short GeneratorPolynomial = 0x0F35; + unsigned short FrameCheckSequence = 0x07FF; + unsigned short Data; + int ByteIndex, Bit; + + /* Do most significant byte skipping the 2 most significant bits */ + Data = *ByteArrayPtr << 5; + ByteArrayPtr++; + for (Bit = 2; Bit < 8; Bit++) { + if ((FrameCheckSequence ^ Data) & 0x400) + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + else + FrameCheckSequence = (FrameCheckSequence << 1); + FrameCheckSequence &= 0x7FF; + Data <<= 1; + } + /* Do rest of the bytes */ + for (ByteIndex = 1; ByteIndex < 13; ByteIndex++) { + Data = *ByteArrayPtr << 3; + ByteArrayPtr++; + for (Bit = 0; Bit < 8; Bit++) { + if ((FrameCheckSequence ^ Data) & 0x0400) { + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + } else { + FrameCheckSequence = (FrameCheckSequence << 1); + } + FrameCheckSequence &= 0x7FF; + Data <<= 1; + } + } + return FrameCheckSequence; +} + +int imail(struct zint_symbol *symbol, unsigned char source[], int length) { + char data_pattern[200]; + int error_number; + int i, j, read; + char zip[35], tracker[35], zip_adder[11], temp[2]; + short int accum[112], x_reg[112], y_reg[112]; + unsigned char byte_array[13]; + unsigned short usps_crc; + int codeword[10]; + unsigned short characters[10]; + short int bar_map[130]; + + error_number = 0; + + if (length > 32) { + strcpy(symbol->errtxt, "450: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(SODIUM, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "451: Invalid characters in data"); + return error_number; + } + + strcpy(zip, ""); + strcpy(tracker, ""); + + /* separate the tracking code from the routing code */ + + read = 0; + j = 0; + for (i = 0; i < length; i++) { + if (source[i] == '-') { + tracker[read] = '\0'; + j = 1; + read = 0; + } else { + if (j == 0) { + /* reading tracker */ + tracker[read] = source[i]; + read++; + } else { + /* reading zip code */ + zip[read] = source[i]; + read++; + } + } + } + if (j == 0) { + tracker[read] = '\0'; + } else { + zip[read] = '\0'; + } + + if (strlen(tracker) != 20) { + strcpy(symbol->errtxt, "452: Invalid length tracking code"); + return ZINT_ERROR_INVALID_DATA; + } + if (strlen(zip) > 11) { + strcpy(symbol->errtxt, "453: Invalid ZIP code"); + return ZINT_ERROR_INVALID_DATA; + } + + /* *** Step 1 - Conversion of Data Fields into Binary Data *** */ + + /* Routing code first */ + + for (i = 0; i < 112; i++) { + accum[i] = 0; + } + + for (read = 0; read < strlen(zip); read++) { + + for (i = 0; i < 112; i++) { + x_reg[i] = accum[i]; + } + + for (i = 0; i < 9; i++) { + binary_add(accum, x_reg); + } + + for (i = 0; i < 112; i++) { + x_reg[i] = 0; + } + + for (i = 0; i < 4; i++) { + if (ctoi(zip[read]) & (0x01 << i)) x_reg[i] = 1; + } + + binary_add(accum, x_reg); + } + + /* add weight to routing code */ + + for (i = 0; i < 112; i++) { + x_reg[i] = accum[i]; + } + + if (strlen(zip) > 9) { + strcpy(zip_adder, "1000100001"); + } else { + if (strlen(zip) > 5) { + strcpy(zip_adder, "100001"); + } else { + if (strlen(zip) > 0) { + strcpy(zip_adder, "1"); + } else { + strcpy(zip_adder, "0"); + } + } + } + + for (i = 0; i < 112; i++) { + accum[i] = 0; + } + + for (read = 0; read < strlen(zip_adder); read++) { + + for (i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for (i = 0; i < 9; i++) { + binary_add(accum, y_reg); + } + + for (i = 0; i < 112; i++) { + y_reg[i] = 0; + } + + for (i = 0; i < 4; i++) { + if (ctoi(zip_adder[read]) & (0x01 << i)) y_reg[i] = 1; + } + + binary_add(accum, y_reg); + } + + binary_add(accum, x_reg); + + /* tracking code */ + + /* multiply by 10 */ + for (i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for (i = 0; i < 9; i++) { + binary_add(accum, y_reg); + } + + for (i = 0; i < 112; i++) { + y_reg[i] = 0; + } + + /* add first digit of tracker */ + for (i = 0; i < 4; i++) { + if (ctoi(tracker[0]) & (0x01 << i)) y_reg[i] = 1; + } + + binary_add(accum, y_reg); + + /* multiply by 5 */ + for (i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for (i = 0; i < 4; i++) { + binary_add(accum, y_reg); + } + + for (i = 0; i < 112; i++) { + y_reg[i] = 0; + } + + /* add second digit */ + for (i = 0; i < 4; i++) { + if (ctoi(tracker[1]) & (0x01 << i)) y_reg[i] = 1; + } + + binary_add(accum, y_reg); + + /* and then the rest */ + + for (read = 2; read < strlen(tracker); read++) { + + for (i = 0; i < 112; i++) { + y_reg[i] = accum[i]; + } + + for (i = 0; i < 9; i++) { + binary_add(accum, y_reg); + } + + for (i = 0; i < 112; i++) { + y_reg[i] = 0; + } + + for (i = 0; i < 4; i++) { + if (ctoi(tracker[read]) & (0x01 << i)) y_reg[i] = 1; + } + + binary_add(accum, y_reg); + } + + /* *** Step 2 - Generation of 11-bit CRC on Binary Data *** */ + + accum[103] = 0; + accum[102] = 0; + + memset(byte_array, 0, 13); + for (j = 0; j < 13; j++) { + i = 96 - (8 * j); + byte_array[j] = 0; + byte_array[j] += accum[i]; + byte_array[j] += 2 * accum[i + 1]; + byte_array[j] += 4 * accum[i + 2]; + byte_array[j] += 8 * accum[i + 3]; + byte_array[j] += 16 * accum[i + 4]; + byte_array[j] += 32 * accum[i + 5]; + byte_array[j] += 64 * accum[i + 6]; + byte_array[j] += 128 * accum[i + 7]; + } + + usps_crc = USPS_MSB_Math_CRC11GenerateFrameCheckSequence(byte_array); + + /* *** Step 3 - Conversion from Binary Data to Codewords *** */ + + /* start with codeword J which is base 636 */ + for (i = 0; i < 112; i++) { + x_reg[i] = 0; + y_reg[i] = 0; + } + + x_reg[101] = 1; + x_reg[98] = 1; + x_reg[97] = 1; + x_reg[96] = 1; + x_reg[95] = 1; + x_reg[94] = 1; + + for (i = 92; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if (y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + codeword[9] = (accum[9] * 512) + (accum[8] * 256) + (accum[7] * 128) + (accum[6] * 64) + + (accum[5] * 32) + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) + + (accum[1] * 2) + accum[0]; + + /* then codewords I to B with base 1365 */ + + for (j = 8; j > 0; j--) { + for (i = 0; i < 112; i++) { + accum[i] = y_reg[i]; + y_reg[i] = 0; + x_reg[i] = 0; + } + x_reg[101] = 1; + x_reg[99] = 1; + x_reg[97] = 1; + x_reg[95] = 1; + x_reg[93] = 1; + x_reg[91] = 1; + for (i = 91; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if (y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + codeword[j] = (accum[10] * 1024) + (accum[9] * 512) + (accum[8] * 256) + + (accum[7] * 128) + (accum[6] * 64) + (accum[5] * 32) + + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) + + (accum[1] * 2) + accum[0]; + } + + codeword[0] = (y_reg[10] * 1024) + (y_reg[9] * 512) + (y_reg[8] * 256) + + (y_reg[7] * 128) + (y_reg[6] * 64) + (y_reg[5] * 32) + + (y_reg[4] * 16) + (y_reg[3] * 8) + (y_reg[2] * 4) + + (y_reg[1] * 2) + y_reg[0]; + + for (i = 0; i < 8; i++) { + if (codeword[i] == 1365) { + codeword[i] = 0; + codeword[i + 1]++; + } + } + + /* *** Step 4 - Inserting Additional Information into Codewords *** */ + + codeword[9] = codeword[9] * 2; + + if (usps_crc >= 1024) { + codeword[0] += 659; + } + + /* *** Step 5 - Conversion from Codewords to Characters *** */ + + for (i = 0; i < 10; i++) { + if (codeword[i] < 1287) { + characters[i] = AppxD_I[codeword[i]]; + } else { + characters[i] = AppxD_II[codeword[i] - 1287]; + } + } + + for (i = 0; i < 10; i++) { + if (usps_crc & (1 << i)) { + characters[i] = 0x1FFF - characters[i]; + } + } + + /* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */ + for (i = 0; i < 10; i++) { + for (j = 0; j < 13; j++) { + if (characters[i] & (1 << j)) { + bar_map[AppxD_IV[(13 * i) + j] - 1] = 1; + } else { + bar_map[AppxD_IV[(13 * i) + j] - 1] = 0; + } + } + } + + strcpy(data_pattern, ""); + temp[1] = '\0'; + for (i = 0; i < 65; i++) { + j = 0; + if (bar_map[i] == 0) + j += 1; + if (bar_map[i + 65] == 0) + j += 2; + temp[0] = itoc(j); + strcat(data_pattern, temp); + } + + /* Translate 4-state data pattern to symbol */ + read = 0; + for (i = 0; i < strlen(data_pattern); i++) { + if ((data_pattern[i] == '1') || (data_pattern[i] == '0')) { + set_module(symbol, 0, read); + } + set_module(symbol, 1, read); + if ((data_pattern[i] == '2') || (data_pattern[i] == '0')) { + set_module(symbol, 2, read); + } + read += 2; + } + + symbol->row_height[0] = 3; + symbol->row_height[1] = 2; + symbol->row_height[2] = 3; + + symbol->rows = 3; + symbol->width = read - 1; + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/large.c b/3rdparty/zint-2.6.1/backend/large.c new file mode 100644 index 0000000..dda4d5f --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/large.c @@ -0,0 +1,191 @@ +/* large.c - Handles binary manipulation of large numbers */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include "common.h" +#include "large.h" + +void binary_add(short int accumulator[], short int input_buffer[]) { /* Binary addition */ + int i, carry, done; + carry = 0; + + for (i = 0; i < 112; i++) { + done = 0; + if (((input_buffer[i] == 0) && (accumulator[i] == 0)) + && ((carry == 0) && (done == 0))) { + accumulator[i] = 0; + carry = 0; + done = 1; + } + if (((input_buffer[i] == 0) && (accumulator[i] == 0)) + && ((carry == 1) && (done == 0))) { + accumulator[i] = 1; + carry = 0; + done = 1; + } + if (((input_buffer[i] == 0) && (accumulator[i] == 1)) + && ((carry == 0) && (done == 0))) { + accumulator[i] = 1; + carry = 0; + done = 1; + } + if (((input_buffer[i] == 0) && (accumulator[i] == 1)) + && ((carry == 1) && (done == 0))) { + accumulator[i] = 0; + carry = 1; + done = 1; + } + if (((input_buffer[i] == 1) && (accumulator[i] == 0)) + && ((carry == 0) && (done == 0))) { + accumulator[i] = 1; + carry = 0; + done = 1; + } + if (((input_buffer[i] == 1) && (accumulator[i] == 0)) + && ((carry == 1) && (done == 0))) { + accumulator[i] = 0; + carry = 1; + done = 1; + } + if (((input_buffer[i] == 1) && (accumulator[i] == 1)) + && ((carry == 0) && (done == 0))) { + accumulator[i] = 0; + carry = 1; + done = 1; + } + if (((input_buffer[i] == 1) && (accumulator[i] == 1)) + && ((carry == 1) && (done == 0))) { + accumulator[i] = 1; + carry = 1; + done = 1; + } + } +} + +void binary_subtract(short int accumulator[], short int input_buffer[]) { + /* 2's compliment subtraction */ + /* take input_buffer from accumulator and put answer in accumulator */ + int i; + short int sub_buffer[112]; + + for (i = 0; i < 112; i++) { + if (input_buffer[i] == 0) { + sub_buffer[i] = 1; + } else { + sub_buffer[i] = 0; + } + } + binary_add(accumulator, sub_buffer); + + sub_buffer[0] = 1; + + for (i = 1; i < 112; i++) { + sub_buffer[i] = 0; + } + binary_add(accumulator, sub_buffer); +} + +void shiftdown(short int buffer[]) { + int i; + + buffer[102] = 0; + buffer[103] = 0; + + for (i = 0; i < 102; i++) { + buffer[i] = buffer[i + 1]; + } +} + +void shiftup(short int buffer[]) { + int i; + + for (i = 102; i > 0; i--) { + buffer[i] = buffer[i - 1]; + } + + buffer[0] = 0; +} + +short int islarger(short int accum[], short int reg[]) { + /* Returns 1 if accum[] is larger than reg[], else 0 */ + int i, latch, larger; + latch = 0; + i = 103; + larger = 0; + + + do { + if ((accum[i] == 1) && (reg[i] == 0)) { + latch = 1; + larger = 1; + } + if ((accum[i] == 0) && (reg[i] == 1)) { + latch = 1; + } + i--; + } while ((latch == 0) && (i >= -1)); + + return larger; +} + +void binary_load(short int reg[], char data[], const size_t src_len) { + size_t read; + int i; + short int temp[112] = {0}; + + for (i = 0; i < 112; i++) { + reg[i] = 0; + } + + for (read = 0; read < src_len; read++) { + + for (i = 0; i < 112; i++) { + temp[i] = reg[i]; + } + + for (i = 0; i < 9; i++) { + binary_add(reg, temp); + } + + for (i = 0; i < 112; i++) { + temp[i] = 0; + } + + for (i = 0; i < 4; i++) { + if (ctoi(data[read]) & (0x01 << i)) temp[i] = 1; + } + + binary_add(reg, temp); + } +} + diff --git a/3rdparty/zint-2.6.1/backend/large.h b/3rdparty/zint-2.6.1/backend/large.h new file mode 100644 index 0000000..c8b6e14 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/large.h @@ -0,0 +1,50 @@ +/* large.h - Handles binary manipulation of large numbers */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ +#ifndef __LARGE_H +#define __LARGE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern void binary_load(short int reg[], char data[], const size_t src_len); +extern void binary_add(short int accumulator[], short int input_buffer[]); +extern void binary_subtract(short int accumulator[], short int input_buffer[]); +extern void shiftdown(short int buffer[]); +extern void shiftup(short int buffer[]); +extern short int islarger(short int accum[], short int reg[]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __LARGE_H */ diff --git a/3rdparty/zint-2.6.1/backend/library.c b/3rdparty/zint-2.6.1/backend/library.c new file mode 100644 index 0000000..9c2eb6e --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/library.c @@ -0,0 +1,1312 @@ +/* library.c - external functions of libzint + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "gs1.h" + +#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%" + +struct zint_symbol *ZBarcode_Create() { + struct zint_symbol *symbol; + + symbol = (struct zint_symbol*) malloc(sizeof (*symbol)); + if (!symbol) return NULL; + + memset(symbol, 0, sizeof (*symbol)); + symbol->symbology = BARCODE_CODE128; + symbol->height = 50; + symbol->whitespace_width = 0; + symbol->border_width = 0; + symbol->output_options = 0; + symbol->rows = 0; + symbol->width = 0; + strcpy(symbol->fgcolour, "000000"); + strcpy(symbol->bgcolour, "ffffff"); + strcpy(symbol->outfile, ""); + symbol->scale = 1.0; + symbol->option_1 = -1; + symbol->option_2 = 0; + symbol->option_3 = 928; // PDF_MAX + symbol->show_hrt = 1; // Show human readable text + symbol->input_mode = DATA_MODE; + strcpy(symbol->primary, ""); + memset(&(symbol->encoded_data[0][0]), 0, sizeof (symbol->encoded_data)); + memset(&(symbol->row_height[0]), 0, sizeof (symbol->row_height)); + symbol->bitmap = NULL; + symbol->bitmap_width = 0; + symbol->bitmap_height = 0; + symbol->eci = 3; + symbol->dot_size = 4.0 / 5.0; + symbol->debug = 0; + return symbol; +} + +void ZBarcode_Clear(struct zint_symbol *symbol) { + int i, j; + + for (i = 0; i < symbol->rows; i++) { + for (j = 0; j < symbol->width; j++) { + unset_module(symbol, i, j); + } + } + symbol->rows = 0; + symbol->width = 0; + memset(symbol->text, 0, sizeof(symbol->text)); + symbol->errtxt[0] = '\0'; + if (symbol->bitmap != NULL) { + free(symbol->bitmap); + symbol->bitmap = NULL; + } + symbol->bitmap_width = 0; + symbol->bitmap_height = 0; +} + +void ZBarcode_Delete(struct zint_symbol *symbol) { + if (symbol->bitmap != NULL) + free(symbol->bitmap); + + // If there is a rendered version, ensure its memory is released + if (symbol->rendered != NULL) { + struct zint_render_line *line, *l; + struct zint_render_string *string, *s; + struct zint_render_ring *ring, *r; + struct zint_render_hexagon *hexagon, *h; + + // Free lines + line = symbol->rendered->lines; + while (line) { + l = line; + line = line->next; + free(l); + } + // Free Strings + string = symbol->rendered->strings; + while (string) { + s = string; + string = string->next; + free(s->text); + free(s); + } + + // Free Rings + ring = symbol->rendered->rings; + while (ring) { + r = ring; + ring = ring->next; + free(r); + } + + // Free Hexagons + hexagon = symbol->rendered->hexagons; + while (hexagon) { + h = hexagon; + hexagon = hexagon->next; + free(h); + } + + // Free Render + free(symbol->rendered); + } + free(symbol); +} + +extern int get_best_eci(unsigned char source[], size_t length); /* Calculate suitable ECI mode */ +extern int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */ + + +extern int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */ +extern int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Code 3 from 9 (or Code 39) */ +extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */ +extern int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */ +extern int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */ +extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */ +extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */ +extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */ +extern int interleaved_two_of_five(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Code 2 of 5 Interleaved */ +extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */ +extern int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */ +extern int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */ +extern int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */ +extern int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */ +extern int code_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Code 128 and NVE-18 */ +extern int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* EAN-128 (GS1-128) */ +extern int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */ +extern int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */ +extern int telepen(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Telepen ASCII */ +extern int telepen_num(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Telepen Numeric */ +extern int plessey(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Plessey Code */ +extern int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */ +extern int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */ +extern int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */ +extern int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */ +extern int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */ +extern int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */ +extern int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */ +extern int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */ +extern int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */ +extern int code16k(struct zint_symbol *symbol, unsigned char source[],const size_t length); /* Code 16k */ +extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* PDF417 */ +extern int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length); /* Micro PDF417 */ +extern int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */ +extern int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */ +extern int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */ +extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */ +extern int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */ +extern int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */ +extern int aztec(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Aztec Code */ +extern int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */ +extern int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */ +extern int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */ +extern int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */ +extern int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Micro QR Code */ +extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */ +extern int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */ +extern int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */ +extern int code_49(struct zint_symbol *symbol, unsigned char source[], const int length); /* Code 49 */ +extern int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */ +extern int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */ +extern int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Grid Matrix */ +extern int han_xin(struct zint_symbol * symbol, const unsigned char source[], size_t length); /* Han Xin */ +extern int dotcode(struct zint_symbol * symbol, const unsigned char source[], int length); /* DotCode */ +extern int codablock(struct zint_symbol * symbol, const unsigned char source[], const size_t length); /* Codablock */ +extern int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* UPNQR */ +extern int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Data Matrix (IEC16022) */ +extern int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* QR Code */ + +extern int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */ +extern int render_plot(struct zint_symbol *symbol, float width, float height); /* Plot to gLabels */ +extern int ps_plot(struct zint_symbol *symbol); /* Plot to EPS */ +extern int svg_plot(struct zint_symbol *symbol); /* Plot to SVG */ +extern int emf_plot(struct zint_symbol *symbol); /* Plot to Metafile */ + +void error_tag(char error_string[], int error_number) { + char error_buffer[100]; + + if (error_number != 0) { + strcpy(error_buffer, error_string); + + if (error_number > 4) { + strcpy(error_string, "Error "); + } else { + strcpy(error_string, "Warning "); + } + + strcat(error_string, error_buffer); + } +} + +/* Output a hexadecimal representation of the rendered symbol */ +int dump_plot(struct zint_symbol *symbol) { + FILE *f; + int i, r; + int byt; + char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + int space = 0; + + if (symbol->output_options & BARCODE_STDOUT) { + f = stdout; + } else { + f = fopen(symbol->outfile, "w"); + if (!f) { + strcpy(symbol->errtxt, "201: Could not open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + } + + for (r = 0; r < symbol->rows; r++) { + byt = 0; + for (i = 0; i < symbol->width; i++) { + byt = byt << 1; + if (module_is_set(symbol, r, i)) { + byt += 1; + } + if (((i + 1) % 4) == 0) { + fputc(hex[byt], f); + space++; + byt = 0; + } + if (space == 2) { + fputc(' ', f); + space = 0; + } + } + + if ((symbol->width % 4) != 0) { + byt = byt << (4 - (symbol->width % 4)); + fputc(hex[byt], f); + } + fputs("\n", f); + space = 0; + } + + if (symbol->output_options & BARCODE_STDOUT) { + fflush(f); + } else { + fclose(f); + } + + return 0; +} + +/* Process health industry bar code data */ +static int hibc(struct zint_symbol *symbol, unsigned char source[], size_t length) { + size_t i; + int counter, error_number; + char to_process[113], temp[2], check_digit; + + /* without "+" and check: max 110 characters in HIBC 2.6 */ + if (length > 110) { + strcpy(symbol->errtxt, "202: Data too long for HIBC LIC"); + return ZINT_ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(TECHNETIUM, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "203: Invalid characters in data"); + return error_number; + } + + strcpy(to_process, "+"); + counter = 41; + for (i = 0; i < length; i++) { + counter += posn(TECHNETIUM, source[i]); + } + counter = counter % 43; + + if (counter < 10) { + check_digit = itoc(counter); + } else { + if (counter < 36) { + check_digit = (counter - 10) + 'A'; + } else { + switch (counter) { + case 36: check_digit = '-'; + break; + case 37: check_digit = '.'; + break; + case 38: check_digit = ' '; + break; + case 39: check_digit = '$'; + break; + case 40: check_digit = '/'; + break; + case 41: check_digit = '+'; + break; + case 42: check_digit = '%'; + break; + default: check_digit = ' '; + break; /* Keep compiler happy */ + } + } + } + + temp[0] = check_digit; + temp[1] = '\0'; + + strcat(to_process, (char *) source); + strcat(to_process, temp); + length = strlen(to_process); + + switch (symbol->symbology) { + case BARCODE_HIBC_128: + error_number = code_128(symbol, (unsigned char *) to_process, length); + ustrcpy(symbol->text, (unsigned char*) "*"); + strcat((char*) symbol->text, to_process); + strcat((char*) symbol->text, "*"); + break; + case BARCODE_HIBC_39: + symbol->option_2 = 0; + error_number = c39(symbol, (unsigned char *) to_process, length); + ustrcpy(symbol->text, (unsigned char*) "*"); + strcat((char*) symbol->text, to_process); + strcat((char*) symbol->text, "*"); + break; + case BARCODE_HIBC_DM: + error_number = dmatrix(symbol, (unsigned char *) to_process, length); + break; + case BARCODE_HIBC_QR: + error_number = qr_code(symbol, (unsigned char *) to_process, length); + break; + case BARCODE_HIBC_PDF: + error_number = pdf417enc(symbol, (unsigned char *) to_process, length); + break; + case BARCODE_HIBC_MICPDF: + error_number = micro_pdf417(symbol, (unsigned char *) to_process, length); + break; + case BARCODE_HIBC_AZTEC: + error_number = aztec(symbol, (unsigned char *) to_process, length); + break; + case BARCODE_HIBC_BLOCKF: + error_number = codablock(symbol, (unsigned char *) to_process, length); + break; + } + + return error_number; +} + +static void check_row_heights(struct zint_symbol *symbol) { + /* Check that rows with undefined heights are never less than 5x */ + int large_bar_count = 0; + int i; + int preset_height = 0; + int large_bar_height = 0; + + for (i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if (symbol->row_height[i] == 0) { + large_bar_count++; + } + } + + if (large_bar_count == 0) { + symbol->height = preset_height; + } else { + large_bar_height = (symbol->height - preset_height) / large_bar_count; + } + + if (large_bar_height < 5) { + for (i = 0; i < symbol->rows; i++) { + if (symbol->row_height[i] == 0) { + symbol->row_height[i] = 5; + preset_height += 5; + } + } + symbol->height = preset_height; + } +} + +static int gs1_compliant(const int symbology) { + /* Returns 1 if symbology supports GS1 data */ + + int result = 0; + + switch (symbology) { + case BARCODE_EAN128: + case BARCODE_RSS_EXP: + case BARCODE_RSS_EXPSTACK: + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + case BARCODE_CODE16K: + case BARCODE_AZTEC: + case BARCODE_DATAMATRIX: + case BARCODE_CODEONE: + case BARCODE_CODE49: + case BARCODE_QRCODE: + case BARCODE_DOTCODE: + result = 1; + break; + } + + return result; +} + +static int is_matrix(const int symbology) { + /* Returns 1 if symbology is a matrix design */ + + int result = 0; + + switch (symbology) { + case BARCODE_QRCODE: + case BARCODE_DATAMATRIX: + case BARCODE_MICROQR: + case BARCODE_HIBC_DM: + case BARCODE_AZTEC: + case BARCODE_HIBC_QR: + case BARCODE_HIBC_AZTEC: + case BARCODE_AZRUNE: + case BARCODE_CODEONE: + case BARCODE_GRIDMATRIX: + case BARCODE_HANXIN: + case BARCODE_DOTCODE: + case BARCODE_UPNQR: + result = 1; + break; + } + + return result; +} + +static int supports_eci(const int symbology) { + /* Returns 1 if symbology can encode the ECI character */ + + int result = 0; + + switch (symbology) { + case BARCODE_AZTEC: + case BARCODE_DATAMATRIX: + case BARCODE_MAXICODE: + case BARCODE_MICROPDF417: + case BARCODE_PDF417: + case BARCODE_PDF417TRUNC: + case BARCODE_QRCODE: + case BARCODE_DOTCODE: + case BARCODE_GRIDMATRIX: + case BARCODE_HANXIN: + result = 1; + break; + } + + return result; +} + +int ZBarcode_ValidID(int symbol_id) { + /* Checks whether a symbology is supported */ + + int result = 0; + + switch (symbol_id) { + case BARCODE_CODE11: + case BARCODE_C25MATRIX: + case BARCODE_C25INTER: + case BARCODE_C25IATA: + case BARCODE_C25LOGIC: + case BARCODE_C25IND: + case BARCODE_CODE39: + case BARCODE_EXCODE39: + case BARCODE_EANX: + case BARCODE_EANX_CHK: + case BARCODE_EAN128: + case BARCODE_CODABAR: + case BARCODE_CODE128: + case BARCODE_DPLEIT: + case BARCODE_DPIDENT: + case BARCODE_CODE16K: + case BARCODE_CODE49: + case BARCODE_CODE93: + case BARCODE_FLAT: + case BARCODE_RSS14: + case BARCODE_RSS_LTD: + case BARCODE_RSS_EXP: + case BARCODE_TELEPEN: + case BARCODE_UPCA: + case BARCODE_UPCA_CHK: + case BARCODE_UPCE: + case BARCODE_UPCE_CHK: + case BARCODE_POSTNET: + case BARCODE_MSI_PLESSEY: + case BARCODE_FIM: + case BARCODE_LOGMARS: + case BARCODE_PHARMA: + case BARCODE_PZN: + case BARCODE_PHARMA_TWO: + case BARCODE_PDF417: + case BARCODE_PDF417TRUNC: + case BARCODE_MAXICODE: + case BARCODE_QRCODE: + case BARCODE_CODE128B: + case BARCODE_AUSPOST: + case BARCODE_AUSREPLY: + case BARCODE_AUSROUTE: + case BARCODE_AUSREDIRECT: + case BARCODE_ISBNX: + case BARCODE_RM4SCC: + case BARCODE_DATAMATRIX: + case BARCODE_EAN14: + case BARCODE_NVE18: + case BARCODE_JAPANPOST: + case BARCODE_KOREAPOST: + case BARCODE_RSS14STACK: + case BARCODE_RSS14STACK_OMNI: + case BARCODE_RSS_EXPSTACK: + case BARCODE_PLANET: + case BARCODE_MICROPDF417: + case BARCODE_ONECODE: + case BARCODE_PLESSEY: + case BARCODE_TELEPEN_NUM: + case BARCODE_ITF14: + case BARCODE_KIX: + case BARCODE_AZTEC: + case BARCODE_DAFT: + case BARCODE_MICROQR: + case BARCODE_HIBC_128: + case BARCODE_HIBC_39: + case BARCODE_HIBC_DM: + case BARCODE_HIBC_QR: + case BARCODE_HIBC_PDF: + case BARCODE_HIBC_MICPDF: + case BARCODE_HIBC_AZTEC: + case BARCODE_HIBC_BLOCKF: + case BARCODE_AZRUNE: + case BARCODE_CODE32: + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + case BARCODE_CHANNEL: + case BARCODE_CODEONE: + case BARCODE_GRIDMATRIX: + case BARCODE_HANXIN: + case BARCODE_DOTCODE: + case BARCODE_CODABLOCKF: + case BARCODE_UPNQR: + result = 1; + break; + } + + return result; +} + +static int extended_charset(struct zint_symbol *symbol, const unsigned char *source, const int length) { + int error_number = 0; + + /* These are the "elite" standards which can support multiple character sets */ + switch (symbol->symbology) { + case BARCODE_QRCODE: error_number = qr_code(symbol, source, length); + break; + case BARCODE_MICROQR: error_number = microqr(symbol, source, length); + break; + case BARCODE_GRIDMATRIX: error_number = grid_matrix(symbol, source, length); + break; + case BARCODE_HANXIN: error_number = han_xin(symbol, source, length); + break; + case BARCODE_UPNQR: error_number = upnqr(symbol, source, length); + break; + } + + return error_number; +} + +static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, size_t in_length) { + /* These are the "norm" standards which only support Latin-1 at most */ + int error_number = 0; + +#ifndef _MSC_VER + unsigned char preprocessed[in_length + 1]; +#else + unsigned char* preprocessed = (unsigned char*) _alloca(in_length + 1); +#endif + + if (symbol->symbology == BARCODE_CODE16K) { + symbol->whitespace_width = 16; + symbol->border_width = 2; + if (!(symbol->output_options & BARCODE_BIND)) { + symbol->output_options += BARCODE_BIND; + } + } + else + if (symbol->symbology == BARCODE_ITF14) { + symbol->whitespace_width = 20; + symbol->border_width = 8; + if (!(symbol->output_options & BARCODE_BOX)) { + symbol->output_options += BARCODE_BOX; + } + } + + switch (symbol->input_mode) { + case DATA_MODE: + case GS1_MODE: + memcpy(preprocessed, source, in_length); + preprocessed[in_length] = '\0'; + break; + case UNICODE_MODE: + error_number = utf_to_eci(symbol->eci, source, preprocessed, &in_length); + if (error_number != 0) { + strcpy(symbol->errtxt, "204: Invalid characters in input data"); + return error_number; + } + break; + } + + switch (symbol->symbology) { + case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, in_length); + break; + case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, in_length); + break; + case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, in_length); + break; + case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, in_length); + break; + case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, in_length); + break; + case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, in_length); + break; + case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, in_length); + break; + case BARCODE_UPCA: + case BARCODE_UPCA_CHK: + case BARCODE_UPCE: + case BARCODE_UPCE_CHK: + case BARCODE_EANX: + case BARCODE_EANX_CHK: + error_number = eanx(symbol, preprocessed, in_length); + break; + case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, in_length); + break; + case BARCODE_CODE39: error_number = c39(symbol, preprocessed, in_length); + break; + case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, in_length); + break; + case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, in_length); + break; + case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, in_length); + break; + case BARCODE_CODE93: error_number = c93(symbol, preprocessed, in_length); + break; + case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, in_length); + break; + case BARCODE_CODE128: + case BARCODE_CODE128B: + error_number = code_128(symbol, preprocessed, in_length); + break; + case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, in_length); + break; + case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, in_length); + break; + case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, in_length); + break; + case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, in_length); + break; + case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, in_length); + break; + case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, in_length); + break; + case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, in_length); + break; + case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, in_length); + break; + case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, in_length); + break; + case BARCODE_FIM: error_number = fim(symbol, preprocessed, in_length); + break; + case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, in_length); + break; + case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, in_length); + break; + case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, in_length); + break; + case BARCODE_AUSPOST: + case BARCODE_AUSREPLY: + case BARCODE_AUSROUTE: + case BARCODE_AUSREDIRECT: + error_number = australia_post(symbol, preprocessed, in_length); + break; + case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, in_length); + break; + case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, in_length); + break; + case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, in_length); + break; + case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, in_length); + break; + case BARCODE_RSS14: + case BARCODE_RSS14STACK: + case BARCODE_RSS14STACK_OMNI: + error_number = rss14(symbol, preprocessed, in_length); + break; + case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, in_length); + break; + case BARCODE_RSS_EXP: + case BARCODE_RSS_EXPSTACK: + error_number = rssexpanded(symbol, preprocessed, in_length); + break; + case BARCODE_EANX_CC: + case BARCODE_EAN128_CC: + case BARCODE_RSS14_CC: + case BARCODE_RSS_LTD_CC: + case BARCODE_RSS_EXP_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + case BARCODE_RSS_EXPSTACK_CC: + error_number = composite(symbol, preprocessed, in_length); + break; + case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, in_length); + break; + case BARCODE_CODE32: error_number = code32(symbol, preprocessed, in_length); + break; + case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, in_length); + break; + case BARCODE_EAN14: + error_number = ean_14(symbol, preprocessed, in_length); + break; + case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, in_length); + break; + case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, in_length); + break; + case BARCODE_HIBC_128: + case BARCODE_HIBC_39: + case BARCODE_HIBC_DM: + case BARCODE_HIBC_QR: + case BARCODE_HIBC_PDF: + case BARCODE_HIBC_MICPDF: + case BARCODE_HIBC_AZTEC: + case BARCODE_HIBC_BLOCKF: + error_number = hibc(symbol, preprocessed, in_length); + break; + case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, in_length); + break; + case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, in_length); + break; + case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, in_length); + break; + case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, in_length); + break; + case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, in_length); + break; + case BARCODE_PDF417: + case BARCODE_PDF417TRUNC: + error_number = pdf417enc(symbol, preprocessed, in_length); + break; + case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, in_length); + break; + case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, in_length); + break; + case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, in_length); + break; + case BARCODE_DOTCODE: error_number = dotcode(symbol, preprocessed, in_length); + break; + case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, in_length); + break; + } + + return error_number; +} + +int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source,int in_length) { + int error_number, error_buffer, i; +#ifdef _MSC_VER + unsigned char* local_source; +#endif + error_number = 0; + + if (in_length == 0) { + in_length = (int)ustrlen(source); + } + if (in_length == 0) { + strcpy(symbol->errtxt, "205: No input data"); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); + return ZINT_ERROR_INVALID_DATA; + } + + if (strcmp(symbol->outfile, "") == 0) { +#ifdef NO_PNG + strcpy(symbol->outfile, "out.gif"); +#else + strcpy(symbol->outfile, "out.png"); +#endif + } +#ifndef _MSC_VER + unsigned char local_source[in_length + 1]; +#else + local_source = (unsigned char*) _alloca(in_length + 1); +#endif + + /* First check the symbology field */ + if (symbol->symbology < 1) { + strcpy(symbol->errtxt, "206: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + + /* symbol->symbologys 1 to 86 are defined by tbarcode */ + if (symbol->symbology == 5) { + symbol->symbology = BARCODE_C25MATRIX; + } + if ((symbol->symbology >= 10) && (symbol->symbology <= 12)) { + symbol->symbology = BARCODE_EANX; + } + if (symbol->symbology == 15) { + symbol->symbology = BARCODE_EANX; + } + if (symbol->symbology == 17) { + symbol->symbology = BARCODE_UPCA; + } + if (symbol->symbology == 19) { + strcpy(symbol->errtxt, "207: Codabar 18 not supported, using Codabar"); + symbol->symbology = BARCODE_CODABAR; + error_number = ZINT_WARN_INVALID_OPTION; + } + if (symbol->symbology == 26) { + symbol->symbology = BARCODE_UPCA; + } + if (symbol->symbology == 27) { + strcpy(symbol->errtxt, "208: UPCD1 not supported"); + error_number = ZINT_ERROR_INVALID_OPTION; + } + if (symbol->symbology == 33) { + symbol->symbology = BARCODE_EAN128; + } + if (symbol->symbology == 36) { + symbol->symbology = BARCODE_UPCA; + } + if (symbol->symbology == 38) { + symbol->symbology = BARCODE_UPCE; + } + if ((symbol->symbology >= 41) && (symbol->symbology <= 45)) { + symbol->symbology = BARCODE_POSTNET; + } + if (symbol->symbology == 46) { + symbol->symbology = BARCODE_PLESSEY; + } + if (symbol->symbology == 48) { + symbol->symbology = BARCODE_NVE18; + } + if (symbol->symbology == 54) { + strcpy(symbol->errtxt, "210: General Parcel Code not supported, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + if ((symbol->symbology == 59) || (symbol->symbology == 61)) { + symbol->symbology = BARCODE_CODE128; + } + if (symbol->symbology == 62) { + symbol->symbology = BARCODE_CODE93; + } + if ((symbol->symbology == 64) || (symbol->symbology == 65)) { + symbol->symbology = BARCODE_AUSPOST; + } + if (symbol->symbology == 73) { + strcpy(symbol->errtxt, "211: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + if (symbol->symbology == 78) { + symbol->symbology = BARCODE_RSS14; + } + if (symbol->symbology == 83) { + symbol->symbology = BARCODE_PLANET; + } + if (symbol->symbology == 88) { + symbol->symbology = BARCODE_EAN128; + } + if (symbol->symbology == 91) { + strcpy(symbol->errtxt, "212: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + if ((symbol->symbology >= 94) && (symbol->symbology <= 96)) { + strcpy(symbol->errtxt, "213: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + if (symbol->symbology == 100) { + symbol->symbology = BARCODE_HIBC_128; + } + if (symbol->symbology == 101) { + symbol->symbology = BARCODE_HIBC_39; + } + if (symbol->symbology == 103) { + symbol->symbology = BARCODE_HIBC_DM; + } + if (symbol->symbology == 105) { + symbol->symbology = BARCODE_HIBC_QR; + } + if (symbol->symbology == 107) { + symbol->symbology = BARCODE_HIBC_PDF; + } + if (symbol->symbology == 109) { + symbol->symbology = BARCODE_HIBC_MICPDF; + } + if (symbol->symbology == 111) { + symbol->symbology = BARCODE_HIBC_BLOCKF; + } + if ((symbol->symbology == 113) || (symbol->symbology == 114)) { + strcpy(symbol->errtxt, "214: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + if (symbol->symbology == 115) { + symbol->symbology = BARCODE_DOTCODE; + } + if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) { + strcpy(symbol->errtxt, "215: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + /* Everything from 128 up is Zint-specific */ + if (symbol->symbology >= 144) { + strcpy(symbol->errtxt, "216: Symbology out of range, using Code 128"); + symbol->symbology = BARCODE_CODE128; + error_number = ZINT_WARN_INVALID_OPTION; + } + + if (error_number > 4) { + error_tag(symbol->errtxt, error_number); + return error_number; + } else { + error_buffer = error_number; + } + + if ((!(supports_eci(symbol->symbology))) && (symbol->eci != 3)) { + strcpy(symbol->errtxt, "217: Symbology does not support ECI switching"); + error_number = ZINT_ERROR_INVALID_OPTION; + } + + if ((symbol->eci < 3) || (symbol->eci > 999999)) { + strcpy(symbol->errtxt, "218: Invalid ECI mode"); + error_number = ZINT_ERROR_INVALID_OPTION; + } + + if ((symbol->input_mode < 0) || (symbol->input_mode > 2)) { + symbol->input_mode = DATA_MODE; + } + + if ((symbol->eci != 3) && (symbol->eci != 26)) { + symbol->input_mode = DATA_MODE; + } + + if (symbol->input_mode == GS1_MODE) { + for (i = 0; i < in_length; i++) { + if (source[i] == '\0') { + strcpy(symbol->errtxt, "219: NULL characters not permitted in GS1 mode"); + return ZINT_ERROR_INVALID_DATA; + } + } + if (gs1_compliant(symbol->symbology) == 1) { + error_number = ugs1_verify(symbol, source, in_length, local_source); + if (error_number != 0) { + return error_number; + } + in_length =(int)ustrlen(local_source); + } else { + strcpy(symbol->errtxt, "220: Selected symbology does not support GS1 mode"); + return ZINT_ERROR_INVALID_OPTION; + } + } else { + memcpy(local_source, source, in_length); + local_source[in_length] = '\0'; + } + + if ((symbol->dot_size < 0.01) || (symbol->dot_size > 20.0)) { + strcpy(symbol->errtxt, "221: Invalid dot size"); + return ZINT_ERROR_INVALID_OPTION; + } + + switch (symbol->symbology) { + case BARCODE_QRCODE: + case BARCODE_MICROQR: + case BARCODE_GRIDMATRIX: + case BARCODE_HANXIN: + case BARCODE_UPNQR: + error_number = extended_charset(symbol, local_source, in_length); + break; + default: + error_number = reduced_charset(symbol, local_source, in_length); + break; + } + + if ((error_number == ZINT_ERROR_INVALID_DATA) && (supports_eci(symbol->symbology) + && (symbol->input_mode == UNICODE_MODE))) { + /* Try another ECI mode */ + symbol->eci = get_best_eci(local_source, in_length); + + error_number = ZINT_WARN_USES_ECI; + strcpy(symbol->errtxt, "222: Encoded data includes ECI codes"); + //printf("Data will encode with ECI %d\n", symbol->eci); + + switch (symbol->symbology) { + case BARCODE_QRCODE: + case BARCODE_MICROQR: + case BARCODE_GRIDMATRIX: + case BARCODE_HANXIN: + error_number = utf_to_eci(symbol->eci, source, local_source, (size_t*)&in_length); + error_number = extended_charset(symbol, local_source, in_length); + break; + default: + error_number = reduced_charset(symbol, local_source, in_length); + break; + } + + } + + if (error_number == 0) { + if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) { + for (i = 0; i < in_length; i++) { + if (local_source[i] == '\0') { + symbol->text[i] = ' '; + } else { + symbol->text[i] = local_source[i]; + } + } + } + error_number = error_buffer; + } + error_tag(symbol->errtxt, error_number); + + if (error_number <= 5) { + check_row_heights(symbol); + } + + return error_number; +} + +int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle) { + int error_number; + char output[4]; + + switch (rotate_angle) { + case 0: + case 90: + case 180: + case 270: + break; + default: + strcpy(symbol->errtxt, "223: Invalid rotation angle"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (symbol->output_options & BARCODE_DOTTY_MODE) { + if (!(is_matrix(symbol->symbology))) { + strcpy(symbol->errtxt, "224: Selected symbology cannot be rendered as dots"); + return ZINT_ERROR_INVALID_OPTION; + } + } + + if (strlen(symbol->outfile) > 3) { + output[0] = symbol->outfile[strlen(symbol->outfile) - 3]; + output[1] = symbol->outfile[strlen(symbol->outfile) - 2]; + output[2] = symbol->outfile[strlen(symbol->outfile) - 1]; + output[3] = '\0'; + to_upper((unsigned char*) output); + + if (!(strcmp(output, "PNG"))) { + if (symbol->scale < 1.0) { + symbol->text[0] = '\0'; + } + error_number = plot_raster(symbol, rotate_angle, OUT_PNG_FILE); + } else + if (!(strcmp(output, "BMP"))) { + if (symbol->scale < 1.0) { + symbol->text[0] = '\0'; + } + error_number = plot_raster(symbol, rotate_angle, OUT_BMP_FILE); + } else + if (!(strcmp(output, "PCX"))) { + if (symbol->scale < 1.0) { + symbol->text[0] = '\0'; + } + error_number = plot_raster(symbol, rotate_angle, OUT_PCX_FILE); + } else + if (!(strcmp(output, "GIF"))) { + if (symbol->scale < 1.0) { + symbol->text[0] = '\0'; + } + error_number = plot_raster(symbol, rotate_angle, OUT_GIF_FILE); + } else + if (!(strcmp(output, "TIF"))) { + if (symbol->scale < 1.0) { + symbol->text[0] = '\0'; + } + error_number = plot_raster(symbol, rotate_angle, OUT_TIF_FILE); + } else + if (!(strcmp(output, "TXT"))) { + error_number = dump_plot(symbol); + } else + if (!(strcmp(output, "EPS"))) { + error_number = ps_plot(symbol); + } else + if (!(strcmp(output, "SVG"))) { + error_number = svg_plot(symbol); + } else + if (!(strcmp(output, "EMF"))) { + error_number = emf_plot(symbol); + } else { + strcpy(symbol->errtxt, "225: Unknown output format"); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION); + return ZINT_ERROR_INVALID_OPTION; + } + } else { + strcpy(symbol->errtxt, "226: Unknown output format"); + error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION); + return ZINT_ERROR_INVALID_OPTION; + } + + if (error_number == ZINT_ERROR_INVALID_OPTION) { + /* If libpng is not installed */ + strcpy(symbol->errtxt, "227: Unknown output format"); + } + + error_tag(symbol->errtxt, error_number); + return error_number; +} + +int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle) { + int error_number; + + switch (rotate_angle) { + case 0: + case 90: + case 180: + case 270: + break; + default: + strcpy(symbol->errtxt, "228: Invalid rotation angle"); + return ZINT_ERROR_INVALID_OPTION; + } + + error_number = plot_raster(symbol, rotate_angle, OUT_BUFFER); + error_tag(symbol->errtxt, error_number); + return error_number; +} + +int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) { + int error_number; + + error_number = ZBarcode_Encode(symbol, input, length); + if (error_number != 0) { + return error_number; + } + + error_number = ZBarcode_Print(symbol, rotate_angle); + return error_number; +} + +int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) { + int error_number; + + error_number = ZBarcode_Encode(symbol, input, length); + if (error_number != 0) { + return error_number; + } + + error_number = ZBarcode_Buffer(symbol, rotate_angle); + return error_number; +} + +int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { + FILE *file; + unsigned char *buffer; + unsigned long fileLen; + unsigned int nRead = 0, n = 0; + int ret; + + if (!strcmp(filename, "-")) { + file = stdin; + fileLen = 7100; + } else { + file = fopen(filename, "rb"); + if (!file) { + strcpy(symbol->errtxt, "229: Unable to read input file"); + return ZINT_ERROR_INVALID_DATA; + } + + /* Get file length */ + fseek(file, 0, SEEK_END); + fileLen = ftell(file); + fseek(file, 0, SEEK_SET); + + if (fileLen > 7100) { + /* The largest amount of data that can be encoded is 7089 numeric digits in QR Code */ + strcpy(symbol->errtxt, "230: Input file too long"); + fclose(file); + return ZINT_ERROR_INVALID_DATA; + } + } + + /* Allocate memory */ + buffer = (unsigned char *) malloc(fileLen * sizeof (unsigned char)); + if (!buffer) { + strcpy(symbol->errtxt, "231: Internal memory error"); + if (strcmp(filename, "-")) + fclose(file); + return ZINT_ERROR_MEMORY; + } + + /* Read file contents into buffer */ + + do { + n = fread(buffer + nRead, 1, fileLen - nRead, file); + if (ferror(file)) { + strcpy(symbol->errtxt, strerror(errno)); + return ZINT_ERROR_INVALID_DATA; + } + nRead += n; + } while (!feof(file) && (0 < n) && (nRead < fileLen)); + + fclose(file); + ret = ZBarcode_Encode(symbol, buffer, nRead); + free(buffer); + return ret; +} + +int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) { + int error_number; + + error_number = ZBarcode_Encode_File(symbol, filename); + if (error_number != 0) { + return error_number; + } + + return ZBarcode_Print(symbol, rotate_angle); +} + +int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle) { + int error_number; + + error_number = ZBarcode_Encode_File(symbol, filename); + if (error_number != 0) { + return error_number; + } + + return ZBarcode_Buffer(symbol, rotate_angle); +} + +/* + * Rendering support, initially added by Sam Lown. + * + * Converts encoded data into an intermediate format to be interpreted + * in other applications using this library. + * + * If the width and height are not set to zero, the barcode will be resized to those + * dimensions. The symbol->scale and symbol->height values are totally ignored in this case. + * + */ +int ZBarcode_Render(struct zint_symbol *symbol, const float width, const float height) { + // Send the request to the render_plot method + return render_plot(symbol, width, height); +} + +int ZBarcode_Version() { + return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE; +} diff --git a/3rdparty/zint-2.6.1/backend/libzint.rc b/3rdparty/zint-2.6.1/backend/libzint.rc new file mode 100644 index 0000000..8e3b780 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/libzint.rc @@ -0,0 +1,42 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include + +#ifdef GCC_WINDRES +VS_VERSION_INFO VERSIONINFO +#else +VS_VERSION_INFO VERSIONINFO +#endif + FILEVERSION 2,6,0,0 + PRODUCTVERSION 2,6,0,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "libzint barcode library\0" + VALUE "FileVersion", "2.6.0.0\0" + VALUE "InternalName", "zint.dll\0" + VALUE "LegalCopyright", "Copyright 2017 Robin Stuart & BogDan Vatra\0" + VALUE "OriginalFilename", "zint.dll\0" + VALUE "ProductName", "libzint\0" + VALUE "ProductVersion", "2.6.0.0\0" + VALUE "License", "BSD License version 3\0" + VALUE "WWW", "http://www.sourceforge.net/projects/zint" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1250 + END +END diff --git a/3rdparty/zint-2.6.1/backend/maxicode.c b/3rdparty/zint-2.6.1/backend/maxicode.c new file mode 100644 index 0000000..a012367 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/maxicode.c @@ -0,0 +1,733 @@ +/* maxicode.c - Handles Maxicode */ + +/* + libzint - the open source barcode library + Copyright (C) 2010-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* Includes corrections thanks to Monica Swanson @ Source Technologies */ + +#include "common.h" +#include "maxicode.h" +#include "reedsol.h" +#include +#include + +int maxi_codeword[144]; + +/* Handles error correction of primary message */ +void maxi_do_primary_check() { + unsigned char data[15]; + unsigned char results[15]; + int j; + int datalen = 10; + int ecclen = 10; + + rs_init_gf(0x43); + rs_init_code(ecclen, 1); + + for (j = 0; j < datalen; j += 1) + data[j] = maxi_codeword[j]; + + rs_encode(datalen, data, results); + + for (j = 0; j < ecclen; j += 1) + maxi_codeword[ datalen + j] = results[ecclen - 1 - j]; + rs_free(); +} + +/* Handles error correction of odd characters in secondary */ +void maxi_do_secondary_chk_odd(int ecclen) { + unsigned char data[100]; + unsigned char results[30]; + int j; + int datalen = 68; + + rs_init_gf(0x43); + rs_init_code(ecclen, 1); + + if (ecclen == 20) + datalen = 84; + + for (j = 0; j < datalen; j += 1) + if (j & 1) // odd + data[(j - 1) / 2] = maxi_codeword[j + 20]; + + rs_encode(datalen / 2, data, results); + + for (j = 0; j < (ecclen); j += 1) + maxi_codeword[ datalen + (2 * j) + 1 + 20 ] = results[ecclen - 1 - j]; + rs_free(); +} + +/* Handles error correction of even characters in secondary */ +void maxi_do_secondary_chk_even(int ecclen) { + unsigned char data[100]; + unsigned char results[30]; + int j; + int datalen = 68; + + if (ecclen == 20) + datalen = 84; + + rs_init_gf(0x43); + rs_init_code(ecclen, 1); + + for (j = 0; j < datalen + 1; j += 1) + if (!(j & 1)) // even + data[j / 2] = maxi_codeword[j + 20]; + + rs_encode(datalen / 2, data, results); + + for (j = 0; j < (ecclen); j += 1) + maxi_codeword[ datalen + (2 * j) + 20] = results[ecclen - 1 - j]; + rs_free(); +} + +/* Moves everything up so that a shift or latch can be inserted */ +void maxi_bump(int set[], int character[], int bump_posn) { + int i; + + for (i = 143; i > bump_posn; i--) { + set[i] = set[i - 1]; + character[i] = character[i - 1]; + } +} + +/* Format text according to Appendix A */ +int maxi_text_process(int mode, unsigned char source[], int length, int eci) { + /* This code doesn't make use of [Lock in C], [Lock in D] + and [Lock in E] and so is not always the most efficient at + compressing data, but should suffice for most applications */ + + int set[144], character[144], i, j, done, count, current_set; + + if (length > 138) { + return ZINT_ERROR_TOO_LONG; + } + + for (i = 0; i < 144; i++) { + set[i] = -1; + character[i] = 0; + } + + for (i = 0; i < length; i++) { + /* Look up characters in table from Appendix A - this gives + value and code set for most characters */ + set[i] = maxiCodeSet[source[i]]; + character[i] = maxiSymbolChar[source[i]]; + } + + /* If a character can be represented in more than one code set, + pick which version to use */ + if (set[0] == 0) { + if (character[0] == 13) { + character[0] = 0; + } + set[0] = 1; + } + + for (i = 1; i < length; i++) { + if (set[i] == 0) { + done = 0; + /* Special character */ + if (character[i] == 13) { + /* Carriage Return */ + if (set[i - 1] == 5) { + character[i] = 13; + set[i] = 5; + } else { + if ((i != length - 1) && (set[i + 1] == 5)) { + character[i] = 13; + set[i] = 5; + } else { + character[i] = 0; + set[i] = 1; + } + } + done = 1; + } + + if ((character[i] == 28) && (done == 0)) { + /* FS */ + if (set[i - 1] == 5) { + character[i] = 32; + set[i] = 5; + } else { + set[i] = set[i - 1]; + } + done = 1; + } + + if ((character[i] == 29) && (done == 0)) { + /* GS */ + if (set[i - 1] == 5) { + character[i] = 33; + set[i] = 5; + } else { + set[i] = set[i - 1]; + } + done = 1; + } + + if ((character[i] == 30) && (done == 0)) { + /* RS */ + if (set[i - 1] == 5) { + character[i] = 34; + set[i] = 5; + } else { + set[i] = set[i - 1]; + } + done = 1; + } + + if ((character[i] == 32) && (done == 0)) { + /* Space */ + if (set[i - 1] == 1) { + character[i] = 32; + set[i] = 1; + } + if (set[i - 1] == 2) { + character[i] = 47; + set[i] = 2; + } + if (set[i - 1] >= 3) { + if (i != length - 1) { + if (set[i + 1] == 1) { + character[i] = 32; + set[i] = 1; + } + if (set[i + 1] == 2) { + character[i] = 47; + set[i] = 2; + } + if (set[i + 1] >= 3) { + character[i] = 59; + set[i] = set[i - 1]; + } + } else { + character[i] = 59; + set[i] = set[i - 1]; + } + } + done = 1; + } + + if ((character[i] == 44) && (done == 0)) { + /* Comma */ + if (set[i - 1] == 2) { + character[i] = 48; + set[i] = 2; + } else { + if ((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 48; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + + if ((character[i] == 46) && (done == 0)) { + /* Full Stop */ + if (set[i - 1] == 2) { + character[i] = 49; + set[i] = 2; + } else { + if ((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 49; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + + if ((character[i] == 47) && (done == 0)) { + /* Slash */ + if (set[i - 1] == 2) { + character[i] = 50; + set[i] = 2; + } else { + if ((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 50; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + + if ((character[i] == 58) && (done == 0)) { + /* Colon */ + if (set[i - 1] == 2) { + character[i] = 51; + set[i] = 2; + } else { + if ((i != length - 1) && (set[i + 1] == 2)) { + character[i] = 51; + set[i] = 2; + } else { + set[i] = 1; + } + } + done = 1; + } + } + } + + for (i = length; i < 144; i++) { + /* Add the padding */ + if (set[length - 1] == 2) { + set[i] = 2; + } else { + set[i] = 1; + } + character[i] = 33; + } + + /* Find candidates for number compression */ + if ((mode == 2) || (mode == 3)) { + j = 0; + } else { + j = 9; + } + /* Number compression not allowed in primary message */ + count = 0; + for (i = j; i < 143; i++) { + if ((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) { + /* Character is a number */ + count++; + } else { + count = 0; + } + if (count == 9) { + /* Nine digits in a row can be compressed */ + set[i] = 6; + set[i - 1] = 6; + set[i - 2] = 6; + set[i - 3] = 6; + set[i - 4] = 6; + set[i - 5] = 6; + set[i - 6] = 6; + set[i - 7] = 6; + set[i - 8] = 6; + count = 0; + } + } + + /* Add shift and latch characters */ + current_set = 1; + i = 0; + do { + + if ((set[i] != current_set) && (set[i] != 6)) { + switch (set[i]) { + case 1: + if (set[i + 1] == 1) { + if (set[i + 2] == 1) { + if (set[i + 3] == 1) { + /* Latch A */ + maxi_bump(set, character, i); + character[i] = 63; + current_set = 1; + length++; + } else { + /* 3 Shift A */ + maxi_bump(set, character, i); + character[i] = 57; + length++; + i += 2; + } + } else { + /* 2 Shift A */ + maxi_bump(set, character, i); + character[i] = 56; + length++; + i++; + } + } else { + /* Shift A */ + maxi_bump(set, character, i); + character[i] = 59; + length++; + } + break; + case 2: + if (set[i + 1] == 2) { + /* Latch B */ + maxi_bump(set, character, i); + character[i] = 63; + current_set = 2; + length++; + } else { + /* Shift B */ + maxi_bump(set, character, i); + character[i] = 59; + length++; + } + break; + case 3: + /* Shift C */ + maxi_bump(set, character, i); + character[i] = 60; + length++; + break; + case 4: + /* Shift D */ + maxi_bump(set, character, i); + character[i] = 61; + length++; + break; + case 5: + /* Shift E */ + maxi_bump(set, character, i); + character[i] = 62; + length++; + break; + } + i++; + } + i++; + } while (i < 144); + + /* Number compression has not been forgotten! - It's handled below */ + i = 0; + do { + if (set[i] == 6) { + /* Number compression */ + char substring[11]; + int value; + + for (j = 0; j < 9; j++) { + substring[j] = character[i + j]; + } + substring[9] = '\0'; + value = atoi(substring); + + character[i] = 31; /* NS */ + character[i + 1] = (value & 0x3f000000) >> 24; + character[i + 2] = (value & 0xfc0000) >> 18; + character[i + 3] = (value & 0x3f000) >> 12; + character[i + 4] = (value & 0xfc0) >> 6; + character[i + 5] = (value & 0x3f); + + i += 6; + for (j = i; j < 140; j++) { + set[j] = set[j + 3]; + character[j] = character[j + 3]; + } + length -= 3; + } else { + i++; + } + } while (i <= 143); + + /* Insert ECI at the beginning of message if needed */ + /* Encode ECI assignment numbers according to table 3 */ + if (eci != 3) { + maxi_bump(set, character, 0); + character[0] = 27; // ECI + if (eci <= 31) { + maxi_bump(set, character, 1); + character[1] = eci; + length += 2; + } + if ((eci >= 32) && (eci <= 1023)) { + maxi_bump(set, character, 1); + maxi_bump(set, character, 1); + character[1] = 0x20 + ((eci >> 6) & 0x0F); + character[2] = eci & 0x3F; + length += 3; + } + if ((eci >= 1024) && (eci <= 32767)) { + maxi_bump(set, character, 1); + maxi_bump(set, character, 1); + maxi_bump(set, character, 1); + character[1] = 0x30 + ((eci >> 12) & 0x03); + character[2] = (eci >> 6) & 0x3F; + character[3] = eci & 0x3F; + length += 4; + } + if (eci >= 32768) { + maxi_bump(set, character, 1); + maxi_bump(set, character, 1); + maxi_bump(set, character, 1); + maxi_bump(set, character, 1); + character[1] = 0x38 + ((eci >> 18) & 0x02); + character[2] = (eci >> 12) & 0x3F; + character[3] = (eci >> 6) & 0x3F; + character[4] = eci & 0x3F; + length += 5; + } + } + + if (((mode == 2) || (mode == 3)) && (length > 84)) { + return ZINT_ERROR_TOO_LONG; + } + + if (((mode == 4) || (mode == 6)) && (length > 93)) { + return ZINT_ERROR_TOO_LONG; + } + + if ((mode == 5) && (length > 77)) { + return ZINT_ERROR_TOO_LONG; + } + + + /* Copy the encoded text into the codeword array */ + if ((mode == 2) || (mode == 3)) { + for (i = 0; i < 84; i++) { /* secondary only */ + maxi_codeword[i + 20] = character[i]; + } + } + + if ((mode == 4) || (mode == 6)) { + for (i = 0; i < 9; i++) { /* primary */ + maxi_codeword[i + 1] = character[i]; + } + for (i = 0; i < 84; i++) { /* secondary */ + maxi_codeword[i + 20] = character[i + 9]; + } + } + + if (mode == 5) { + for (i = 0; i < 9; i++) { /* primary */ + maxi_codeword[i + 1] = character[i]; + } + for (i = 0; i < 68; i++) { /* secondary */ + maxi_codeword[i + 20] = character[i + 9]; + } + } + + return 0; +} + +/* Format structured primary for Mode 2 */ +void maxi_do_primary_2(char postcode[], int country, int service) { + size_t postcode_length; + int postcode_num, i; + + for (i = 0; i < 10; i++) { + if ((postcode[i] < '0') || (postcode[i] > '9')) { + postcode[i] = '\0'; + } + } + + postcode_length = strlen(postcode); + postcode_num = atoi(postcode); + + maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2; + maxi_codeword[1] = ((postcode_num & 0xfc) >> 2); + maxi_codeword[2] = ((postcode_num & 0x3f00) >> 8); + maxi_codeword[3] = ((postcode_num & 0xfc000) >> 14); + maxi_codeword[4] = ((postcode_num & 0x3f00000) >> 20); + maxi_codeword[5] = ((postcode_num & 0x3c000000) >> 26) | ((postcode_length & 0x3) << 4); + maxi_codeword[6] = ((postcode_length & 0x3c) >> 2) | ((country & 0x3) << 4); + maxi_codeword[7] = (country & 0xfc) >> 2; + maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); + maxi_codeword[9] = ((service & 0x3f0) >> 4); +} + +/* Format structured primary for Mode 3 */ +void maxi_do_primary_3(char postcode[], int country, int service) { + int i, h; + + h = strlen(postcode); + to_upper((unsigned char*) postcode); + for (i = 0; i < h; i++) { + if ((postcode[i] >= 'A') && (postcode[i] <= 'Z')) { + /* (Capital) letters shifted to Code Set A values */ + postcode[i] -= 64; + } + if (((postcode[i] == 27) || (postcode[i] == 31)) || ((postcode[i] == 33) || (postcode[i] >= 59))) { + /* Not a valid postcode character */ + postcode[i] = ' '; + } + /* Input characters lower than 27 (NUL - SUB) in postcode are + interpreted as capital letters in Code Set A (e.g. LF becomes 'J') */ + } + + maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3; + maxi_codeword[1] = ((postcode[4] & 0x03) << 4) | ((postcode[5] & 0x3c) >> 2); + maxi_codeword[2] = ((postcode[3] & 0x03) << 4) | ((postcode[4] & 0x3c) >> 2); + maxi_codeword[3] = ((postcode[2] & 0x03) << 4) | ((postcode[3] & 0x3c) >> 2); + maxi_codeword[4] = ((postcode[1] & 0x03) << 4) | ((postcode[2] & 0x3c) >> 2); + maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2); + maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4); + maxi_codeword[7] = (country & 0xfc) >> 2; + maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2); + maxi_codeword[9] = ((service & 0x3f0) >> 4); +} + +int maxicode(struct zint_symbol *symbol, unsigned char local_source[], int length) { + int i, j, block, bit, mode, countrycode = 0, service = 0, lp = 0; + int bit_pattern[7], internal_error = 0, eclen; + char postcode[12], countrystr[4], servicestr[4]; + + mode = symbol->option_1; + strcpy(postcode, ""); + strcpy(countrystr, ""); + strcpy(servicestr, ""); + + memset(maxi_codeword, 0, sizeof (maxi_codeword)); + + if (mode == -1) { /* If mode is unspecified */ + lp = strlen(symbol->primary); + if (lp == 0) { + mode = 4; + } else { + mode = 2; + for (i = 0; i < 10 && i < lp; i++) { + if ((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) { + mode = 3; + break; + } + } + } + } + + if ((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */ + strcpy(symbol->errtxt, "550: Invalid Maxicode Mode"); + return ZINT_ERROR_INVALID_OPTION; + } + + if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */ + if (lp == 0) { /* Mode set manually means lp doesn't get set */ + lp = strlen(symbol->primary); + } + if (lp != 15) { + strcpy(symbol->errtxt, "551: Invalid Primary String"); + return ZINT_ERROR_INVALID_DATA; + } + + for (i = 9; i < 15; i++) { /* check that country code and service are numeric */ + if ((symbol->primary[i] < '0') || (symbol->primary[i] > '9')) { + strcpy(symbol->errtxt, "552: Invalid Primary String"); + return ZINT_ERROR_INVALID_DATA; + } + } + + memcpy(postcode, symbol->primary, 9); + postcode[9] = '\0'; + + if (mode == 2) { + for (i = 0; i < 10; i++) { + if (postcode[i] == ' ') { + postcode[i] = '\0'; + } + } + } else if (mode == 3) { + postcode[6] = '\0'; + } + + countrystr[0] = symbol->primary[9]; + countrystr[1] = symbol->primary[10]; + countrystr[2] = symbol->primary[11]; + countrystr[3] = '\0'; + + servicestr[0] = symbol->primary[12]; + servicestr[1] = symbol->primary[13]; + servicestr[2] = symbol->primary[14]; + servicestr[3] = '\0'; + + countrycode = atoi(countrystr); + service = atoi(servicestr); + + if (mode == 2) { + maxi_do_primary_2(postcode, countrycode, service); + } + if (mode == 3) { + maxi_do_primary_3(postcode, countrycode, service); + } + } else { + maxi_codeword[0] = mode; + } + + i = maxi_text_process(mode, local_source, length, symbol->eci); + if (i == ZINT_ERROR_TOO_LONG) { + strcpy(symbol->errtxt, "553: Input data too long"); + return i; + } + + /* All the data is sorted - now do error correction */ + maxi_do_primary_check(); /* always EEC */ + + if (mode == 5) + eclen = 56; // 68 data codewords , 56 error corrections + else + eclen = 40; // 84 data codewords, 40 error corrections + + maxi_do_secondary_chk_even(eclen / 2); // do error correction of even + maxi_do_secondary_chk_odd(eclen / 2); // do error correction of odd + + /* Copy data into symbol grid */ + for (i = 0; i < 33; i++) { + for (j = 0; j < 30; j++) { + block = (MaxiGrid[(i * 30) + j] + 5) / 6; + bit = (MaxiGrid[(i * 30) + j] + 5) % 6; + + if (block != 0) { + + bit_pattern[0] = (maxi_codeword[block - 1] & 0x20) >> 5; + bit_pattern[1] = (maxi_codeword[block - 1] & 0x10) >> 4; + bit_pattern[2] = (maxi_codeword[block - 1] & 0x8) >> 3; + bit_pattern[3] = (maxi_codeword[block - 1] & 0x4) >> 2; + bit_pattern[4] = (maxi_codeword[block - 1] & 0x2) >> 1; + bit_pattern[5] = (maxi_codeword[block - 1] & 0x1); + + if (bit_pattern[bit] != 0) { + set_module(symbol, i, j); + } + } + } + } + + /* Add orientation markings */ + set_module(symbol, 0, 28); // Top right filler + set_module(symbol, 0, 29); + set_module(symbol, 9, 10); // Top left marker + set_module(symbol, 9, 11); + set_module(symbol, 10, 11); + set_module(symbol, 15, 7); // Left hand marker + set_module(symbol, 16, 8); + set_module(symbol, 16, 20); // Right hand marker + set_module(symbol, 17, 20); + set_module(symbol, 22, 10); // Bottom left marker + set_module(symbol, 23, 10); + set_module(symbol, 22, 17); // Bottom right marker + set_module(symbol, 23, 17); + + symbol->width = 30; + symbol->rows = 33; + + return internal_error; +} diff --git a/3rdparty/zint-2.6.1/backend/maxicode.h b/3rdparty/zint-2.6.1/backend/maxicode.h new file mode 100644 index 0000000..2d22459 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/maxicode.h @@ -0,0 +1,104 @@ +/* maxicode.h - Handles Maxicode */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +static const unsigned short int MaxiGrid[] = { + /* ISO/IEC 16023 Figure 5 - MaxiCode Module Sequence */ /* 30 x 33 data grid */ + 122, 121, 128, 127, 134, 133, 140, 139, 146, 145, 152, 151, 158, 157, 164, 163, 170, 169, 176, 175, 182, 181, 188, 187, 194, 193, 200, 199, 0, 0, + 124, 123, 130, 129, 136, 135, 142, 141, 148, 147, 154, 153, 160, 159, 166, 165, 172, 171, 178, 177, 184, 183, 190, 189, 196, 195, 202, 201, 817, 0, + 126, 125, 132, 131, 138, 137, 144, 143, 150, 149, 156, 155, 162, 161, 168, 167, 174, 173, 180, 179, 186, 185, 192, 191, 198, 197, 204, 203, 819, 818, + 284, 283, 278, 277, 272, 271, 266, 265, 260, 259, 254, 253, 248, 247, 242, 241, 236, 235, 230, 229, 224, 223, 218, 217, 212, 211, 206, 205, 820, 0, + 286, 285, 280, 279, 274, 273, 268, 267, 262, 261, 256, 255, 250, 249, 244, 243, 238, 237, 232, 231, 226, 225, 220, 219, 214, 213, 208, 207, 822, 821, + 288, 287, 282, 281, 276, 275, 270, 269, 264, 263, 258, 257, 252, 251, 246, 245, 240, 239, 234, 233, 228, 227, 222, 221, 216, 215, 210, 209, 823, 0, + 290, 289, 296, 295, 302, 301, 308, 307, 314, 313, 320, 319, 326, 325, 332, 331, 338, 337, 344, 343, 350, 349, 356, 355, 362, 361, 368, 367, 825, 824, + 292, 291, 298, 297, 304, 303, 310, 309, 316, 315, 322, 321, 328, 327, 334, 333, 340, 339, 346, 345, 352, 351, 358, 357, 364, 363, 370, 369, 826, 0, + 294, 293, 300, 299, 306, 305, 312, 311, 318, 317, 324, 323, 330, 329, 336, 335, 342, 341, 348, 347, 354, 353, 360, 359, 366, 365, 372, 371, 828, 827, + 410, 409, 404, 403, 398, 397, 392, 391, 80, 79, 0, 0, 14, 13, 38, 37, 3, 0, 45, 44, 110, 109, 386, 385, 380, 379, 374, 373, 829, 0, + 412, 411, 406, 405, 400, 399, 394, 393, 82, 81, 41, 0, 16, 15, 40, 39, 4, 0, 0, 46, 112, 111, 388, 387, 382, 381, 376, 375, 831, 830, + 414, 413, 408, 407, 402, 401, 396, 395, 84, 83, 42, 0, 0, 0, 0, 0, 6, 5, 48, 47, 114, 113, 390, 389, 384, 383, 378, 377, 832, 0, + 416, 415, 422, 421, 428, 427, 104, 103, 56, 55, 17, 0, 0, 0, 0, 0, 0, 0, 21, 20, 86, 85, 434, 433, 440, 439, 446, 445, 834, 833, + 418, 417, 424, 423, 430, 429, 106, 105, 58, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 22, 88, 87, 436, 435, 442, 441, 448, 447, 835, 0, + 420, 419, 426, 425, 432, 431, 108, 107, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 90, 89, 438, 437, 444, 443, 450, 449, 837, 836, + 482, 481, 476, 475, 470, 469, 49, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 54, 53, 464, 463, 458, 457, 452, 451, 838, 0, + 484, 483, 478, 477, 472, 471, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 465, 460, 459, 454, 453, 840, 839, + 486, 485, 480, 479, 474, 473, 52, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 43, 468, 467, 462, 461, 456, 455, 841, 0, + 488, 487, 494, 493, 500, 499, 98, 97, 62, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 92, 91, 506, 505, 512, 511, 518, 517, 843, 842, + 490, 489, 496, 495, 502, 501, 100, 99, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 29, 28, 94, 93, 508, 507, 514, 513, 520, 519, 844, 0, + 492, 491, 498, 497, 504, 503, 102, 101, 66, 65, 18, 0, 0, 0, 0, 0, 0, 0, 19, 30, 96, 95, 510, 509, 516, 515, 522, 521, 846, 845, + 560, 559, 554, 553, 548, 547, 542, 541, 74, 73, 33, 0, 0, 0, 0, 0, 0, 11, 68, 67, 116, 115, 536, 535, 530, 529, 524, 523, 847, 0, + 562, 561, 556, 555, 550, 549, 544, 543, 76, 75, 0, 0, 8, 7, 36, 35, 12, 0, 70, 69, 118, 117, 538, 537, 532, 531, 526, 525, 849, 848, + 564, 563, 558, 557, 552, 551, 546, 545, 78, 77, 0, 34, 10, 9, 26, 25, 0, 0, 72, 71, 120, 119, 540, 539, 534, 533, 528, 527, 850, 0, + 566, 565, 572, 571, 578, 577, 584, 583, 590, 589, 596, 595, 602, 601, 608, 607, 614, 613, 620, 619, 626, 625, 632, 631, 638, 637, 644, 643, 852, 851, + 568, 567, 574, 573, 580, 579, 586, 585, 592, 591, 598, 597, 604, 603, 610, 609, 616, 615, 622, 621, 628, 627, 634, 633, 640, 639, 646, 645, 853, 0, + 570, 569, 576, 575, 582, 581, 588, 587, 594, 593, 600, 599, 606, 605, 612, 611, 618, 617, 624, 623, 630, 629, 636, 635, 642, 641, 648, 647, 855, 854, + 728, 727, 722, 721, 716, 715, 710, 709, 704, 703, 698, 697, 692, 691, 686, 685, 680, 679, 674, 673, 668, 667, 662, 661, 656, 655, 650, 649, 856, 0, + 730, 729, 724, 723, 718, 717, 712, 711, 706, 705, 700, 699, 694, 693, 688, 687, 682, 681, 676, 675, 670, 669, 664, 663, 658, 657, 652, 651, 858, 857, + 732, 731, 726, 725, 720, 719, 714, 713, 708, 707, 702, 701, 696, 695, 690, 689, 684, 683, 678, 677, 672, 671, 666, 665, 660, 659, 654, 653, 859, 0, + 734, 733, 740, 739, 746, 745, 752, 751, 758, 757, 764, 763, 770, 769, 776, 775, 782, 781, 788, 787, 794, 793, 800, 799, 806, 805, 812, 811, 861, 860, + 736, 735, 742, 741, 748, 747, 754, 753, 760, 759, 766, 765, 772, 771, 778, 777, 784, 783, 790, 789, 796, 795, 802, 801, 808, 807, 814, 813, 862, 0, + 738, 737, 744, 743, 750, 749, 756, 755, 762, 761, 768, 767, 774, 773, 780, 779, 786, 785, 792, 791, 798, 797, 804, 803, 810, 809, 816, 815, 864, 863 +}; + +static const char maxiCodeSet[256] = { + /* from Appendix A - ASCII character to Code Set (e.g. 2 = Set B) */ + /* set 0 refers to special characters that fit into more than one set (e.g. GS) */ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 3, 4, 3, 5, 5, 4, 4, 3, 3, 3, + 4, 3, 5, 4, 4, 3, 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +static const char maxiSymbolChar[256] = { + /* from Appendix A - ASCII character to symbol value */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 30, 28, 29, 30, 35, 32, 53, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 37, + 38, 39, 40, 41, 52, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 42, 43, 44, 45, 46, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 32, 54, 34, 35, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 36, + 37, 37, 38, 39, 40, 41, 42, 43, 38, 44, 37, 39, 38, 45, 46, 40, 41, 39, 40, 41, + 42, 42, 47, 43, 44, 43, 44, 45, 45, 46, 47, 46, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, + 33, 34, 35, 36, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 33, 34, 35, 36 +}; + diff --git a/3rdparty/zint-2.6.1/backend/medical.c b/3rdparty/zint-2.6.1/backend/medical.c new file mode 100644 index 0000000..94bd72a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/medical.c @@ -0,0 +1,306 @@ +/* medical.c - Handles 1 track and 2 track pharmacode and Codabar */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" + +extern int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length); +/* Codabar table checked against EN 798:1995 */ + +#define CALCIUM "0123456789-$:/.+ABCD" + +static const char *CodaTable[20] = { + "11111221", "11112211", "11121121", "22111111", "11211211", "21111211", + "12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121", + "21212111", "11212121", "11221211", "12121121", "11121221", "11122211" +}; + +int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length) { + /* "Pharmacode can represent only a single integer from 3 to 131070. Unlike other + commonly used one-dimensional barcode schemes, pharmacode does not store the data in a + form corresponding to the human-readable digits; the number is encoded in binary, rather + than decimal. Pharmacode is read from right to left: with n as the bar position starting + at 0 on the right, each narrow bar adds 2n to the value and each wide bar adds 2(2^n). + The minimum barcode is 2 bars and the maximum 16, so the smallest number that could + be encoded is 3 (2 narrow bars) and the biggest is 131070 (16 wide bars)." + - http://en.wikipedia.org/wiki/Pharmacode */ + + /* This code uses the One Track Pharamacode calculating algorithm as recommended by + the specification at http://www.laetus.com/laetus.php?request=file&id=69 */ + + unsigned long int tester; + int counter, error_number, h; + char inter[18] = {0}; /* 131070 -> 17 bits */ + char dest[64]; /* 17 * 2 + 1 */ + + if (length > 6) { + strcpy(symbol->errtxt, "350: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "351: Invalid characters in data"); + return error_number; + } + + tester = atoi((char*) source); + + if ((tester < 3) || (tester > 131070)) { + strcpy(symbol->errtxt, "352: Data out of range"); + return ZINT_ERROR_INVALID_DATA; + } + + do { + if (!(tester & 1)) { + strcat(inter, "W"); + tester = (tester - 2) / 2; + } else { + strcat(inter, "N"); + tester = (tester - 1) / 2; + } + } while (tester != 0); + + h = strlen(inter) - 1; + *dest = '\0'; + for (counter = h; counter >= 0; counter--) { + if (inter[counter] == 'W') { + strcat(dest, "32"); + } else { + strcat(dest, "12"); + } + } + + expand(symbol, dest); + + return error_number; +} + +int pharma_two_calc(struct zint_symbol *symbol, unsigned char source[], char dest[]) { + /* This code uses the Two Track Pharamacode defined in the document at + http://www.laetus.com/laetus.php?request=file&id=69 and using a modified + algorithm from the One Track system. This standard accepts integet values + from 4 to 64570080. */ + + unsigned long int tester; + int counter, h; + char inter[17]; + int error_number; + + tester = atoi((char*) source); + + if ((tester < 4) || (tester > 64570080)) { + strcpy(symbol->errtxt, "353: Data out of range"); + return ZINT_ERROR_INVALID_DATA; + } + error_number = 0; + strcpy(inter, ""); + do { + switch (tester % 3) { + case 0: + strcat(inter, "3"); + tester = (tester - 3) / 3; + break; + case 1: + strcat(inter, "1"); + tester = (tester - 1) / 3; + break; + case 2: + strcat(inter, "2"); + tester = (tester - 2) / 3; + break; + } + } while (tester != 0); + + h = strlen(inter) - 1; + for (counter = h; counter >= 0; counter--) { + dest[h - counter] = inter[counter]; + } + dest[h + 1] = '\0'; + + return error_number; +} + +int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length) { + /* Draws the patterns for two track pharmacode */ + char height_pattern[200]; + unsigned int loopey, h; + int writer; + int error_number = 0; + strcpy(height_pattern, ""); + + if (length > 8) { + strcpy(symbol->errtxt, "354: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "355: Invalid characters in data"); + return error_number; + } + error_number = pharma_two_calc(symbol, source, height_pattern); + if (error_number != 0) { + return error_number; + } + + writer = 0; + h = strlen(height_pattern); + for (loopey = 0; loopey < h; loopey++) { + if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '3')) { + set_module(symbol, 0, writer); + } + if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '3')) { + set_module(symbol, 1, writer); + } + writer += 2; + } + symbol->rows = 2; + symbol->width = writer - 1; + + + return error_number; +} + +/* The Codabar system consisting of simple substitution */ +int codabar(struct zint_symbol *symbol, unsigned char source[], int length) { + + int i, error_number; + char dest[512]; + + strcpy(dest, ""); + + if (length > 60) { /* No stack smashing please */ + strcpy(symbol->errtxt, "356: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(CALCIUM, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "357: Invalid characters in data"); + return error_number; + } + /* Codabar must begin and end with the characters A, B, C or D */ + if ((source[0] != 'A') && (source[0] != 'B') && (source[0] != 'C') + && (source[0] != 'D')) { + strcpy(symbol->errtxt, "358: Invalid characters in data"); + return ZINT_ERROR_INVALID_DATA; + } + + if ((source[length - 1] != 'A') && (source[length - 1] != 'B') && + (source[length - 1] != 'C') && (source[length - 1] != 'D')) { + strcpy(symbol->errtxt, "359: Invalid characters in data"); + return ZINT_ERROR_INVALID_DATA; + } + + for (i = 0; i < length; i++) { + lookup(CALCIUM, CodaTable, source[i], dest); + } + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return error_number; +} + +/* Italian Pharmacode */ +int code32(struct zint_symbol *symbol, unsigned char source[], int length) { + int i, zeroes, error_number, checksum, checkpart, checkdigit; + char localstr[10], risultante[7]; + long int pharmacode, remainder, devisor; + int codeword[6]; + char tabella[34]; + + /* Validate the input */ + if (length > 8) { + strcpy(symbol->errtxt, "360: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "361: Invalid characters in data"); + return error_number; + } + + /* Add leading zeros as required */ + zeroes = 8 - length; + memset(localstr, '0', zeroes); + strcpy(localstr + zeroes, (char*) source); + + /* Calculate the check digit */ + checksum = 0; + checkpart = 0; + for (i = 0; i < 4; i++) { + checkpart = ctoi(localstr[i * 2]); + checksum += checkpart; + checkpart = 2 * (ctoi(localstr[(i * 2) + 1])); + if (checkpart >= 10) { + checksum += (checkpart - 10) + 1; + } else { + checksum += checkpart; + } + } + + /* Add check digit to data string */ + checkdigit = checksum % 10; + localstr[8] = itoc(checkdigit); + localstr[9] = '\0'; + + /* Convert string into an integer value */ + pharmacode = atoi(localstr); + + /* Convert from decimal to base-32 */ + devisor = 33554432; + for (i = 5; i >= 0; i--) { + codeword[i] = pharmacode / devisor; + remainder = pharmacode % devisor; + pharmacode = remainder; + devisor /= 32; + } + + /* Look up values in 'Tabella di conversione' */ + strcpy(tabella, "0123456789BCDFGHJKLMNPQRSTUVWXYZ"); + for (i = 5; i >= 0; i--) { + risultante[5 - i] = tabella[codeword[i]]; + } + risultante[6] = '\0'; + /* Plot the barcode using Code 39 */ + error_number = c39(symbol, (unsigned char*) risultante, strlen(risultante)); + if (error_number != 0) { + return error_number; + } + + /* Override the normal text output with the Pharmacode number */ + strcpy((char*) symbol->text, "A"); + strcat((char*) symbol->text, (char*) localstr); + + return error_number; +} diff --git a/3rdparty/zint-2.4.4/backend/ms_stdint.h b/3rdparty/zint-2.6.1/backend/ms_stdint.h similarity index 100% rename from 3rdparty/zint-2.4.4/backend/ms_stdint.h rename to 3rdparty/zint-2.6.1/backend/ms_stdint.h diff --git a/3rdparty/zint-2.6.1/backend/pcx.c b/3rdparty/zint-2.6.1/backend/pcx.c new file mode 100644 index 0000000..0a77ffa --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/pcx.c @@ -0,0 +1,172 @@ +/* pcx.c - Handles output to ZSoft PCX file */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" +#include "pcx.h" /* PCX header structure */ +#include +#ifdef _MSC_VER +#include +#include +#include +#endif + +#define SSET "0123456789ABCDEF" + +int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + int row, column, i, colour; + int run_count; + FILE *pcx_file; + pcx_header_t header; +#ifdef _MSC_VER + unsigned char* rle_row; +#endif + +#ifndef _MSC_VER + unsigned char rle_row[symbol->bitmap_width]; +#else + rle_row = (unsigned char *) _alloca((symbol->bitmap_width * 6) * sizeof (unsigned char)); +#endif /* _MSC_VER */ + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + + header.manufacturer = 10; // ZSoft + header.version = 5; // Version 3.0 + header.encoding = 1; // Run length encoding + header.bits_per_pixel = 8; + header.window_xmin = 0; + header.window_ymin = 0; + header.window_xmax = symbol->bitmap_width - 1; + header.window_ymax = symbol->bitmap_height - 1; + header.horiz_dpi = 300; + header.vert_dpi = 300; + + for (i = 0; i < 48; i++) { + header.colourmap[i] = 0x00; + } + + header.reserved = 0; + header.number_of_planes = 3; + + if (symbol->bitmap_width % 2) { + header.bytes_per_line = symbol->bitmap_width + 1; + } else { + header.bytes_per_line = symbol->bitmap_width; + } + + header.palette_info = 1; // Colour + header.horiz_screen_size = 0; + header.vert_screen_size = 0; + + for (i = 0; i < 54; i++) { + header.filler[i] = 0x00; + } + + /* Open output file in binary mode */ + if (symbol->output_options & BARCODE_STDOUT) { +#ifdef _MSC_VER + if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { + strcpy(symbol->errtxt, "620: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } +#endif + pcx_file = stdout; + } else { + if (!(pcx_file = fopen(symbol->outfile, "wb"))) { + strcpy(symbol->errtxt, "621: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + } + + fwrite(&header, sizeof (pcx_header_t), 1, pcx_file); + + for (row = 0; row < symbol->bitmap_height; row++) { + for (colour = 0; colour < 3; colour++) { + for (column = 0; column < symbol->bitmap_width; column++) { + switch (colour) { + case 0: + if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') { + rle_row[column] = fgred; + } else { + rle_row[column] = bgred; + } + break; + case 1: + if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') { + rle_row[column] = fggrn; + } else { + rle_row[column] = bggrn; + } + break; + case 2: + if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') { + rle_row[column] = fgblu; + } else { + rle_row[column] = bgblu; + } + break; + } + } + + run_count = 1; + for (column = 1; column < symbol->bitmap_width; column++) { + if ((rle_row[column - 1] == rle_row[column]) && (run_count < 63)) { + run_count++; + } else { + run_count += 0xc0; + fputc(run_count, pcx_file); + fputc(rle_row[column - 1], pcx_file); + run_count = 1; + } + } + + if (run_count > 1) { + run_count += 0xc0; + fputc(run_count, pcx_file); + fputc(rle_row[column - 1], pcx_file); + } + } + } + + fclose(pcx_file); + + return 0; +} \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/pcx.h b/3rdparty/zint-2.6.1/backend/pcx.h new file mode 100644 index 0000000..4497cc2 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/pcx.h @@ -0,0 +1,76 @@ +/* pcx.h - header structure for ZSoft PCX files + + libzint - the open source barcode library + Copyright (C) 2016-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#ifndef PCX_H +#define PCX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#include +#include "stdint_msvc.h" +#else +#include +#endif + +#pragma pack (1) + + typedef struct pcx_header { + uint8_t manufacturer; + uint8_t version; + uint8_t encoding; + uint8_t bits_per_pixel; + uint16_t window_xmin; + uint16_t window_ymin; + uint16_t window_xmax; + uint16_t window_ymax; + uint16_t horiz_dpi; + uint16_t vert_dpi; + uint8_t colourmap[48]; + uint8_t reserved; + uint8_t number_of_planes; + uint16_t bytes_per_line; + uint16_t palette_info; + uint16_t horiz_screen_size; + uint16_t vert_screen_size; + uint8_t filler[54]; + } pcx_header_t; + +#pragma pack () + +#ifdef __cplusplus +} +#endif + +#endif /* PCX_H */ + diff --git a/3rdparty/zint-2.6.1/backend/pdf417.c b/3rdparty/zint-2.6.1/backend/pdf417.c new file mode 100644 index 0000000..ca64578 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/pdf417.c @@ -0,0 +1,1296 @@ +/* pdf417.c - Handles PDF417 stacked symbology */ + +/* Zint - A barcode generating program using libpng + Copyright (C) 2008-2017 Robin Stuart + Portions Copyright (C) 2004 Grandzebu + Bug Fixes thanks to KL Chin + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* This code is adapted from "Code barre PDF 417 / PDF 417 barcode" v2.5.0 + which is Copyright (C) 2004 (Grandzebu). + The original code can be downloaded from http://grandzebu.net/index.php */ + +/* NOTE: symbol->option_1 is used to specify the security level (i.e. control the + number of check codewords) + + symbol->option_2 is used to adjust the width of the resulting symbol (i.e. the + number of codeword columns not including row start and end data) */ + +#include +#include +#include +#include +#ifndef _MSC_VER +#include +#else +#include +#include "ms_stdint.h" +#endif +#include "pdf417.h" +#include "common.h" +#include "large.h" + +/* + Three figure numbers in comments give the location of command equivalents in the + original Visual Basic source code file pdf417.frm + this code retains some original (French) procedure and variable names to ease conversion */ + +/* text mode processing tables */ + +static const char asciix[95] = { + 7, 8, 8, 4, 12, 4, 4, 8, 8, 8, 12, 4, 12, 12, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 12, 8, 8, 4, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 8, 8, 8, 4, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 8, 8, 8, 8 +}; + +static const char asciiy[95] = { + 26, 10, 20, 15, 18, 21, 10, 28, 23, 24, 22, 20, 13, 16, 17, 19, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 14, 0, 1, 23, 2, 25, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 4, 5, 6, 24, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 21, 27, 9 +}; + +/* Automatic sizing table */ + +static const char MicroAutosize[56] = { + 4, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19, 20, 24, 29, 30, 33, 34, 37, 39, 46, 54, 58, 70, 72, 82, 90, 108, 126, + 1, 14, 2, 7, 3, 25, 8, 16, 5, 17, 9, 6, 10, 11, 28, 12, 19, 13, 29, 20, 30, 21, 22, 31, 23, 32, 33, 34 +}; + +int liste[2][1000]; /* global */ + +/* 866 */ + +int quelmode(char codeascii) { + int mode = BYT; + if ((codeascii == '\t') || (codeascii == '\n') || (codeascii == '\r') || ((codeascii >= ' ') && (codeascii <= '~'))) { + mode = TEX; + } else if ((codeascii >= '0') && (codeascii <= '9')) { + mode = NUM; + } + /* 876 */ + + return mode; +} + +/* 844 */ +void regroupe(int *indexliste) { + int i, j; + + /* bring together same type blocks */ + if (*(indexliste) > 1) { + i = 1; + while (i < *(indexliste)) { + if (liste[1][i - 1] == liste[1][i]) { + /* bring together */ + liste[0][i - 1] = liste[0][i - 1] + liste[0][i]; + j = i + 1; + + /* decreace the list */ + while (j < *(indexliste)) { + liste[0][j - 1] = liste[0][j]; + liste[1][j - 1] = liste[1][j]; + j++; + } + *(indexliste) = *(indexliste) - 1; + i--; + } + i++; + } + } + /* 865 */ +} + +/* 478 */ +void pdfsmooth(int *indexliste) { + int i, crnt, last, next, length; + + for (i = 0; i < *(indexliste); i++) { + crnt = liste[1][i]; + length = liste[0][i]; + if (i != 0) { + last = liste[1][i - 1]; + } else { + last = FALSE; + } + if (i != *(indexliste) - 1) { + next = liste[1][i + 1]; + } else { + next = FALSE; + } + + if (crnt == NUM) { + if (i == 0) { + /* first block */ + if (*(indexliste) > 1) { + /* and there are others */ + if ((next == TEX) && (length < 8)) { + liste[1][i] = TEX; + } + if ((next == BYT) && (length == 1)) { + liste[1][i] = BYT; + } + } + } else { + if (i == *(indexliste) - 1) { + /* last block */ + if ((last == TEX) && (length < 7)) { + liste[1][i] = TEX; + } + if ((last == BYT) && (length == 1)) { + liste[1][i] = BYT; + } + } else { + /* not first or last block */ + if (((last == BYT) && (next == BYT)) && (length < 4)) { + liste[1][i] = BYT; + } + if (((last == BYT) && (next == TEX)) && (length < 4)) { + liste[1][i] = TEX; + } + if (((last == TEX) && (next == BYT)) && (length < 5)) { + liste[1][i] = TEX; + } + if (((last == TEX) && (next == TEX)) && (length < 8)) { + liste[1][i] = TEX; + } + } + } + } + } + regroupe(indexliste); + /* 520 */ + for (i = 0; i < *(indexliste); i++) { + crnt = liste[1][i]; + length = liste[0][i]; + if (i != 0) { + last = liste[1][i - 1]; + } else { + last = FALSE; + } + if (i != *(indexliste) - 1) { + next = liste[1][i + 1]; + } else { + next = FALSE; + } + + if ((crnt == TEX) && (i > 0)) { + /* not the first */ + if (i == *(indexliste) - 1) { + /* the last one */ + if ((last == BYT) && (length == 1)) { + liste[1][i] = BYT; + } + } else { + /* not the last one */ + if (((last == BYT) && (next == BYT)) && (length < 5)) { + liste[1][i] = BYT; + } + if ((((last == BYT) && (next != BYT)) || ((last != BYT) + && (next == BYT))) && (length < 3)) { + liste[1][i] = BYT; + } + } + } + } + /* 540 */ + regroupe(indexliste); +} + +/* 547 */ +void textprocess(int *chainemc, int *mclength, char chaine[], int start, int length, int block) { + int j, indexlistet, curtable, listet[2][5000], chainet[5000], wnet; + char codeascii; + + codeascii = 0; + wnet = 0; + + for (j = 0; j < 1000; j++) { + listet[0][j] = 0; + } + /* listet will contain the table numbers and the value of each characters */ + for (indexlistet = 0; indexlistet < length; indexlistet++) { + codeascii = chaine[start + indexlistet]; + switch (codeascii) { + case '\t': listet[0][indexlistet] = 12; + listet[1][indexlistet] = 12; + break; + case '\n': listet[0][indexlistet] = 8; + listet[1][indexlistet] = 15; + break; + case 13: listet[0][indexlistet] = 12; + listet[1][indexlistet] = 11; + break; + default: listet[0][indexlistet] = asciix[codeascii - 32]; + listet[1][indexlistet] = asciiy[codeascii - 32]; + break; + } + } + + /* 570 */ + curtable = 1; /* default table */ + for (j = 0; j < length; j++) { + if (listet[0][j] & curtable) { + /* The character is in the current table */ + chainet[wnet] = listet[1][j]; + wnet++; + } else { + /* Obliged to change table */ + int flag = FALSE; /* True if we change table for only one character */ + if (j == (length - 1)) { + flag = TRUE; + } else { + if (!(listet[0][j] & listet[0][j + 1])) { + flag = TRUE; + } + } + + if (flag) { + /* we change only one character - look for temporary switch */ + if ((listet[0][j] & 1) && (curtable == 2)) { /* T_UPP */ + chainet[wnet] = 27; + chainet[wnet + 1] = listet[1][j]; + wnet += 2; + } + if (listet[0][j] & 8) { /* T_PUN */ + chainet[wnet] = 29; + chainet[wnet + 1] = listet[1][j]; + wnet += 2; + } + if (!(((listet[0][j] & 1) && (curtable == 2)) || (listet[0][j] & 8))) { + /* No temporary switch available */ + flag = FALSE; + } + } + + /* 599 */ + if (!(flag)) { + int newtable; + + if (j == (length - 1)) { + newtable = listet[0][j]; + } else { + if (!(listet[0][j] & listet[0][j + 1])) { + newtable = listet[0][j]; + } else { + newtable = listet[0][j] & listet[0][j + 1]; + } + } + + /* Maintain the first if several tables are possible */ + switch (newtable) { + case 3: + case 5: + case 7: + case 9: + case 11: + case 13: + case 15: + newtable = 1; + break; + case 6: + case 10: + case 14: + newtable = 2; + break; + case 12: + newtable = 4; + break; + } + + /* 619 - select the switch */ + switch (curtable) { + case 1: + switch (newtable) { + case 2: chainet[wnet] = 27; + wnet++; + break; + case 4: chainet[wnet] = 28; + wnet++; + break; + case 8: chainet[wnet] = 28; + wnet++; + chainet[wnet] = 25; + wnet++; + break; + } + break; + case 2: + switch (newtable) { + case 1: chainet[wnet] = 28; + wnet++; + chainet[wnet] = 28; + wnet++; + break; + case 4: chainet[wnet] = 28; + wnet++; + break; + case 8: chainet[wnet] = 28; + wnet++; + chainet[wnet] = 25; + wnet++; + break; + } + break; + case 4: + switch (newtable) { + case 1: chainet[wnet] = 28; + wnet++; + break; + case 2: chainet[wnet] = 27; + wnet++; + break; + case 8: chainet[wnet] = 25; + wnet++; + break; + } + break; + case 8: + switch (newtable) { + case 1: chainet[wnet] = 29; + wnet++; + break; + case 2: chainet[wnet] = 29; + wnet++; + chainet[wnet] = 27; + wnet++; + break; + case 4: chainet[wnet] = 29; + wnet++; + chainet[wnet] = 28; + wnet++; + break; + } + break; + } + curtable = newtable; + /* 659 - at last we add the character */ + chainet[wnet] = listet[1][j]; + wnet++; + } + } + } + + /* 663 */ + if (wnet & 1) { + chainet[wnet] = 29; + wnet++; + } + /* Now translate the string chainet into codewords */ + chainemc[*(mclength)] = 900; + *(mclength) = *(mclength) + 1; + + for (j = 0; j < wnet; j += 2) { + int cw_number; + + cw_number = (30 * chainet[j]) + chainet[j + 1]; + chainemc[*(mclength)] = cw_number; + *(mclength) = *(mclength) + 1; + + } +} + +/* 671 */ +void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int block) { + int debug = 0; + int len = 0; + unsigned int chunkLen = 0; +#if defined(_MSC_VER) && _MSC_VER == 1200 + uint64_t mantisa = 0; + uint64_t total = 0; +#else + uint64_t mantisa = 0ULL; + uint64_t total = 0ULL; +#endif + + if (debug) printf("\nEntering byte mode at position %d\n", start); + + if (length == 1) { + chainemc[(*mclength)++] = 913; + chainemc[(*mclength)++] = chaine[start]; + if (debug) { + printf("913 %d\n", chainemc[*mclength - 1]); + } + } else { + /* select the switch for multiple of 6 bytes */ + if (length % 6 == 0) { + chainemc[(*mclength)++] = 924; + if (debug) printf("924 "); + } else { + chainemc[(*mclength)++] = 901; + if (debug) printf("901 "); + } + + while (len < length) { + chunkLen = length - len; + if (6 <= chunkLen) /* Take groups of 6 */ { + chunkLen = 6; + len += chunkLen; +#if defined(_MSC_VER) && _MSC_VER == 1200 + total = 0; +#else + total = 0ULL; +#endif + + while (chunkLen--) { + mantisa = chaine[start++]; +#if defined(_MSC_VER) && _MSC_VER == 1200 + total |= mantisa << (uint64_t) (chunkLen * 8); +#else + total |= mantisa << (uint64_t) (chunkLen * 8ULL); +#endif + } + + chunkLen = 5; + + while (chunkLen--) { +#if defined(_MSC_VER) && _MSC_VER == 1200 + chainemc[*mclength + chunkLen] = (int) (total % 900); + total /= 900; +#else + chainemc[*mclength + chunkLen] = (int) (total % 900ULL); + total /= 900ULL; +#endif + } + *mclength += 5; + } else /* If it remain a group of less than 6 bytes */ { + len += chunkLen; + while (chunkLen--) { + chainemc[(*mclength)++] = chaine[start++]; + } + } + } + } +} + +/* 712 */ +void numbprocess(int *chainemc, int *mclength, char chaine[], int start, int length, int block) { + int j, loop, longueur, dummy[100], dumlength, diviseur, nombre; + char chainemod[50], chainemult[100], temp; + + strcpy(chainemod, ""); + for (loop = 0; loop <= 50; loop++) { + dummy[loop] = 0; + } + + chainemc[*(mclength)] = 902; + *(mclength) = *(mclength) + 1; + + j = 0; + while (j < length) { + dumlength = 0; + strcpy(chainemod, ""); + longueur = length - j; + if (longueur > 44) { + longueur = 44; + } + strcat(chainemod, "1"); + for (loop = 1; loop <= longueur; loop++) { + chainemod[loop] = chaine[start + loop + j - 1]; + } + chainemod[longueur + 1] = '\0'; + do { + diviseur = 900; + + /* 877 - gosub Modulo */ + strcpy(chainemult, ""); + nombre = 0; + while (strlen(chainemod) != 0) { + nombre *= 10; + nombre += ctoi(chainemod[0]); + for (loop = 0; loop < strlen(chainemod); loop++) { + chainemod[loop] = chainemod[loop + 1]; + } + if (nombre < diviseur) { + if (strlen(chainemult) != 0) { + strcat(chainemult, "0"); + } + } else { + temp = (nombre / diviseur) + '0'; + chainemult[strlen(chainemult) + 1] = '\0'; + chainemult[strlen(chainemult)] = temp; + } + nombre = nombre % diviseur; + } + diviseur = nombre; + /* return to 723 */ + + for (loop = dumlength; loop > 0; loop--) { + dummy[loop] = dummy[loop - 1]; + } + dummy[0] = diviseur; + dumlength++; + strcpy(chainemod, chainemult); + } while (strlen(chainemult) != 0); + for (loop = 0; loop < dumlength; loop++) { + chainemc[*(mclength)] = dummy[loop]; + *(mclength) = *(mclength) + 1; + } + j += longueur; + } +} + +/* 366 */ +static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length) { + int i, k, j, indexchaine, indexliste, mode, longueur, loop, mccorrection[520], offset; + int total, chainemc[2700], mclength, c1, c2, c3, dummy[35]; + char pattern[580]; + int debug = symbol->debug; + + /* 456 */ + indexliste = 0; + indexchaine = 0; + + mode = quelmode(chaine[indexchaine]); + + for (i = 0; i < 1000; i++) { + liste[0][i] = 0; + } + + /* 463 */ + do { + liste[1][indexliste] = mode; + while ((liste[1][indexliste] == mode) && (indexchaine < length)) { + liste[0][indexliste]++; + indexchaine++; + mode = quelmode(chaine[indexchaine]); + } + indexliste++; + } while (indexchaine < length); + + /* 474 */ + pdfsmooth(&indexliste); + + if (debug) { + printf("Initial block pattern:\n"); + for (i = 0; i < indexliste; i++) { + printf("Len: %d Type: ", liste[0][i]); + switch (liste[1][i]) { + case TEX: printf("Text\n"); + break; + case BYT: printf("Byte\n"); + break; + case NUM: printf("Number\n"); + break; + default: printf("ERROR\n"); + break; + } + } + } + + /* 541 - now compress the data */ + indexchaine = 0; + mclength = 0; + + if (symbol->output_options & READER_INIT) { + chainemc[mclength] = 921; /* Reader Initialisation */ + mclength++; + } + + if (symbol->eci != 3) { + /* Encoding ECI assignment number, according to Table 8 */ + if (symbol->eci <= 899) { + chainemc[mclength] = 927; /* ECI */ + mclength++; + chainemc[mclength] = symbol->eci; + mclength++; + } + if ((symbol->eci >= 900) && (symbol->eci <= 810899)) { + chainemc[mclength] = 926; /* ECI */ + mclength++; + chainemc[mclength] = (symbol->eci / 900) - 1; + mclength++; + chainemc[mclength] = symbol->eci % 900; + mclength++; + } + if (symbol->eci >= 810900) { + chainemc[mclength] = 925; /* ECI */ + mclength++; + chainemc[mclength] = symbol->eci - 810900; + mclength++; + } + } + + if (symbol->eci > 811799) { + strcpy(symbol->errtxt, "472: Invalid ECI"); + return ZINT_ERROR_INVALID_OPTION; + } + + for (i = 0; i < indexliste; i++) { + switch (liste[1][i]) { + case TEX: /* 547 - text mode */ + textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i); + break; + case BYT: /* 670 - octet stream mode */ + byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i); + break; + case NUM: /* 712 - numeric mode */ + numbprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i); + break; + } + indexchaine = indexchaine + liste[0][i]; + } + + if (debug) { + printf("\nCompressed data stream:\n"); + for (i = 0; i < mclength; i++) { + printf("%d ", chainemc[i]); + } + printf("\n\n"); + } + + /* 752 - Now take care of the number of CWs per row */ + if (symbol->option_1 < 0) { + symbol->option_1 = 6; + if (mclength <= 863) { + symbol->option_1 = 5; + } + if (mclength <= 320) { + symbol->option_1 = 4; + } + if (mclength <= 160) { + symbol->option_1 = 3; + } + if (mclength <= 40) { + symbol->option_1 = 2; + } + } + k = 1; + for (loop = 1; loop <= (symbol->option_1 + 1); loop++) { + k *= 2; + } + longueur = mclength; + if (symbol->option_2 > 30) { + symbol->option_2 = 30; + } + if (symbol->option_2 < 1) { + symbol->option_2 =(int)(0.5 + sqrt((longueur + k) / 3.0)); + } + if (((longueur + k) / symbol->option_2) > 90) { + /* stop the symbol from becoming too high */ + symbol->option_2 = symbol->option_2 + 1; + } + + if (longueur + k > 928) { + /* Enforce maximum codeword limit */ + return 2; + } + + if (((longueur + k) / symbol->option_2) > 90) { + return 4; + } + + /* 781 - Padding calculation */ + longueur = mclength + 1 + k; + i = 0; + if ((longueur / symbol->option_2) < 3) { + i = (symbol->option_2 * 3) - longueur; /* A bar code must have at least three rows */ + } else { + if ((longueur % symbol->option_2) > 0) { + i = symbol->option_2 - (longueur % symbol->option_2); + } + } + /* We add the padding */ + while (i > 0) { + chainemc[mclength] = 900; + mclength++; + i--; + } + /* we add the length descriptor */ + for (i = mclength; i > 0; i--) { + chainemc[i] = chainemc[i - 1]; + } + chainemc[0] = mclength + 1; + mclength++; + + /* 796 - we now take care of the Reed Solomon codes */ + switch (symbol->option_1) { + case 1: offset = 2; + break; + case 2: offset = 6; + break; + case 3: offset = 14; + break; + case 4: offset = 30; + break; + case 5: offset = 62; + break; + case 6: offset = 126; + break; + case 7: offset = 254; + break; + case 8: offset = 510; + break; + default: offset = 0; + break; + } + + longueur = mclength; + for (loop = 0; loop < 520; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for (i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for (j = k - 1; j > 0; j--) { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * coefrs[offset + j]) % 929) % 929; + } + mccorrection[0] = (929 - (total * coefrs[offset + j]) % 929) % 929; + } + + /* we add these codes to the string */ + for (i = k - 1; i >= 0; i--) { + chainemc[mclength++] = mccorrection[i] ? 929 - mccorrection[i] : 0; + } + + /* 818 - The CW string is finished */ + c1 = (mclength / symbol->option_2 - 1) / 3; + c2 = symbol->option_1 * 3 + (mclength / symbol->option_2 - 1) % 3; + c3 = symbol->option_2 - 1; + + /* we now encode each row */ + for (i = 0; i <= (mclength / symbol->option_2) - 1; i++) { + for (j = 0; j < symbol->option_2; j++) { + dummy[j + 1] = chainemc[i * symbol->option_2 + j]; + } + k = (i / 3) * 30; + switch (i % 3) { + case 0: + dummy[0] = k + c1; + dummy[symbol->option_2 + 1] = k + c3; + offset = 0; /* cluster(0) */ + break; + case 1: + dummy[0] = k + c2; + dummy[symbol->option_2 + 1] = k + c1; + offset = 929; /* cluster(3) */ + break; + case 2: + dummy[0] = k + c3; + dummy[symbol->option_2 + 1] = k + c2; + offset = 1858; /* cluster(6) */ + break; + } + strcpy(pattern, ""); + bin_append(0x1FEA8, 17, pattern); /* Row start */ + + for (j = 0; j <= symbol->option_2; j++) { + bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern); + strcat(pattern, "0"); + } + + if (symbol->symbology != BARCODE_PDF417TRUNC) { + bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern); + strcat(pattern, "0"); + bin_append(0x3FA29, 18, pattern); /* Row Stop */ + } + + for (loop = 0; loop < strlen(pattern); loop++) { + if (pattern[loop] == '1') { + set_module(symbol, i, loop); + } + } + + symbol->row_height[i] = 3; + + } + symbol->rows = (mclength / symbol->option_2); + symbol->width =(int)strlen(pattern); + + /* 843 */ + return 0; +} + +/* 345 */ +int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + int codeerr, error_number; + + error_number = 0; + + if ((symbol->option_1 < -1) || (symbol->option_1 > 8)) { + strcpy(symbol->errtxt, "460: Security value out of range"); + symbol->option_1 = -1; + error_number = ZINT_WARN_INVALID_OPTION; + } + if ((symbol->option_2 < 0) || (symbol->option_2 > 30)) { + strcpy(symbol->errtxt, "461: Number of columns out of range"); + symbol->option_2 = 0; + error_number = ZINT_WARN_INVALID_OPTION; + } + + /* 349 */ + codeerr = pdf417(symbol, source, length); + + /* 352 */ + if (codeerr != 0) { + switch (codeerr) { + case 1: + strcpy(symbol->errtxt, "462: No such file or file unreadable"); + error_number = ZINT_ERROR_INVALID_OPTION; + break; + case 2: + strcpy(symbol->errtxt, "463: Input string too long"); + error_number = ZINT_ERROR_TOO_LONG; + break; + case 3: + strcpy(symbol->errtxt, "464: Number of codewords per row too small"); + error_number = ZINT_WARN_INVALID_OPTION; + break; + case 4: + strcpy(symbol->errtxt, "465: Data too long for specified number of columns"); + error_number = ZINT_ERROR_TOO_LONG; + break; + case ZINT_ERROR_INVALID_OPTION: + error_number = codeerr; + break; + default: + strcpy(symbol->errtxt, "466: Something strange happened"); + error_number = ZINT_ERROR_ENCODING_PROBLEM; + break; + } + } + + /* 364 */ + return error_number; +} + +/* like PDF417 only much smaller! */ +int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length) { + int i, k, j, indexchaine, indexliste, mode, longueur, mccorrection[50], offset; + int total, chainemc[2700], mclength, dummy[5], codeerr; + char pattern[580]; + int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster; + int LeftRAP, CentreRAP, RightRAP, Cluster, loop; + int debug = 0; + + /* Encoding starts out the same as PDF417, so use the same code */ + codeerr = 0; + + /* 456 */ + indexliste = 0; + indexchaine = 0; + + mode = quelmode(chaine[indexchaine]); + + for (i = 0; i < 1000; i++) { + liste[0][i] = 0; + } + + /* 463 */ + do { + liste[1][indexliste] = mode; + while ((liste[1][indexliste] == mode) && (indexchaine < length)) { + liste[0][indexliste]++; + indexchaine++; + mode = quelmode(chaine[indexchaine]); + } + indexliste++; + } while (indexchaine < length); + + /* 474 */ + pdfsmooth(&indexliste); + + if (debug) { + printf("Initial mapping:\n"); + for (i = 0; i < indexliste; i++) { + printf("len: %d type: ", liste[0][i]); + switch (liste[1][i]) { + case TEX: printf("TEXT\n"); + break; + case BYT: printf("BYTE\n"); + break; + case NUM: printf("NUMBER\n"); + break; + default: printf("*ERROR*\n"); + break; + } + } + } + + /* 541 - now compress the data */ + indexchaine = 0; + mclength = 0; + + if (symbol->output_options & READER_INIT) { + chainemc[mclength] = 921; /* Reader Initialisation */ + mclength++; + } + + if (symbol->eci > 811799) { + strcpy(symbol->errtxt, "473: Invalid ECI"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (symbol->eci != 3) { + /* Encoding ECI assignment number, according to Table 8 */ + if (symbol->eci <= 899) { + chainemc[mclength] = 927; /* ECI */ + mclength++; + chainemc[mclength] = symbol->eci; + mclength++; + } + if ((symbol->eci >= 900) && (symbol->eci <= 810899)) { + chainemc[mclength] = 926; /* ECI */ + mclength++; + chainemc[mclength] = (symbol->eci / 900) - 1; + mclength++; + chainemc[mclength] = symbol->eci % 900; + mclength++; + } + if (symbol->eci >= 810900) { + chainemc[mclength] = 925; /* ECI */ + mclength++; + chainemc[mclength] = symbol->eci - 810900; + mclength++; + } + } + + for (i = 0; i < indexliste; i++) { + switch (liste[1][i]) { + case TEX: /* 547 - text mode */ + textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i); + break; + case BYT: /* 670 - octet stream mode */ + byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i], i); + break; + case NUM: /* 712 - numeric mode */ + numbprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i], i); + break; + } + indexchaine = indexchaine + liste[0][i]; + } + + /* This is where it all changes! */ + + if (mclength > 126) { + strcpy(symbol->errtxt, "467: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + if (symbol->option_2 > 4) { + strcpy(symbol->errtxt, "468: Specified width out of range"); + symbol->option_2 = 0; + codeerr = ZINT_WARN_INVALID_OPTION; + } + + if (debug) { + printf("\nEncoded Data Stream:\n"); + for (i = 0; i < mclength; i++) { + printf("0x%02X ", chainemc[i]); + } + printf("\n"); + } + + /* Now figure out which variant of the symbol to use and load values accordingly */ + + variant = 0; + + if ((symbol->option_2 == 1) && (mclength > 20)) { + /* the user specified 1 column but the data doesn't fit - go to automatic */ + symbol->option_2 = 0; + strcpy(symbol->errtxt, "469: Specified symbol size too small for data"); + codeerr = ZINT_WARN_INVALID_OPTION; + } + + if ((symbol->option_2 == 2) && (mclength > 37)) { + /* the user specified 2 columns but the data doesn't fit - go to automatic */ + symbol->option_2 = 0; + strcpy(symbol->errtxt, "470: Specified symbol size too small for data"); + codeerr = ZINT_WARN_INVALID_OPTION; + } + + if ((symbol->option_2 == 3) && (mclength > 82)) { + /* the user specified 3 columns but the data doesn't fit - go to automatic */ + symbol->option_2 = 0; + strcpy(symbol->errtxt, "471: Specified symbol size too small for data"); + codeerr = ZINT_WARN_INVALID_OPTION; + } + + if (symbol->option_2 == 1) { + /* the user specified 1 column and the data does fit */ + variant = 6; + if (mclength <= 16) { + variant = 5; + } + if (mclength <= 12) { + variant = 4; + } + if (mclength <= 10) { + variant = 3; + } + if (mclength <= 7) { + variant = 2; + } + if (mclength <= 4) { + variant = 1; + } + } + + if (symbol->option_2 == 2) { + /* the user specified 2 columns and the data does fit */ + variant = 13; + if (mclength <= 33) { + variant = 12; + } + if (mclength <= 29) { + variant = 11; + } + if (mclength <= 24) { + variant = 10; + } + if (mclength <= 19) { + variant = 9; + } + if (mclength <= 13) { + variant = 8; + } + if (mclength <= 8) { + variant = 7; + } + } + + if (symbol->option_2 == 3) { + /* the user specified 3 columns and the data does fit */ + variant = 23; + if (mclength <= 70) { + variant = 22; + } + if (mclength <= 58) { + variant = 21; + } + if (mclength <= 46) { + variant = 20; + } + if (mclength <= 34) { + variant = 19; + } + if (mclength <= 24) { + variant = 18; + } + if (mclength <= 18) { + variant = 17; + } + if (mclength <= 14) { + variant = 16; + } + if (mclength <= 10) { + variant = 15; + } + if (mclength <= 6) { + variant = 14; + } + } + + if (symbol->option_2 == 4) { + /* the user specified 4 columns and the data does fit */ + variant = 34; + if (mclength <= 108) { + variant = 33; + } + if (mclength <= 90) { + variant = 32; + } + if (mclength <= 72) { + variant = 31; + } + if (mclength <= 54) { + variant = 30; + } + if (mclength <= 39) { + variant = 29; + } + if (mclength <= 30) { + variant = 28; + } + if (mclength <= 24) { + variant = 27; + } + if (mclength <= 18) { + variant = 26; + } + if (mclength <= 12) { + variant = 25; + } + if (mclength <= 8) { + variant = 24; + } + } + + if (variant == 0) { + /* Zint can choose automatically from all available variations */ + for (i = 27; i >= 0; i--) { + + if (MicroAutosize[i] >= mclength) { + variant = MicroAutosize[i + 28]; + } + } + } + + /* Now we have the variant we can load the data */ + variant--; + symbol->option_2 = MicroVariants[variant]; /* columns */ + symbol->rows = MicroVariants[variant + 34]; /* rows */ + k = MicroVariants[variant + 68]; /* number of EC CWs */ + longueur = (symbol->option_2 * symbol->rows) - k; /* number of non-EC CWs */ + i = longueur - mclength; /* amount of padding required */ + offset = MicroVariants[variant + 102]; /* coefficient offset */ + + if (debug) { + printf("\nChoose symbol size:\n"); + printf("%d columns x %d rows\n", symbol->option_2, symbol->rows); + printf("%d data codewords (including %d pads), %d ecc codewords\n", longueur, i, k); + printf("\n"); + } + + /* We add the padding */ + while (i > 0) { + chainemc[mclength] = 900; + mclength++; + i--; + } + + /* Reed-Solomon error correction */ + longueur = mclength; + for (loop = 0; loop < 50; loop++) { + mccorrection[loop] = 0; + } + total = 0; + for (i = 0; i < longueur; i++) { + total = (chainemc[i] + mccorrection[k - 1]) % 929; + for (j = k - 1; j >= 0; j--) { + if (j == 0) { + mccorrection[j] = (929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } else { + mccorrection[j] = (mccorrection[j - 1] + 929 - (total * Microcoeffs[offset + j]) % 929) % 929; + } + } + } + + for (j = 0; j < k; j++) { + if (mccorrection[j] != 0) { + mccorrection[j] = 929 - mccorrection[j]; + } + } + /* we add these codes to the string */ + for (i = k - 1; i >= 0; i--) { + chainemc[mclength] = mccorrection[i]; + mclength++; + } + + if (debug) { + printf("Encoded Data Stream with ECC:\n"); + for (i = 0; i < mclength; i++) { + printf("0x%02X ", chainemc[i]); + } + printf("\n"); + } + + /* Now get the RAP (Row Address Pattern) start values */ + LeftRAPStart = RAPTable[variant]; + CentreRAPStart = RAPTable[variant + 34]; + RightRAPStart = RAPTable[variant + 68]; + StartCluster = RAPTable[variant + 102] / 3; + + /* That's all values loaded, get on with the encoding */ + + LeftRAP = LeftRAPStart; + CentreRAP = CentreRAPStart; + RightRAP = RightRAPStart; + Cluster = StartCluster; + /* Cluster can be 0, 1 or 2 for Cluster(0), Cluster(3) and Cluster(6) */ + + if (debug) printf("\nInternal row representation:\n"); + for (i = 0; i < symbol->rows; i++) { + if (debug) printf("row %d: ", i); + strcpy(pattern, ""); + offset = 929 * Cluster; + for (j = 0; j < 5; j++) { + dummy[j] = 0; + } + for (j = 0; j < symbol->option_2; j++) { + dummy[j + 1] = chainemc[i * symbol->option_2 + j]; + if (debug) printf("[%d] ", dummy[j + 1]); + } + + /* Copy the data into codebarre */ + bin_append(rap_side[LeftRAP - 1], 10, pattern); + bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern); + strcat(pattern, "0"); + if (symbol->option_2 == 3) { + bin_append(rap_centre[CentreRAP - 1], 10, pattern); + } + if (symbol->option_2 >= 2) { + bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern); + strcat(pattern, "0"); + } + if (symbol->option_2 == 4) { + bin_append(rap_centre[CentreRAP - 1], 10, pattern); + } + if (symbol->option_2 >= 3) { + bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern); + strcat(pattern, "0"); + } + if (symbol->option_2 == 4) { + bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern); + strcat(pattern, "0"); + } + bin_append(rap_side[RightRAP - 1], 10, pattern); + strcat(pattern, "1"); /* stop */ + if (debug) printf("%s\n", pattern); + + /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */ + for (loop = 0; loop < strlen(pattern); loop++) { + if (pattern[loop] == '1') { + set_module(symbol, i, loop); + } + } + symbol->row_height[i] = 2; + symbol->width = strlen(pattern); + + /* Set up RAPs and Cluster for next row */ + LeftRAP++; + CentreRAP++; + RightRAP++; + Cluster++; + + if (LeftRAP == 53) { + LeftRAP = 1; + } + if (CentreRAP == 53) { + CentreRAP = 1; + } + if (RightRAP == 53) { + RightRAP = 1; + } + if (Cluster == 3) { + Cluster = 0; + } + } + + return codeerr; +} diff --git a/3rdparty/zint-2.6.1/backend/pdf417.h b/3rdparty/zint-2.6.1/backend/pdf417.h new file mode 100644 index 0000000..2c2f551 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/pdf417.h @@ -0,0 +1,514 @@ +/* pdf417.h - PDF417 tables and coefficients */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + Portions Copyright (C) 2004 Grandzebu + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* this file contains the character table, the pre-calculated coefficients and the + codeword patterns taken from lines 416 to 454 of pdf417.frm */ + +#define TRUE 1 +#define FALSE 0 +#define TEX 900 +#define BYT 901 +#define NUM 902 + +/* PDF417 error correction coefficients from Grand Zebu */ +static const unsigned short int coefrs[1022] = { + /* k = 2 */ + 27, 917, + + /* k = 4 */ + 522, 568, 723, 809, + + /* k = 8 */ + 237, 308, 436, 284, 646, 653, 428, 379, + + /* k = 16 */ + 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, + + /* k = 32 */ + 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, + 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, + + /* k = 64 */ + 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, + 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, + 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, + 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543, + + /* k = 128 */ + 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, + 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, + 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, + 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, + 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, + 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, + 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, + 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539, + + /* k = 256 */ + 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, + 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, + 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, + 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, + 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, + 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, + 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, + 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, + 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, + 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, + 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, + 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, + 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, + 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, + 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, + 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10, + + /* k = 512 */ + 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, + 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, + 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, + 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, + 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, + 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, + 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, + 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, + 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, + 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, + 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, + 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, + 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, + 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, + 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, + 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, + 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, + 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, + 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, + 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, + 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, + 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, + 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, + 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, + 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, + 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, + 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, + 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, + 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, + 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, + 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, + 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 +}; + +static const unsigned short int pdf_bitpattern[2787] = { + 0xEAE0, 0xF578, 0xFABE, 0xEA70, 0xF53C, 0xFA9F, 0xD460, 0xEA38, 0xD430, 0xA820, + 0xD418, 0xA810, 0xD6E0, 0xEB78, 0xF5BE, 0xD670, 0xEB3C, 0xF59F, 0xAC60, 0xD638, + 0xAC30, 0xAEE0, 0xD778, 0xEBBE, 0xAE70, 0xD73C, 0xEB9F, 0xAE38, 0xD71E, 0xAF78, + 0xD7BE, 0xAF3C, 0xD79F, 0xAFBE, 0xFAFD, 0xE970, 0xF4BC, 0xFA5F, 0xD260, 0xE938, + 0xF49E, 0xD230, 0xE91C, 0xA420, 0xD218, 0xE90E, 0xA410, 0xD20C, 0xA408, 0xD370, + 0xE9BC, 0xF4DF, 0xA660, 0xD338, 0xE99E, 0xA630, 0xD31C, 0xE98F, 0xA618, 0xD30E, + 0xA770, 0xD3BC, 0xE9DF, 0xA738, 0xD39E, 0xA71C, 0xD38F, 0xA7BC, 0xD3DF, 0xA79E, + 0xA78F, 0xD160, 0xE8B8, 0xF45E, 0xD130, 0xE89C, 0xF44F, 0xA220, 0xD118, 0xE88E, + 0xA210, 0xD10C, 0xA208, 0xA204, 0xA360, 0xD1B8, 0xE8DE, 0xA330, 0xD19C, 0xE8CF, + 0xA318, 0xD18E, 0xA30C, 0xA306, 0xA3B8, 0xD1DE, 0xA39C, 0xD1CF, 0xA38E, 0xA3DE, + 0xD0B0, 0xE85C, 0xF42F, 0xA120, 0xD098, 0xE84E, 0xA110, 0xD08C, 0xE847, 0xA108, + 0xD086, 0xA104, 0xD083, 0xA1B0, 0xD0DC, 0xE86F, 0xA198, 0xD0CE, 0xA18C, 0xD0C7, + 0xA186, 0xA183, 0xD0EF, 0xA1C7, 0xA0A0, 0xD058, 0xE82E, 0xA090, 0xD04C, 0xE827, + 0xA088, 0xD046, 0xA084, 0xD043, 0xA082, 0xA0D8, 0xA0CC, 0xA0C6, 0xA050, 0xE817, + 0xD026, 0xD023, 0xA041, 0xE570, 0xF2BC, 0xF95F, 0xCA60, 0xE538, 0xF29E, 0xCA30, + 0xE51C, 0xF28F, 0x9420, 0xCA18, 0x9410, 0xCB70, 0xE5BC, 0xF2DF, 0x9660, 0xCB38, + 0xE59E, 0x9630, 0xCB1C, 0x9618, 0x960C, 0x9770, 0xCBBC, 0xE5DF, 0x9738, 0xCB9E, + 0x971C, 0x970E, 0x97BC, 0xCBDF, 0x979E, 0x97DF, 0xED60, 0xF6B8, 0xFB5E, 0xED30, + 0xF69C, 0xFB4F, 0xDA20, 0xED18, 0xF68E, 0xDA10, 0xED0C, 0xF687, 0xDA08, 0xED06, + 0xC960, 0xE4B8, 0xF25E, 0xDB60, 0xC930, 0xE49C, 0xF24F, 0xDB30, 0xED9C, 0xF6CF, + 0xB620, 0x9210, 0xC90C, 0xE487, 0xB610, 0xDB0C, 0xB608, 0x9360, 0xC9B8, 0xE4DE, + 0xB760, 0x9330, 0xC99C, 0xE4CF, 0xB730, 0xDB9C, 0xEDCF, 0xB718, 0x930C, 0xB70C, + 0x93B8, 0xC9DE, 0xB7B8, 0x939C, 0xC9CF, 0xB79C, 0xDBCF, 0xB78E, 0x93DE, 0xB7DE, + 0x93CF, 0xB7CF, 0xECB0, 0xF65C, 0xFB2F, 0xD920, 0xEC98, 0xF64E, 0xD910, 0xEC8C, + 0xF647, 0xD908, 0xEC86, 0xD904, 0xD902, 0xC8B0, 0xE45C, 0xF22F, 0xD9B0, 0xC898, + 0xE44E, 0xB320, 0x9110, 0xECCE, 0xE447, 0xB310, 0x9108, 0xC886, 0xB308, 0xD986, + 0xC883, 0x9102, 0x91B0, 0xC8DC, 0xE46F, 0xB3B0, 0x9198, 0xC8CE, 0xB398, 0xD9CE, + 0xC8C7, 0xB38C, 0x9186, 0x9183, 0x91DC, 0xC8EF, 0xB3DC, 0x91CE, 0xB3CE, 0x91C7, + 0xB3C7, 0xB3EF, 0xD8A0, 0xEC58, 0xF62E, 0xD890, 0xEC4C, 0xF627, 0xD888, 0xEC46, + 0xD884, 0xEC43, 0xD882, 0xD881, 0x90A0, 0xC858, 0xE42E, 0xB1A0, 0x9090, 0xC84C, + 0xE427, 0xB190, 0xD8CC, 0xEC67, 0xB188, 0x9084, 0xC843, 0xB184, 0xD8C3, 0xB182, + 0x90D8, 0xC86E, 0xB1D8, 0x90CC, 0xC867, 0xB1CC, 0xD8E7, 0xB1C6, 0x90C3, 0xB1C3, + 0xB1EE, 0xB1E7, 0xD850, 0xEC2C, 0xF617, 0xD848, 0xEC26, 0xD844, 0xEC23, 0xD842, + 0xD841, 0x9050, 0xC82C, 0xE417, 0xB0D0, 0x9048, 0xC826, 0xB0C8, 0xD866, 0xC823, + 0xB0C4, 0x9042, 0xB0C2, 0x9041, 0x906C, 0xB0EC, 0xB0E6, 0xB0E3, 0xEC16, 0xEC13, + 0xD821, 0xC816, 0x9024, 0xB064, 0xB062, 0xB061, 0xC560, 0xE2B8, 0xF15E, 0xC530, + 0xE29C, 0x8A20, 0xC518, 0xE28E, 0x8A10, 0xC50C, 0x8A08, 0x8A04, 0x8B60, 0xC5B8, + 0xE2DE, 0x8B30, 0xC59C, 0xE2CF, 0x8B18, 0xC58E, 0x8B0C, 0x8B06, 0x8BB8, 0xC5DE, + 0x8B9C, 0xC5CF, 0x8B8E, 0x8BDE, 0x8BCF, 0xE6B0, 0xF35C, 0xF9AF, 0xCD20, 0xE698, + 0xF34E, 0xCD10, 0xE68C, 0xF347, 0xCD08, 0xE686, 0xCD04, 0xE683, 0xC4B0, 0xE25C, + 0xF12F, 0xCDB0, 0xC498, 0xE24E, 0x9B20, 0x8910, 0xE6CE, 0xE247, 0x9B10, 0xCD8C, + 0xC486, 0x9B08, 0x8904, 0x9B04, 0x89B0, 0xC4DC, 0xE26F, 0x9BB0, 0x8998, 0xE6EF, + 0x9B98, 0xCDCE, 0xC4C7, 0x9B8C, 0x8986, 0x9B86, 0x89DC, 0xC4EF, 0x9BDC, 0x89CE, + 0x9BCE, 0x89C7, 0x89EF, 0x9BEF, 0xEEA0, 0xF758, 0xFBAE, 0xEE90, 0xF74C, 0xFBA7, + 0xEE88, 0xF746, 0xEE84, 0xF743, 0xEE82, 0xCCA0, 0xE658, 0xF32E, 0xDDA0, 0xCC90, + 0xF76E, 0xF327, 0xDD90, 0xEECC, 0xF767, 0xDD88, 0xCC84, 0xE643, 0xDD84, 0xEEC3, + 0xCC81, 0x88A0, 0xC458, 0xE22E, 0x99A0, 0x8890, 0xC44C, 0xE227, 0xBBA0, 0x9990, + 0xCCCC, 0xE667, 0xBB90, 0xDDCC, 0xEEE7, 0xC443, 0xBB88, 0x9984, 0xCCC3, 0xBB84, + 0x8881, 0x88D8, 0xC46E, 0x99D8, 0x88CC, 0xC467, 0xBBD8, 0x99CC, 0xCCE7, 0xBBCC, + 0xDDE7, 0x88C3, 0x99C3, 0x88EE, 0x99EE, 0x88E7, 0xBBEE, 0x99E7, 0xEE50, 0xF72C, + 0xFB97, 0xEE48, 0xF726, 0xEE44, 0xF723, 0xEE42, 0xEE41, 0xCC50, 0xE62C, 0xF317, + 0xDCD0, 0xCC48, 0xF737, 0xDCC8, 0xEE66, 0xE623, 0xDCC4, 0xCC42, 0xDCC2, 0xCC41, + 0xDCC1, 0x8850, 0xC42C, 0xE217, 0x98D0, 0x8848, 0xC426, 0xB9D0, 0x98C8, 0xCC66, + 0xC423, 0xB9C8, 0xDCE6, 0x8842, 0xB9C4, 0x98C2, 0x8841, 0x98C1, 0x886C, 0xC437, + 0x98EC, 0x8866, 0xB9EC, 0x98E6, 0x8863, 0xB9E6, 0x98E3, 0x8877, 0xB9F7, 0xEE28, + 0xF716, 0xEE24, 0xF713, 0xEE22, 0xEE21, 0xCC28, 0xE616, 0xDC68, 0xCC24, 0xE613, + 0xDC64, 0xEE33, 0xDC62, 0xCC21, 0xDC61, 0x8828, 0xC416, 0x9868, 0x8824, 0xC413, + 0xB8E8, 0x9864, 0xCC33, 0xB8E4, 0xDC73, 0x8821, 0xB8E2, 0x9861, 0xB8E1, 0x9876, + 0xB8F6, 0xB8F3, 0xF70B, 0xEE11, 0xE60B, 0xCC12, 0xCC11, 0x8814, 0x9834, 0xB874, + 0x8811, 0x9831, 0xC2B0, 0x8520, 0xC298, 0x8510, 0xC28C, 0xE147, 0x8508, 0xC286, + 0x8504, 0xC283, 0x85B0, 0xC2DC, 0xE16F, 0x8598, 0xC2CE, 0x858C, 0xC2C7, 0x8586, + 0x8583, 0x85DC, 0xC2EF, 0x85CE, 0x85C7, 0x85EF, 0xC6A0, 0xE358, 0xF1AE, 0xC690, + 0xE34C, 0xC688, 0xE346, 0xC684, 0xE343, 0xC682, 0x84A0, 0xC258, 0xE12E, 0x8DA0, + 0x8490, 0xE36E, 0xE127, 0x8D90, 0xC6CC, 0xE367, 0x8D88, 0x8484, 0xC243, 0x8D84, + 0xC6C3, 0x8481, 0x84D8, 0xC26E, 0x8DD8, 0x84CC, 0xC267, 0x8DCC, 0xC6E7, 0x8DC6, + 0x84C3, 0x84EE, 0x8DEE, 0x84E7, 0x8DE7, 0xE750, 0xF3AC, 0xF9D7, 0xE748, 0xF3A6, + 0xE744, 0xF3A3, 0xE742, 0xE741, 0xC650, 0xE32C, 0xCED0, 0xC648, 0xE326, 0xCEC8, + 0xE766, 0xE323, 0xCEC4, 0xC642, 0xCEC2, 0xC641, 0xCEC1, 0x8450, 0xC22C, 0x8CD0, + 0x8448, 0xE337, 0x9DD0, 0x8CC8, 0xC666, 0xC223, 0x9DC8, 0xCEE6, 0x8442, 0x9DC4, + 0x8CC2, 0x8441, 0x8CC1, 0x846C, 0xC237, 0x8CEC, 0x8466, 0x9DEC, 0x8CE6, 0x8463, + 0x9DE6, 0x8CE3, 0x8477, 0x8CF7, 0x9DF7, 0xF7A8, 0xFBD6, 0xF7A4, 0xFBD3, 0xF7A2, + 0xF7A1, 0xE728, 0xF396, 0xEF68, 0xF7B6, 0xF393, 0xEF64, 0xF7B3, 0xEF62, 0xE721, + 0xEF61, 0xC628, 0xE316, 0xCE68, 0xC624, 0xE313, 0xDEE8, 0xCE64, 0xE733, 0xDEE4, + 0xEF73, 0xC621, 0xDEE2, 0xCE61, 0xDEE1, 0x8428, 0xC216, 0x8C68, 0x8424, 0xC213, + 0x9CE8, 0x8C64, 0xC633, 0xBDE8, 0x9CE4, 0xCE73, 0x8421, 0xBDE4, 0xDEF3, 0x8C61, + 0xBDE2, 0x8436, 0x8C76, 0x8433, 0x9CF6, 0x8C73, 0xBDF6, 0x9CF3, 0xBDF3, 0xF794, + 0xFBCB, 0xF792, 0xF791, 0xE714, 0xF38B, 0xEF34, 0xF79B, 0xEF32, 0xE711, 0xEF31, + 0xC614, 0xE30B, 0xCE34, 0xC612, 0xDE74, 0xCE32, 0xC611, 0xDE72, 0xCE31, 0xDE71, + 0x8414, 0xC20B, 0x8C34, 0xC61B, 0x9C74, 0x8C32, 0x8411, 0xBCF4, 0x9C72, 0x8C31, + 0xBCF2, 0x9C71, 0xBCF1, 0x8C3B, 0xBCFB, 0xF789, 0xEF1A, 0xEF19, 0xCE1A, 0xDE3A, + 0xDE39, 0x8C1A, 0x9C3A, 0xBC7A, 0xBC79, 0x82A0, 0x8290, 0xC14C, 0x8288, 0x8284, + 0x8282, 0x82D8, 0x82CC, 0x82C6, 0x82C3, 0x82EE, 0x82E7, 0xC350, 0xC348, 0xE1A6, + 0xC344, 0xE1A3, 0xC342, 0xC341, 0x8250, 0xC12C, 0x86D0, 0xC36C, 0xC126, 0x86C8, + 0xC366, 0x86C4, 0xC363, 0x86C2, 0x8241, 0x86C1, 0x826C, 0xC137, 0x86EC, 0xC377, + 0x86E6, 0x8263, 0x86E3, 0x8277, 0x86F7, 0xE3A8, 0xE3A4, 0xE3A2, 0xE3A1, 0xC328, + 0xC768, 0xE3B6, 0xE193, 0xC764, 0xE3B3, 0xC762, 0xC321, 0xC761, 0x8228, 0x8668, + 0x8224, 0xC113, 0x8EE8, 0x8664, 0x8222, 0x8EE4, 0x8662, 0x8221, 0x8EE2, 0x8661, + 0x8236, 0x8676, 0x8233, 0x8EF6, 0x8673, 0x8EF3, 0xF3D4, 0xF3D2, 0xF3D1, 0xE394, + 0xE7B4, 0xF3DB, 0xE7B2, 0xE391, 0xE7B1, 0xC314, 0xE18B, 0xC734, 0xE39B, 0xCF74, + 0xC732, 0xC311, 0xCF72, 0xC731, 0xCF71, 0x8214, 0xC10B, 0x8634, 0xC31B, 0x8E74, + 0x8632, 0x8211, 0x9EF4, 0x8E72, 0x8631, 0x9EF2, 0x8E71, 0x821B, 0x863B, 0x8E7B, + 0x9EFB, 0xFBEA, 0xFBE9, 0xF3CA, 0xF7DA, 0xF3C9, 0xF7D9, 0xE38A, 0xE79A, 0xE389, + 0xEFBA, 0xE799, 0xEFB9, 0xC30A, 0xC71A, 0xC309, 0xCF3A, 0xC719, 0xDF7A, 0xFAB0, + 0xFD5C, 0xF520, 0xFA98, 0xFD4E, 0xF510, 0xFA8C, 0xFD47, 0xF508, 0xFA86, 0xF504, + 0xFA83, 0xF502, 0xF5B0, 0xFADC, 0xFD6F, 0xEB20, 0xF598, 0xFACE, 0xEB10, 0xF58C, + 0xFAC7, 0xEB08, 0xF586, 0xEB04, 0xF583, 0xEB02, 0xEBB0, 0xF5DC, 0xFAEF, 0xD720, + 0xEB98, 0xF5CE, 0xD710, 0xEB8C, 0xF5C7, 0xD708, 0xEB86, 0xD704, 0xEB83, 0xD702, + 0xD7B0, 0xEBDC, 0xF5EF, 0xAF20, 0xD798, 0xEBCE, 0xAF10, 0xD78C, 0xEBC7, 0xAF08, + 0xD786, 0xAF04, 0xD783, 0xAFB0, 0xD7DC, 0xEBEF, 0xAF98, 0xD7CE, 0xAF8C, 0xD7C7, + 0xAF86, 0xAFDC, 0xD7EF, 0xAFCE, 0xAFC7, 0xF4A0, 0xFA58, 0xFD2E, 0xF490, 0xFA4C, + 0xFD27, 0xF488, 0xFA46, 0xF484, 0xFA43, 0xF482, 0xF481, 0xE9A0, 0xF4D8, 0xFA6E, + 0xE990, 0xF4CC, 0xFA67, 0xE988, 0xF4C6, 0xE984, 0xF4C3, 0xE982, 0xE981, 0xD3A0, + 0xE9D8, 0xF4EE, 0xD390, 0xE9CC, 0xF4E7, 0xD388, 0xE9C6, 0xD384, 0xE9C3, 0xD382, + 0xD381, 0xA7A0, 0xD3D8, 0xE9EE, 0xA790, 0xD3CC, 0xE9E7, 0xA788, 0xD3C6, 0xA784, + 0xD3C3, 0xA782, 0xA7D8, 0xD3EE, 0xA7CC, 0xD3E7, 0xA7C6, 0xA7C3, 0xA7EE, 0xA7E7, + 0xF450, 0xFA2C, 0xFD17, 0xF448, 0xFA26, 0xF444, 0xFA23, 0xF442, 0xF441, 0xE8D0, + 0xF46C, 0xFA37, 0xE8C8, 0xF466, 0xE8C4, 0xF463, 0xE8C2, 0xE8C1, 0xD1D0, 0xE8EC, + 0xF477, 0xD1C8, 0xE8E6, 0xD1C4, 0xE8E3, 0xD1C2, 0xD1C1, 0xA3D0, 0xD1EC, 0xE8F7, + 0xA3C8, 0xD1E6, 0xA3C4, 0xD1E3, 0xA3C2, 0xA3C1, 0xA3EC, 0xD1F7, 0xA3E6, 0xA3E3, + 0xA3F7, 0xF428, 0xFA16, 0xF424, 0xFA13, 0xF422, 0xF421, 0xE868, 0xF436, 0xE864, + 0xF433, 0xE862, 0xE861, 0xD0E8, 0xE876, 0xD0E4, 0xE873, 0xD0E2, 0xD0E1, 0xA1E8, + 0xD0F6, 0xA1E4, 0xD0F3, 0xA1E2, 0xA1E1, 0xA1F6, 0xA1F3, 0xF414, 0xFA0B, 0xF412, + 0xF411, 0xE834, 0xF41B, 0xE832, 0xE831, 0xD074, 0xE83B, 0xD072, 0xD071, 0xA0F4, + 0xD07B, 0xA0F2, 0xA0F1, 0xF40A, 0xF409, 0xE81A, 0xE819, 0xD03A, 0xD039, 0xF2A0, + 0xF958, 0xFCAE, 0xF290, 0xF94C, 0xFCA7, 0xF288, 0xF946, 0xF284, 0xF943, 0xF282, + 0xF281, 0xE5A0, 0xF2D8, 0xF96E, 0xE590, 0xF2CC, 0xF967, 0xE588, 0xF2C6, 0xE584, + 0xF2C3, 0xE582, 0xE581, 0xCBA0, 0xE5D8, 0xF2EE, 0xCB90, 0xE5CC, 0xF2E7, 0xCB88, + 0xE5C6, 0xCB84, 0xE5C3, 0xCB82, 0xCB81, 0x97A0, 0xCBD8, 0xE5EE, 0x9790, 0xCBCC, + 0xE5E7, 0x9788, 0xCBC6, 0x9784, 0xCBC3, 0x9782, 0x97D8, 0xCBEE, 0x97CC, 0xCBE7, + 0x97C6, 0x97C3, 0x97EE, 0x97E7, 0xFB50, 0xFDAC, 0xB5F8, 0xFB48, 0xFDA6, 0xB4FC, + 0xFB44, 0xFDA3, 0xB47E, 0xFB42, 0xFB41, 0xF250, 0xF92C, 0xFC97, 0xF6D0, 0xF248, + 0xFDB7, 0xF6C8, 0xFB66, 0xF923, 0xF6C4, 0xF242, 0xF6C2, 0xF241, 0xF6C1, 0xE4D0, + 0xF26C, 0xF937, 0xEDD0, 0xE4C8, 0xF266, 0xEDC8, 0xF6E6, 0xF263, 0xEDC4, 0xE4C2, + 0xEDC2, 0xE4C1, 0xEDC1, 0xC9D0, 0xE4EC, 0xF277, 0xDBD0, 0xC9C8, 0xE4E6, 0xDBC8, + 0xEDE6, 0xE4E3, 0xDBC4, 0xC9C2, 0xDBC2, 0xC9C1, 0xDBC1, 0x93D0, 0xC9EC, 0xE4F7, + 0xB7D0, 0x93C8, 0xC9E6, 0xB7C8, 0xDBE6, 0xC9E3, 0xB7C4, 0x93C2, 0xB7C2, 0x93C1, + 0x93EC, 0xC9F7, 0xB7EC, 0x93E6, 0xB7E6, 0x93E3, 0xB7E3, 0x93F7, 0xFB28, 0xFD96, + 0xB2FC, 0xFB24, 0xFD93, 0xB27E, 0xFB22, 0xB23F, 0xFB21, 0xF228, 0xF916, 0xF668, + 0xF224, 0xF913, 0xF664, 0xFB33, 0xF662, 0xF221, 0xF661, 0xE468, 0xF236, 0xECE8, + 0xE464, 0xF233, 0xECE4, 0xF673, 0xECE2, 0xE461, 0xECE1, 0xC8E8, 0xE476, 0xD9E8, + 0xC8E4, 0xE473, 0xD9E4, 0xECF3, 0xD9E2, 0xC8E1, 0xD9E1, 0x91E8, 0xC8F6, 0xB3E8, + 0x91E4, 0xC8F3, 0xB3E4, 0xD9F3, 0xB3E2, 0x91E1, 0xB3E1, 0x91F6, 0xB3F6, 0x91F3, + 0xB3F3, 0xFB14, 0xFD8B, 0xB17E, 0xFB12, 0xB13F, 0xFB11, 0xF214, 0xF90B, 0xF634, + 0xFB1B, 0xF632, 0xF211, 0xF631, 0xE434, 0xF21B, 0xEC74, 0xE432, 0xEC72, 0xE431, + 0xEC71, 0xC874, 0xE43B, 0xD8F4, 0xEC7B, 0xD8F2, 0xC871, 0xD8F1, 0x90F4, 0xC87B, + 0xB1F4, 0x90F2, 0xB1F2, 0x90F1, 0xB1F1, 0x90FB, 0xB1FB, 0xFB0A, 0xB0BF, 0xFB09, + 0xF20A, 0xF61A, 0xF209, 0xF619, 0xE41A, 0xEC3A, 0xE419, 0xEC39, 0xC83A, 0xD87A, + 0xC839, 0xD879, 0x907A, 0xB0FA, 0x9079, 0xB0F9, 0xFB05, 0xF205, 0xF60D, 0xE40D, + 0xEC1D, 0xC81D, 0xD83D, 0xF150, 0xF8AC, 0xFC57, 0xF148, 0xF8A6, 0xF144, 0xF8A3, + 0xF142, 0xF141, 0xE2D0, 0xF16C, 0xF8B7, 0xE2C8, 0xF166, 0xE2C4, 0xF163, 0xE2C2, + 0xE2C1, 0xC5D0, 0xE2EC, 0xF177, 0xC5C8, 0xE2E6, 0xC5C4, 0xE2E3, 0xC5C2, 0xC5C1, + 0x8BD0, 0xC5EC, 0xE2F7, 0x8BC8, 0xC5E6, 0x8BC4, 0xC5E3, 0x8BC2, 0x8BC1, 0x8BEC, + 0xC5F7, 0x8BE6, 0x8BE3, 0x8BF7, 0xF9A8, 0xFCD6, 0x9AFC, 0xF9A4, 0xFCD3, 0x9A7E, + 0xF9A2, 0x9A3F, 0xF9A1, 0xF128, 0xF896, 0xF368, 0xF124, 0xF893, 0xF364, 0xF9B3, + 0xF362, 0xF121, 0xF361, 0xE268, 0xF136, 0xE6E8, 0xE264, 0xF133, 0xE6E4, 0xF373, + 0xE6E2, 0xE261, 0xE6E1, 0xC4E8, 0xE276, 0xCDE8, 0xC4E4, 0xE273, 0xCDE4, 0xE6F3, + 0xCDE2, 0xC4E1, 0xCDE1, 0x89E8, 0xC4F6, 0x9BE8, 0x89E4, 0xC4F3, 0x9BE4, 0xCDF3, + 0x9BE2, 0x89E1, 0x9BE1, 0x89F6, 0x9BF6, 0x89F3, 0x9BF3, 0xFDD4, 0xBAF8, 0xDD7E, + 0xFDD2, 0xBA7C, 0xDD3F, 0xFDD1, 0xBA3E, 0xBA1F, 0xF994, 0xFCCB, 0x997E, 0xFBB4, + 0xFDDB, 0xBB7E, 0x993F, 0xFBB2, 0xF991, 0xBB3F, 0xFBB1, 0xF114, 0xF88B, 0xF334, + 0xF112, 0xF774, 0xFBBB, 0xF111, 0xF772, 0xF331, 0xF771, 0xE234, 0xF11B, 0xE674, + 0xE232, 0xEEF4, 0xE672, 0xE231, 0xEEF2, 0xE671, 0xEEF1, 0xC474, 0xE23B, 0xCCF4, + 0xC472, 0xDDF4, 0xCCF2, 0xC471, 0xDDF2, 0xCCF1, 0xDDF1, 0x88F4, 0xC47B, 0x99F4, + 0x88F2, 0xBBF4, 0x99F2, 0x88F1, 0xBBF2, 0x99F1, 0xBBF1, 0x88FB, 0x99FB, 0xFDCA, + 0xB97C, 0xDCBF, 0xFDC9, 0xB93E, 0xB91F, 0xF98A, 0x98BF, 0xFB9A, 0xF989, 0xB9BF, + 0xFB99, 0xF10A, 0xF31A, 0xF109, 0xF73A, 0xF319, 0xF739, 0xE21A, 0xE63A, 0xE219, + 0xEE7A, 0xE639, 0xEE79, 0xC43A, 0xCC7A, 0xC439, 0xDCFA, 0xCC79, 0xDCF9, 0x887A, + 0x98FA, 0x8879, 0xB9FA, 0x98F9, 0xB9F9, 0xFDC5, 0xB8BE, 0xB89F, 0xF985, 0xFB8D, + 0xF105, 0xF30D, 0xF71D, 0xE20D, 0xE61D, 0xEE3D, 0xC41D, 0xCC3D, 0xDC7D, 0x883D, + 0x987D, 0xB8FD, 0xB85F, 0xF0A8, 0xF856, 0xF0A4, 0xF853, 0xF0A2, 0xF0A1, 0xE168, + 0xF0B6, 0xE164, 0xF0B3, 0xE162, 0xE161, 0xC2E8, 0xE176, 0xC2E4, 0xE173, 0xC2E2, + 0xC2E1, 0x85E8, 0xC2F6, 0x85E4, 0xC2F3, 0x85E2, 0x85E1, 0x85F6, 0x85F3, 0xF8D4, + 0xFC6B, 0x8D7E, 0xF8D2, 0x8D3F, 0xF8D1, 0xF094, 0xF84B, 0xF1B4, 0xF092, 0xF1B2, + 0xF091, 0xF1B1, 0xE134, 0xF09B, 0xE374, 0xE132, 0xE372, 0xE131, 0xE371, 0xC274, + 0xE13B, 0xC6F4, 0xC272, 0xC6F2, 0xC271, 0xC6F1, 0x84F4, 0xC27B, 0x8DF4, 0x84F2, + 0x8DF2, 0x84F1, 0x8DF1, 0x84FB, 0x8DFB, 0xFCEA, 0x9D7C, 0xCEBF, 0xFCE9, 0x9D3E, + 0x9D1F, 0xF8CA, 0x8CBF, 0xF9DA, 0xF8C9, 0x9DBF, 0xF9D9, 0xF08A, 0xF19A, 0xF089, + 0xF3BA, 0xF199, 0xF3B9, 0xE11A, 0xE33A, 0xE119, 0xE77A, 0xE339, 0xE779, 0xC23A, + 0xC67A, 0xC239, 0xCEFA, 0xC679, 0xCEF9, 0x847A, 0x8CFA, 0x8479, 0x9DFA, 0x8CF9, + 0x9DF9, 0xBD78, 0xDEBE, 0xBD3C, 0xDE9F, 0xBD1E, 0xBD0F, 0xFCE5, 0x9CBE, 0xFDED, + 0xBDBE, 0x9C9F, 0xBD9F, 0xF8C5, 0xF9CD, 0xFBDD, 0xF085, 0xF18D, 0xF39D, 0xF7BD, + 0xE10D, 0xE31D, 0xE73D, 0xEF7D, 0xC21D, 0xC63D, 0xCE7D, 0xDEFD, 0x843D, 0x8C7D, + 0x9CFD, 0xBCBC, 0xDE5F, 0xBC9E, 0xBC8F, 0x9C5F, 0xBCDF, 0xBC5E, 0xBC4F, 0xBC2F, + 0xF054, 0xF052, 0xF051, 0xE0B4, 0xF05B, 0xE0B2, 0xE0B1, 0xC174, 0xE0BB, 0xC172, + 0xC171, 0x82F4, 0xC17B, 0x82F2, 0x82F1, 0x82FB, 0xF86A, 0x86BF, 0xF869, 0xF04A, + 0xF0DA, 0xF049, 0xF0D9, 0xE09A, 0xE1BA, 0xE099, 0xE1B9, 0xC13A, 0xC37A, 0xC139, + 0xC379, 0x827A, 0x86FA, 0x8279, 0x86F9, 0xFC75, 0x8EBE, 0x8E9F, 0xF865, 0xF8ED, + 0xF045, 0xF0CD, 0xF1DD, 0xE08D, 0xE19D, 0xE3BD, 0xC11D, 0xC33D, 0xC77D, 0x823D, + 0x867D, 0x8EFD, 0x9EBC, 0xCF5F, 0x9E9E, 0x9E8F, 0x8E5F, 0x9EDF, 0xBEB8, 0xDF5E, + 0xBE9C, 0xDF4F, 0xBE8E, 0xBE87, 0x9E5E, 0xBEDE, 0x9E4F, 0xBECF, 0xBE5C, 0xDF2F, + 0xBE4E, 0xBE47, 0x9E2F, 0xBE6F, 0xBE2E, 0xBE27, 0xBE17, 0xE05A, 0xE059, 0xC0BA, + 0xC0B9, 0x817A, 0x8179, 0xF06D, 0xE04D, 0xE0DD, 0xC09D, 0xC1BD, 0x813D, 0x837D, + 0x875F, 0x8F5E, 0x8F4F, 0x9F5C, 0xCFAF, 0x9F4E, 0x9F47, 0x8F2F, 0x9F6F, 0xBF58, + 0xDFAE, 0xBF4C, 0xDFA7, 0xBF46, 0xBF43, 0x9F2E, 0xBF6E, 0x9F27, 0xBF67, 0xBF2C, + 0xDF97, 0xBF26, 0xBF23, 0x9F17, 0xBF37, 0xBF16, 0xBF13, 0x87AF, 0x8FAE, 0x8FA7, + 0x9FAC, 0xCFD7, 0x9FA6, 0x9FA3, 0x8F97, 0x9FB7, 0x9F96, 0x9F93, 0xD5F0, 0xEAFC, + 0xA9E0, 0xD4F8, 0xEA7E, 0xA8F0, 0xD47C, 0xEA3F, 0xA878, 0xD43E, 0xA83C, 0xFD68, + 0xADF0, 0xD6FC, 0xFD64, 0xACF8, 0xD67E, 0xFD62, 0xAC7C, 0xD63F, 0xFD61, 0xAC3E, + 0xFAE8, 0xFD76, 0xAEFC, 0xFAE4, 0xFD73, 0xAE7E, 0xFAE2, 0xAE3F, 0xFAE1, 0xF5E8, + 0xFAF6, 0xF5E4, 0xFAF3, 0xF5E2, 0xF5E1, 0xEBE8, 0xF5F6, 0xEBE4, 0xF5F3, 0xEBE2, + 0xEBE1, 0xD7E8, 0xEBF6, 0xD7E4, 0xEBF3, 0xD7E2, 0xA5E0, 0xD2F8, 0xE97E, 0xA4F0, + 0xD27C, 0xE93F, 0xA478, 0xD23E, 0xA43C, 0xD21F, 0xA41E, 0xFD34, 0xA6F8, 0xD37E, + 0xFD32, 0xA67C, 0xD33F, 0xFD31, 0xA63E, 0xA61F, 0xFA74, 0xFD3B, 0xA77E, 0xFA72, + 0xA73F, 0xFA71, 0xF4F4, 0xFA7B, 0xF4F2, 0xF4F1, 0xE9F4, 0xF4FB, 0xE9F2, 0xE9F1, + 0xD3F4, 0xE9FB, 0xD3F2, 0xD3F1, 0xA2F0, 0xD17C, 0xE8BF, 0xA278, 0xD13E, 0xA23C, + 0xD11F, 0xA21E, 0xA20F, 0xFD1A, 0xA37C, 0xD1BF, 0xFD19, 0xA33E, 0xA31F, 0xFA3A, + 0xA3BF, 0xFA39, 0xF47A, 0xF479, 0xE8FA, 0xE8F9, 0xD1FA, 0xD1F9, 0xA178, 0xD0BE, + 0xA13C, 0xD09F, 0xA11E, 0xA10F, 0xFD0D, 0xA1BE, 0xA19F, 0xFA1D, 0xF43D, 0xE87D, + 0xA0BC, 0xD05F, 0xA09E, 0xA08F, 0xA0DF, 0xA05E, 0xA04F, 0x95E0, 0xCAF8, 0xE57E, + 0x94F0, 0xCA7C, 0xE53F, 0x9478, 0xCA3E, 0x943C, 0xCA1F, 0x941E, 0xFCB4, 0x96F8, + 0xCB7E, 0xFCB2, 0x967C, 0xCB3F, 0xFCB1, 0x963E, 0x961F, 0xF974, 0xFCBB, 0x977E, + 0xF972, 0x973F, 0xF971, 0xF2F4, 0xF97B, 0xF2F2, 0xF2F1, 0xE5F4, 0xF2FB, 0xE5F2, + 0xE5F1, 0xCBF4, 0xE5FB, 0xCBF2, 0xCBF1, 0xDAF0, 0xED7C, 0xF6BF, 0xB4E0, 0xDA78, + 0xED3E, 0xB470, 0xDA3C, 0xED1F, 0xB438, 0xDA1E, 0xB41C, 0xDA0F, 0xB40E, 0x92F0, + 0xC97C, 0xE4BF, 0xB6F0, 0x9278, 0xC93E, 0xB678, 0xDB3E, 0xC91F, 0xB63C, 0x921E, + 0xB61E, 0x920F, 0xB60F, 0xFC9A, 0x937C, 0xC9BF, 0xFDBA, 0xFC99, 0xB77C, 0x933E, + 0xFDB9, 0xB73E, 0x931F, 0xB71F, 0xF93A, 0x93BF, 0xFB7A, 0xF939, 0xB7BF, 0xFB79, + 0xF27A, 0xF6FA, 0xF279, 0xF6F9, 0xE4FA, 0xEDFA, 0xE4F9, 0xEDF9, 0xC9FA, 0xC9F9, + 0xB2E0, 0xD978, 0xECBE, 0xB270, 0xD93C, 0xEC9F, 0xB238, 0xD91E, 0xB21C, 0xD90F, + 0xB20E, 0xB207, 0x9178, 0xC8BE, 0xB378, 0x913C, 0xC89F, 0xB33C, 0xD99F, 0xB31E, + 0x910F, 0xB30F, 0xFC8D, 0x91BE, 0xFD9D, 0xB3BE, 0x919F, 0xB39F, 0xF91D, 0xFB3D, + 0xF23D, 0xF67D, 0xE47D, 0xECFD, 0xC8FD, 0xB170, 0xD8BC, 0xEC5F, 0xB138, 0xD89E, + 0xB11C, 0xD88F, 0xB10E, 0xB107, 0x90BC, 0xC85F, 0xB1BC, 0x909E, 0xB19E, 0x908F, + 0xB18F, 0x90DF, 0xB1DF, 0xB0B8, 0xD85E, 0xB09C, 0xD84F, 0xB08E, 0xB087, 0x905E, + 0xB0DE, 0x904F, 0xB0CF, 0xB05C, 0xD82F, 0xB04E, 0xB047, 0x902F, 0xB06F, 0xB02E, + 0xB027, 0x8AF0, 0xC57C, 0xE2BF, 0x8A78, 0xC53E, 0x8A3C, 0xC51F, 0x8A1E, 0x8A0F, + 0xFC5A, 0x8B7C, 0xC5BF, 0xFC59, 0x8B3E, 0x8B1F, 0xF8BA, 0x8BBF, 0xF8B9, 0xF17A, + 0xF179, 0xE2FA, 0xE2F9, 0xC5FA, 0xC5F9, 0x9AE0, 0xCD78, 0xE6BE, 0x9A70, 0xCD3C, + 0xE69F, 0x9A38, 0xCD1E, 0x9A1C, 0xCD0F, 0x9A0E, 0x9A07, 0x8978, 0xC4BE, 0x9B78, + 0x893C, 0xC49F, 0x9B3C, 0xCD9F, 0x9B1E, 0x890F, 0x9B0F, 0xFC4D, 0x89BE, 0xFCDD, + 0x9BBE, 0x899F, 0x9B9F, 0xF89D, 0xF9BD, 0xF13D, 0xF37D, 0xE27D, 0xE6FD, 0xC4FD, + 0xDD70, 0xEEBC, 0xF75F, 0xBA60, 0xDD38, 0xEE9E, 0xBA30, 0xDD1C, 0xEE8F, 0xBA18, + 0xDD0E, 0xBA0C, 0xDD07, 0xBA06, 0x9970, 0xCCBC, 0xE65F, 0xBB70, 0x9938, 0xCC9E, + 0xBB38, 0xDD9E, 0xCC8F, 0xBB1C, 0x990E, 0xBB0E, 0x9907, 0xBB07, 0x88BC, 0xC45F, + 0x99BC, 0x889E, 0xBBBC, 0x999E, 0x888F, 0xBB9E, 0x998F, 0xBB8F, 0x88DF, 0x99DF, + 0xBBDF, 0xB960, 0xDCB8, 0xEE5E, 0xB930, 0xDC9C, 0xEE4F, 0xB918, 0xDC8E, 0xB90C, + 0xDC87, 0xB906, 0xB903, 0x98B8, 0xCC5E, 0xB9B8, 0x989C, 0xCC4F, 0xB99C, 0xDCCF, + 0xB98E, 0x9887, 0xB987, 0x885E, 0x98DE, 0x884F, 0xB9DE, 0x98CF, 0xB9CF, 0xB8B0, + 0xDC5C, 0xEE2F, 0xB898, 0xDC4E, 0xB88C, 0xDC47, 0xB886, 0xB883, 0x985C, 0xCC2F, + 0xB8DC, 0x984E, 0xB8CE, 0x9847, 0xB8C7, 0x882F, 0x986F, 0xB8EF, 0xB858, 0xDC2E, + 0xB84C, 0xDC27, 0xB846, 0xB843, 0x982E, 0xB86E, 0x9827, 0xB867, 0xB82C, 0xDC17, + 0xB826, 0xB823, 0x9817, 0xB837, 0xB816, 0xB813, 0x8578, 0xC2BE, 0x853C, 0xC29F, + 0x851E, 0x850F, 0x85BE, 0x859F, 0xF85D, 0xF0BD, 0xE17D, 0xC2FD, 0x8D70, 0xC6BC, + 0xE35F, 0x8D38, 0xC69E, 0x8D1C, 0xC68F, 0x8D0E, 0x8D07, 0x84BC, 0xC25F, 0x8DBC, + 0x849E, 0x8D9E, 0x848F, 0x8D8F, 0x84DF, 0x8DDF, 0x9D60, 0xCEB8, 0xE75E, 0x9D30, + 0xCE9C, 0xE74F, 0x9D18, 0xCE8E, 0x9D0C, 0xCE87, 0x9D06, 0x9D03, 0x8CB8, 0xC65E, + 0x9DB8, 0x8C9C, 0xC64F, 0x9D9C, 0x8C8E, 0x9D8E, 0x8C87, 0x9D87, 0x845E, 0x8CDE, + 0x844F, 0x9DDE, 0x8CCF, 0x9DCF, 0xDEB0, 0xEF5C, 0xF7AF, 0xBD20, 0xDE98, 0xEF4E, + 0xBD10, 0xDE8C, 0xEF47, 0xBD08, 0xDE86, 0xBD04, 0xDE83, 0xBD02, 0x9CB0, 0xCE5C, + 0xE72F, 0xBDB0, 0x9C98, 0xCE4E, 0xBD98, 0xDECE, 0xCE47, 0xBD8C, 0x9C86, 0xBD86, + 0x9C83, 0xBD83, 0x8C5C, 0xC62F, 0x9CDC, 0x8C4E, 0xBDDC, 0x9CCE, 0x8C47, 0xBDCE, + 0x9CC7, 0xBDC7, 0x842F, 0x8C6F, 0x9CEF, 0xBDEF, 0xBCA0, 0xDE58, 0xEF2E, 0xBC90, + 0xDE4C, 0xEF27, 0xBC88, 0xDE46, 0xBC84, 0xDE43, 0xBC82, 0xBC81, 0x9C58, 0xCE2E, + 0xBCD8, 0x9C4C, 0xCE27, 0xBCCC, 0xDE67, 0xBCC6, 0x9C43, 0xBCC3, 0x8C2E, 0x9C6E, + 0x8C27, 0xBCEE, 0x9C67, 0xBCE7, 0xBC50, 0xDE2C, 0xEF17, 0xBC48, 0xDE26, 0xBC44, + 0xDE23, 0xBC42, 0xBC41, 0x9C2C, 0xCE17, 0xBC6C, 0x9C26, 0xBC66, 0x9C23, 0xBC63, + 0x8C17, 0x9C37, 0xBC77, 0xBC28, 0xDE16, 0xBC24, 0xDE13, 0xBC22, 0xBC21, 0x9C16, + 0xBC36, 0x9C13, 0xBC33, 0xBC14, 0xDE0B, 0xBC12, 0xBC11, 0x9C0B, 0xBC1B, 0x82BC, + 0xC15F, 0x829E, 0x828F, 0x82DF, 0x86B8, 0xC35E, 0x869C, 0xC34F, 0x868E, 0x8687, + 0x825E, 0x86DE, 0x824F, 0x86CF, 0x8EB0, 0xC75C, 0xE3AF, 0x8E98, 0xC74E, 0x8E8C, + 0xC747, 0x8E86, 0x8E83, 0x865C, 0xC32F, 0x8EDC, 0x864E, 0x8ECE, 0x8647, 0x8EC7, + 0x822F, 0x866F, 0x8EEF, 0x9EA0, 0xCF58, 0xE7AE, 0x9E90, 0xCF4C, 0xE7A7, 0x9E88, + 0xCF46, 0x9E84, 0xCF43, 0x9E82, 0x9E81, 0x8E58, 0xC72E, 0x9ED8, 0x8E4C, 0xC727, + 0x9ECC, 0xCF67, 0x9EC6, 0x8E43, 0x9EC3, 0x862E, 0x8E6E, 0x8627, 0x9EEE, 0x8E67, + 0x9EE7, 0xDF50, 0xEFAC, 0xF7D7, 0xDF48, 0xEFA6, 0xDF44, 0xEFA3, 0xDF42, 0xDF41, + 0x9E50, 0xCF2C, 0xE797, 0xBED0, 0x9E48, 0xCF26, 0xBEC8, 0xDF66, 0xCF23, 0xBEC4, + 0x9E42, 0xBEC2, 0x9E41, 0xBEC1, 0x8E2C, 0xC717, 0x9E6C, 0x8E26, 0xBEEC, 0x9E66, + 0x8E23, 0xBEE6, 0x9E63, 0xBEE3, 0x8617, 0x8E37, 0x9E77, 0xBEF7, 0xDF28, 0xEF96, + 0xDF24, 0xEF93, 0xDF22, 0xDF21, 0x9E28, 0xCF16, 0xBE68, 0x9E24, 0xCF13, 0xBE64, + 0xDF33, 0xBE62, 0x9E21, 0xBE61, 0x8E16, 0x9E36, 0x8E13, 0xBE76, 0x9E33, 0xBE73, + 0xDF14, 0xEF8B, 0xDF12, 0xDF11, 0x9E14, 0xCF0B, 0xBE34, 0x9E12, 0xBE32, 0x9E11, + 0xBE31, 0x8E0B, 0x9E1B, 0xBE3B, 0xDF0A, 0xDF09, 0x9E0A, 0xBE1A, 0x9E09, 0xBE19, + 0x815E, 0x814F, 0x835C, 0xC1AF, 0x834E, 0x8347, 0x812F, 0x836F, 0x8758, 0xC3AE, + 0x874C, 0xC3A7, 0x8746, 0x8743, 0x832E, 0x876E, 0x8327, 0x8767, 0x8F50, 0xC7AC, + 0xE3D7, 0x8F48, 0xC7A6, 0x8F44, 0xC7A3, 0x8F42, 0x8F41, 0x872C, 0xC397, 0x8F6C, + 0xC7B7, 0x8F66, 0x8723, 0x8F63, 0x8317, 0x8737, 0x8F77, 0xCFA8, 0xE7D6, 0xCFA4, + 0xE7D3, 0xCFA2, 0xCFA1, 0x8F28, 0xC796, 0x9F68, 0xCFB6, 0xC793, 0x9F64, 0x8F22, + 0x9F62, 0x8F21, 0x9F61, 0x8716, 0x8F36, 0x8713, 0x9F76, 0x8F33, 0x9F73, 0xEFD4, + 0xF7EB, 0xEFD2, 0xEFD1, 0xCF94, 0xE7CB, 0xDFB4, 0xCF92, 0xDFB2, 0xCF91, 0xDFB1, + 0x8F14, 0xC78B, 0x9F34, 0x8F12, 0xBF74, 0x9F32, 0x8F11, 0xBF72, 0x9F31, 0xBF71, + 0x870B, 0x8F1B, 0x9F3B, 0xBF7B, 0xEFCA, 0xEFC9, 0xCF8A, 0xDF9A, 0xCF89, 0xDF99, + 0x8F0A, 0x9F1A, 0x8F09, 0xBF3A, 0x9F19, 0xBF39, 0xEFC5, 0xCF85, 0xDF8D, 0x8F05, + 0x9F0D, 0xBF1D, 0x81AE, 0x81A7, 0x83AC, 0xC1D7, 0x83A6, 0x83A3, 0x8197, 0x83B7, + 0x87A8, 0xC3D6, 0x87A4, 0xC3D3, 0x87A2, 0x87A1, 0x8396, 0x87B6, 0x8393, 0x87B3, + 0xC7D4, 0xE3EB, 0xC7D2, 0xC7D1, 0x8794, 0xC3CB, 0x8FB4, 0xC7DB, 0x8FB2, 0x8791, + 0x8FB1, 0x838B, 0x879B, 0x8FBB, 0xE7EA, 0xE7E9, 0xC7CA, 0xCFDA, 0xC7C9, 0xCFD9, + 0x878A, 0x8F9A, 0x8789, 0x9FBA, 0x8F99, 0x9FB9, 0xE7E5, 0xC7C5, 0xCFCD, 0x8785, + 0x8F8D, 0x9F9D, 0x81D6, 0x81D3, 0x83D4, 0xC1EB, 0x83D2, 0x83D1, 0x81CB, 0x83DB, + 0xC3EA, 0xC3E9, 0x83CA, 0x87DA, 0x83C9, 0x87D9, 0xE3F5 +}; + +/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */ +static const unsigned short int Microcoeffs[344] = { + /* k = 7 */ + 76, 925, 537, 597, 784, 691, 437, + + /* k = 8 */ + 237, 308, 436, 284, 646, 653, 428, 379, + + /* k = 9 */ + 567, 527, 622, 257, 289, 362, 501, 441, 205, + + /* k = 10 */ + 377, 457, 64, 244, 826, 841, 818, 691, 266, 612, + + /* k = 11 */ + 462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904, + + /* k = 12 */ + 597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851, + + /* k = 13 */ + 764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692, + + /* k = 14 */ + 669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215, + + /* k = 15 */ + 460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642, + + /* k = 16 */ + 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, + + /* k = 18 */ + 279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756, + 760, 573, + + /* k = 21 */ + 108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691, + 347, 165, 193, 259, 568, + + /* k = 26 */ + 443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893, + 699, 245, 441, 454, 325, 858, 131, 847, 764, 169, + + /* k = 32 */ + 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, + 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, + + /* k = 38 */ + 234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684, + 445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771, + 554, 289, 231, 125, 117, 518, + + /* k = 44 */ + 476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405, + 417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213, + 31, 560, 231, 758, 103, 271, 572, 436, 339, 730, 82, 285, + + /* k = 50 */ + 923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303, + 188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26, + 579, 623, 766, 146, 10, 739, 246, 127, 71, 244, 211, 477, 920, 876, 427, 820, + 718, 435 +}; + +/* rows, columns, error codewords, k-offset of valid MicroPDF417 sizes from ISO/IEC 24728:2006 */ +static const unsigned short int MicroVariants[170] ={ + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, + 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, + 0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 +}; +/* rows, columns, error codewords, k-offset */ + +/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables 10, 11 and 12 */ +static const char RAPTable[136] ={ + 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, + 9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, + 0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 +}; + +/* Left and Right Row Address Pattern from Table 2 */ +static const unsigned short int rap_side[52] = { + 0x322, 0x3A2, 0x3B2, 0x332, 0x372, 0x37A, 0x33A, 0x3BA, 0x39A, 0x3DA, + 0x3CA, 0x38A, 0x30A, 0x31A, 0x312, 0x392, 0x3D2, 0x3D6, 0x3D4, 0x394, + 0x3B4, 0x3A4, 0x3A6, 0x3AE, 0x3AC, 0x3A8, 0x328, 0x32C, 0x32E, 0x326, + 0x336, 0x3B6, 0x396, 0x316, 0x314, 0x334, 0x374, 0x364, 0x366, 0x36E, + 0x36C, 0x368, 0x348, 0x358, 0x35C, 0x35E, 0x34E, 0x34C, 0x344, 0x346, + 0x342, 0x362 +}; + +/* Centre Row Address Pattern from Table 2 */ +static const unsigned short int rap_centre[52] = { + 0x2CE, 0x24E, 0x26E, 0x22E, 0x226, 0x236, 0x216, 0x212, 0x21A, 0x23A, + 0x232, 0x222, 0x262, 0x272, 0x27A, 0x2FA, 0x2F2, 0x2F6, 0x276, 0x274, + 0x264, 0x266, 0x246, 0x242, 0x2C2, 0x2E2, 0x2E6, 0x2E4, 0x2EC, 0x26C, + 0x22C, 0x228, 0x268, 0x2E8, 0x2C8, 0x2CC, 0x2C4, 0x2C6, 0x286, 0x28E, + 0x28C, 0x29C, 0x298, 0x2B8, 0x2B0, 0x290, 0x2D0, 0x250, 0x258, 0x25C, + 0x2DC, 0x2DE +}; + +void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length, int block); \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/plessey.c b/3rdparty/zint-2.6.1/backend/plessey.c new file mode 100644 index 0000000..1154845 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/plessey.c @@ -0,0 +1,492 @@ +/* plessey.c - Handles Plessey and MSI Plessey */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include "common.h" + + +#define SSET "0123456789ABCDEF" +static const char *PlessTable[16] = { + "13131313", "31131313", "13311313", "31311313", "13133113", "31133113", + "13313113", "31313113", "13131331", "31131331", "13311331", "31311331", "13133131", + "31133131", "13313131", "31313131" +}; + +static const char *MSITable[10] = { + "12121212", "12121221", "12122112", "12122121", "12211212", "12211221", + "12212112", "12212121", "21121212", "21121221" +}; + +/* Not MSI/Plessey but the older Plessey standard */ +int plessey(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + + unsigned int i, check; + unsigned char *checkptr; + static const char grid[9] = {1, 1, 1, 1, 0, 1, 0, 0, 1}; + char dest[1024]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 ~ 1024 */ + int error_number; + + if (length > 65) { + strcpy(symbol->errtxt, "370: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(SSET, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "371: Invalid characters in data"); + return error_number; + } + checkptr = (unsigned char *) calloc(1, length * 4 + 8); + + /* Start character */ + strcpy(dest, "31311331"); + + /* Data area */ + for (i = 0; i < length; i++) { + check = posn(SSET, source[i]); + lookup(SSET, PlessTable, source[i], dest); + checkptr[4 * i] = check & 1; + checkptr[4 * i + 1] = (check >> 1) & 1; + checkptr[4 * i + 2] = (check >> 2) & 1; + checkptr[4 * i + 3] = (check >> 3) & 1; + } + + /* CRC check digit code adapted from code by Leonid A. Broukhis + used in GNU Barcode */ + + for (i = 0; i < (4 * length); i++) { + int j; + if (checkptr[i]) + for (j = 0; j < 9; j++) + checkptr[i + j] ^= grid[j]; + } + + for (i = 0; i < 8; i++) { + switch (checkptr[length * 4 + i]) { + case 0: strcat(dest, "13"); + break; + case 1: strcat(dest, "31"); + break; + } + } + + /* Stop character */ + strcat(dest, "331311313"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + free(checkptr); + return error_number; +} + +/* Plain MSI Plessey - does not calculate any check character */ +int msi_plessey(struct zint_symbol *symbol, unsigned char source[], const size_t length) { + + size_t i; + char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */ + + if (length > 55) { + strcpy(symbol->errtxt, "372: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + for (i = 0; i < length; i++) { + lookup(NEON, MSITable, source[i], dest); + } + + /* Stop character */ + strcat(dest, "121"); + + expand(symbol, dest); + ustrcpy(symbol->text, source); + return 0; +} + +/* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island + * http://www.barcodeisland.com/ */ +int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], int length) { + + + unsigned long i, wright, dau, pedwar, pump, n; + char un[200], tri[32]; + int error_number, h; + char dest[1000]; + + error_number = 0; + + if (length > 18) { + strcpy(symbol->errtxt, "373: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for (i = 0; i < length; i++) { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate check digit */ + wright = 0; + n = !(length & 1); + for (i = n; i < length; i += 2) { + un[wright++] = source[i]; + } + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for (i = 0; i < h; i++) { + pedwar += ctoi(tri[i]); + } + + n = length & 1; + for (i = n; i < length; i += 2) { + pedwar += ctoi(source[i]); + } + + pump = (10 - pedwar % 10); + if (pump == 10) { + pump = 0; + } + + /* draw check digit */ + lookup(NEON, MSITable, itoc(pump), dest); + + /* Stop character */ + strcat(dest, "121"); + expand(symbol, dest); + + ustrcpy(symbol->text, source); + symbol->text[length] = itoc(pump); + symbol->text[length + 1] = '\0'; + return error_number; +} + +/* MSI Plessey with two Modulo 10 check digits - algorithm from + * Barcode Island http://www.barcodeisland.com/ */ +int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) { + + + unsigned long i, n, wright, dau, pedwar, pump, chwech; + char un[16], tri[32]; + int error_number, h; + char dest[1000]; + + error_number = 0; + + if (src_len > 18) { + /* No Entry Stack Smashers! limit because of str->number conversion*/ + strcpy(symbol->errtxt, "374: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for (i = 0; i < src_len; i++) { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate first check digit */ + wright = 0; + + n = !(src_len & 1); + for (i = n; i < src_len; i += 2) { + un[wright++] = source[i]; + } + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for (i = 0; i < h; i++) { + pedwar += ctoi(tri[i]); + } + + n = src_len & 1; + for (i = n; i < src_len; i += 2) { + pedwar += ctoi(source[i]); + } + + pump = 10 - pedwar % 10; + if (pump == 10) { + pump = 0; + } + + /* calculate second check digit */ + wright = 0; + n = src_len & 1; + for (i = n; i < src_len; i += 2) { + un[wright++] = source[i]; + } + un[wright++] = itoc(pump); + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for (i = 0; i < h; i++) { + pedwar += ctoi(tri[i]); + } + + + i = !(src_len & 1); + for (; i < src_len; i += 2) { + pedwar += ctoi(source[i]); + } + + chwech = 10 - pedwar % 10; + if (chwech == 10) { + chwech = 0; + } + + /* Draw check digits */ + lookup(NEON, MSITable, itoc(pump), dest); + lookup(NEON, MSITable, itoc(chwech), dest); + + /* Stop character */ + strcat(dest, "121"); + + expand(symbol, dest); + + ustrcpy(symbol->text, source); + symbol->text[src_len] = itoc(pump); + symbol->text[src_len + 1] = itoc(chwech); + symbol->text[src_len + 2] = '\0'; + + return error_number; +} + +/* Calculate a Modulo 11 check digit using the system discussed on Wikipedia - + see http://en.wikipedia.org/wiki/Talk:MSI_Barcode */ +int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) { + /* uses the IBM weight system */ + int i, weight, x, check; + int error_number; + char dest[1000]; + + error_number = 0; + + if (src_len > 55) { + strcpy(symbol->errtxt, "375: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for (i = 0; i < src_len; i++) { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate check digit */ + x = 0; + weight = 2; + for (i = src_len - 1; i >= 0; i--) { + x += weight * ctoi(source[i]); + weight++; + if (weight > 7) { + weight = 2; + } + } + + check = (11 - (x % 11)) % 11; + if (check == 10) { + lookup(NEON, MSITable, '1', dest); + lookup(NEON, MSITable, '0', dest); + } else { + lookup(NEON, MSITable, itoc(check), dest); + } + + /* stop character */ + strcat(dest, "121"); + + expand(symbol, dest); + + ustrcpy(symbol->text, source); + if (check == 10) { + strcat((char*) symbol->text, "10"); + } else { + symbol->text[src_len] = itoc(check); + symbol->text[src_len + 1] = '\0'; + } + + return error_number; +} + +/* Combining the Barcode Island and Wikipedia code + * Verified against http://www.bokai.com/BarcodeJSP/applet/BarcodeSampleApplet.htm */ +int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len) { + /* Weighted using the IBM system */ + unsigned long i, weight, x, check, wright, dau, pedwar, pump; + size_t h; + long si; + char un[16], tri[16]; + int error_number; + char dest[1000]; + unsigned char temp[32]; + unsigned int temp_len; + + error_number = 0; + + if (src_len > 18) { + strcpy(symbol->errtxt, "376: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* start character */ + strcpy(dest, "21"); + + /* draw data section */ + for (i = 0; i < src_len; i++) { + lookup(NEON, MSITable, source[i], dest); + } + + /* calculate first (mod 11) digit */ + x = 0; + weight = 2; + for (si = src_len - 1; si >= 0; si--) { + x += weight * ctoi(source[si]); + weight++; + if (weight > 7) { + weight = 2; + } + } + + check = (11 - (x % 11)) % 11; + ustrcpy(temp, source); + temp_len = src_len; + if (check == 10) { + lookup(NEON, MSITable, '1', dest); + lookup(NEON, MSITable, '0', dest); + strcat((char*) temp, "10"); + temp_len += 2; + } else { + lookup(NEON, MSITable, itoc(check), dest); + temp[temp_len++] = itoc(check); + temp[temp_len] = '\0'; + } + + /* calculate second (mod 10) check digit */ + wright = 0; + i = !(temp_len & 1); + for (; i < temp_len; i += 2) { + un[wright++] = temp[i]; + } + un[wright] = '\0'; + + dau = strtoul(un, NULL, 10); + dau *= 2; + + sprintf(tri, "%ld", dau); + + pedwar = 0; + h = strlen(tri); + for (i = 0; i < h; i++) { + pedwar += ctoi(tri[i]); + } + + i = temp_len & 1; + for (; i < temp_len; i += 2) { + pedwar += ctoi(temp[i]); + } + + pump = 10 - pedwar % 10; + if (pump == 10) { + pump = 0; + } + + /* draw check digit */ + lookup(NEON, MSITable, itoc(pump), dest); + + /* stop character */ + strcat(dest, "121"); + expand(symbol, dest); + + temp[temp_len++] = itoc(pump); + temp[temp_len] = '\0'; + + + ustrcpy(symbol->text, temp); + return error_number; +} + +int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) { + int error_number; + + error_number = is_sane(NEON, source, length); + if (error_number != 0) { + strcpy(symbol->errtxt, "377: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + + + if ((symbol->option_2 < 0) || (symbol->option_2 > 4)) { + symbol->option_2 = 0; + } + + switch (symbol->option_2) { + case 0: error_number = msi_plessey(symbol, source, length); + break; + case 1: error_number = msi_plessey_mod10(symbol, source, length); + break; + case 2: error_number = msi_plessey_mod1010(symbol, source, length); + break; + case 3: error_number = msi_plessey_mod11(symbol, source, length); + break; + case 4: error_number = msi_plessey_mod1110(symbol, source, length); + break; + } + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/png.c b/3rdparty/zint-2.6.1/backend/png.c new file mode 100644 index 0000000..a726d51 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/png.c @@ -0,0 +1,191 @@ +/* png.c - Handles output to PNG file */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#ifdef _MSC_VER +#include +#include +#include +#endif +#include +#include +#include "common.h" + +#ifndef NO_PNG +#include +#include +#include + +#define SSET "0123456789ABCDEF" + +struct mainprog_info_type { + long width; + long height; + FILE *outfile; + jmp_buf jmpbuf; +}; + +static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) { + struct mainprog_info_type *graphic; + + fprintf(stderr, "writepng libpng error: %s (F30)\n", msg); + fflush(stderr); + + graphic = (struct mainprog_info_type*) png_get_error_ptr(png_ptr); + if (graphic == NULL) { + /* we are completely hosed now */ + fprintf(stderr, + "writepng severe error: jmpbuf not recoverable; terminating. (F31)\n"); + fflush(stderr); + return; + } + longjmp(graphic->jmpbuf, 1); +} + +int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { + struct mainprog_info_type wpng_info; + struct mainprog_info_type *graphic; + png_structp png_ptr; + png_infop info_ptr; + unsigned char *image_data; + int i, row, column; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + +#ifndef _MSC_VER + unsigned char outdata[symbol->bitmap_width * 3]; +#else + unsigned char* outdata = (unsigned char*) _alloca(symbol->bitmap_width * 3); +#endif + + graphic = &wpng_info; + + graphic->width = symbol->bitmap_width; + graphic->height = symbol->bitmap_height; + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + /* Open output file in binary mode */ + if (symbol->output_options & BARCODE_STDOUT) { +#ifdef _MSC_VER + if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { + strcpy(symbol->errtxt, "631: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } +#endif + graphic->outfile = stdout; + } else { + if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) { + strcpy(symbol->errtxt, "632: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + } + + /* Set up error handling routine as proc() above */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic, writepng_error_handler, NULL); + if (!png_ptr) { + strcpy(symbol->errtxt, "633: Out of memory"); + return ZINT_ERROR_MEMORY; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, NULL); + strcpy(symbol->errtxt, "634: Out of memory"); + return ZINT_ERROR_MEMORY; + } + + /* catch jumping here */ + if (setjmp(graphic->jmpbuf)) { + png_destroy_write_struct(&png_ptr, &info_ptr); + strcpy(symbol->errtxt, "635: libpng error occurred"); + return ZINT_ERROR_MEMORY; + } + + /* open output file with libpng */ + png_init_io(png_ptr, graphic->outfile); + + /* set compression */ + png_set_compression_level(png_ptr, 9); + + /* set Header block */ + png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + /* write all chunks up to (but not including) first IDAT */ + png_write_info(png_ptr, info_ptr); + + /* set up the transformations: for now, just pack low-bit-depth pixels + into bytes (one, two or four pixels per byte) */ + png_set_packing(png_ptr); + + /* Pixel Plotting */ + for (row = 0; row < symbol->bitmap_height; row++) { + for (column = 0; column < symbol->bitmap_width; column++) { + i = column * 3; + switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) { + case '1': + outdata[i] = fgred; + outdata[i + 1] = fggrn; + outdata[i + 2] = fgblu; + break; + default: + outdata[i] = bgred; + outdata[i + 1] = bggrn; + outdata[i + 2] = bgblu; + break; + + } + } + /* write row contents to file */ + image_data = outdata; + png_write_row(png_ptr, image_data); + } + + /* End the file */ + png_write_end(png_ptr, NULL); + + /* make sure we have disengaged */ + if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); + if (symbol->output_options & BARCODE_STDOUT) { + fflush(wpng_info.outfile); + } else { + fclose(wpng_info.outfile); + } + return 0; +} +#endif /* NO_PNG */ diff --git a/3rdparty/zint-2.6.1/backend/postal.c b/3rdparty/zint-2.6.1/backend/postal.c new file mode 100644 index 0000000..1a8844b --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/postal.c @@ -0,0 +1,621 @@ +/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + Including bug fixes by Bryan Hatton + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" + +#define DAFTSET "DAFT" +#define KRSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define KASUTSET "1234567890-abcdefgh" +#define CHKASUTSET "0123456789-abcdefgh" +#define SHKASUTSET "1234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +/* PostNet number encoding table - In this table L is long as S is short */ +static const char *PNTable[10] = { + "LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL", + "LSSLS", "LSLSS" +}; + +static const char *PLTable[10] = { + "SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS", + "SLLSL", "SLSLL" +}; + +static const char *RoyalValues[36] = { + "11", "12", "13", "14", "15", "10", "21", "22", "23", "24", "25", + "20", "31", "32", "33", "34", "35", "30", "41", "42", "43", "44", "45", "40", "51", "52", + "53", "54", "55", "50", "01", "02", "03", "04", "05", "00" +}; + +/* 0 = Full, 1 = Ascender, 2 = Descender, 3 = Tracker */ +static const char *RoyalTable[36] = { + "3300", "3210", "3201", "2310", "2301", "2211", "3120", "3030", "3021", + "2130", "2121", "2031", "3102", "3012", "3003", "2112", "2103", "2013", "1320", "1230", + "1221", "0330", "0321", "0231", "1302", "1212", "1203", "0312", "0303", "0213", "1122", + "1032", "1023", "0132", "0123", "0033" +}; + +static const char *FlatTable[10] = { + "0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711", "0810" +}; + +static const char *KoreaTable[10] = { + "1313150613", "0713131313", "0417131313", "1506131313", + "0413171313", "17171313", "1315061313", "0413131713", "17131713", "13171713" +}; + +static const char *JapanTable[19] = { + "114", "132", "312", "123", "141", "321", "213", "231", "411", "144", + "414", "324", "342", "234", "432", "243", "423", "441", "111" +}; + +/* Handles the PostNet system used for Zip codes in the US */ +int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) { + unsigned int i, sum, check_digit; + int error_number; + + error_number = 0; + + if (length > 38) { + strcpy(symbol->errtxt, "480: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "481: Invalid characters in data"); + return error_number; + } + sum = 0; + + /* start character */ + strcpy(dest, "L"); + + for (i = 0; i < length; i++) { + lookup(NEON, PNTable, source[i], dest); + sum += ctoi(source[i]); + } + + check_digit = (10 - (sum % 10)) % 10; + strcat(dest, PNTable[check_digit]); + + /* stop character */ + strcat(dest, "L"); + + return error_number; +} + +/* Puts PostNet barcodes into the pattern matrix */ +int post_plot(struct zint_symbol *symbol, unsigned char source[], int length) { + char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */ + unsigned int loopey, h; + int writer; + int error_number; + + error_number = 0; + + error_number = postnet(symbol, source, height_pattern, length); + if (error_number != 0) { + return error_number; + } + + writer = 0; + h = strlen(height_pattern); + for (loopey = 0; loopey < h; loopey++) { + if (height_pattern[loopey] == 'L') { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + writer += 3; + } + symbol->row_height[0] = 6; + symbol->row_height[1] = 6; + symbol->rows = 2; + symbol->width = writer - 1; + + return error_number; +} + +/* Handles the PLANET system used for item tracking in the US */ +int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) { + unsigned int i, sum, check_digit; + int error_number; + + error_number = 0; + + if (length > 38) { + strcpy(symbol->errtxt, "482: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "483: Invalid characters in data"); + return error_number; + } + sum = 0; + + /* start character */ + strcpy(dest, "L"); + + for (i = 0; i < length; i++) { + lookup(NEON, PLTable, source[i], dest); + sum += ctoi(source[i]); + } + + check_digit = (10 - (sum % 10)) % 10; + strcat(dest, PLTable[check_digit]); + + /* stop character */ + strcat(dest, "L"); + + return error_number; +} + +/* Puts PLANET barcodes into the pattern matrix */ +int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length) { + char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */ + unsigned int loopey, h; + int writer; + int error_number; + + error_number = 0; + + error_number = planet(symbol, source, height_pattern, length); + if (error_number != 0) { + return error_number; + } + + writer = 0; + h = strlen(height_pattern); + for (loopey = 0; loopey < h; loopey++) { + if (height_pattern[loopey] == 'L') { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + writer += 3; + } + symbol->row_height[0] = 6; + symbol->row_height[1] = 6; + symbol->rows = 2; + symbol->width = writer - 1; + return error_number; +} + +/* Korean Postal Authority */ +int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) { + int total, loop, check, zeroes, error_number; + char localstr[8], dest[80]; + + error_number = 0; + if (length > 6) { + strcpy(symbol->errtxt, "484: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "485: Invalid characters in data"); + return error_number; + } + zeroes = 6 - length; + memset(localstr, '0', zeroes); + strcpy(localstr + zeroes, (char *) source); + + total = 0; + for (loop = 0; loop < 6; loop++) { + total += ctoi(localstr[loop]); + } + check = 10 - (total % 10); + if (check == 10) { + check = 0; + } + localstr[6] = itoc(check); + localstr[7] = '\0'; + *dest = '\0'; + for (loop = 5; loop >= 0; loop--) { + lookup(NEON, KoreaTable, localstr[loop], dest); + } + lookup(NEON, KoreaTable, localstr[6], dest); + expand(symbol, dest); + ustrcpy(symbol->text, (unsigned char*) localstr); + return error_number; +} + +/* The simplest barcode symbology ever! Supported by MS Word, so here it is! + glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */ +int fim(struct zint_symbol *symbol, unsigned char source[], int length) { + + + char dest[16] = {0}; + + if (length > 1) { + strcpy(symbol->errtxt, "486: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + switch ((char) source[0]) { + case 'a': + case 'A': + strcpy(dest, "111515111"); + break; + case 'b': + case 'B': + strcpy(dest, "13111311131"); + break; + case 'c': + case 'C': + strcpy(dest, "11131313111"); + break; + case 'd': + case 'D': + strcpy(dest, "1111131311111"); + break; + default: + strcpy(symbol->errtxt, "487: Invalid characters in data"); + return ZINT_ERROR_INVALID_DATA; + break; + } + + expand(symbol, dest); + return 0; +} + +/* Handles the 4 State barcodes used in the UK by Royal Mail */ +char rm4scc(char source[], unsigned char dest[], int length) { + unsigned int i; + int top, bottom, row, column, check_digit; + char values[3], set_copy[] = KRSET; + + top = 0; + bottom = 0; + + /* start character */ + strcpy((char*) dest, "1"); + + for (i = 0; i < length; i++) { + lookup(KRSET, RoyalTable, source[i], (char*) dest); + strcpy(values, RoyalValues[posn(KRSET, source[i])]); + top += ctoi(values[0]); + bottom += ctoi(values[1]); + } + + /* Calculate the check digit */ + row = (top % 6) - 1; + column = (bottom % 6) - 1; + if (row == -1) { + row = 5; + } + if (column == -1) { + column = 5; + } + check_digit = (6 * row) + column; + strcat((char*) dest, RoyalTable[check_digit]); + + /* stop character */ + strcat((char*) dest, "0"); + + return set_copy[check_digit]; +} + +/* Puts RM4SCC into the data matrix */ +int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) { + char height_pattern[210]; + unsigned int loopey, h; + int writer; + int error_number; + strcpy(height_pattern, ""); + + error_number = 0; + + if (length > 50) { + strcpy(symbol->errtxt, "488: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(KRSET, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "489: Invalid characters in data"); + return error_number; + } + /*check = */rm4scc((char*) source, (unsigned char*) height_pattern, length); + + writer = 0; + h = strlen(height_pattern); + for (loopey = 0; loopey < h; loopey++) { + if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 3; + symbol->row_height[1] = 2; + symbol->row_height[2] = 3; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + +/* Handles Dutch Post TNT KIX symbols + The same as RM4SCC but without check digit + Specification at http://www.tntpost.nl/zakelijk/klantenservice/downloads/kIX_code/download.aspx */ +int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) { + char height_pattern[75], localstr[20]; + unsigned int loopey; + int writer, i, h; + int error_number; /* zeroes; */ + strcpy(height_pattern, ""); + + error_number = 0; + + if (length > 18) { + strcpy(symbol->errtxt, "490: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + to_upper(source); + error_number = is_sane(KRSET, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "491: Invalid characters in data"); + return error_number; + } + + strcpy(localstr, (char *) source); + + /* Encode data */ + for (i = 0; i < length; i++) { + lookup(KRSET, RoyalTable, localstr[i], height_pattern); + } + + writer = 0; + h = strlen(height_pattern); + for (loopey = 0; loopey < h; loopey++) { + if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 3; + symbol->row_height[1] = 2; + symbol->row_height[2] = 3; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + +/* Handles DAFT Code symbols */ +int daft_code(struct zint_symbol *symbol, unsigned char source[], int length) { + char height_pattern[100]; + unsigned int loopey, h; + int writer, i, error_number; + strcpy(height_pattern, ""); + + error_number = 0; + if (length > 50) { + strcpy(symbol->errtxt, "492: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + to_upper((unsigned char*) source); + error_number = is_sane(DAFTSET, (unsigned char*) source, length); + + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "493: Invalid characters in data"); + return error_number; + } + + for (i = 0; i < length; i++) { + if (source[i] == 'D') { + strcat(height_pattern, "2"); + } + if (source[i] == 'A') { + strcat(height_pattern, "1"); + } + if (source[i] == 'F') { + strcat(height_pattern, "0"); + } + if (source[i] == 'T') { + strcat(height_pattern, "3"); + } + } + + writer = 0; + h = strlen(height_pattern); + for (loopey = 0; loopey < h; loopey++) { + if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if ((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0')) { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 3; + symbol->row_height[1] = 2; + symbol->row_height[2] = 3; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} + +/* Flattermarken - Not really a barcode symbology! */ +int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) { + int loop, error_number; + char dest[512]; /* 90 * 4 + 1 ~ */ + + error_number = 0; + + if (length > 90) { + strcpy(symbol->errtxt, "494: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "495: Invalid characters in data"); + return error_number; + } + *dest = '\0'; + for (loop = 0; loop < length; loop++) { + lookup(NEON, FlatTable, source[loop], dest); + } + + expand(symbol, dest); + return error_number; +} + +/* Japanese Postal Code (Kasutama Barcode) */ +int japan_post(struct zint_symbol *symbol, unsigned char source[], int length) { + int error_number, h; + char pattern[69]; + int writer, loopey, inter_posn, i, sum, check; + char check_char; + char inter[23]; + +#ifndef _MSC_VER + char local_source[length + 1]; +#else + char* local_source = (char*) _alloca(length + 1); +#endif + + if (length > 20) { + strcpy(symbol->errtxt, "496: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + inter_posn = 0; + error_number = 0; + + strcpy(local_source, (char*) source); + for (i = 0; i < length; i++) { + local_source[i] = source[i]; + } + to_upper((unsigned char*) local_source); + error_number = is_sane(SHKASUTSET, (unsigned char*) local_source, length); + + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "497: Invalid characters in data"); + return error_number; + } + memset(inter, 'd', 20); /* Pad character CC4 */ + inter[20] = '\0'; + + i = 0; + inter_posn = 0; + do { + if (((local_source[i] >= '0') && (local_source[i] <= '9')) || (local_source[i] == '-')) { + inter[inter_posn] = local_source[i]; + inter_posn++; + } else { + if ((local_source[i] >= 'A') && (local_source[i] <= 'J')) { + inter[inter_posn] = 'a'; + inter[inter_posn + 1] = local_source[i] - 'A' + '0'; + inter_posn += 2; + } + if ((local_source[i] >= 'K') && (local_source[i] <= 'T')) { + inter[inter_posn] = 'b'; + inter[inter_posn + 1] = local_source[i] - 'K' + '0'; + inter_posn += 2; + } + if ((local_source[i] >= 'U') && (local_source[i] <= 'Z')) { + inter[inter_posn] = 'c'; + inter[inter_posn + 1] = local_source[i] - 'U' + '0'; + inter_posn += 2; + } + } + i++; + } while ((i < length) && (inter_posn < 20)); + inter[20] = '\0'; + + strcpy(pattern, "13"); /* Start */ + + sum = 0; + for (i = 0; i < 20; i++) { + strcat(pattern, JapanTable[posn(KASUTSET, inter[i])]); + sum += posn(CHKASUTSET, inter[i]); + } + + /* Calculate check digit */ + check = 19 - (sum % 19); + if (check == 19) { + check = 0; + } + if (check <= 9) { + check_char = check + '0'; + } + if (check == 10) { + check_char = '-'; + } + if (check >= 11) { + check_char = (check - 11) + 'a'; + } + strcat(pattern, JapanTable[posn(KASUTSET, check_char)]); + + strcat(pattern, "31"); /* Stop */ + + /* Resolve pattern to 4-state symbols */ + writer = 0; + h = strlen(pattern); + for (loopey = 0; loopey < h; loopey++) { + if ((pattern[loopey] == '2') || (pattern[loopey] == '1')) { + set_module(symbol, 0, writer); + } + set_module(symbol, 1, writer); + if ((pattern[loopey] == '3') || (pattern[loopey] == '1')) { + set_module(symbol, 2, writer); + } + writer += 2; + } + + symbol->row_height[0] = 3; + symbol->row_height[1] = 2; + symbol->row_height[2] = 3; + symbol->rows = 3; + symbol->width = writer - 1; + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/ps.c b/3rdparty/zint-2.6.1/backend/ps.c new file mode 100644 index 0000000..60b05a4 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/ps.c @@ -0,0 +1,974 @@ +/* ps.c - Post Script output */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include "common.h" + +#define SSET "0123456789ABCDEF" + +int ps_plot(struct zint_symbol *symbol) { + int i, block_width, latch, r, this_row; + float textpos, large_bar_height, preset_height, row_height, row_posn; + FILE *feps; + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; + float cyan_ink, magenta_ink, yellow_ink, black_ink; + float cyan_paper, magenta_paper, yellow_paper, black_paper; + int error_number = 0; + int textoffset, xoffset, yoffset, textdone, main_width; + char textpart[10], addon[6]; + int large_bar_count, comp_offset; + float addon_text_posn; + float scaler = symbol->scale; + float default_text_posn; + const char *locale = NULL; +#ifndef _MSC_VER + unsigned char local_text[ustrlen(symbol->text) + 1]; +#else + unsigned char* local_text = (unsigned char*) malloc(ustrlen(symbol->text) + 1); +#endif + + row_height = 0; + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + + if (symbol->show_hrt != 0) { + /* Copy text from symbol */ + ustrcpy(local_text, symbol->text); + } else { + /* No text needed */ + switch (symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CC: + case BARCODE_ISBNX: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + /* For these symbols use dummy text to ensure formatting is done + * properly even if no text is required */ + for (i = 0; i < ustrlen(symbol->text); i++) { + if (symbol->text[i] == '+') { + local_text[i] = '+'; + } else { + local_text[i] = ' '; + } + local_text[ustrlen(symbol->text)] = '\0'; + } + break; + default: + /* For everything else, just remove the text */ + local_text[0] = '\0'; + break; + } + } + + if (symbol->output_options & BARCODE_STDOUT) { + feps = stdout; + } else { + feps = fopen(symbol->outfile, "w"); + } + if (feps == NULL) { + strcpy(symbol->errtxt, "645: Could not open output file"); +#ifdef _MSC_VER + free(local_text); +#endif + return ZINT_ERROR_FILE_ACCESS; + } + + /* sort out colour options */ + to_upper((unsigned char*) symbol->fgcolour); + to_upper((unsigned char*) symbol->bgcolour); + + if (strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "646: Malformed foreground colour target"); + fclose(feps); +#ifdef _MSC_VER + free(local_text); +#endif + return ZINT_ERROR_INVALID_OPTION; + } + if (strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "647: Malformed background colour target"); + fclose(feps); +#ifdef _MSC_VER + free(local_text); +#endif + return ZINT_ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "648: Malformed foreground colour target"); + fclose(feps); +#ifdef _MSC_VER + free(local_text); +#endif + return ZINT_ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "649: Malformed background colour target"); + fclose(feps); +#ifdef _MSC_VER + free(local_text); +#endif + return ZINT_ERROR_INVALID_OPTION; + } + locale = setlocale(LC_ALL, "C"); + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + red_ink = fgred / 256.0; + green_ink = fggrn / 256.0; + blue_ink = fgblu / 256.0; + red_paper = bgred / 256.0; + green_paper = bggrn / 256.0; + blue_paper = bgblu / 256.0; + + /* Convert RGB to CMYK */ + if (red_ink > green_ink) { + if (blue_ink > red_ink) { + black_ink = 1 - blue_ink; + } else { + black_ink = 1 - red_ink; + } + } else { + if (blue_ink > red_ink) { + black_ink = 1 - blue_ink; + } else { + black_ink = 1 - green_ink; + } + } + if (black_ink < 1.0) { + cyan_ink = (1 - red_ink - black_ink) / (1 - black_ink); + magenta_ink = (1 - green_ink - black_ink) / (1 - black_ink); + yellow_ink = (1 - blue_ink - black_ink) / (1 - black_ink); + } else { + cyan_ink = 0.0; + magenta_ink = 0.0; + yellow_ink = 0.0; + } + + if (red_paper > green_paper) { + if (blue_paper > red_paper) { + black_paper = 1 - blue_paper; + } else { + black_paper = 1 - red_paper; + } + } else { + if (blue_paper > red_paper) { + black_paper = 1 - blue_paper; + } else { + black_paper = 1 - green_paper; + } + } + if (black_paper < 1.0) { + cyan_paper = (1 - red_paper - black_paper) / (1 - black_paper); + magenta_paper = (1 - green_paper - black_paper) / (1 - black_paper); + yellow_paper = (1 - blue_paper - black_paper) / (1 - black_paper); + } else { + cyan_paper = 0.0; + magenta_paper = 0.0; + yellow_paper = 0.0; + } + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for (i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if (symbol->row_height[i] == 0) { + large_bar_count++; + } + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if (large_bar_count == 0) { + symbol->height = preset_height; + } + + while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch (ustrlen(local_text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + if (is_extendable(symbol->symbology)) { + for (i = 0; i < ustrlen(local_text); i++) { + if (latch == 1) { + addon[r] = local_text[i]; + r++; + } + if (local_text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + if (ustrlen(local_text) != 0) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + /* Start writing the header */ + fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n"); + fprintf(feps, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE); + if ((ustrlen(local_text) != 0) && (symbol->show_hrt != 0)) { + fprintf(feps, "%%%%Title: %s\n", local_text); + } else { + fprintf(feps, "%%%%Title: Zint Generated Symbol\n"); + } + fprintf(feps, "%%%%Pages: 0\n"); + if (symbol->symbology != BARCODE_MAXICODE) { + fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil((symbol->width + xoffset + xoffset) * scaler), (int) ceil((symbol->height + textoffset + yoffset + yoffset) * scaler)); + } else { + fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil((74.0F + xoffset + xoffset) * scaler), (int) ceil((72.0F + yoffset + yoffset) * scaler)); + } + fprintf(feps, "%%%%EndComments\n"); + + /* Definitions */ + fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n"); + fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n"); + fprintf(feps, "/TD { newpath 0 360 arc fill } bind def\n"); + fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n"); + fprintf(feps, "/TB { 2 copy } bind def\n"); + fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n"); + fprintf(feps, "/TE { pop pop } bind def\n"); + + fprintf(feps, "newpath\n"); + + /* Now the actual representation */ + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_paper, magenta_paper, yellow_paper, black_paper); + } + fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", (symbol->height + textoffset + yoffset + yoffset) * scaler, (symbol->width + xoffset + xoffset) * scaler); + + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + default_text_posn = 0.5 * scaler; + } else { + default_text_posn = (symbol->border_width + 0.5) * scaler; + } + + if (symbol->symbology == BARCODE_MAXICODE) { + /* Maxicode uses hexagons */ + float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; + + + textoffset = 0.0; + if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) { + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + 72.0 + symbol->border_width) * scaler, 0.0, (74.0 + xoffset + xoffset) * scaler); + } + if ((symbol->output_options & BARCODE_BOX) != 0) { + /* side bars */ + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (72.0 + (2 * symbol->border_width)) * scaler, textoffset * scaler, (74.0 + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); + } + + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, (44.73 + xoffset) * scaler, (35.60 + yoffset) * scaler); + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, (40.98 + xoffset) * scaler, (35.60 + yoffset) * scaler); + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TC\n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, (37.19 + xoffset) * scaler, (35.60 + yoffset) * scaler); + for (r = 0; r < symbol->rows; r++) { + for (i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, r, i)) { + /* Dump a hexagon */ + my = ((symbol->rows - r - 1)) * 2.135 + 1.43; + ay = my + 1.0 + yoffset; + by = my + 0.5 + yoffset; + cy = my - 0.5 + yoffset; + dy = my - 1.0 + yoffset; + ey = my - 0.5 + yoffset; + fy = my + 0.5 + yoffset; + + mx = 2.46 * i + 1.23 + (r & 1 ? 1.23 : 0); + + ax = mx + xoffset; + bx = mx + 0.86 + xoffset; + cx = mx + 0.86 + xoffset; + dx = mx + xoffset; + ex = mx - 0.86 + xoffset; + fx = mx - 0.86 + xoffset; + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); + } + } + } + } + + if (symbol->symbology != BARCODE_MAXICODE) { + /* everything else uses rectangles (or squares) */ + /* Works from the bottom of the symbol up */ + + int addon_latch = 0; + + for (r = 0; r < symbol->rows; r++) { + this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ + if (symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for (i = 0; i < r; i++) { + if (symbol->row_height[symbol->rows - i - 1] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[symbol->rows - i - 1]; + } + } + row_posn += (textoffset + yoffset); + + if ((symbol->output_options & BARCODE_DOTTY_MODE) != 0) { + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + + /* Use dots instead of squares */ + for (i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, this_row, i)) { + fprintf(feps, "%.2f %.2f %.2f TD\n", ((i + xoffset) * scaler) + (scaler / 2.0), (row_posn * scaler) + (scaler / 2.0), (symbol->dot_size / 2.0) * scaler); + } + } + } else { + /* Normal mode, with rectangles */ + + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + + fprintf(feps, "%.2f %.2f ", row_height * scaler, row_posn * scaler); + i = 0; + if (module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if ((addon_latch == 0) && (r == 0) && (i > main_width)) { + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f ", (row_height - 5.0) * scaler, (row_posn - 5.0) * scaler); + addon_text_posn = row_posn + row_height - 8.0; + addon_latch = 1; + } + if (latch == 1) { + /* a bar */ + fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset) * scaler, block_width * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + } + } + /* That's done the actual data area, everything else is human-friendly */ + + xoffset += comp_offset; + + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || + (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch (ustrlen(local_text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (32 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (34 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (64 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (66 + xoffset) * scaler, 1 * scaler); + for (i = 0; i < 4; i++) { + textpart[i] = local_text[i]; + } + textpart[4] = '\0'; + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 17; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for (i = 0; i < 4; i++) { + textpart[i] = local_text[i + 4]; + } + textpart[4] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 50; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 86; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 100; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (92 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (94 + xoffset) * scaler, 1 * scaler); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = -7; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 24; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 7]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 71; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 114; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 128; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + break; + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if (latch == 1) { + /* a bar */ + fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if (latch == 1) { + /* a bar */ + fprintf(feps, "TB %.2f %.2f TR\n", (i + xoffset - comp_offset) * scaler, block_width * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = -5; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for (i = 0; i < 5; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[5] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 27; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for (i = 0; i < 5; i++) { + textpart[i] = local_text[i + 6]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 68; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textpart[0] = local_text[11]; + textpart[1] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = 100; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 116; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 130; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f ", 5.0 * scaler, (4.0 + yoffset) * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (0 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (2 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (46 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (48 + xoffset) * scaler, 1 * scaler); + fprintf(feps, "TB %.2f %.2f TR\n", (50 + xoffset) * scaler, 1 * scaler); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + fprintf(feps, "TE\n"); + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = -5; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[6] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = 24; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textpart[0] = local_text[7]; + textpart[1] = '\0'; + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = 55; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", textpart); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", textpart); + fprintf(feps, "setmatrix\n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 70; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + case 5: + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 11.0 * scaler); + textpos = xoffset + 84; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos * scaler, addon_text_posn * scaler); + fprintf(feps, " (%s) stringwidth\n", addon); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", addon); + fprintf(feps, "setmatrix\n"); + break; + } + + } + + xoffset -= comp_offset; + + switch (symbol->symbology) { + case BARCODE_MAXICODE: + /* Do nothing! (It's already been done) */ + break; + default: + if (symbol->output_options & BARCODE_BIND) { + if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + if (symbol->symbology != BARCODE_CODABLOCKF) { + for (r = 1; r < symbol->rows; r++) { + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, xoffset * scaler, symbol->width * scaler); + } + } else { + for (r = 1; r < symbol->rows; r++) { + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", 2.0 * scaler, ((r * row_height) + textoffset + yoffset - 1) * scaler, (xoffset + 11) * scaler, (symbol->width - 25) * scaler); + } + } + } + } + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + if (symbol->symbology != BARCODE_CODABLOCKF) { + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, 0.0, (symbol->width + xoffset + xoffset) * scaler); + } else { + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, textoffset * scaler, xoffset * scaler, symbol->width * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", symbol->border_width * scaler, (textoffset + symbol->height + symbol->border_width) * scaler, xoffset * scaler, symbol->width * scaler); + } + } + if (symbol->output_options & BARCODE_BOX) { + /* side bars */ + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, 0.0, symbol->border_width * scaler); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", (symbol->height + (2 * symbol->border_width)) * scaler, textoffset * scaler, (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, symbol->border_width * scaler); + } + break; + } + + /* Put the human readable text at the bottom */ + if ((textdone == 0) && (ustrlen(local_text))) { + fprintf(feps, "TE\n"); + if ((symbol->output_options & CMYK_COLOUR) == 0) { + fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink); + } else { + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink); + } + fprintf(feps, "matrix currentmatrix\n"); + fprintf(feps, "/Helvetica findfont\n"); + fprintf(feps, "%.2f scalefont setfont\n", 8.0 * scaler); + textpos = symbol->width / 2.0; + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", (textpos + xoffset) * scaler, default_text_posn); + fprintf(feps, " (%s) stringwidth\n", local_text); + fprintf(feps, "pop\n"); + fprintf(feps, "-2 div 0 rmoveto\n"); + fprintf(feps, " (%s) show\n", local_text); + fprintf(feps, "setmatrix\n"); + } + fprintf(feps, "\nshowpage\n"); + + if (symbol->output_options & BARCODE_STDOUT) { + fflush(feps); + } else { + fclose(feps); + } + + if (locale) + setlocale(LC_ALL, locale); + +#ifdef _MSC_VER + free(local_text); +#endif + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/qr.c b/3rdparty/zint-2.6.1/backend/qr.c new file mode 100644 index 0000000..b6aabc4 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/qr.c @@ -0,0 +1,2983 @@ +/* qr.c Handles QR Code */ + +/* + libzint - the open source barcode library + Copyright (C) 2009 -2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include +#include "sjis.h" +#include "qr.h" +#include "reedsol.h" +#include /* abs */ +#include + +extern int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */ + +/* Returns true if input glyph is in the Alphanumeric set */ +static int in_alpha(const int glyph) { + int retval = 0; + char cglyph = (char) glyph; + + if ((cglyph >= '0') && (cglyph <= '9')) { + retval = 1; + } + if ((cglyph >= 'A') && (cglyph <= 'Z')) { + retval = 1; + } + switch (cglyph) { + case ' ': + case '$': + case '%': + case '*': + case '+': + case '-': + case '.': + case '/': + case ':': + retval = 1; + break; + } + + return retval; +} + +static void define_mode(char mode[],const int jisdata[], const size_t length,const int gs1) { + /* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */ + size_t i; + int mlen, j; + + for (i = 0; i < length; i++) { + if (jisdata[i] > 0xff) { + mode[i] = 'K'; + } else { + mode[i] = 'B'; + if (in_alpha(jisdata[i])) { + mode[i] = 'A'; + } + if (gs1 && (jisdata[i] == '[')) { + mode[i] = 'A'; + } + if ((jisdata[i] >= '0') && (jisdata[i] <= '9')) { + mode[i] = 'N'; + } + } + } + + /* If less than 6 numeric digits together then don't use numeric mode */ + for (i = 0; i < length; i++) { + if (mode[i] == 'N') { + if (((i != 0) && (mode[i - 1] != 'N')) || (i == 0)) { + mlen = 0; + while (((mlen + i) < length) && (mode[mlen + i] == 'N')) { + mlen++; + }; + if (mlen < 6) { + for (j = 0; j < mlen; j++) { + mode[i + j] = 'A'; + } + } + } + } + } + + /* If less than 4 alphanumeric characters together then don't use alphanumeric mode */ + for (i = 0; i < length; i++) { + if (mode[i] == 'A') { + if (((i != 0) && (mode[i - 1] != 'A')) || (i == 0)) { + mlen = 0; + while (((mlen + i) < length) && (mode[mlen + i] == 'A')) { + mlen++; + }; + if (mlen < 6) { + for (j = 0; j < mlen; j++) { + mode[i + j] = 'B'; + } + } + } + } + } +} + +/* Choose from three numbers based on version */ +static int tribus(const int version,const int a,const int b,const int c) { + int RetVal; + + RetVal = c; + + if (version < 10) { + RetVal = a; + } + + if ((version >= 10) && (version <= 26)) { + RetVal = b; + } + + return RetVal; +} + +/* Convert input data to a binary stream and add padding */ +static void qr_binary(int datastream[], const int version, const int target_binlen, const char mode[], const int jisdata[], const size_t length, const int gs1, const int eci, const int est_binlen,const int debug) { + int position = 0; + int short_data_block_length, i; + char data_block, padbits; + int current_binlen, current_bytes; + int toggle, percent; + +#ifndef _MSC_VER + char binary[est_binlen + 12]; +#else + char* binary = (char *) _alloca(est_binlen + 12); +#endif + strcpy(binary, ""); + + if (gs1) { + strcat(binary, "0101"); /* FNC1 */ + } + + if (eci != 3) { + strcat(binary, "0111"); /* ECI (Table 4) */ + if (eci <= 127) { + bin_append(eci, 8, binary); /* 000000 to 000127 */ + } else if (eci <= 16383) { + bin_append(0x8000 + eci, 16, binary); /* 000000 to 016383 */ + } else { + bin_append(0xC00000 + eci, 24, binary); /* 000000 to 999999 */ + } + } + + if (debug) { + for (i = 0; i < length; i++) { + printf("%c", mode[i]); + } + printf("\n"); + } + + percent = 0; + + do { + data_block = mode[position]; + short_data_block_length = 0; + do { + short_data_block_length++; + } while (((short_data_block_length + position) < length) + && (mode[position + short_data_block_length] == data_block)); + + switch (data_block) { + case 'K': + /* Kanji mode */ + /* Mode indicator */ + strcat(binary, "1000"); + + /* Character count indicator */ + bin_append(short_data_block_length, tribus(version, 8, 10, 12), binary); + + if (debug) { + printf("Kanji block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + for (i = 0; i < short_data_block_length; i++) { + int jis = jisdata[position + i]; + int prod; + + if (jis >= 0x8140 && jis <= 0x9ffc) + jis -= 0x8140; + + else if (jis >= 0xe040 && jis <= 0xebbf) + jis -= 0xc140; + + prod = ((jis >> 8) * 0xc0) + (jis & 0xff); + + bin_append(prod, 13, binary); + + if (debug) { + printf("0x%4X ", prod); + } + } + + if (debug) { + printf("\n"); + } + + break; + case 'B': + /* Byte mode */ + /* Mode indicator */ + strcat(binary, "0100"); + + /* Character count indicator */ + bin_append(short_data_block_length, tribus(version, 8, 16, 16), binary); + + if (debug) { + printf("Byte block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + for (i = 0; i < short_data_block_length; i++) { + int byte = jisdata[position + i]; + + if (gs1 && (byte == '[')) { + byte = 0x1d; /* FNC1 */ + } + + bin_append(byte, 8, binary); + + if (debug) { + printf("0x%2X(%d) ", byte, byte); + } + } + + if (debug) { + printf("\n"); + } + + break; + case 'A': + /* Alphanumeric mode */ + /* Mode indicator */ + strcat(binary, "0010"); + + /* Character count indicator */ + bin_append(short_data_block_length, tribus(version, 9, 11, 13), binary); + + if (debug) { + printf("Alpha block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + i = 0; + while (i < short_data_block_length) { + int count; + int first = 0, second = 0, prod; + + if (percent == 0) { + if (gs1 && (jisdata[position + i] == '%')) { + first = posn(RHODIUM, '%'); + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + i++; + } else { + if (gs1 && (jisdata[position + i] == '[')) { + first = posn(RHODIUM, '%'); /* FNC1 */ + } else { + first = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 1; + i++; + prod = first; + + if (i < short_data_block_length && mode[position + i] == 'A') { + if (gs1 && (jisdata[position + i] == '%')) { + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + percent = 1; + } else { + if (gs1 && (jisdata[position + i] == '[')) { + second = posn(RHODIUM, '%'); /* FNC1 */ + } else { + second = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 2; + i++; + prod = (first * 45) + second; + } + } + } + } else { + first = posn(RHODIUM, '%'); + count = 1; + i++; + prod = first; + percent = 0; + + if (i < short_data_block_length && mode[position + i] == 'A') { + if (gs1 && (jisdata[position + i] == '%')) { + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + percent = 1; + } else { + if (gs1 && (jisdata[position + i] == '[')) { + second = posn(RHODIUM, '%'); /* FNC1 */ + } else { + second = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 2; + i++; + prod = (first * 45) + second; + } + } + } + + bin_append(prod, 1 + (5 * count), binary); + + if (debug) { + printf("0x%4X ", prod); + } + }; + + if (debug) { + printf("\n"); + } + + break; + case 'N': + /* Numeric mode */ + /* Mode indicator */ + strcat(binary, "0001"); + + /* Character count indicator */ + bin_append(short_data_block_length, tribus(version, 10, 12, 14), binary); + + if (debug) { + printf("Number block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + i = 0; + while (i < short_data_block_length) { + int count; + int first = 0, second = 0, third = 0, prod; + + first = posn(NEON, (char) jisdata[position + i]); + count = 1; + prod = first; + + if (i + 1 < short_data_block_length && mode[position + i + 1] == 'N') { + second = posn(NEON, (char) jisdata[position + i + 1]); + count = 2; + prod = (prod * 10) + second; + + if (i + 2 < short_data_block_length && mode[position + i + 2] == 'N') { + third = posn(NEON, (char) jisdata[position + i + 2]); + count = 3; + prod = (prod * 10) + third; + } + } + + bin_append(prod, 1 + (3 * count), binary); + + if (debug) { + printf("0x%4X (%d)", prod, prod); + } + + i += count; + }; + + if (debug) { + printf("\n"); + } + + break; + } + + position += short_data_block_length; + } while (position < length); + + /* Terminator */ + strcat(binary, "0000"); + + current_binlen = (int)strlen(binary); + padbits = 8 - (current_binlen % 8); + if (padbits == 8) { + padbits = 0; + } + current_bytes = (current_binlen + padbits) / 8; + + /* Padding bits */ + for (i = 0; i < padbits; i++) { + strcat(binary, "0"); + } + + /* Put data into 8-bit codewords */ + for (i = 0; i < current_bytes; i++) { + int p; + datastream[i] = 0x00; + for (p = 0; p < 8; p++) { + if (binary[i * 8 + p] == '1') { + datastream[i] += (0x80 >> p); + } + } + } + + /* Add pad codewords */ + toggle = 0; + for (i = current_bytes; i < target_binlen; i++) { + if (toggle == 0) { + datastream[i] = 0xec; + toggle = 1; + } else { + datastream[i] = 0x11; + toggle = 0; + } + } + + if (debug) { + printf("Resulting codewords:\n\t"); + for (i = 0; i < target_binlen; i++) { + printf("0x%2X ", datastream[i]); + } + printf("\n"); + } +} + +/* Split data into blocks, add error correction and then interleave the blocks and error correction data */ +static void add_ecc(int fullstream[],const int datastream[],const int version,const int data_cw,const int blocks) { + int ecc_cw = qr_total_codewords[version - 1] - data_cw; + int short_data_block_length = data_cw / blocks; + int qty_long_blocks = data_cw % blocks; + int qty_short_blocks = blocks - qty_long_blocks; + int ecc_block_length = ecc_cw / blocks; + int i, j, length_this_block, posn, debug = 0; + + +#ifndef _MSC_VER + unsigned char data_block[short_data_block_length + 2]; + unsigned char ecc_block[ecc_block_length + 2]; + int interleaved_data[data_cw + 2]; + int interleaved_ecc[ecc_cw + 2]; +#else + unsigned char* data_block = (unsigned char *) _alloca(short_data_block_length + 2); + unsigned char* ecc_block = (unsigned char *) _alloca(ecc_block_length + 2); + int* interleaved_data = (int *) _alloca((data_cw + 2) * sizeof (int)); + int* interleaved_ecc = (int *) _alloca((ecc_cw + 2) * sizeof (int)); +#endif + + posn = 0; + + for (i = 0; i < blocks; i++) { + if (i < qty_short_blocks) { + length_this_block = short_data_block_length; + } else { + length_this_block = short_data_block_length + 1; + } + + for (j = 0; j < ecc_block_length; j++) { + ecc_block[j] = 0; + } + + for (j = 0; j < length_this_block; j++) { + data_block[j] = (unsigned char) datastream[posn + j]; + } + + rs_init_gf(0x11d); + rs_init_code(ecc_block_length, 0); + rs_encode(length_this_block, data_block, ecc_block); + rs_free(); + + if (debug) { + printf("Block %d: ", i + 1); + for (j = 0; j < length_this_block; j++) { + printf("%2X ", data_block[j]); + } + if (i < qty_short_blocks) { + printf(" "); + } + printf(" // "); + for (j = 0; j < ecc_block_length; j++) { + printf("%2X ", ecc_block[ecc_block_length - j - 1]); + } + printf("\n"); + } + + for (j = 0; j < short_data_block_length; j++) { + interleaved_data[(j * blocks) + i] = (int) data_block[j]; + } + + if (i >= qty_short_blocks) { + interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = (int) data_block[short_data_block_length]; + } + + for (j = 0; j < ecc_block_length; j++) { + interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1]; + } + + posn += length_this_block; + } + + for (j = 0; j < data_cw; j++) { + fullstream[j] = interleaved_data[j]; + } + for (j = 0; j < ecc_cw; j++) { + fullstream[j + data_cw] = interleaved_ecc[j]; + } + + if (debug) { + printf("\nData Stream: \n"); + for (j = 0; j < (data_cw + ecc_cw); j++) { + printf("%2X ", fullstream[j]); + } + printf("\n"); + } +} + +static void place_finder(unsigned char grid[],const int size,const int x,const int y) { + int xp, yp; + char finder[] = {0x7F, 0x41, 0x5D, 0x5D, 0x5D, 0x41, 0x7F}; + + for (xp = 0; xp < 7; xp++) { + for (yp = 0; yp < 7; yp++) { + if (finder[yp] & 0x40 >> xp) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +static void place_align(unsigned char grid[],const int size,int x,int y) { + int xp, yp; + char alignment[] = {0x1F, 0x11, 0x15, 0x11, 0x1F}; + + x -= 2; + y -= 2; /* Input values represent centre of pattern */ + + for (xp = 0; xp < 5; xp++) { + for (yp = 0; yp < 5; yp++) { + if (alignment[yp] & 0x10 >> xp) { + grid[((yp + y) * size) + (xp + x)] = 0x11; + } else { + grid[((yp + y) * size) + (xp + x)] = 0x10; + } + } + } +} + +static void setup_grid(unsigned char* grid,const int size,const int version) { + int i, toggle = 1; + int loopsize, x, y, xcoord, ycoord; + + /* Add timing patterns */ + for (i = 0; i < size; i++) { + if (toggle == 1) { + grid[(6 * size) + i] = 0x21; + grid[(i * size) + 6] = 0x21; + toggle = 0; + } else { + grid[(6 * size) + i] = 0x20; + grid[(i * size) + 6] = 0x20; + toggle = 1; + } + } + + /* Add finder patterns */ + place_finder(grid, size, 0, 0); + place_finder(grid, size, 0, size - 7); + place_finder(grid, size, size - 7, 0); + + /* Add separators */ + for (i = 0; i < 7; i++) { + grid[(7 * size) + i] = 0x10; + grid[(i * size) + 7] = 0x10; + grid[(7 * size) + (size - 1 - i)] = 0x10; + grid[(i * size) + (size - 8)] = 0x10; + grid[((size - 8) * size) + i] = 0x10; + grid[((size - 1 - i) * size) + 7] = 0x10; + } + grid[(7 * size) + 7] = 0x10; + grid[(7 * size) + (size - 8)] = 0x10; + grid[((size - 8) * size) + 7] = 0x10; + + /* Add alignment patterns */ + if (version != 1) { + /* Version 1 does not have alignment patterns */ + + loopsize = qr_align_loopsize[version - 1]; + for (x = 0; x < loopsize; x++) { + for (y = 0; y < loopsize; y++) { + xcoord = qr_table_e1[((version - 2) * 7) + x]; + ycoord = qr_table_e1[((version - 2) * 7) + y]; + + if (!(grid[(ycoord * size) + xcoord] & 0x10)) { + place_align(grid, size, xcoord, ycoord); + } + } + } + } + + /* Reserve space for format information */ + for (i = 0; i < 8; i++) { + grid[(8 * size) + i] += 0x20; + grid[(i * size) + 8] += 0x20; + grid[(8 * size) + (size - 1 - i)] = 0x20; + grid[((size - 1 - i) * size) + 8] = 0x20; + } + grid[(8 * size) + 8] += 20; + grid[((size - 1 - 7) * size) + 8] = 0x21; /* Dark Module from Figure 25 */ + + /* Reserve space for version information */ + if (version >= 7) { + for (i = 0; i < 6; i++) { + grid[((size - 9) * size) + i] = 0x20; + grid[((size - 10) * size) + i] = 0x20; + grid[((size - 11) * size) + i] = 0x20; + grid[(i * size) + (size - 9)] = 0x20; + grid[(i * size) + (size - 10)] = 0x20; + grid[(i * size) + (size - 11)] = 0x20; + } + } +} + +static int cwbit(const int* datastream,const int i) { + int resultant = 0; + + if (datastream[(i / 8)] & (0x80 >> (i % 8))) { + resultant = 1; + } + + return resultant; +} + +static void populate_grid(unsigned char* grid,const int size,const int* datastream,const int cw) { + int direction = 1; /* up */ + int row = 0; /* right hand side */ + + int i, n, x, y; + + n = cw * 8; + y = size - 1; + i = 0; + do { + x = (size - 2) - (row * 2); + if (x < 6) + x--; /* skip over vertical timing pattern */ + + if (!(grid[(y * size) + (x + 1)] & 0xf0)) { + if (cwbit(datastream, i)) { + grid[(y * size) + (x + 1)] = 0x01; + } else { + grid[(y * size) + (x + 1)] = 0x00; + } + i++; + } + + if (i < n) { + if (!(grid[(y * size) + x] & 0xf0)) { + if (cwbit(datastream, i)) { + grid[(y * size) + x] = 0x01; + } else { + grid[(y * size) + x] = 0x00; + } + i++; + } + } + + if (direction) { + y--; + } else { + y++; + } + if (y == -1) { + /* reached the top */ + row++; + y = 0; + direction = 0; + } + if (y == size) { + /* reached the bottom */ + row++; + y = size - 1; + direction = 1; + } + } while (i < n); +} + +#ifdef ZINTLOG + +int append_log(char log) { + FILE *file; + + file = fopen("zintlog.txt", "a+"); + fprintf(file, "%c", log); + fclose(file); + return 0; +} + +int write_log(char log[]) { + FILE *file; + + file = fopen("zintlog.txt", "a+"); + fprintf(file, log); /*writes*/ + fprintf(file, "\r\n"); /*writes*/ + fclose(file); + return 0; +} +#endif + +static int evaluate(unsigned char *eval,const int size,const int pattern) { + int x, y, block, weight; + int result = 0; + char state; + int p; + int dark_mods; + int percentage, k; + int a, b, afterCount, beforeCount; +#ifdef ZINTLOG + int result_b = 0; + char str[15]; +#endif + +#ifndef _MSC_VER + char local[size * size]; +#else + char* local = (char *) _alloca((size * size) * sizeof (char)); +#endif + + +#ifdef ZINTLOG + write_log(""); + sprintf(str, "%d", pattern); + write_log(str); +#endif + + /* all eight bitmask variants have been encoded in the 8 bits of the bytes + * that make up the grid array. select them for evaluation according to the + * desired pattern.*/ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if ((eval[(y * size) + x] & (0x01 << pattern)) != 0) { + local[(y * size) + x] = '1'; + } else { + local[(y * size) + x] = '0'; + } + } + } + +#ifdef ZINTLOG + //bitmask output + for (y = 0; y < size; y++) { + strcpy(str, ""); + for (x = 0; x < size; x++) { + state = local[(y * size) + x]; + append_log(state); + } + write_log(""); + } + write_log(""); +#endif + + /* Test 1: Adjacent modules in row/column in same colour */ + /* Vertical */ + for (x = 0; x < size; x++) { + state = local[x]; + block = 0; + for (y = 0; y < size; y++) { + if (local[(y * size) + x] == state) { + block++; + } else { + if (block > 5) { + result += (3 + (block - 5)); + } + block = 0; + state = local[(y * size) + x]; + } + } + if (block > 5) { + result += (3 + (block - 5)); + } + } + + /* Horizontal */ + for (y = 0; y < size; y++) { + state = local[y * size]; + block = 0; + for (x = 0; x < size; x++) { + if (local[(y * size) + x] == state) { + block++; + } else { + if (block > 5) { + result += (3 + (block - 5)); + } + block = 0; + state = local[(y * size) + x]; + } + } + if (block > 5) { + result += (3 + (block - 5)); + } + } + +#ifdef ZINTLOG + /* output Test 1 */ + sprintf(str, "%d", result); + result_b = result; + write_log(str); +#endif + + /* Test 2: Block of modules in same color */ + for (x = 0; x < size - 1; x++) { + for (y = 0; y < size - 1; y++) { + if (((local[(y * size) + x] == local[((y + 1) * size) + x]) && + (local[(y * size) + x] == local[(y * size) + (x + 1)])) && + (local[(y * size) + x] == local[((y + 1) * size) + (x + 1)])) { + result += 3; + } + } + } + +#ifdef ZINTLOG + /* output Test 2 */ + sprintf(str, "%d", result - result_b); + result_b = result; + write_log(str); +#endif + + /* Test 3: 1:1:3:1:1 ratio pattern in row/column */ + /* Vertical */ + for (x = 0; x < size; x++) { + for (y = 0; y < (size - 7); y++) { + p = 0; + for (weight = 0; weight < 7; weight++) { + if (local[((y + weight) * size) + x] == '1') { + p += (0x40 >> weight); + } + } + if (p == 0x5d) { + /* Pattern found, check before and after */ + beforeCount = 0; + for (b = (y - 4); b < y; b++) { + if (b < 0) { + beforeCount++; + } else { + if (local[(b * size) + x] == '0') { + beforeCount++; + } else { + beforeCount = 0; + } + } + } + + afterCount = 0; + for (a = (y + 7); a <= (y + 10); a++) { + if (a >= size) { + afterCount++; + } else { + if (local[(a * size) + x] == '0') { + afterCount++; + } else { + afterCount = 0; + } + } + } + + if ((beforeCount == 4) || (afterCount == 4)) { + /* Pattern is preceeded or followed by light area + 4 modules wide */ + result += 40; + } + } + } + } + + /* Horizontal */ + for (y = 0; y < size; y++) { + for (x = 0; x < (size - 7); x++) { + p = 0; + for (weight = 0; weight < 7; weight++) { + if (local[(y * size) + x + weight] == '1') { + p += (0x40 >> weight); + } + } + if (p == 0x5d) { + /* Pattern found, check before and after */ + beforeCount = 0; + for (b = (x - 4); b < x; b++) { + if (b < 0) { + beforeCount++; + } else { + if (local[(y * size) + b] == '0') { + beforeCount++; + } else { + beforeCount = 0; + } + } + } + + afterCount = 0; + for (a = (x + 7); a <= (x + 10); a++) { + if (a >= size) { + afterCount++; + } else { + if (local[(y * size) + a] == '0') { + afterCount++; + } else { + afterCount = 0; + } + } + } + + if ((beforeCount == 4) || (afterCount == 4)) { + /* Pattern is preceeded or followed by light area + 4 modules wide */ + result += 40; + } + } + } + } + +#ifdef ZINTLOG + /* output Test 3 */ + sprintf(str, "%d", result - result_b); + result_b = result; + write_log(str); +#endif + + /* Test 4: Proportion of dark modules in entire symbol */ + dark_mods = 0; + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (local[(y * size) + x] == '1') { + dark_mods++; + } + } + } + percentage = 100 * (dark_mods / (size * size)); + if (percentage <= 50) { + k = ((100 - percentage) - 50) / 5; + } else { + k = (percentage - 50) / 5; + } + + result += 10 * k; + +#ifdef ZINTLOG + /* output Test 4+summary */ + sprintf(str, "%d", result - result_b); + write_log(str); + write_log("=========="); + sprintf(str, "%d", result); + write_log(str); +#endif + + return result; +} + +static void add_format_info_eval(unsigned char *eval,const int size,const int ecc_level,const int pattern) { + /* Add format information to grid */ + + int format = pattern; + unsigned int seq; + int i; + + switch (ecc_level) { + case LEVEL_L: format += 0x08; + break; + case LEVEL_Q: format += 0x18; + break; + case LEVEL_H: format += 0x10; + break; + } + + seq = qr_annex_c[format]; + + for (i = 0; i < 6; i++) { + eval[(i * size) + 8] = (seq >> i) & 0x01 ? (0x01 >> pattern) : 0x00; + } + + for (i = 0; i < 8; i++) { + eval[(8 * size) + (size - i - 1)] = (seq >> i) & 0x01 ? (0x01 >> pattern) : 0x00; + } + + for (i = 0; i < 6; i++) { + eval[(8 * size) + (5 - i)] = (seq >> (i + 9)) & 0x01 ? (0x01 >> pattern) : 0x00; + } + + for (i = 0; i < 7; i++) { + eval[(((size - 7) + i) * size) + 8] = (seq >> (i + 8)) & 0x01 ? (0x01 >> pattern) : 0x00; + } + + eval[(7 * size) + 8] = (seq >> 6) & 0x01 ? (0x01 >> pattern) : 0x00; + eval[(8 * size) + 8] = (seq >> 7) & 0x01 ? (0x01 >> pattern) : 0x00; + eval[(8 * size) + 7] = (seq >> 8) & 0x01 ? (0x01 >> pattern) : 0x00; +} + +static int apply_bitmask(unsigned char *grid,const int size,const int ecc_level) { + int x, y; + unsigned char p; + int pattern, penalty[8]; + int best_val, best_pattern; + +#ifndef _MSC_VER + unsigned char mask[size * size]; + unsigned char eval[size * size]; +#else + unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); + unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + /* Perform data masking */ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + mask[(y * size) + x] = 0x00; + + // all eight bitmask variants are encoded in the 8 bits of the bytes that make up the mask array. + if (!(grid[(y * size) + x] & 0xf0)) { // exclude areas not to be masked. + if (((y + x) & 1) == 0) { + mask[(y * size) + x] += 0x01; + } + if ((y & 1) == 0) { + mask[(y * size) + x] += 0x02; + } + if ((x % 3) == 0) { + mask[(y * size) + x] += 0x04; + } + if (((y + x) % 3) == 0) { + mask[(y * size) + x] += 0x08; + } + if ((((y / 2) + (x / 3)) & 1) == 0) { + mask[(y * size) + x] += 0x10; + } + if ((((y * x) & 1) + ((y * x) % 3)) == 0) { + mask[(y * size) + x] += 0x20; + } + if (((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { + mask[(y * size) + x] += 0x40; + } + if (((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { + mask[(y * size) + x] += 0x80; + } + } + } + } + + // apply data masks to grid, result in eval + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (grid[(y * size) + x] & 0x01) { + p = 0xff; + } else { + p = 0x00; + } + + eval[(y * size) + x] = mask[(y * size) + x] ^ p; + } + } + + + /* Evaluate result */ + for (pattern = 0; pattern < 8; pattern++) { + + add_format_info_eval(eval, size, ecc_level, pattern); + + penalty[pattern] = evaluate(eval, size, pattern); + } + + best_pattern = 0; + best_val = penalty[0]; + for (pattern = 1; pattern < 8; pattern++) { + if (penalty[pattern] < best_val) { + best_pattern = pattern; + best_val = penalty[pattern]; + } + } + +#ifdef ZINTLOG + char str[15]; + sprintf(str, "%d", best_val); + write_log("choosed pattern:"); + write_log(str); +#endif + + /* Apply mask */ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (mask[(y * size) + x] & (0x01 << best_pattern)) { + if (grid[(y * size) + x] & 0x01) { + grid[(y * size) + x] = 0x00; + } else { + grid[(y * size) + x] = 0x01; + } + } + } + } + + return best_pattern; +} + +/* Add format information to grid */ +static void add_format_info(unsigned char *grid,const int size,const int ecc_level,const int pattern) { + int format = pattern; + unsigned int seq; + int i; + + switch (ecc_level) { + case LEVEL_L: format += 0x08; + break; + case LEVEL_Q: format += 0x18; + break; + case LEVEL_H: format += 0x10; + break; + } + + seq = qr_annex_c[format]; + + for (i = 0; i < 6; i++) { + grid[(i * size) + 8] += (seq >> i) & 0x01; + } + + for (i = 0; i < 8; i++) { + grid[(8 * size) + (size - i - 1)] += (seq >> i) & 0x01; + } + + for (i = 0; i < 6; i++) { + grid[(8 * size) + (5 - i)] += (seq >> (i + 9)) & 0x01; + } + + for (i = 0; i < 7; i++) { + grid[(((size - 7) + i) * size) + 8] += (seq >> (i + 8)) & 0x01; + } + + grid[(7 * size) + 8] += (seq >> 6) & 0x01; + grid[(8 * size) + 8] += (seq >> 7) & 0x01; + grid[(8 * size) + 7] += (seq >> 8) & 0x01; +} + +/* Add version information */ +static void add_version_info(unsigned char *grid,const int size,const int version) { + int i; + + long int version_data = qr_annex_d[version - 7]; + for (i = 0; i < 6; i++) { + grid[((size - 11) * size) + i] += (version_data >> (i * 3)) & 0x41; + grid[((size - 10) * size) + i] += (version_data >> ((i * 3) + 1)) & 0x41; + grid[((size - 9) * size) + i] += (version_data >> ((i * 3) + 2)) & 0x41; + grid[(i * size) + (size - 11)] += (version_data >> (i * 3)) & 0x41; + grid[(i * size) + (size - 10)] += (version_data >> ((i * 3) + 1)) & 0x41; + grid[(i * size) + (size - 9)] += (version_data >> ((i * 3) + 2)) & 0x41; + } +} + +/* Implements a custom optimisation algorithm, more efficient than that + given in Annex J. */ +static void applyOptimisation(const int version,char inputMode[], const size_t inputLength) { + + + int blockCount = 0, block; + int i, j; + char currentMode = ' '; // Null + int *blockLength; + char *blockMode; + + for (i = 0; i < inputLength; i++) { + if (inputMode[i] != currentMode) { + currentMode = inputMode[i]; + blockCount++; + } + } + + blockLength = (int*) malloc(sizeof (int)*blockCount); + assert(blockLength); + if (!blockLength) return; + blockMode = (char*) malloc(sizeof (char)*blockCount); + assert(blockMode); + if (!blockMode) { + free(blockLength); + return; + } + + j = -1; + currentMode = ' '; // Null + for (i = 0; i < inputLength; i++) { + if (inputMode[i] != currentMode) { + j++; + blockLength[j] = 1; + blockMode[j] = inputMode[i]; + currentMode = inputMode[i]; + } else { + blockLength[j]++; + } + } + + if (blockCount > 1) { + // Search forward + for (i = 0; i <= (blockCount - 2); i++) { + if (blockMode[i] == 'B') { + switch (blockMode[i + 1]) { + case 'K': + if (blockLength[i + 1] < tribus(version, 4, 5, 6)) { + blockMode[i + 1] = 'B'; + } + break; + case 'A': + if (blockLength[i + 1] < tribus(version, 7, 8, 9)) { + blockMode[i + 1] = 'B'; + } + break; + case 'N': + if (blockLength[i + 1] < tribus(version, 3, 4, 5)) { + blockMode[i + 1] = 'B'; + } + break; + } + } + + if ((blockMode[i] == 'A') + && (blockMode[i + 1] == 'N')) { + if (blockLength[i + 1] < tribus(version, 6, 8, 10)) { + blockMode[i + 1] = 'A'; + } + } + } + + // Search backward + for (i = blockCount - 1; i > 0; i--) { + if (blockMode[i] == 'B') { + switch (blockMode[i - 1]) { + case 'K': + if (blockLength[i - 1] < tribus(version, 4, 5, 6)) { + blockMode[i - 1] = 'B'; + } + break; + case 'A': + if (blockLength[i - 1] < tribus(version, 7, 8, 9)) { + blockMode[i - 1] = 'B'; + } + break; + case 'N': + if (blockLength[i - 1] < tribus(version, 3, 4, 5)) { + blockMode[i - 1] = 'B'; + } + break; + } + } + + if ((blockMode[i] == 'A') + && (blockMode[i - 1] == 'N')) { + if (blockLength[i - 1] < tribus(version, 6, 8, 10)) { + blockMode[i - 1] = 'A'; + } + } + } + } + + j = 0; + for (block = 0; block < blockCount; block++) { + currentMode = blockMode[block]; + for (i = 0; i < blockLength[block]; i++) { + inputMode[j] = currentMode; + j++; + } + } + + free(blockLength); + free(blockMode); +} + +static size_t blockLength(const size_t start,const char inputMode[],const size_t inputLength) { + /* Find the length of the block starting from 'start' */ + size_t i; + int count; + char mode = inputMode[start]; + + count = 0; + i = start; + + do { + count++; + } while (((i + count) < inputLength) && (inputMode[i + count] == mode)); + + return count; +} + +static int getBinaryLength(const int version,char inputMode[],const int inputData[],const size_t inputLength,const int gs1,const int eci) { + /* Calculate the actual bitlength of the proposed binary string */ + size_t i; + char currentMode; + int j; + int count = 0; + + applyOptimisation(version, inputMode, inputLength); + + currentMode = ' '; // Null + + if (gs1 == 1) { + count += 4; + } + + if (eci != 3) { + count += 12; + } + + for (i = 0; i < inputLength; i++) { + if (inputMode[i] != currentMode) { + count += 4; + switch (inputMode[i]) { + case 'K': + count += tribus(version, 8, 10, 12); + count += (blockLength(i, inputMode, inputLength) * 13); + break; + case 'B': + count += tribus(version, 8, 16, 16); + for (j = i; j < (i + blockLength(i, inputMode, inputLength)); j++) { + if (inputData[j] > 0xff) { + count += 16; + } else { + count += 8; + } + } + break; + case 'A': + count += tribus(version, 9, 11, 13); + switch (blockLength(i, inputMode, inputLength) % 2) { + case 0: + count += (blockLength(i, inputMode, inputLength) / 2) * 11; + break; + case 1: + count += ((blockLength(i, inputMode, inputLength) - 1) / 2) * 11; + count += 6; + break; + } + break; + case 'N': + count += tribus(version, 10, 12, 14); + switch (blockLength(i, inputMode, inputLength) % 3) { + case 0: + count += (blockLength(i, inputMode, inputLength) / 3) * 10; + break; + case 1: + count += ((blockLength(i, inputMode, inputLength) - 1) / 3) * 10; + count += 4; + break; + case 2: + count += ((blockLength(i, inputMode, inputLength) - 2) / 3) * 10; + count += 7; + break; + } + break; + } + currentMode = inputMode[i]; + } + } + + return count; +} + +int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length) { + int i, j, est_binlen; + int error_number,glyph; + int ecc_level, autosize, version, max_cw, target_binlen, blocks, size; + int bitmask, gs1; + int canShrink; + +#ifndef _MSC_VER + int utfdata[length + 1]; + int jisdata[length + 1]; + char mode[length + 1]; +#else + int* datastream; + int* fullstream; + unsigned char* grid; + int* utfdata = (int *) _alloca((length + 1) * sizeof (int)); + int* jisdata = (int *) _alloca((length + 1) * sizeof (int)); + char* mode = (char *) _alloca(length + 1); +#endif + + gs1 = (symbol->input_mode == GS1_MODE); + + if ((symbol->input_mode == DATA_MODE) || (symbol->eci != 3)) { + for (i = 0; i < length; i++) { + jisdata[i] = (int) source[i]; + } + } else { + /* Convert Unicode input to Shift-JIS */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if (error_number != 0) { + return error_number; + } + + for (i = 0; i < length; i++) { + if (utfdata[i] <= 0xff) { + jisdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if (sjis_lookup[j * 2] == utfdata[i]) { + glyph = sjis_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 6843) && (glyph == 0)); + if (glyph == 0) { + strcpy(symbol->errtxt, "560: Invalid character in input data"); + return ZINT_ERROR_INVALID_DATA; + } + jisdata[i] = glyph; + } + } + } + + define_mode(mode, jisdata, length, gs1); + est_binlen = getBinaryLength(40, mode, jisdata, length, gs1, symbol->eci); + + ecc_level = LEVEL_L; + max_cw = 2956; + if ((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) { + switch (symbol->option_1) { + case 1: ecc_level = LEVEL_L; + max_cw = 2956; + break; + case 2: ecc_level = LEVEL_M; + max_cw = 2334; + break; + case 3: ecc_level = LEVEL_Q; + max_cw = 1666; + break; + case 4: ecc_level = LEVEL_H; + max_cw = 1276; + break; + } + } + + if (est_binlen > (8 * max_cw)) { + strcpy(symbol->errtxt, "561: Input too long for selected error correction level"); + return ZINT_ERROR_TOO_LONG; + } + + autosize = 40; + for (i = 39; i >= 0; i--) { + switch (ecc_level) { + case LEVEL_L: + if ((8 * qr_data_codewords_L[i]) >= est_binlen) { + autosize = i + 1; + } + break; + case LEVEL_M: + if ((8 * qr_data_codewords_M[i]) >= est_binlen) { + autosize = i + 1; + } + break; + case LEVEL_Q: + if ((8 * qr_data_codewords_Q[i]) >= est_binlen) { + autosize = i + 1; + } + break; + case LEVEL_H: + if ((8 * qr_data_codewords_H[i]) >= est_binlen) { + autosize = i + 1; + } + break; + } + } + + // Now see if the optimised binary will fit in a smaller symbol. + canShrink = 1; + + do { + if (autosize == 1) { + canShrink = 0; + } else { + est_binlen = getBinaryLength(autosize - 1, mode, jisdata, length, gs1, symbol->eci); + + switch (ecc_level) { + case LEVEL_L: + if ((8 * qr_data_codewords_L[autosize - 2]) < est_binlen) { + canShrink = 0; + } + break; + case LEVEL_M: + if ((8 * qr_data_codewords_M[autosize - 2]) < est_binlen) { + canShrink = 0; + } + break; + case LEVEL_Q: + if ((8 * qr_data_codewords_Q[autosize - 2]) < est_binlen) { + canShrink = 0; + } + break; + case LEVEL_H: + if ((8 * qr_data_codewords_H[autosize - 2]) < est_binlen) { + canShrink = 0; + } + break; + } + + if (canShrink == 1) { + // Optimisation worked - data will fit in a smaller symbol + autosize--; + } else { + // Data did not fit in the smaller symbol, revert to original size + est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1, symbol->eci); + } + } + } while (canShrink == 1); + + version = autosize; + + if ((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) { + /* If the user has selected a larger symbol than the smallest available, + then use the size the user has selected, and re-optimise for this + symbol size. + */ + if (symbol->option_2 > version) { + version = symbol->option_2; + est_binlen = getBinaryLength(symbol->option_2, mode, jisdata, length, gs1, symbol->eci); + } + + if (symbol->option_2 < version) { + strcpy(symbol->errtxt, "569: Input too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + } + + /* Ensure maxium error correction capacity */ + if (est_binlen <= qr_data_codewords_M[version - 1]) { + ecc_level = LEVEL_M; + } + if (est_binlen <= qr_data_codewords_Q[version - 1]) { + ecc_level = LEVEL_Q; + } + if (est_binlen <= qr_data_codewords_H[version - 1]) { + ecc_level = LEVEL_H; + } + + target_binlen = qr_data_codewords_L[version - 1]; + blocks = qr_blocks_L[version - 1]; + switch (ecc_level) { + case LEVEL_M: target_binlen = qr_data_codewords_M[version - 1]; + blocks = qr_blocks_M[version - 1]; + break; + case LEVEL_Q: target_binlen = qr_data_codewords_Q[version - 1]; + blocks = qr_blocks_Q[version - 1]; + break; + case LEVEL_H: target_binlen = qr_data_codewords_H[version - 1]; + blocks = qr_blocks_H[version - 1]; + break; + } + +#ifndef _MSC_VER + int datastream[target_binlen + 1]; + int fullstream[qr_total_codewords[version - 1] + 1]; +#else + datastream = (int *) _alloca((target_binlen + 1) * sizeof (int)); + fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int)); +#endif + + qr_binary(datastream, version, target_binlen, mode, jisdata, length, gs1, symbol->eci, est_binlen, symbol->debug); + add_ecc(fullstream, datastream, version, target_binlen, blocks); + + size = qr_sizes[version - 1]; +#ifndef _MSC_VER + unsigned char grid[size * size]; +#else + grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + grid[(i * size) + j] = 0; + } + } + + setup_grid(grid, size, version); + populate_grid(grid, size, fullstream, qr_total_codewords[version - 1]); + + if (version >= 7) { + add_version_info(grid, size, version); + } + + bitmask = apply_bitmask(grid, size, ecc_level); + + add_format_info(grid, size, ecc_level, bitmask); + + + + symbol->width = size; + symbol->rows = size; + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + if (grid[(i * size) + j] & 0x01) { + set_module(symbol, i, j); + } + } + symbol->row_height[i] = 1; + } + + return 0; +} + +/* NOTE: From this point forward concerns Micro QR Code only */ + +static int micro_qr_intermediate(char binary[], const int jisdata[], const char mode[], const size_t length, int *kanji_used, int *alphanum_used, int *byte_used,const int debug) { + /* Convert input data to an "intermediate stage" where data is binary encoded but + control information is not */ + int position = 0; + int short_data_block_length, i; + char data_block; + char buffer[2]; + + strcpy(binary, ""); + + if (debug) { + for (i = 0; i < length; i++) { + printf("%c", mode[i]); + } + printf("\n"); + } + + do { + if (strlen(binary) > 128) { + return ZINT_ERROR_TOO_LONG; + } + + data_block = mode[position]; + short_data_block_length = 0; + do { + short_data_block_length++; + } while (((short_data_block_length + position) < length) && (mode[position + short_data_block_length] == data_block)); + + switch (data_block) { + case 'K': + /* Kanji mode */ + /* Mode indicator */ + strcat(binary, "K"); + *kanji_used = 1; + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + strcat(binary, buffer); + + if (debug) { + printf("Kanji block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + for (i = 0; i < short_data_block_length; i++) { + int jis = jisdata[position + i]; + int prod; + + if (jis >= 0x8140 && jis <= 0x9ffc) + jis -= 0x8140; + + else if (jis >= 0xe040 && jis <= 0xebbf) + jis -= 0xc140; + + prod = ((jis >> 8) * 0xc0) + (jis & 0xff); + + bin_append(prod, 13, binary); + + if (debug) { + printf("0x%4X ", prod); + } + + if (strlen(binary) > 128) { + return ZINT_ERROR_TOO_LONG; + } + } + + if (debug) { + printf("\n"); + } + + break; + case 'B': + /* Byte mode */ + /* Mode indicator */ + strcat(binary, "B"); + *byte_used = 1; + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + strcat(binary, buffer); + + if (debug) { + printf("Byte block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + for (i = 0; i < short_data_block_length; i++) { + int byte = jisdata[position + i]; + + bin_append(byte, 8, binary); + + if (debug) { + printf("0x%4X ", byte); + } + + if (strlen(binary) > 128) { + return ZINT_ERROR_TOO_LONG; + } + } + + if (debug) { + printf("\n"); + } + + break; + case 'A': + /* Alphanumeric mode */ + /* Mode indicator */ + strcat(binary, "A"); + *alphanum_used = 1; + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + strcat(binary, buffer); + + if (debug) { + printf("Alpha block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + i = 0; + while (i < short_data_block_length) { + int count; + int first = 0, second = 0, prod; + + first = posn(RHODIUM, (char) jisdata[position + i]); + count = 1; + prod = first; + + if (i + 1 < short_data_block_length && mode[position + i + 1] == 'A') { + second = posn(RHODIUM, (char) jisdata[position + i + 1]); + count = 2; + prod = (first * 45) + second; + } + + bin_append(prod, 1 + (5 * count), binary); + + if (debug) { + printf("0x%4X ", prod); + } + + if (strlen(binary) > 128) { + return ZINT_ERROR_TOO_LONG; + } + + i += 2; + }; + + if (debug) { + printf("\n"); + } + + break; + case 'N': + /* Numeric mode */ + /* Mode indicator */ + strcat(binary, "N"); + + /* Character count indicator */ + buffer[0] = short_data_block_length; + buffer[1] = '\0'; + strcat(binary, buffer); + + if (debug) { + printf("Number block (length %d)\n\t", short_data_block_length); + } + + /* Character representation */ + i = 0; + while (i < short_data_block_length) { + int count; + int first = 0, second = 0, third = 0, prod; + + first = posn(NEON, (char) jisdata[position + i]); + count = 1; + prod = first; + + if (i + 1 < short_data_block_length && mode[position + i + 1] == 'N') { + second = posn(NEON, (char) jisdata[position + i + 1]); + count = 2; + prod = (prod * 10) + second; + } + + if (i + 2 < short_data_block_length && mode[position + i + 2] == 'N') { + third = posn(NEON, (char) jisdata[position + i + 2]); + count = 3; + prod = (prod * 10) + third; + } + + bin_append(prod, 1 + (3 * count), binary); + + if (debug) { + printf("0x%4X (%d)", prod, prod); + } + + if (strlen(binary) > 128) { + return ZINT_ERROR_TOO_LONG; + } + + i += 3; + }; + + if (debug) { + printf("\n"); + } + + break; + } + + position += short_data_block_length; + } while (position < length - 1); + + return 0; +} + +static void get_bitlength(int count[],const char stream[]) { + size_t length; + int i; + + length = strlen(stream); + + for (i = 0; i < 4; i++) { + count[i] = 0; + } + + i = 0; + do { + if ((stream[i] == '0') || (stream[i] == '1')) { + count[0]++; + count[1]++; + count[2]++; + count[3]++; + i++; + } else { + switch (stream[i]) { + case 'K': + count[2] += 5; + count[3] += 7; + i += 2; + break; + case 'B': + count[2] += 6; + count[3] += 8; + i += 2; + break; + case 'A': + count[1] += 4; + count[2] += 6; + count[3] += 8; + i += 2; + break; + case 'N': + count[0] += 3; + count[1] += 5; + count[2] += 7; + count[3] += 9; + i += 2; + break; + } + } + } while (i < length); +} + +static void microqr_expand_binary(const char binary_stream[], char full_stream[],const int version) { + int i; + size_t length; + + length = strlen(binary_stream); + + i = 0; + do { + switch (binary_stream[i]) { + case '1': strcat(full_stream, "1"); + i++; + break; + case '0': strcat(full_stream, "0"); + i++; + break; + case 'N': + /* Numeric Mode */ + /* Mode indicator */ + switch (version) { + case 1: strcat(full_stream, "0"); + break; + case 2: strcat(full_stream, "00"); + break; + case 3: strcat(full_stream, "000"); + break; + } + + /* Character count indicator */ + bin_append(binary_stream[i + 1], 3 + version, full_stream); /* version = 0..3 */ + + i += 2; + break; + case 'A': + /* Alphanumeric Mode */ + /* Mode indicator */ + switch (version) { + case 1: strcat(full_stream, "1"); + break; + case 2: strcat(full_stream, "01"); + break; + case 3: strcat(full_stream, "001"); + break; + } + + /* Character count indicator */ + bin_append(binary_stream[i + 1], 2 + version, full_stream); /* version = 1..3 */ + + i += 2; + break; + case 'B': + /* Byte Mode */ + /* Mode indicator */ + switch (version) { + case 2: strcat(full_stream, "10"); + break; + case 3: strcat(full_stream, "010"); + break; + } + + /* Character count indicator */ + bin_append(binary_stream[i + 1], 2 + version, full_stream); /* version = 2..3 */ + + i += 2; + break; + case 'K': + /* Kanji Mode */ + /* Mode indicator */ + switch (version) { + case 2: strcat(full_stream, "11"); + break; + case 3: strcat(full_stream, "011"); + break; + } + + /* Character count indicator */ + bin_append(binary_stream[i + 1], 1 + version, full_stream); /* version = 2..3 */ + + i += 2; + break; + } + + } while (i < length); +} + +static void micro_qr_m1(char binary_data[]) { + int i, j, latch; + int bits_total, bits_left, remainder; + int data_codewords, ecc_codewords; + unsigned char data_blocks[4], ecc_blocks[3]; + + bits_total = 20; + latch = 0; + + /* Add terminator */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left <= 3) { + for (i = 0; i < bits_left; i++) { + strcat(binary_data, "0"); + } + latch = 1; + } else { + strcat(binary_data, "000"); + } + + if (latch == 0) { + /* Manage last (4-bit) block */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left <= 4) { + for (i = 0; i < bits_left; i++) { + strcat(binary_data, "0"); + } + latch = 1; + } + } + + if (latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if (remainder == 8) { + remainder = 0; + } + for (i = 0; i < remainder; i++) { + strcat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left > 4) { + remainder = (bits_left - 4) / 8; + for (i = 0; i < remainder; i++) { + strcat(binary_data, i & 1 ? "00010001" : "11101100"); + } + } + bin_append(0, 4, binary_data); + } + + data_codewords = 3; + ecc_codewords = 2; + + /* Copy data into codewords */ + for (i = 0; i < (data_codewords - 1); i++) { + data_blocks[i] = 0; + for (j = 0; j < 8; j++) { + if (binary_data[(i * 8) + j] == '1') { + data_blocks[i] += 0x80 >> j; + } + } + } + data_blocks[2] = 0; + for (j = 0; j < 4; j++) { + if (binary_data[16 + j] == '1') { + data_blocks[2] += 0x80 >> j; + } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords, data_blocks, ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for (i = 0; i < ecc_codewords; i++) { + bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data); + } +} + +static void micro_qr_m2(char binary_data[],const int ecc_mode) { + int i, j, latch; + int bits_total=0, bits_left, remainder; + int data_codewords=0, ecc_codewords=0; + unsigned char data_blocks[6], ecc_blocks[7]; + + latch = 0; + + if (ecc_mode == LEVEL_L) { + bits_total = 40; + } + else if (ecc_mode == LEVEL_M) { + bits_total = 32; + } + else assert(0); + + /* Add terminator */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left <= 5) { + for (i = 0; i < bits_left; i++) { + strcat(binary_data, "0"); + } + latch = 1; + } else { + bin_append(0, 5, binary_data); + } + + if (latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if (remainder == 8) { + remainder = 0; + } + for (i = 0; i < remainder; i++) { + strcat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - (int)strlen(binary_data); + remainder = bits_left / 8; + for (i = 0; i < remainder; i++) { + strcat(binary_data, i & 1 ? "00010001" : "11101100"); + } + } + + if (ecc_mode == LEVEL_L) { + data_codewords = 5; + ecc_codewords = 5; + } + else if (ecc_mode == LEVEL_M) { + data_codewords = 4; + ecc_codewords = 6; + } + else assert(0); + + /* Copy data into codewords */ + for (i = 0; i < data_codewords; i++) { + data_blocks[i] = 0; + + for (j = 0; j < 8; j++) { + if (binary_data[(i * 8) + j] == '1') { + data_blocks[i] += 0x80 >> j; + } + } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords, data_blocks, ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for (i = 0; i < ecc_codewords; i++) { + bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data); + } + + return; +} + +static void micro_qr_m3(char binary_data[],const int ecc_mode) { + int i, j, latch; + int bits_total=0, bits_left, remainder; + int data_codewords=0, ecc_codewords=0; + unsigned char data_blocks[12], ecc_blocks[9]; + + latch = 0; + + if (ecc_mode == LEVEL_L) { + bits_total = 84; + } + else if (ecc_mode == LEVEL_M) { + bits_total = 68; + } + else assert(0); + + /* Add terminator */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left <= 7) { + for (i = 0; i < bits_left; i++) { + strcat(binary_data, "0"); + } + latch = 1; + } else { + bin_append(0, 7, binary_data); + } + + if (latch == 0) { + /* Manage last (4-bit) block */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left <= 4) { + for (i = 0; i < bits_left; i++) { + strcat(binary_data, "0"); + } + latch = 1; + } + } + + if (latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if (remainder == 8) { + remainder = 0; + } + for (i = 0; i < remainder; i++) { + strcat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left > 4) { + remainder = (bits_left - 4) / 8; + for (i = 0; i < remainder; i++) { + strcat(binary_data, i & 1 ? "00010001" : "11101100"); + } + } + bin_append(0, 4, binary_data); + } + + if (ecc_mode == LEVEL_L) { + data_codewords = 11; + ecc_codewords = 6; + } + else if (ecc_mode == LEVEL_M) { + data_codewords = 9; + ecc_codewords = 8; + } + else assert(0); + + /* Copy data into codewords */ + for (i = 0; i < (data_codewords - 1); i++) { + data_blocks[i] = 0; + + for (j = 0; j < 8; j++) { + if (binary_data[(i * 8) + j] == '1') { + data_blocks[i] += 0x80 >> j; + } + } + } + + if (ecc_mode == LEVEL_L) { + data_blocks[10] = 0; + for (j = 0; j < 4; j++) { + if (binary_data[80 + j] == '1') { + data_blocks[10] += 0x80 >> j; + } + } + } + + if (ecc_mode == LEVEL_M) { + data_blocks[8] = 0; + for (j = 0; j < 4; j++) { + if (binary_data[64 + j] == '1') { + data_blocks[8] += 0x80 >> j; + } + } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords, data_blocks, ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for (i = 0; i < ecc_codewords; i++) { + bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data); + } + + return; +} + +static void micro_qr_m4(char binary_data[],const int ecc_mode) { + int i, j, latch; + int bits_total=0, bits_left, remainder; + int data_codewords=0, ecc_codewords=0; + unsigned char data_blocks[17], ecc_blocks[15]; + + latch = 0; + + if (ecc_mode == LEVEL_L) { + bits_total = 128; + } + else if (ecc_mode == LEVEL_M) { + bits_total = 112; + } + else if (ecc_mode == LEVEL_Q) { + bits_total = 80; + } + else assert(0); + + /* Add terminator */ + bits_left = bits_total - (int)strlen(binary_data); + if (bits_left <= 9) { + for (i = 0; i < bits_left; i++) { + strcat(binary_data, "0"); + } + latch = 1; + } else { + bin_append(0, 9, binary_data); + } + + if (latch == 0) { + /* Complete current byte */ + remainder = 8 - (strlen(binary_data) % 8); + if (remainder == 8) { + remainder = 0; + } + for (i = 0; i < remainder; i++) { + strcat(binary_data, "0"); + } + + /* Add padding */ + bits_left = bits_total - (int)strlen(binary_data); + remainder = bits_left / 8; + for (i = 0; i < remainder; i++) { + strcat(binary_data, i & 1 ? "00010001" : "11101100"); + } + } + + if (ecc_mode == LEVEL_L) { + data_codewords = 16; + ecc_codewords = 8; + } + else if (ecc_mode == LEVEL_M) { + data_codewords = 14; + ecc_codewords = 10; + } + else if (ecc_mode == LEVEL_Q) { + data_codewords = 10; + ecc_codewords = 14; + } + else assert(0); + + /* Copy data into codewords */ + for (i = 0; i < data_codewords; i++) { + data_blocks[i] = 0; + + for (j = 0; j < 8; j++) { + if (binary_data[(i * 8) + j] == '1') { + data_blocks[i] += 0x80 >> j; + } + } + } + + /* Calculate Reed-Solomon error codewords */ + rs_init_gf(0x11d); + rs_init_code(ecc_codewords, 0); + rs_encode(data_codewords, data_blocks, ecc_blocks); + rs_free(); + + /* Add Reed-Solomon codewords to binary data */ + for (i = 0; i < ecc_codewords; i++) { + bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data); + } +} + +static void micro_setup_grid(unsigned char* grid,const int size) { + int i, toggle = 1; + + /* Add timing patterns */ + for (i = 0; i < size; i++) { + if (toggle == 1) { + grid[i] = 0x21; + grid[(i * size)] = 0x21; + toggle = 0; + } else { + grid[i] = 0x20; + grid[(i * size)] = 0x20; + toggle = 1; + } + } + + /* Add finder patterns */ + place_finder(grid, size, 0, 0); + + /* Add separators */ + for (i = 0; i < 7; i++) { + grid[(7 * size) + i] = 0x10; + grid[(i * size) + 7] = 0x10; + } + grid[(7 * size) + 7] = 0x10; + + + /* Reserve space for format information */ + for (i = 0; i < 8; i++) { + grid[(8 * size) + i] += 0x20; + grid[(i * size) + 8] += 0x20; + } + grid[(8 * size) + 8] += 20; +} + +static void micro_populate_grid(unsigned char* grid,const int size,const char full_stream[]) { + int direction = 1; /* up */ + int row = 0; /* right hand side */ + size_t n; + int i,x, y; + + n = strlen(full_stream); + y = size - 1; + i = 0; + do { + x = (size - 2) - (row * 2); + + if (!(grid[(y * size) + (x + 1)] & 0xf0)) { + if (full_stream[i] == '1') { + grid[(y * size) + (x + 1)] = 0x01; + } else { + grid[(y * size) + (x + 1)] = 0x00; + } + i++; + } + + if (i < n) { + if (!(grid[(y * size) + x] & 0xf0)) { + if (full_stream[i] == '1') { + grid[(y * size) + x] = 0x01; + } else { + grid[(y * size) + x] = 0x00; + } + i++; + } + } + + if (direction) { + y--; + } else { + y++; + } + if (y == 0) { + /* reached the top */ + row++; + y = 1; + direction = 0; + } + if (y == size) { + /* reached the bottom */ + row++; + y = size - 1; + direction = 1; + } + } while (i < n); +} + +static int micro_evaluate(const unsigned char *grid,const int size,const int pattern) { + int sum1, sum2, i, filter = 0, retval; + + switch (pattern) { + case 0: filter = 0x01; + break; + case 1: filter = 0x02; + break; + case 2: filter = 0x04; + break; + case 3: filter = 0x08; + break; + } + + sum1 = 0; + sum2 = 0; + for (i = 1; i < size; i++) { + if (grid[(i * size) + size - 1] & filter) { + sum1++; + } + if (grid[((size - 1) * size) + i] & filter) { + sum2++; + } + } + + if (sum1 <= sum2) { + retval = (sum1 * 16) + sum2; + } else { + retval = (sum2 * 16) + sum1; + } + + return retval; +} + +static int micro_apply_bitmask(unsigned char *grid,const int size) { + int x, y; + unsigned char p; + int pattern, value[8]; + int best_val, best_pattern; + +#ifndef _MSC_VER + unsigned char mask[size * size]; + unsigned char eval[size * size]; +#else + unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); + unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + /* Perform data masking */ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + mask[(y * size) + x] = 0x00; + + if (!(grid[(y * size) + x] & 0xf0)) { + if ((y & 1) == 0) { + mask[(y * size) + x] += 0x01; + } + + if ((((y / 2) + (x / 3)) & 1) == 0) { + mask[(y * size) + x] += 0x02; + } + + if (((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { + mask[(y * size) + x] += 0x04; + } + + if (((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { + mask[(y * size) + x] += 0x08; + } + } + } + } + + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (grid[(y * size) + x] & 0x01) { + p = 0xff; + } else { + p = 0x00; + } + + eval[(y * size) + x] = mask[(y * size) + x] ^ p; + } + } + + + /* Evaluate result */ + for (pattern = 0; pattern < 8; pattern++) { + value[pattern] = micro_evaluate(eval, size, pattern); + } + + best_pattern = 0; + best_val = value[0]; + for (pattern = 1; pattern < 4; pattern++) { + if (value[pattern] > best_val) { + best_pattern = pattern; + best_val = value[pattern]; + } + } + + /* Apply mask */ + for (x = 0; x < size; x++) { + for (y = 0; y < size; y++) { + if (mask[(y * size) + x] & (0x01 << best_pattern)) { + if (grid[(y * size) + x] & 0x01) { + grid[(y * size) + x] = 0x00; + } else { + grid[(y * size) + x] = 0x01; + } + } + } + } + + return best_pattern; +} + +int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t length) { + size_t i; + int j,size; + char binary_stream[200]; + char full_stream[200]; + int utfdata[40],glyph; + + int jisdata[40]; + char mode[40]; + int error_number, kanji_used = 0, alphanum_used = 0, byte_used = 0; + int version_valid[4]; + int binary_count[4]; + int ecc_level, autoversion, version; + int n_count, a_count, bitmask, format, format_full; +#ifdef _MSC_VER + unsigned char* grid; +#endif + + if (length > 35) { + strcpy(symbol->errtxt, "562: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + for (i = 0; i < 4; i++) { + version_valid[i] = 1; + } + + if (symbol->input_mode == DATA_MODE) { + for (i = 0; i < length; i++) { + jisdata[i] = (int) source[i]; + } + } else { + /* Convert Unicode input to Shift-JIS */ + error_number = utf8toutf16(symbol, source, utfdata, &length); + if (error_number != 0) { + return error_number; + } + + for (i = 0; i < length; i++) { + if (utfdata[i] <= 0xff) { + jisdata[i] = utfdata[i]; + } else { + j = 0; + glyph = 0; + do { + if (sjis_lookup[j * 2] == utfdata[i]) { + glyph = sjis_lookup[(j * 2) + 1]; + } + j++; + } while ((j < 6843) && (glyph == 0)); + if (glyph == 0) { + strcpy(symbol->errtxt, "563: Invalid character in input data"); + return ZINT_ERROR_INVALID_DATA; + } + jisdata[i] = glyph; + } + } + } + + define_mode(mode, jisdata, length, 0); + + n_count = 0; + a_count = 0; + for (i = 0; i < length; i++) { + if ((jisdata[i] >= '0') && (jisdata[i] <= '9')) { + n_count++; + } + if (in_alpha(jisdata[i])) { + a_count++; + } + } + + if (a_count == length) { + /* All data can be encoded in Alphanumeric mode */ + for (i = 0; i < length; i++) { + mode[i] = 'A'; + } + } + + if (n_count == length) { + /* All data can be encoded in Numeric mode */ + for (i = 0; i < length; i++) { + mode[i] = 'N'; + } + } + + error_number = micro_qr_intermediate(binary_stream, jisdata, mode, length, &kanji_used, &alphanum_used, &byte_used, symbol->debug); + if (error_number != 0) { + strcpy(symbol->errtxt, "564: Input data too long"); + return error_number; + } + + get_bitlength(binary_count, binary_stream); + + /* Eliminate possivle versions depending on type of content */ + if (byte_used) { + version_valid[0] = 0; + version_valid[1] = 0; + } + + if (alphanum_used) { + version_valid[0] = 0; + } + + if (kanji_used) { + version_valid[0] = 0; + version_valid[1] = 0; + } + + /* Eliminate possible versions depending on length of binary data */ + if (binary_count[0] > 20) { + version_valid[0] = 0; + } + if (binary_count[1] > 40) { + version_valid[1] = 0; + } + if (binary_count[2] > 84) { + version_valid[2] = 0; + } + if (binary_count[3] > 128) { + strcpy(symbol->errtxt, "565: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Eliminate possible versions depending on error correction level specified */ + ecc_level = LEVEL_L; + if ((symbol->option_1 >= 1) && (symbol->option_2 <= 4)) { + ecc_level = symbol->option_1; + } + + if (ecc_level == LEVEL_H) { + strcpy(symbol->errtxt, "566: Error correction level H not available"); + return ZINT_ERROR_INVALID_OPTION; + } + + if (ecc_level == LEVEL_Q) { + version_valid[0] = 0; + version_valid[1] = 0; + version_valid[2] = 0; + if (binary_count[3] > 80) { + strcpy(symbol->errtxt, "567: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + } + + if (ecc_level == LEVEL_M) { + version_valid[0] = 0; + if (binary_count[1] > 32) { + version_valid[1] = 0; + } + if (binary_count[2] > 68) { + version_valid[2] = 0; + } + if (binary_count[3] > 112) { + strcpy(symbol->errtxt, "568: Input data too long"); + return ZINT_ERROR_TOO_LONG; + } + } + + autoversion = 3; + if (version_valid[2]) { + autoversion = 2; + } + if (version_valid[1]) { + autoversion = 1; + } + if (version_valid[0]) { + autoversion = 0; + } + + version = autoversion; + /* Get version from user */ + if ((symbol->option_2 >= 1) && (symbol->option_2 <= 4)) { + if (symbol->option_2 >= autoversion) { + version = symbol->option_2; + } else { + strcpy(symbol->errtxt, "570: Input too long for selected symbol size"); + return ZINT_ERROR_TOO_LONG; + } + } + + /* If there is enough unused space then increase the error correction level */ + if (version == 3) { + if (binary_count[3] <= 112) { + ecc_level = LEVEL_M; + } + if (binary_count[3] <= 80) { + ecc_level = LEVEL_Q; + } + } + + if (version == 2) { + if (binary_count[2] <= 68) { + ecc_level = LEVEL_M; + } + } + + if (version == 1) { + if (binary_count[1] <= 32) { + ecc_level = LEVEL_M; + } + } + + strcpy(full_stream, ""); + microqr_expand_binary(binary_stream, full_stream, version); + + switch (version) { + case 0: micro_qr_m1(full_stream); + break; + case 1: micro_qr_m2(full_stream, ecc_level); + break; + case 2: micro_qr_m3(full_stream, ecc_level); + break; + case 3: micro_qr_m4(full_stream, ecc_level); + break; + } + + size = micro_qr_sizes[version]; +#ifndef _MSC_VER + unsigned char grid[size * size]; +#else + grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + grid[(i * size) + j] = 0; + } + } + + micro_setup_grid(grid, size); + micro_populate_grid(grid, size, full_stream); + bitmask = micro_apply_bitmask(grid, size); + + /* Add format data */ + format = 0; + switch (version) { + case 1: switch (ecc_level) { + case 1: format = 1; + break; + case 2: format = 2; + break; + } + break; + case 2: switch (ecc_level) { + case 1: format = 3; + break; + case 2: format = 4; + break; + } + break; + case 3: switch (ecc_level) { + case 1: format = 5; + break; + case 2: format = 6; + break; + case 3: format = 7; + break; + } + break; + } + + format_full = qr_annex_c1[(format << 2) + bitmask]; + + if (format_full & 0x4000) { + grid[(8 * size) + 1] += 0x01; + } + if (format_full & 0x2000) { + grid[(8 * size) + 2] += 0x01; + } + if (format_full & 0x1000) { + grid[(8 * size) + 3] += 0x01; + } + if (format_full & 0x800) { + grid[(8 * size) + 4] += 0x01; + } + if (format_full & 0x400) { + grid[(8 * size) + 5] += 0x01; + } + if (format_full & 0x200) { + grid[(8 * size) + 6] += 0x01; + } + if (format_full & 0x100) { + grid[(8 * size) + 7] += 0x01; + } + if (format_full & 0x80) { + grid[(8 * size) + 8] += 0x01; + } + if (format_full & 0x40) { + grid[(7 * size) + 8] += 0x01; + } + if (format_full & 0x20) { + grid[(6 * size) + 8] += 0x01; + } + if (format_full & 0x10) { + grid[(5 * size) + 8] += 0x01; + } + if (format_full & 0x08) { + grid[(4 * size) + 8] += 0x01; + } + if (format_full & 0x04) { + grid[(3 * size) + 8] += 0x01; + } + if (format_full & 0x02) { + grid[(2 * size) + 8] += 0x01; + } + if (format_full & 0x01) { + grid[(1 * size) + 8] += 0x01; + } + + symbol->width = size; + symbol->rows = size; + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + if (grid[(i * size) + j] & 0x01) { + set_module(symbol, i, j); + } + } + symbol->row_height[i] = 1; + } + + return 0; +} + +/* For UPNQR the symbol size and error correction capacity is fixed */ +int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t length) { + int i, j, est_binlen; + int ecc_level, version, target_binlen, blocks, size; + int bitmask, error_number; + +#ifndef _MSC_VER + int jisdata[length + 1]; + char mode[length + 1]; +#else + int* datastream; + int* fullstream; + unsigned char* grid; + int* jisdata = (int *) _alloca((length + 1) * sizeof (int)); + char* mode = (char *) _alloca(length + 1); +#endif + +#ifndef _MSC_VER + unsigned char preprocessed[length + 1]; +#else + unsigned char* preprocessed = (unsigned char*) _alloca(length + 1); +#endif + + switch(symbol->input_mode) { + case DATA_MODE: + /* Input is already in ISO-8859-2 format */ + for (i = 0; i < length; i++) { + jisdata[i] = (int) source[i]; + mode[i] = 'B'; + } + break; + case GS1_MODE: + strcpy(symbol->errtxt, "571: UPNQR does not support GS-1 encoding"); + return ZINT_ERROR_INVALID_OPTION; + break; + case UNICODE_MODE: + error_number = utf_to_eci(4, source, preprocessed, &length); + if (error_number != 0) { + strcpy(symbol->errtxt, "572: Invalid characters in input data"); + return error_number; + } + for (i = 0; i < length; i++) { + jisdata[i] = (int) preprocessed[i]; + mode[i] = 'B'; + } + break; + } + + symbol->eci = 4; + est_binlen = getBinaryLength(15, mode, jisdata, length, 0, symbol->eci); + + ecc_level = LEVEL_M; + + if (est_binlen > 3320) { + strcpy(symbol->errtxt, "573: Input too long for selected symbol"); + return ZINT_ERROR_TOO_LONG; + } + + version = 15; // 77 x 77 + + target_binlen = qr_data_codewords_M[version - 1]; + blocks = qr_blocks_M[version - 1]; + +#ifndef _MSC_VER + int datastream[target_binlen + 1]; + int fullstream[qr_total_codewords[version - 1] + 1]; +#else + datastream = (int *) _alloca((target_binlen + 1) * sizeof (int)); + fullstream = (int *) _alloca((qr_total_codewords[version - 1] + 1) * sizeof (int)); +#endif + + qr_binary(datastream, version, target_binlen, mode, jisdata, length, 0, symbol->eci, est_binlen, symbol->debug); + add_ecc(fullstream, datastream, version, target_binlen, blocks); + + size = qr_sizes[version - 1]; +#ifndef _MSC_VER + unsigned char grid[size * size]; +#else + grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char)); +#endif + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + grid[(i * size) + j] = 0; + } + } + + setup_grid(grid, size, version); + populate_grid(grid, size, fullstream, qr_total_codewords[version - 1]); + + add_version_info(grid, size, version); + + bitmask = apply_bitmask(grid, size, ecc_level); + + add_format_info(grid, size, ecc_level, bitmask); + + symbol->width = size; + symbol->rows = size; + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + if (grid[(i * size) + j] & 0x01) { + set_module(symbol, i, j); + } + } + symbol->row_height[i] = 1; + } + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/qr.h b/3rdparty/zint-2.6.1/backend/qr.h new file mode 100644 index 0000000..c5a23c9 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/qr.h @@ -0,0 +1,167 @@ +/* qr.h Data for QR Code */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + Copyright (C) 2006 Kentaro Fukuchi + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define LEVEL_L 1 +#define LEVEL_M 2 +#define LEVEL_Q 3 +#define LEVEL_H 4 + +#define RHODIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + +/* From ISO/IEC 18004:2006 Table 7 */ +static const unsigned short int qr_data_codewords_L[] = { + 19, 34, 55, 80, 108, 136, 156, 194, 232, 274, 324, 370, 428, 461, 523, 589, 647, + 721, 795, 861, 932, 1006, 1094, 1174, 1276, 1370, 1468, 1531, 1631, + 1735, 1843, 1955, 2071, 2191, 2306, 2434, 2566, 2702, 2812, 2956 +}; + +static const unsigned short int qr_data_codewords_M[] = { + 16, 28, 44, 64, 86, 108, 124, 154, 182, 216, 254, 290, 334, 365, 415, 453, 507, + 563, 627, 669, 714, 782, 860, 914, 1000, 1062, 1128, 1193, 1267, + 1373, 1455, 1541, 1631, 1725, 1812, 1914, 1992, 2102, 2216, 2334 +}; + +static const unsigned short int qr_data_codewords_Q[] = { + 13, 22, 34, 48, 62, 76, 88, 110, 132, 154, 180, 206, 244, 261, 295, 325, 367, + 397, 445, 485, 512, 568, 614, 664, 718, 754, 808, 871, 911, + 985, 1033, 1115, 1171, 1231, 1286, 1354, 1426, 1502, 1582, 1666 +}; + +static const unsigned short int qr_data_codewords_H[] = { + 9, 16, 26, 36, 46, 60, 66, 86, 100, 122, 140, 158, 180, 197, 223, 253, 283, + 313, 341, 385, 406, 442, 464, 514, 538, 596, 628, 661, 701, + 745, 793, 845, 901, 961, 986, 1054, 1096, 1142, 1222, 1276 +}; + +static const unsigned short int qr_total_codewords[] = { + 26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815, + 901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, + 2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706 +}; + +static const char qr_blocks_L[] = { + 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25 +}; + +static const char qr_blocks_M[] = { + 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, + 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49 +}; + +static const char qr_blocks_Q[] = { + 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, + 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68 +}; + +static const char qr_blocks_H[] = { + 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, + 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81 +}; + +static const unsigned short int qr_sizes[] = { + 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, + 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177 +}; + +static const char micro_qr_sizes[] = { + 11, 13, 15, 17 +}; + +static const char qr_align_loopsize[] = { + 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 +}; + +static const unsigned short int qr_table_e1[] = { + 6, 18, 0, 0, 0, 0, 0, + 6, 22, 0, 0, 0, 0, 0, + 6, 26, 0, 0, 0, 0, 0, + 6, 30, 0, 0, 0, 0, 0, + 6, 34, 0, 0, 0, 0, 0, + 6, 22, 38, 0, 0, 0, 0, + 6, 24, 42, 0, 0, 0, 0, + 6, 26, 46, 0, 0, 0, 0, + 6, 28, 50, 0, 0, 0, 0, + 6, 30, 54, 0, 0, 0, 0, + 6, 32, 58, 0, 0, 0, 0, + 6, 34, 62, 0, 0, 0, 0, + 6, 26, 46, 66, 0, 0, 0, + 6, 26, 48, 70, 0, 0, 0, + 6, 26, 50, 74, 0, 0, 0, + 6, 30, 54, 78, 0, 0, 0, + 6, 30, 56, 82, 0, 0, 0, + 6, 30, 58, 86, 0, 0, 0, + 6, 34, 62, 90, 0, 0, 0, + 6, 28, 50, 72, 94, 0, 0, + 6, 26, 50, 74, 98, 0, 0, + 6, 30, 54, 78, 102, 0, 0, + 6, 28, 54, 80, 106, 0, 0, + 6, 32, 58, 84, 110, 0, 0, + 6, 30, 58, 86, 114, 0, 0, + 6, 34, 62, 90, 118, 0, 0, + 6, 26, 50, 74, 98, 122, 0, + 6, 30, 54, 78, 102, 126, 0, + 6, 26, 52, 78, 104, 130, 0, + 6, 30, 56, 82, 108, 134, 0, + 6, 34, 60, 86, 112, 138, 0, + 6, 30, 58, 86, 114, 142, 0, + 6, 34, 62, 90, 118, 146, 0, + 6, 30, 54, 78, 102, 126, 150, + 6, 24, 50, 76, 102, 128, 154, + 6, 28, 54, 80, 106, 132, 158, + 6, 32, 58, 84, 110, 136, 162, + 6, 26, 54, 82, 110, 138, 166, + 6, 30, 58, 86, 114, 142, 170 +}; + +static const unsigned int qr_annex_c[] = { + /* Format information bit sequences */ + 0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, 0x77c4, 0x72f3, 0x7daa, 0x789d, + 0x662f, 0x6318, 0x6c41, 0x6976, 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b, + 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed +}; + +static const unsigned int qr_annex_d[] = { + /* Version information bit sequences */ + 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78, + 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, 0x177ec, 0x18ec4, 0x191e1, 0x1afab, + 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, + 0x2542e, 0x26a64, 0x27541, 0x28c69 +}; + +static const unsigned int qr_annex_c1[] = { + /* Micro QR Code format information */ + 0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7, 0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f, + 0x7c16, 0x7921, 0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c, 0x2508, 0x203f, 0x2f66, 0x2a51, 0x34e3, + 0x31d4, 0x3e8d, 0x3bba +}; diff --git a/3rdparty/zint-2.6.1/backend/raster.c b/3rdparty/zint-2.6.1/backend/raster.c new file mode 100644 index 0000000..08bf9a7 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/raster.c @@ -0,0 +1,1138 @@ +/* raster.c - Handles output to raster files */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#ifdef _MSC_VER +#include +#include +#endif +#include +#include +#include "common.h" + +#ifdef _MSC_VER +#include +#endif /* _MSC_VER */ + +#include "font.h" /* Font for human readable text */ + +#define SSET "0123456789ABCDEF" + +#ifndef NO_PNG +extern int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +#endif /* NO_PNG */ +extern int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); +extern int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf); + +void buffer_plot(struct zint_symbol *symbol, char *pixelbuf) { + /* Place pixelbuffer into symbol */ + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + int row, column, i; + + symbol->bitmap = (char *) malloc(symbol->bitmap_width * symbol->bitmap_height * 3); + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + for (row = 0; row < symbol->bitmap_height; row++) { + for (column = 0; column < symbol->bitmap_width; column++) { + i = ((row * symbol->bitmap_width) + column) * 3; + switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) { + case '1': + symbol->bitmap[i] = fgred; + symbol->bitmap[i + 1] = fggrn; + symbol->bitmap[i + 2] = fgblu; + break; + default: + symbol->bitmap[i] = bgred; + symbol->bitmap[i + 1] = bggrn; + symbol->bitmap[i + 2] = bgblu; + break; + + } + } + } +} + +int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) { + int error_number; + int row, column; + + char *rotated_pixbuf; + + if (!(rotated_pixbuf = (char *) malloc(image_width * image_height))) { + strcpy(symbol->errtxt, "650: Insufficient memory for pixel buffer"); + return ZINT_ERROR_ENCODING_PROBLEM; + } + + switch (rotate_angle) { + case 0: + case 180: + symbol->bitmap_width = image_width; + symbol->bitmap_height = image_height; + break; + case 90: + case 270: + symbol->bitmap_width = image_height; + symbol->bitmap_height = image_width; + break; + } + + /* sort out colour options */ + to_upper((unsigned char*) symbol->fgcolour); + to_upper((unsigned char*) symbol->bgcolour); + + if (strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "651: Malformed foreground colour target"); + free(rotated_pixbuf); + return ZINT_ERROR_INVALID_OPTION; + } + if (strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "652: Malformed background colour target"); + free(rotated_pixbuf); + return ZINT_ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "653: Malformed foreground colour target"); + free(rotated_pixbuf); + return ZINT_ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->fgcolour)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "654: Malformed background colour target"); + free(rotated_pixbuf); + return ZINT_ERROR_INVALID_OPTION; + } + + /* Rotate image before plotting */ + switch (rotate_angle) { + case 0: /* Plot the right way up */ + for (row = 0; row < image_height; row++) { + for (column = 0; column < image_width; column++) { + rotated_pixbuf[(row * image_width) + column] = + pixelbuf[(image_width * row) + column]; + } + } + break; + case 90: /* Plot 90 degrees clockwise */ + for (row = 0; row < image_width; row++) { + for (column = 0; column < image_height; column++) { + rotated_pixbuf[(row * image_height) + column] = + *(pixelbuf + (image_width * (image_height - column - 1)) + row); + } + } + break; + case 180: /* Plot upside down */ + for (row = 0; row < image_height; row++) { + for (column = 0; column < image_width; column++) { + rotated_pixbuf[(row * image_width) + column] = + *(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1)); + } + } + break; + case 270: /* Plot 90 degrees anti-clockwise */ + for (row = 0; row < image_width; row++) { + for (column = 0; column < image_height; column++) { + rotated_pixbuf[(row * image_height) + column] = + *(pixelbuf + (image_width * column) + (image_width - row - 1)); + } + } + break; + } + + switch (image_type) { + case OUT_BUFFER: + buffer_plot(symbol, rotated_pixbuf); + error_number = 0; + break; + case OUT_PNG_FILE: +#ifndef NO_PNG + error_number = png_pixel_plot(symbol, rotated_pixbuf); +#else + free(rotated_pixbuf); + return ZINT_ERROR_INVALID_OPTION; +#endif + break; + case OUT_PCX_FILE: + error_number = pcx_pixel_plot(symbol, rotated_pixbuf); + break; + case OUT_GIF_FILE: + error_number = gif_pixel_plot(symbol, rotated_pixbuf); + break; + case OUT_TIF_FILE: + error_number = tif_pixel_plot(symbol, rotated_pixbuf); + break; + default: + error_number = bmp_pixel_plot(symbol, rotated_pixbuf); + break; + } + + free(rotated_pixbuf); + return error_number; +} + +void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height) { + /* Draw a rectangle */ + int i, j, png_ypos; + + png_ypos = image_height - ypos - ylen; + /* This fudge is needed because EPS measures height from the bottom up but + PNG measures y position from the top down */ + + for (i = (xpos); i < (xpos + xlen); i++) { + for (j = (png_ypos); j < (png_ypos + ylen); j++) { + *(pixelbuf + (image_width * j) + i) = '1'; + } + } +} + +void draw_circle(char *pixelbuf, int image_width, int image_height, int x0, int y0, float radius, char fill) { + int x, y; + int radius_i = (int) radius; + + for (y = -radius_i; y <= radius_i; y++) { + for (x = -radius_i; x <= radius_i; x++) { + if ((x * x) + (y * y) <= (radius_i * radius_i)) { + if ((y + y0 >= 0) && (y + y0 < image_height) + && (x + x0 >= 0) && (x + x0 < image_width)) { + *(pixelbuf + ((y + y0) * image_width) + (x + x0)) = fill; + } + } + } + } +} + +void draw_bullseye(char *pixelbuf, int image_width, int image_height, int xoffset, int yoffset, int scaler) { + /* Central bullseye in Maxicode symbols */ + draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(4.571 * scaler) + 1, '1'); + draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(3.779 * scaler) + 1, '0'); + draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(2.988 * scaler) + 1, '1'); + draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(2.196 * scaler) + 1, '0'); + draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(1.394 * scaler) + 1, '1'); + draw_circle(pixelbuf, image_width, image_height, (int)(14.5 * scaler) + xoffset, (int)(15 * scaler) + yoffset, (int)(0.602 * scaler) + 1, '0'); + +} + +void draw_hexagon(char *pixelbuf, int image_width, char *scaled_hexagon, int hexagon_size, int xposn, int yposn) { + /* Put a hexagon into the pixel buffer */ + int i, j; + + for (i = 0; i < hexagon_size; i++) { + for (j = 0; j < hexagon_size; j++) { + if (scaled_hexagon[(i * hexagon_size) + j] == '1') { + *(pixelbuf + (image_width * i) + (image_width * yposn) + xposn + j) = '1'; + } + } + } +} + +void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int textflags, int image_width, int image_height) { + /* Put a letter into a position */ + int skip, x, y, glyph_no, max_x, max_y; + + skip = 0; + + if (letter < 33) { + skip = 1; + } + + if ((letter > 127) && (letter < 161)) { + skip = 1; + } + + if (xposn < 0 || yposn < 0) { + skip = 1; + } + + if (skip == 0) { + if (letter > 128) { + glyph_no = letter - 66; + } else { + glyph_no = letter - 33; + } + + + switch (textflags) { + case 1: // small font 5x9 + max_x = 5; + max_y = 9; + + if (xposn + max_x >= image_width) { + max_x = image_width - xposn - 1; + } + + if (yposn + max_y >= image_height) { + max_y = image_height - yposn - 1; + } + + for (y = 0; y < max_y; y++) { + for (x = 0; x < max_x; x++) { + if (small_font[(glyph_no * 9) + y] & (0x10 >> x)) { + *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = '1'; + } + } + } + break; + + case 2: // bold font -> twice the regular font + { + char * linePtr; + max_x = 7; + max_y = 14; + + if (xposn + max_x + 1 >= image_width) { + max_x = image_width - xposn - 2; + } + + if (yposn + max_y >= image_height) { + max_y = image_height - yposn - 1; + } + + linePtr = pixelbuf + (yposn * image_width) + xposn + 1; + for (y = 0; y < max_y; y++) { + char * pixelPtr = linePtr; + int extra_dot = 0; + for (x = 0; x < 7; x++) { + if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) { + *pixelPtr = '1'; + extra_dot = 1; + } else { + if (extra_dot) { + *pixelPtr = '1'; + } + + extra_dot = 0; + } + + ++pixelPtr; + } + + if (extra_dot) { + *pixelPtr = '1'; + } + + linePtr += image_width; + } + } + break; + + default: // regular font 7x15 + max_x = 7; + max_y = 14; + + if (xposn + max_x >= image_width) { + max_x = image_width - xposn - 1; + } + + if (yposn + max_y >= image_height) { + max_y = image_height - yposn - 1; + } + + for (y = 0; y < max_y; y++) { + for (x = 0; x < 7; x++) { + if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) { + *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = '1'; + } + } + } + break; + } + } +} + +/* Plot a string into the pixel buffer */ +void draw_string(char *pixbuf, char input_string[], int xposn, int yposn, int textflags, int image_width, int image_height) { + int i, string_length, string_left_hand, letter_width = 7; + + switch (textflags) { + case 1: // small font 5x9 + letter_width = 5; + break; + + case 2: // bold font -> width of the regular font + 1 extra dot + 1 extra space + letter_width = 9; + break; + + default: // regular font 7x15 + letter_width = 7; + break; + } + + string_length = strlen(input_string); + string_left_hand = xposn - ((letter_width * string_length) / 2); + + for (i = 0; i < string_length; i++) { + draw_letter(pixbuf, input_string[i], string_left_hand + (i * letter_width), yposn, textflags, image_width, image_height); + } + +} + +void plot_hexline(char *scaled_hexagon, int hexagon_size, float start_x, float start_y, float end_x, float end_y) { + /* Draw a straight line from start to end */ + int i; + float inc_x, inc_y; + float this_x, this_y; + + inc_x = (end_x - start_x) / hexagon_size; + inc_y = (end_y - start_y) / hexagon_size; + + for (i = 0; i < hexagon_size; i++) { + this_x = start_x + ((float)i * inc_x); + this_y = start_y + ((float)i * inc_y); + if (((this_x >= 0) && (this_x < hexagon_size)) && ((this_y >= 0) && (this_y < hexagon_size))) { + scaled_hexagon[(hexagon_size * (int)this_y) + (int)this_x] = '1'; + } + } +} + +void plot_hexagon(char *scaled_hexagon, int hexagon_size) { + /* Create a hexagon shape and fill it */ + int line, i; + char ink; + + float x_offset[6]; + float y_offset[6]; + float start_x, start_y; + float end_x, end_y; + + x_offset[0] = 0.0; + x_offset[1] = 0.86; + x_offset[2] = 0.86; + x_offset[3] = 0.0; + x_offset[4] = -0.86; + x_offset[5] = -0.86; + + y_offset[0] = 1.0; + y_offset[1] = 0.5; + y_offset[2] = -0.5; + y_offset[3] = -1.0; + y_offset[4] = -0.5; + y_offset[5] = 0.5; + + /* Plot hexagon outline */ + for (line = 0; line < 5; line++) { + start_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line]); + start_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line]); + end_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line + 1]); + end_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line + 1]); + plot_hexline(scaled_hexagon, hexagon_size, start_x, start_y, end_x, end_y); + } + start_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line]); + start_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line]); + end_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[0]); + end_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[0]); + plot_hexline(scaled_hexagon, hexagon_size, start_x, start_y, end_x, end_y); + + /* Fill hexagon */ + for (line = 0; line < hexagon_size; line++) { + ink = '0'; + for (i = 0; i < hexagon_size; i++) { + if (scaled_hexagon[(hexagon_size * line) + i] == '1') { + if (i < (hexagon_size / 2)) { + ink = '1'; + } else { + ink = '0'; + } + } + + if (ink == '1') { + scaled_hexagon[(hexagon_size * line) + i] = ink; + } + } + } +} + +int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_type) { + /* Plot a MaxiCode symbol with hexagons and bullseye */ + int i, row, column, xposn, yposn; + int image_height, image_width; + char *pixelbuf; + int error_number; + int xoffset, yoffset; + float scaler = symbol->scale; + char *scaled_hexagon; + int hexagon_size; + + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + image_width = (300 + (2 * xoffset * 2)) * scaler; + image_height = (300 + (2 * yoffset * 2)) * scaler; + + if (!(pixelbuf = (char *) malloc(image_width * image_height))) { + strcpy(symbol->errtxt, "655: Insufficient memory for pixel buffer"); + return ZINT_ERROR_ENCODING_PROBLEM; + } else { + for (i = 0; i < (image_width * image_height); i++) { + *(pixelbuf + i) = '0'; + } + } + + hexagon_size = (int)scaler * 10; + + if (!(scaled_hexagon = (char *) malloc(hexagon_size * hexagon_size))) { + strcpy(symbol->errtxt, "656: Insufficient memory for pixel buffer"); + free(scaled_hexagon); + free(pixelbuf); + return ZINT_ERROR_ENCODING_PROBLEM; + } else { + for (i = 0; i < (hexagon_size * hexagon_size); i++) { + *(scaled_hexagon + i) = '0'; + } + } + + plot_hexagon(scaled_hexagon, hexagon_size); + + draw_bullseye(pixelbuf, image_width, image_height, (2 * xoffset), (2 * yoffset), scaler * 10); + + for (row = 0; row < symbol->rows; row++) { + yposn = row * 9; + for (column = 0; column < symbol->width; column++) { + xposn = column * 10; + if (module_is_set(symbol, row, column)) { + if (row & 1) { + /* Odd (reduced) row */ + xposn += 5; + draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, (xposn + (2 * xoffset)) * scaler, (yposn + (2 * yoffset)) * scaler); + } else { + /* Even (full) row */ + draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, (xposn + (2 * xoffset)) * scaler, (yposn + (2 * yoffset)) * scaler); + } + } + } + } + + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + /* boundary bars */ + draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height); + draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height); + } + + if (symbol->output_options & BARCODE_BOX) { + /* side bars */ + draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height); + draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height); + } + + error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); + free(scaled_hexagon); + free(pixelbuf); + return error_number; +} + +/* Convert UTF-8 to Latin1 Codepage for the interpretation line */ +void to_latin1(unsigned char source[], unsigned char preprocessed[]) { + int j, i, input_length; + + input_length = ustrlen(source); + + j = 0; + i = 0; + while (i < input_length) { + switch (source[i]) { + case 0xC2: + /* UTF-8 C2xxh */ + /* Character range: C280h (latin: 80h) to C2BFh (latin: BFh) */ + i++; + preprocessed[j] = source[i]; + j++; + break; + case 0xC3: + /* UTF-8 C3xx */ + /* Character range: C380h (latin: C0h) to C3BFh (latin: FFh) */ + i++; + preprocessed[j] = source[i] + 64; + j++; + break; + default: + /* Process ASCII (< 80h), all other unicode points are ignored */ + if (source[i] < 128) { + preprocessed[j] = source[i]; + j++; + } + break; + } + i++; + } + preprocessed[j] = '\0'; + + return; +} + +int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_type) { + float scaler = 2 * symbol->scale; + char *scaled_pixelbuf; + int r, i; + int scale_width, scale_height; + int error_number = 0; + int xoffset, yoffset, image_width, image_height; + + symbol->height = symbol->rows; // This is true because only 2d matrix symbols are processed here + + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + image_width = symbol->width + xoffset + xoffset; + image_height = symbol->height + yoffset + yoffset; + + if (scaler < 2.0) { + scaler = 2.0; + } + scale_width = (image_width * scaler) + 1; + scale_height = (image_height * scaler) + 1; + + /* Apply scale options by creating another pixel buffer */ + if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { + strcpy(symbol->errtxt, "657: Insufficient memory for pixel buffer"); + return ZINT_ERROR_ENCODING_PROBLEM; + } else { + for (i = 0; i < (scale_width * scale_height); i++) { + *(scaled_pixelbuf + i) = '0'; + } + } + + /* Plot the body of the symbol to the pixel buffer */ + for (r = 0; r < symbol->rows; r++) { + for (i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, r, i)) { + draw_circle(scaled_pixelbuf, scale_width, scale_height, + (int) ((i + xoffset) * scaler) + (scaler / 2.0), + (int) ((r + yoffset) * scaler) + (scaler / 2.0), + (symbol->dot_size / 2.0) * scaler, + '1'); + } + } + } + + error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type); + free(scaled_pixelbuf); + + return error_number; +} + +int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_type) { + int textdone, main_width, comp_offset, large_bar_count; + char textpart[10], addon[6]; + float addon_text_posn, preset_height, large_bar_height; + int i, r, textoffset, yoffset, xoffset, latch, image_width, image_height; + char *pixelbuf; + int addon_latch = 0, textflags = 0; + int this_row, block_width, plot_height, plot_yposn, textpos; + float row_height, row_posn; + int error_number; + int default_text_posn; + int next_yposn; + float scaler = symbol->scale; + char *scaled_pixelbuf; + int horiz, vert; + int scale_width, scale_height; +#ifndef _MSC_VER + unsigned char local_text[ustrlen(symbol->text) + 1]; +#else + unsigned char* local_text = (unsigned char*) _alloca(ustrlen(symbol->text) + 1); +#endif + + if (symbol->show_hrt != 0) { + /* Copy text from symbol */ + to_latin1(symbol->text, local_text); + } else { + /* No text needed */ + switch (symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CC: + case BARCODE_ISBNX: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + /* For these symbols use dummy text to ensure formatting is done + * properly even if no text is required */ + for (i = 0; i < ustrlen(symbol->text); i++) { + if (symbol->text[i] == '+') { + local_text[i] = '+'; + } else { + local_text[i] = ' '; + } + local_text[ustrlen(symbol->text)] = '\0'; + } + break; + default: + /* For everything else, just remove the text */ + local_text[0] = '\0'; + break; + } + } + + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + row_height = 0; + if (symbol->output_options & SMALL_TEXT) { + textflags = 1; + } else if (symbol->output_options & BOLD_TEXT) { + textflags = 2; + } + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for (i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if (symbol->row_height[i] == 0) { + large_bar_count++; + } + } + + if (large_bar_count == 0) { + symbol->height = preset_height; + large_bar_height = 10; + } else { + large_bar_height = (symbol->height - preset_height) / large_bar_count; + } + + while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch (ustrlen(local_text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + if (is_extendable(symbol->symbology)) { + for (i = 0; i < ustrlen(local_text); i++) { + if (latch == 1) { + addon[r] = local_text[i]; + r++; + } + if (symbol->text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + if (ustrlen(local_text) != 0) { + textoffset = 9; + } else { + textoffset = 0; + } + + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + image_width = 2 * (symbol->width + xoffset + xoffset); + image_height = 2 * (symbol->height + textoffset + yoffset + yoffset); + + if (!(pixelbuf = (char *) malloc(image_width * image_height))) { + strcpy(symbol->errtxt, "658: Insufficient memory for pixel buffer"); + return ZINT_ERROR_ENCODING_PROBLEM; + } else { + for (i = 0; i < (image_width * image_height); i++) { + *(pixelbuf + i) = '0'; + } + } + + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + default_text_posn = image_height - 17; + } else { + default_text_posn = image_height - 17 - symbol->border_width - symbol->border_width; + } + + row_posn = textoffset + yoffset; + next_yposn = textoffset + yoffset; + row_height = 0; + + /* Plot the body of the symbol to the pixel buffer */ + for (r = 0; r < symbol->rows; r++) { + this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */ + row_posn += row_height; + plot_yposn = next_yposn; + if (symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + next_yposn = (int) (row_posn + row_height); + plot_height = next_yposn - plot_yposn; + + i = 0; + if (module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while ((i + block_width < symbol->width )&& module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if ((addon_latch == 0) && (r == 0) && (i > main_width)) { + plot_height = (int) (row_height - 5.0); + plot_yposn = (int) (row_posn - 5.0); + addon_text_posn = row_posn + row_height - 8.0; + addon_latch = 1; + } + if (latch == 1) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + + xoffset += comp_offset; + + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch (ustrlen(local_text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + for (i = 0; i < 4; i++) { + textpart[i] = local_text[i]; + } + textpart[4] = '\0'; + textpos = 2 * (17 + xoffset); + + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + for (i = 0; i < 4; i++) { + textpart[i] = local_text[i + 4]; + } + textpart[4] = '\0'; + textpos = 2 * (50 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 86); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 100); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + } + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + + textpart[0] = local_text[0]; + textpart[1] = '\0'; + textpos = 2 * (-7 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[6] = '\0'; + textpos = 2 * (24 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 7]; + } + textpart[6] = '\0'; + textpos = 2 * (71 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 114); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 128); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + } + break; + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if (latch == 1) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if (latch == 1) { + /* a bar */ + draw_bar(pixelbuf, (i + xoffset - comp_offset) * 2, block_width * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + textpos = 2 * (-5 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + for (i = 0; i < 5; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[5] = '\0'; + textpos = 2 * (27 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + for (i = 0; i < 5; i++) { + textpart[i] = local_text[i + 6]; + } + textpart[6] = '\0'; + textpos = 2 * (68 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + textpart[0] = local_text[11]; + textpart[1] = '\0'; + textpos = 2 * (100 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 116); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 130); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + } + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + draw_bar(pixelbuf, (0 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height); + + textpart[0] = local_text[0]; + textpart[1] = '\0'; + textpos = 2 * (-5 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[6] = '\0'; + textpos = 2 * (24 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + textpart[0] = local_text[7]; + textpart[1] = '\0'; + textpos = 2 * (55 + xoffset); + draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = 2 * (xoffset + 70); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + case 5: + textpos = 2 * (xoffset + 84); + draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height); + break; + } + + } + + xoffset -= comp_offset; + + /* Put boundary bars or box around symbol */ + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + /* boundary bars */ + if (symbol->symbology != BARCODE_CODABLOCKF) { + draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height); + draw_bar(pixelbuf, 0, (symbol->width + xoffset + xoffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height); + } else { + draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height); + draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height); + } + if ((symbol->output_options & BARCODE_BIND) != 0) { + if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + if (symbol->symbology != BARCODE_CODABLOCKF) { + for (r = 1; r < symbol->rows; r++) { + draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height); + } + } else { + for (r = 1; r < symbol->rows; r++) { + draw_bar(pixelbuf, (xoffset + 11) * 2 , (symbol->width - 25) * 2, ((r * row_height) + textoffset + yoffset - 1) * 2, 2 * 2, image_width, image_height); + } + } + } + } + } + + if (symbol->output_options & BARCODE_BOX) { + /* side bars */ + draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); + draw_bar(pixelbuf, (symbol->width + xoffset + xoffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height); + } + + /* Put the human readable text at the bottom */ + if ((textdone == 0) && (ustrlen(local_text) != 0)) { + textpos = (image_width / 2); + draw_string(pixelbuf, (char*) local_text, textpos, default_text_posn, textflags, image_width, image_height); + } + + + if (scaler == 0) { + scaler = 0.5; + } + scale_width = image_width * scaler; + scale_height = image_height * scaler; + + /* Apply scale options by creating another pixel buffer */ + if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { + free(pixelbuf); + strcpy(symbol->errtxt, "659: Insufficient memory for pixel buffer"); + return ZINT_ERROR_ENCODING_PROBLEM; + } else { + for (i = 0; i < (scale_width * scale_height); i++) { + *(scaled_pixelbuf + i) = '0'; + } + } + + for (vert = 0; vert < scale_height; vert++) { + for (horiz = 0; horiz < scale_width; horiz++) { + *(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int) (vert / scaler) * image_width) + (int) (horiz / scaler)); + } + } + + error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type); + free(scaled_pixelbuf); + free(pixelbuf); + return error_number; +} + +int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type) { + int error; + +#ifdef NO_PNG + if (file_type == OUT_PNG_FILE) { + return ZINT_ERROR_INVALID_OPTION; + } +#endif /* NO_PNG */ + + if (symbol->output_options & BARCODE_DOTTY_MODE) { + error = plot_raster_dotty(symbol, rotate_angle, file_type); + } else { + if (symbol->symbology == BARCODE_MAXICODE) { + error = plot_raster_maxicode(symbol, rotate_angle, file_type); + } else { + error = plot_raster_default(symbol, rotate_angle, file_type); + } + } + + return error; +} diff --git a/3rdparty/zint-2.6.1/backend/reedsol.c b/3rdparty/zint-2.6.1/backend/reedsol.c new file mode 100644 index 0000000..affe150 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/reedsol.c @@ -0,0 +1,164 @@ +/** + + This is a simple Reed-Solomon encoder + (C) Cliff Hones 2004 + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +// It is not written with high efficiency in mind, so is probably +// not suitable for real-time encoding. The aim was to keep it +// simple, general and clear. +// +// + +// Usage: +// First call rs_init_gf(poly) to set up the Galois Field parameters. +// Then call rs_init_code(size, index) to set the encoding size +// Then call rs_encode(datasize, data, out) to encode the data. +// +// These can be called repeatedly as required - but note that +// rs_init_code must be called following any rs_init_gf call. +// +// If the parameters are fixed, some of the statics below can be +// replaced with constants in the obvious way, and additionally +// malloc/free can be avoided by using static arrays of a suitable +// size. + +#include // only needed for debug (main) +#include // only needed for malloc/free +#include "reedsol.h" +static int logmod; // 2**symsize - 1 +static int rlen; + +static int *logt = NULL, *alog = NULL, *rspoly = NULL; + +// rs_init_gf(poly) initialises the parameters for the Galois Field. +// The symbol size is determined from the highest bit set in poly +// This implementation will support sizes up to 30 bits (though that +// will result in very large log/antilog tables) - bit sizes of +// 8 or 4 are typical +// +// The poly is the bit pattern representing the GF characteristic +// polynomial. e.g. for ECC200 (8-bit symbols) the polynomial is +// a**8 + a**5 + a**3 + a**2 + 1, which translates to 0x12d. + +void rs_init_gf(const int poly) { + int m, b, p, v; + + // Find the top bit, and hence the symbol size + for (b = 1, m = 0; b <= poly; b <<= 1) + m++; + b >>= 1; + m--; + + // Calculate the log/alog tables + logmod = (1 << m) - 1; + logt = (int *) malloc(sizeof (int) * (logmod + 1)); + alog = (int *) malloc(sizeof (int) * logmod); + + for (p = 1, v = 0; v < logmod; v++) { + alog[v] = p; + logt[p] = v; + p <<= 1; + if (p & b) + p ^= poly; + } +} + +// rs_init_code(nsym, index) initialises the Reed-Solomon encoder +// nsym is the number of symbols to be generated (to be appended +// to the input data). index is usually 1 - it is the index of +// the constant in the first term (i) of the RS generator polynomial: +// (x + 2**i)*(x + 2**(i+1))*... [nsym terms] +// For ECC200, index is 1. + +void rs_init_code(const int nsym, int index) { + int i, k; + + rspoly = (int *) malloc(sizeof (int) * (nsym + 1)); + + rlen = nsym; + + rspoly[0] = 1; + for (i = 1; i <= nsym; i++) { + rspoly[i] = 1; + for (k = i - 1; k > 0; k--) { + if (rspoly[k]) + rspoly[k] = alog[(logt[rspoly[k]] + index) % logmod]; + rspoly[k] ^= rspoly[k - 1]; + } + rspoly[0] = alog[(logt[rspoly[0]] + index) % logmod]; + index++; + } +} + +void rs_encode(const size_t len,const unsigned char *data, unsigned char *res) { + int i, k, m; + for (i = 0; i < rlen; i++) + res[i] = 0; + for (i = 0; i < len; i++) { + m = res[rlen - 1] ^ data[i]; + for (k = rlen - 1; k > 0; k--) { + if (m && rspoly[k]) + res[k] = (unsigned char) (res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]); + else + res[k] = res[k - 1]; + } + if (m && rspoly[0]) + res[0] = (unsigned char) (alog[(logt[m] + logt[rspoly[0]]) % logmod]); + else + res[0] = 0; + } +} + +/* The same as above but for larger bitlengths - Aztec code compatible */ +void rs_encode_long(const int len, const unsigned int *data, unsigned int *res) { + int i, k, m; + for (i = 0; i < rlen; i++) + res[i] = 0; + for (i = 0; i < len; i++) { + m = res[rlen - 1] ^ data[i]; + for (k = rlen - 1; k > 0; k--) { + if (m && rspoly[k]) + res[k] = res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]; + else + res[k] = res[k - 1]; + } + if (m && rspoly[0]) + res[0] = alog[(logt[m] + logt[rspoly[0]]) % logmod]; + else + res[0] = 0; + } +} + +/* Free memory */ +void rs_free(void) { + free(logt); + free(alog); + free(rspoly); + rspoly = NULL; +} diff --git a/3rdparty/zint-2.6.1/backend/reedsol.h b/3rdparty/zint-2.6.1/backend/reedsol.h new file mode 100644 index 0000000..24e336e --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/reedsol.h @@ -0,0 +1,50 @@ +/* + + This is a simple Reed-Solomon encoder + (C) Cliff Hones 2004 + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + */ + +#ifndef __REEDSOL_H +#define __REEDSOL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern void rs_init_gf(const int poly); +extern void rs_init_code(const int nsym,int index); +extern void rs_encode(const size_t len,const unsigned char *data, unsigned char *res); +extern void rs_encode_long(const int len,const unsigned int *data, unsigned int *res); + extern void rs_free(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __REEDSOL_H */ diff --git a/3rdparty/zint-2.6.1/backend/render.c b/3rdparty/zint-2.6.1/backend/render.c new file mode 100644 index 0000000..9f56b2a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/render.c @@ -0,0 +1,778 @@ +/* + * render.c - Generic Rendered Format + * + * Initiall written by Sam Lown for use in gLabels. Converts encoded + * data into a generic internal structure of lines and characters + * usable in external applications. + */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" + +#define GL_CONST 2.8346 + +struct zint_render_line *render_plot_create_line(float x, float y, float width, float length); +int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line); +struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width); +int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring); +struct zint_render_hexagon *render_plot_create_hexagon(float x, float y); +int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *ring, struct zint_render_hexagon **last_hexagon); + +int render_plot_add_string(struct zint_symbol *symbol, unsigned char *text, float x, float y, float fsize, float width, struct zint_render_string **last_string); + +int render_plot(struct zint_symbol *symbol, const float width, const float height) { + struct zint_render *render; + struct zint_render_line *line, *last_line = NULL; + struct zint_render_string *last_string = NULL; + struct zint_render_ring *ring, *last_ring = NULL; + struct zint_render_hexagon *hexagon, *last_hexagon = NULL; + + int i, r, block_width, latch, this_row; + float textpos, textwidth, large_bar_height, preset_height, row_height, row_posn = 0.0; + // int error_number = 0; + int text_offset, text_height, xoffset, yoffset, textdone, main_symbol_width_x, addon_width_x; + char addon[6], textpart[10]; + int large_bar_count, symbol_lead_in, total_symbol_width_x, total_area_width_x; + float addon_text_posn; + float default_text_posn; + float scaler; + const char *locale = NULL; + int hide_text = 0; + float required_aspect; + float symbol_aspect = 1; + float x_dimension; + int upceanflag = 0; + + // Allocate memory for the rendered version + render = symbol->rendered = (struct zint_render *) malloc(sizeof (struct zint_render)); + if (!symbol->rendered) return ZINT_ERROR_MEMORY; + render->lines = NULL; + render->strings = NULL; + render->rings = NULL; + render->hexagons = NULL; + + locale = setlocale(LC_ALL, "C"); + + row_height = 0; + textdone = 0; + textpos = 0.0; + main_symbol_width_x = symbol->width; + strcpy(addon, ""); + symbol_lead_in = 0; + addon_text_posn = 0.0; + addon_width_x = 0; + + /* + * Determine if there will be any addon texts and text height + */ + latch = 0; + r = 0; + /* Isolate add-on text */ + if (is_extendable(symbol->symbology)) { + for(i = 0; i < (int)ustrlen(symbol->text); i++) { + if (latch == 1) { + addon[r] = symbol->text[i]; + r++; + } + if (symbol->text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + if ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)) { + hide_text = 1; + text_height = text_offset = 0.0; + } else { + text_height = 9.0; + text_offset = 2.0; + } + + + /* + * Calculate the width of the barcode, especially if there are any extra + * borders or white space to add. + */ + + while (!(module_is_set(symbol, symbol->rows - 1, symbol_lead_in))) { + symbol_lead_in++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch (ustrlen(symbol->text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_symbol_width_x = 96 + symbol_lead_in; + upceanflag = 13; + break; + case 2: + main_symbol_width_x = 22 + symbol_lead_in; + upceanflag = 2; + break; + case 5: + main_symbol_width_x = 49 + symbol_lead_in; + upceanflag = 5; + break; + default: + main_symbol_width_x = 68 + symbol_lead_in; + upceanflag = 8; + } + switch (ustrlen(symbol->text)) { + case 11: + case 16: + /* EAN-2 add-on */ + addon_width_x = 31; + break; + case 14: + case 19: + /* EAN-5 add-on */ + addon_width_x = 58; + break; + } + } + else if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + upceanflag = 12; + if (symbol->whitespace_width < 10) { + symbol->whitespace_width = 10; + main_symbol_width_x = 96 + symbol_lead_in; + } + switch (ustrlen(symbol->text)) { + case 15: + /* EAN-2 add-on */ + addon_width_x = 31; + break; + case 18: + /* EAN-5 add-on */ + addon_width_x = 58; + break; + } + } + else if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + upceanflag = 6; + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_symbol_width_x = 51 + symbol_lead_in; + } + switch (ustrlen(symbol->text)) { + case 11: + /* EAN-2 add-on */ + addon_width_x = 31; + break; + case 14: + /* EAN-5 add-on */ + addon_width_x = 58; + break; + } + } + + total_symbol_width_x = 0.0 + main_symbol_width_x + addon_width_x; + total_area_width_x = total_symbol_width_x + (2 * (symbol->border_width + symbol->whitespace_width)); + + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + // Determine if height should be overridden + large_bar_count = 0; + preset_height = 0.0; + for (i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if (symbol->row_height[i] == 0) { + large_bar_count++; + } + } + + if (large_bar_count == 0) { + required_aspect = width / height; + symbol_aspect = (total_symbol_width_x + (2 * xoffset)) / (preset_height + (2 * yoffset) + text_offset + text_height); + symbol->height = (int) preset_height; + if (required_aspect > symbol_aspect) { + /* the area is too wide */ + scaler = height / (preset_height + (2 * yoffset) + text_offset + text_height); + render->width = symbol_aspect * height; + render->height = height; + } else { + /* the area is too high */ + scaler = width / (total_symbol_width_x + (2 * xoffset)); + render->width = width; + render->height = width / symbol_aspect; + } + } else { + scaler = width / (total_symbol_width_x + (2 * xoffset)); + symbol->height = (int) ((height / scaler) - ((2 * yoffset) + text_offset + text_height)); + + render->width = width; + render->height = height; + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler; + } else { + default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler; + } + + x_dimension = render->width / total_area_width_x; + x_dimension /= GL_CONST; + + /* Set minimum size of symbol */ + /* Barcode must be at least 2mm high by 2mm across */ + if (render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST) { + render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST; + } + if (render->width < (2.0 * GL_CONST)) { + render->width = (2.0 * GL_CONST); + } + + if (symbol->symbology == BARCODE_CODABAR) { + /* The minimum X-dimension of Codabar is 0.191mm. The minimum bar height is 5mm */ + if (x_dimension < 0.191) { + render->width = 0.191 * GL_CONST * total_area_width_x; + } + if (render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST) { + render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST; + } + } + else if (symbol->symbology == BARCODE_CODE49) { + /* The minimum X-dimension of Code 49 is 0.191mm */ + if (x_dimension < 0.191) { + render->width = 0.191 * GL_CONST * total_area_width_x; + render->height = render->width / symbol_aspect; + } + } + + if (upceanflag != 0) { + /* The X-dimension of UPC/EAN symbols is fixed at 0.330mm */ + /* NOTE: This code will need adjustment before it correctly deals with composite symbols */ + render->width = 0.330 * GL_CONST * total_area_width_x; + /* The height is also fixed */ + switch (upceanflag) { + case 6: + case 12: + case 13: + /* UPC-A, UPC-E and EAN-13 */ + /* Height of bars should be 22.85mm */ + render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 22.85) * GL_CONST; + break; + case 8: + /* EAN-8 */ + /* Height of bars should be 18.23mm */ + render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 18.23) * GL_CONST; + break; + default: + /* EAN-2 and EAN-5 */ + /* Height of bars should be 21.10mm */ + render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 21.10) * GL_CONST; + } + } + + if (symbol->symbology == BARCODE_ONECODE) { + /* The size of USPS Intelligent Mail barcode is fixed */ + render->width = 0.508 * GL_CONST * total_area_width_x; + render->height = 4.064 * GL_CONST; + } + else if ((symbol->symbology == BARCODE_POSTNET) || (symbol->symbology == BARCODE_PLANET)) { + /* The size of PostNet and PLANET are fized */ + render->width = 0.508 * GL_CONST * total_area_width_x; + render->height = 2.921 * GL_CONST; + } + else if (((symbol->symbology == BARCODE_AUSPOST) || (symbol->symbology == BARCODE_AUSREPLY)) || + ((symbol->symbology == BARCODE_AUSROUTE) || (symbol->symbology == BARCODE_AUSREDIRECT))) { + /* Australia Post use the same sizes as USPS */ + render->width = 0.508 * GL_CONST * total_area_width_x; + render->height = 4.064 * GL_CONST; + } + else if ((symbol->symbology == BARCODE_RM4SCC) || (symbol->symbology == BARCODE_KIX)) { + /* Royal Mail and KIX Code uses 22 bars per inch */ + render->width = 0.577 * GL_CONST * total_area_width_x; + render->height = 5.22 * GL_CONST; + } + + if (symbol->symbology == BARCODE_MAXICODE) { + /* Maxicode is a fixed size */ + scaler = GL_CONST; /* Converts from millimeters to the scale used by glabels */ + render->width = 28.16 * scaler; + render->height = 26.86 * scaler; + + /* Central bullseye pattern */ + ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 0.85 * scaler, 0.67 * scaler); + render_plot_add_ring(symbol, ring, &last_ring); + ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 2.20 * scaler, 0.67 * scaler); + render_plot_add_ring(symbol, ring, &last_ring); + ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 3.54 * scaler, 0.67 * scaler); + render_plot_add_ring(symbol, ring, &last_ring); + + /* Hexagons */ + for (r = 0; r < symbol->rows; r++) { + for (i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, r, i)) { + hexagon = render_plot_create_hexagon(((i * 0.88) + (r & 1 ? 1.76 : 1.32)) * scaler, ((r * 0.76) + 0.76) * scaler); + render_plot_add_hexagon(symbol, hexagon, &last_hexagon); + } + } + } + + } else { + /* everything else uses rectangles (or squares) */ + /* Works from the bottom of the symbol up */ + int addon_latch = 0; + + for (r = 0; r < symbol->rows; r++) { + this_row = r; + if (symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for (i = 0; i < r; i++) { + if (symbol->row_height[i] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[i]; + } + } + row_posn += yoffset; + + i = 0; + if (module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_symbol_width_x)) { + addon_text_posn = row_posn * scaler; + addon_latch = 1; + } + if (latch == 1) { + /* a bar */ + if (addon_latch == 0) { + line = render_plot_create_line((i + xoffset) * scaler, (row_posn) * scaler, block_width * scaler, row_height * scaler); + } else { + line = render_plot_create_line((i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); + } + latch = 0; + + render_plot_add_line(symbol, line, &last_line); + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + } + /* That's done the actual data area, everything else is human-friendly */ + + + /* Add the text */ + xoffset -= symbol_lead_in; + row_posn = (row_posn + large_bar_height) * scaler; + + if (!hide_text) { + if (upceanflag == 8) { + /* guard bar extensions and text formatting for EAN-8 */ + i = 0; + for (line = symbol->rendered->lines; line != NULL; line = line->next) { + switch (i) { + case 0: + case 1: + case 10: + case 11: + case 20: + case 21: + line->length += (5.0 * scaler); + break; + } + i++; + } + + for (i = 0; i < 4; i++) { + textpart[i] = symbol->text[i]; + } + textpart[4] = '\0'; + textpos = 17; + textwidth = 4.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + for (i = 0; i < 4; i++) { + textpart[i] = symbol->text[i + 4]; + } + textpart[4] = '\0'; + textpos = 50; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 86; + textwidth = 2.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + case 5: + textpos = xoffset + 100; + textwidth = 5.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + } + + } + + if (upceanflag == 13) { + /* guard bar extensions and text formatting for EAN-13 */ + i = 0; + for (line = symbol->rendered->lines; line != NULL; line = line->next) { + switch (i) { + case 0: + case 1: + case 14: + case 15: + case 28: + case 29: + line->length += (5.0 * scaler); + break; + } + i++; + } + + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = -5; // 7 + textwidth = 8.5; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + + for (i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + textpos = 25; + textwidth = 6.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + for (i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 7]; + } + textpart[6] = '\0'; + textpos = 72; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 114; + textwidth = 2.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + case 5: + textpos = xoffset + 128; + textwidth = 5.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + } + } + + if (upceanflag == 12) { + /* guard bar extensions and text formatting for UPCA */ + i = 0; + for (line = symbol->rendered->lines; line != NULL; line = line->next) { + switch (i) { + case 0: + case 1: + case 2: + case 3: + case 14: + case 15: + case 26: + case 27: + case 28: + case 29: + line->length += (5.0 * scaler); + break; + } + i++; + } + + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = -5; + textwidth = 6.2; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); + for (i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[5] = '\0'; + textpos = 27; + textwidth = 5.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + for (i = 0; i < 5; i++) { + textpart[i] = symbol->text[i + 6]; + } + textpos = 68; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + textpart[0] = symbol->text[11]; + textpart[1] = '\0'; + textpos = 100; + textwidth = 6.2; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 116; + textwidth = 2.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + case 5: + textpos = xoffset + 130; + textwidth = 5.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + } + } + + if (upceanflag == 6) { + /* guard bar extensions and text formatting for UPCE */ + i = 0; + for (line = symbol->rendered->lines; line != NULL; line = line->next) { + switch (i) { + case 0: + case 1: + case 14: + case 15: + case 16: + line->length += (5.0 * scaler); + break; + } + i++; + } + + textpart[0] = symbol->text[0]; + textpart[1] = '\0'; + textpos = -5; + textwidth = 6.2; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); + for (i = 0; i < 6; i++) { + textpart[i] = symbol->text[i + 1]; + } + textpart[6] = '\0'; + textpos = 24; + textwidth = 6.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string); + textpart[0] = symbol->text[7]; + textpart[1] = '\0'; + textpos = 55; + textwidth = 6.2; + render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 70; + textwidth = 2.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + case 5: + textpos = xoffset + 84; + textwidth = 5.0 * 8.5; + render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string); + break; + } + } + + /* Put normal human readable text at the bottom (and centered) */ + if (textdone == 0) { + // caculate start xoffset to center text + render_plot_add_string(symbol, symbol->text, ((symbol->width / 2.0) + xoffset) * scaler, default_text_posn, 9.0 * scaler, 0.0, &last_string); + } + } + + switch (symbol->symbology) { + case BARCODE_MAXICODE: + /* Do nothing! */ + break; + default: + if ((symbol->output_options & BARCODE_BIND) != 0) { + if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + for (r = 1; r < symbol->rows; r++) { + line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); + render_plot_add_line(symbol, line, &last_line); + } + } + } + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + render_plot_add_line(symbol, line, &last_line); + line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + render_plot_add_line(symbol, line, &last_line); + } + if (symbol->output_options & BARCODE_BOX) { + /* side bars */ + line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + render_plot_add_line(symbol, line, &last_line); + line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + render_plot_add_line(symbol, line, &last_line); + } + break; + } + + if (locale) + setlocale(LC_ALL, locale); + + return 1; +} + +/* + * Create a new line with its memory allocated ready for adding to the + * rendered structure. + * + * This is much quicker than writing out each line manually (in some cases!) + */ +struct zint_render_line *render_plot_create_line(float x, float y, float width, float length) { + struct zint_render_line *line; + + line = (struct zint_render_line*) malloc(sizeof (struct zint_render_line)); + if (!line) return NULL; + + line->next = NULL; + line->x = x; + line->y = y; + line->width = width; + line->length = length; + + return line; +} + +/* + * Add the line to the current rendering and update the last line's + * next value. + */ +int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line) { + if (!line) return ZINT_ERROR_MEMORY; + if (*last_line) + (*last_line)->next = line; + else + symbol->rendered->lines = line; // first line + + *last_line = line; + return 1; +} + +struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width) { + struct zint_render_ring *ring; + + ring = (struct zint_render_ring *) malloc(sizeof (struct zint_render_ring)); + if (!ring) return NULL; + ring->next = NULL; + ring->x = x; + ring->y = y; + ring->radius = radius; + ring->line_width = line_width; + + return ring; +} + +int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring) { + if (!ring) return ZINT_ERROR_MEMORY; + if (*last_ring) + (*last_ring)->next = ring; + else + symbol->rendered->rings = ring; // first ring + + *last_ring = ring; + return 1; +} + +struct zint_render_hexagon *render_plot_create_hexagon(float x, float y) { + struct zint_render_hexagon *hexagon; + + hexagon = (struct zint_render_hexagon*) malloc(sizeof (struct zint_render_hexagon)); + if (!hexagon) return NULL; + hexagon->next = NULL; + hexagon->x = x; + hexagon->y = y; + + return hexagon; +} + +int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *hexagon, struct zint_render_hexagon **last_hexagon) { + if (!hexagon) return ZINT_ERROR_MEMORY; + if (*last_hexagon) + (*last_hexagon)->next = hexagon; + else + symbol->rendered->hexagons = hexagon; // first hexagon + + *last_hexagon = hexagon; + return 1; +} + +/* + * Add a string structure to the symbol. + * Coordinates assumed to be from top-center. + */ +int render_plot_add_string(struct zint_symbol *symbol, + unsigned char *text, float x, float y, float fsize, float width, + struct zint_render_string **last_string) { + struct zint_render_string *string; + + string = (struct zint_render_string*) malloc(sizeof (struct zint_render_string)); + string->next = NULL; + string->x = x; + string->y = y; + string->width = width; + string->fsize = fsize; + string->length = ustrlen(text); + string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1)); + ustrcpy(string->text, text); + + if (*last_string) + (*last_string)->next = string; + else + symbol->rendered->strings = string; // First character + *last_string = string; + + return 1; +} diff --git a/3rdparty/zint-2.6.1/backend/rss.c b/3rdparty/zint-2.6.1/backend/rss.c new file mode 100644 index 0000000..c34b615 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/rss.c @@ -0,0 +1,2307 @@ +/* rss.c - Handles Reduced Space Symbology (GS1 DataBar) */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* The functions "combins" and "getRSSwidths" are copyright BSI and are + released with permission under the following terms: + + "Copyright subsists in all BSI publications. BSI also holds the copyright, in the + UK, of the international standardisation bodies. Except as + permitted under the Copyright, Designs and Patents Act 1988 no extract may be + reproduced, stored in a retrieval system or transmitted in any form or by any + means - electronic, photocopying, recording or otherwise - without prior written + permission from BSI. + + "This does not preclude the free use, in the course of implementing the standard, + of necessary details such as symbols, and size, type or grade designations. If these + details are to be used for any other purpose than implementation then the prior + written permission of BSI must be obtained." + + The date of publication for these functions is 30 November 2006 + */ + +/* Includes numerous bugfixes thanks to Pablo Orduña @ the PIRAmIDE project */ + +/* Note: This code reflects the symbol names as used in ISO/IEC 24724:2006. These names + * were updated in ISO/IEC 24724:2011 as follows: + * + * RSS-14 > GS1 DataBar Omnidirectional + * RSS-14 Truncated > GS1 DataBar Truncated + * RSS-14 Stacked > GS1 DataBar Stacked + * RSS-14 Stacked Omnidirectional > GS1 DataBar Stacked Omnidirectional + * RSS Limited > GS1 DataBar Limited + * RSS Expanded > GS1 DataBar Expanded Omnidirectional + * RSS Expanded Stacked > GS1 DataBar Expanded Stacked Omnidirectional + */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#endif +#include "common.h" +#include "large.h" +#include "rss.h" +#include "gs1.h" + +/********************************************************************** + * combins(n,r): returns the number of Combinations of r selected from n: + * Combinations = n! / ((n - r)! * r!) + **********************************************************************/ +int combins(int n, int r) { + int i, j; + int maxDenom, minDenom; + int val; + + if (n - r > r) { + minDenom = r; + maxDenom = n - r; + } else { + minDenom = n - r; + maxDenom = r; + } + val = 1; + j = 1; + for (i = n; i > maxDenom; i--) { + val *= i; + if (j <= minDenom) { + val /= j; + j++; + } + } + for (; j <= minDenom; j++) { + val /= j; + } + return (val); +} + +/********************************************************************** + * getRSSwidths + * routine to generate widths for RSS elements for a given value.# + * + * Calling arguments: + * val = required value + * n = number of modules + * elements = elements in a set (RSS-14 & Expanded = 4; RSS Limited = 7) + * maxWidth = maximum module width of an element + * noNarrow = 0 will skip patterns without a one module wide element + * + * Return: + * static int widths[] = element widths + **********************************************************************/ +void getRSSwidths(int val, int n, int elements, int maxWidth, int noNarrow) { + int bar; + int elmWidth; + int mxwElement; + int subVal, lessVal; + int narrowMask = 0; + for (bar = 0; bar < elements - 1; bar++) { + for (elmWidth = 1, narrowMask |= (1 << bar); + ; + elmWidth++, narrowMask &= ~(1 << bar)) { + /* get all combinations */ + subVal = combins(n - elmWidth - 1, elements - bar - 2); + /* less combinations with no single-module element */ + if ((!noNarrow) && (!narrowMask) && + (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) { + subVal -= combins(n - elmWidth - (elements - bar), elements - bar - 2); + } + /* less combinations with elements > maxVal */ + if (elements - bar - 1 > 1) { + lessVal = 0; + for (mxwElement = n - elmWidth - (elements - bar - 2); + mxwElement > maxWidth; + mxwElement--) { + lessVal += combins(n - elmWidth - mxwElement - 1, elements - bar - 3); + } + subVal -= lessVal * (elements - 1 - bar); + } else if (n - elmWidth > maxWidth) { + subVal--; + } + val -= subVal; + if (val < 0) break; + } + val += subVal; + n -= elmWidth; + widths[bar] = elmWidth; + } + widths[bar] = n; + return; +} + +/* GS1 DataBar-14 */ +int rss14(struct zint_symbol *symbol, unsigned char source[], int src_len) { + int error_number = 0, i, j, mask; + short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112]; + int data_character[4], data_group[4], v_odd[4], v_even[4]; + int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer; + char latch, hrt[15], temp[32]; + int check_digit, count, separator_row; + + separator_row = 0; + + if (src_len > 13) { + strcpy(symbol->errtxt, "380: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, src_len); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "381: Invalid characters in data"); + return error_number; + } + + /* make some room for a separator row for composite symbols */ + switch (symbol->symbology) { + case BARCODE_RSS14_CC: + case BARCODE_RSS14STACK_CC: + case BARCODE_RSS14_OMNI_CC: + separator_row = symbol->rows; + symbol->row_height[separator_row] = 1; + symbol->rows += 1; + break; + } + + for (i = 0; i < 112; i++) { + accum[i] = 0; + x_reg[i] = 0; + y_reg[i] = 0; + } + + for (i = 0; i < 4; i++) { + data_character[i] = 0; + data_group[i] = 0; + } + + binary_load(accum, (char*) source, src_len); + strcpy(temp, "10000000000000"); + if (symbol->option_1 == 2) { + /* Add symbol linkage flag */ + binary_load(y_reg, temp, strlen(temp)); + binary_add(accum, y_reg); + for (i = 0; i < 112; i++) { + y_reg[i] = 0; + } + } + + /* Calculate left and right pair values */ + strcpy(temp, "4537077"); + binary_load(x_reg, temp, strlen(temp)); + + for (i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for (i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if (y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + for (i = 0; i < 112; i++) { + left_reg[i] = y_reg[i]; + right_reg[i] = accum[i]; + } + + /* Calculate four data characters */ + strcpy(temp, "1597"); + binary_load(x_reg, temp, strlen(temp)); + for (i = 0; i < 112; i++) { + accum[i] = left_reg[i]; + } + + for (i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for (i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if (y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + data_character[0] = 0; + data_character[1] = 0; + mask = 0x2000; + for (i = 13; i >= 0; i--) { + if (y_reg[i] == 1) { + data_character[0] += mask; + } + if (accum[i] == 1) { + data_character[1] += mask; + } + mask = mask >> 1; + } + strcpy(temp, "1597"); + binary_load(x_reg, temp, strlen(temp)); + for (i = 0; i < 112; i++) { + accum[i] = right_reg[i]; + } + + for (i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for (i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if (y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + data_character[2] = 0; + data_character[3] = 0; + mask = 0x2000; + for (i = 13; i >= 0; i--) { + if (y_reg[i] == 1) { + data_character[2] += mask; + } + if (accum[i] == 1) { + data_character[3] += mask; + } + mask = mask >> 1; + } + + /* Calculate odd and even subset values */ + + if ((data_character[0] >= 0) && (data_character[0] <= 160)) { + data_group[0] = 0; + } + if ((data_character[0] >= 161) && (data_character[0] <= 960)) { + data_group[0] = 1; + } + if ((data_character[0] >= 961) && (data_character[0] <= 2014)) { + data_group[0] = 2; + } + if ((data_character[0] >= 2015) && (data_character[0] <= 2714)) { + data_group[0] = 3; + } + if ((data_character[0] >= 2715) && (data_character[0] <= 2840)) { + data_group[0] = 4; + } + if ((data_character[1] >= 0) && (data_character[1] <= 335)) { + data_group[1] = 5; + } + if ((data_character[1] >= 336) && (data_character[1] <= 1035)) { + data_group[1] = 6; + } + if ((data_character[1] >= 1036) && (data_character[1] <= 1515)) { + data_group[1] = 7; + } + if ((data_character[1] >= 1516) && (data_character[1] <= 1596)) { + data_group[1] = 8; + } + if ((data_character[3] >= 0) && (data_character[3] <= 335)) { + data_group[3] = 5; + } + if ((data_character[3] >= 336) && (data_character[3] <= 1035)) { + data_group[3] = 6; + } + if ((data_character[3] >= 1036) && (data_character[3] <= 1515)) { + data_group[3] = 7; + } + if ((data_character[3] >= 1516) && (data_character[3] <= 1596)) { + data_group[3] = 8; + } + if ((data_character[2] >= 0) && (data_character[2] <= 160)) { + data_group[2] = 0; + } + if ((data_character[2] >= 161) && (data_character[2] <= 960)) { + data_group[2] = 1; + } + if ((data_character[2] >= 961) && (data_character[2] <= 2014)) { + data_group[2] = 2; + } + if ((data_character[2] >= 2015) && (data_character[2] <= 2714)) { + data_group[2] = 3; + } + if ((data_character[2] >= 2715) && (data_character[2] <= 2840)) { + data_group[2] = 4; + } + + v_odd[0] = (data_character[0] - g_sum_table[data_group[0]]) / t_table[data_group[0]]; + v_even[0] = (data_character[0] - g_sum_table[data_group[0]]) % t_table[data_group[0]]; + v_odd[1] = (data_character[1] - g_sum_table[data_group[1]]) % t_table[data_group[1]]; + v_even[1] = (data_character[1] - g_sum_table[data_group[1]]) / t_table[data_group[1]]; + v_odd[3] = (data_character[3] - g_sum_table[data_group[3]]) % t_table[data_group[3]]; + v_even[3] = (data_character[3] - g_sum_table[data_group[3]]) / t_table[data_group[3]]; + v_odd[2] = (data_character[2] - g_sum_table[data_group[2]]) / t_table[data_group[2]]; + v_even[2] = (data_character[2] - g_sum_table[data_group[2]]) % t_table[data_group[2]]; + + + /* Use RSS subset width algorithm */ + for (i = 0; i < 4; i++) { + if ((i == 0) || (i == 2)) { + getRSSwidths(v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 1); + data_widths[0][i] = widths[0]; + data_widths[2][i] = widths[1]; + data_widths[4][i] = widths[2]; + data_widths[6][i] = widths[3]; + getRSSwidths(v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 0); + data_widths[1][i] = widths[0]; + data_widths[3][i] = widths[1]; + data_widths[5][i] = widths[2]; + data_widths[7][i] = widths[3]; + } else { + getRSSwidths(v_odd[i], modules_odd[data_group[i]], 4, widest_odd[data_group[i]], 0); + data_widths[0][i] = widths[0]; + data_widths[2][i] = widths[1]; + data_widths[4][i] = widths[2]; + data_widths[6][i] = widths[3]; + getRSSwidths(v_even[i], modules_even[data_group[i]], 4, widest_even[data_group[i]], 1); + data_widths[1][i] = widths[0]; + data_widths[3][i] = widths[1]; + data_widths[5][i] = widths[2]; + data_widths[7][i] = widths[3]; + } + } + + + checksum = 0; + /* Calculate the checksum */ + for (i = 0; i < 8; i++) { + checksum += checksum_weight[i] * data_widths[i][0]; + checksum += checksum_weight[i + 8] * data_widths[i][1]; + checksum += checksum_weight[i + 16] * data_widths[i][2]; + checksum += checksum_weight[i + 24] * data_widths[i][3]; + } + checksum %= 79; + + /* Calculate the two check characters */ + if (checksum >= 8) { + checksum++; + } + if (checksum >= 72) { + checksum++; + } + c_left = checksum / 9; + c_right = checksum % 9; + + /* Put element widths together */ + total_widths[0] = 1; + total_widths[1] = 1; + total_widths[44] = 1; + total_widths[45] = 1; + for (i = 0; i < 8; i++) { + total_widths[i + 2] = data_widths[i][0]; + total_widths[i + 15] = data_widths[7 - i][1]; + total_widths[i + 23] = data_widths[i][3]; + total_widths[i + 36] = data_widths[7 - i][2]; + } + for (i = 0; i < 5; i++) { + total_widths[i + 10] = finder_pattern[i + (5 * c_left)]; + total_widths[i + 31] = finder_pattern[(4 - i) + (5 * c_right)]; + } + + /* Put this data into the symbol */ + if ((symbol->symbology == BARCODE_RSS14) || (symbol->symbology == BARCODE_RSS14_CC)) { + writer = 0; + latch = '0'; + for (i = 0; i < 46; i++) { + for (j = 0; j < total_widths[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } + writer++; + } + if (latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if (symbol->width < writer) { + symbol->width = writer; + } + if (symbol->symbology == BARCODE_RSS14_CC) { + /* separator pattern for composite symbol */ + for (i = 4; i < 92; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + latch = '1'; + for (i = 16; i < 32; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + if (latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + latch = '1'; + for (i = 63; i < 78; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + if (latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + } + symbol->rows = symbol->rows + 1; + + count = 0; + check_digit = 0; + + /* Calculate check digit from Annex A and place human readable text */ + ustrcpy(symbol->text, (unsigned char*) "(01)"); + for (i = 0; i < 14; i++) { + hrt[i] = '0'; + } + for (i = 0; i < src_len; i++) { + hrt[12 - i] = source[src_len - i - 1]; + } + hrt[14] = '\0'; + + for (i = 0; i < 13; i++) { + count += ctoi(hrt[i]); + + if (!(i & 1)) { + count += 2 * (ctoi(hrt[i])); + } + } + + check_digit = 10 - (count % 10); + if (check_digit == 10) { + check_digit = 0; + } + hrt[13] = itoc(check_digit); + + strcat((char*) symbol->text, hrt); + + set_minimum_height(symbol, 14); // Minimum height is 14X for truncated symbol + } + + if ((symbol->symbology == BARCODE_RSS14STACK) || (symbol->symbology == BARCODE_RSS14STACK_CC)) { + /* top row */ + writer = 0; + latch = '0'; + for (i = 0; i < 23; i++) { + for (j = 0; j < total_widths[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } else { + unset_module(symbol, symbol->rows, writer); + } + writer++; + } + if (latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + set_module(symbol, symbol->rows, writer); + unset_module(symbol, symbol->rows, writer + 1); + symbol->row_height[symbol->rows] = 5; + /* bottom row */ + symbol->rows = symbol->rows + 2; + set_module(symbol, symbol->rows, 0); + unset_module(symbol, symbol->rows, 1); + writer = 0; + latch = '1'; + for (i = 23; i < 46; i++) { + for (j = 0; j < total_widths[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer + 2); + } else { + unset_module(symbol, symbol->rows, writer + 2); + } + writer++; + } + if (latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + symbol->row_height[symbol->rows] = 7; + /* separator pattern */ + for (i = 4; i < 46; i++) { + if (module_is_set(symbol, symbol->rows - 2, i) == module_is_set(symbol, symbol->rows, i)) { + if (!(module_is_set(symbol, symbol->rows - 2, i))) { + set_module(symbol, symbol->rows - 1, i); + } + } else { + if (!(module_is_set(symbol, symbol->rows - 1, i - 1))) { + set_module(symbol, symbol->rows - 1, i); + } + } + } + symbol->row_height[symbol->rows - 1] = 1; + if (symbol->symbology == BARCODE_RSS14STACK_CC) { + /* separator pattern for composite symbol */ + for (i = 4; i < 46; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + latch = '1'; + for (i = 16; i < 32; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + if (latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + } + symbol->rows = symbol->rows + 1; + if (symbol->width < 50) { + symbol->width = 50; + } + } + + if ((symbol->symbology == BARCODE_RSS14STACK_OMNI) || (symbol->symbology == BARCODE_RSS14_OMNI_CC)) { + /* top row */ + writer = 0; + latch = '0'; + for (i = 0; i < 23; i++) { + for (j = 0; j < total_widths[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } else { + unset_module(symbol, symbol->rows, writer); + } + writer++; + } + latch = (latch == '1' ? '0' : '1'); + } + set_module(symbol, symbol->rows, writer); + unset_module(symbol, symbol->rows, writer + 1); + /* bottom row */ + symbol->rows = symbol->rows + 4; + set_module(symbol, symbol->rows, 0); + unset_module(symbol, symbol->rows, 1); + writer = 0; + latch = '1'; + for (i = 23; i < 46; i++) { + for (j = 0; j < total_widths[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer + 2); + } else { + unset_module(symbol, symbol->rows, writer + 2); + } + writer++; + } + if (latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + /* middle separator */ + for (i = 5; i < 46; i += 2) { + set_module(symbol, symbol->rows - 2, i); + } + symbol->row_height[symbol->rows - 2] = 1; + /* top separator */ + for (i = 4; i < 46; i++) { + if (!(module_is_set(symbol, symbol->rows - 4, i))) { + set_module(symbol, symbol->rows - 3, i); + } + } + latch = '1'; + for (i = 17; i < 33; i++) { + if (!(module_is_set(symbol, symbol->rows - 4, i))) { + if (latch == '1') { + set_module(symbol, symbol->rows - 3, i); + latch = '0'; + } else { + unset_module(symbol, symbol->rows - 3, i); + latch = '1'; + } + } else { + unset_module(symbol, symbol->rows - 3, i); + latch = '1'; + } + } + symbol->row_height[symbol->rows - 3] = 1; + /* bottom separator */ + for (i = 4; i < 46; i++) { + if (!(module_is_set(symbol, symbol->rows, i))) { + set_module(symbol, symbol->rows - 1, i); + } + } + latch = '1'; + for (i = 16; i < 32; i++) { + if (!(module_is_set(symbol, symbol->rows, i))) { + if (latch == '1') { + set_module(symbol, symbol->rows - 1, i); + latch = '0'; + } else { + unset_module(symbol, symbol->rows - 1, i); + latch = '1'; + } + } else { + unset_module(symbol, symbol->rows - 1, i); + latch = '1'; + } + } + symbol->row_height[symbol->rows - 1] = 1; + if (symbol->width < 50) { + symbol->width = 50; + } + if (symbol->symbology == BARCODE_RSS14_OMNI_CC) { + /* separator pattern for composite symbol */ + for (i = 4; i < 46; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + latch = '1'; + for (i = 16; i < 32; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + if (latch == '1') { + set_module(symbol, separator_row, i); + latch = '0'; + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } else { + unset_module(symbol, separator_row, i); + latch = '1'; + } + } + } + symbol->rows = symbol->rows + 1; + + set_minimum_height(symbol, 33); + } + + + return error_number; +} + +/* GS1 DataBar Limited */ +int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) { + int error_number = 0, i, mask; + short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112]; + int left_group, right_group, left_odd, left_even, right_odd, right_even; + int left_character, right_character, left_widths[14], right_widths[14]; + int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count; + char latch, hrt[15], temp[32]; + int separator_row; + + separator_row = 0; + + if (src_len > 13) { + strcpy(symbol->errtxt, "382: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + error_number = is_sane(NEON, source, src_len); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "383: Invalid characters in data"); + return error_number; + } + if (src_len == 13) { + if ((source[0] != '0') && (source[0] != '1')) { + strcpy(symbol->errtxt, "384: Input out of range"); + return ZINT_ERROR_INVALID_DATA; + } + } + + /* make some room for a separator row for composite symbols */ + if (symbol->symbology == BARCODE_RSS_LTD_CC) { + separator_row = symbol->rows; + symbol->row_height[separator_row] = 1; + symbol->rows += 1; + } + + for (i = 0; i < 112; i++) { + accum[i] = 0; + x_reg[i] = 0; + y_reg[i] = 0; + } + + binary_load(accum, (char*) source, src_len); + if (symbol->option_1 == 2) { + /* Add symbol linkage flag */ + strcpy(temp, "2015133531096"); + binary_load(y_reg, temp, strlen(temp)); + binary_add(accum, y_reg); + for (i = 0; i < 112; i++) { + y_reg[i] = 0; + } + } + + /* Calculate left and right pair values */ + strcpy(temp, "2013571"); + binary_load(x_reg, temp, strlen(temp)); + + for (i = 0; i < 24; i++) { + shiftup(x_reg); + } + + for (i = 24; i >= 0; i--) { + y_reg[i] = islarger(accum, x_reg); + if (y_reg[i] == 1) { + binary_subtract(accum, x_reg); + } + shiftdown(x_reg); + } + + for (i = 0; i < 112; i++) { + left_reg[i] = y_reg[i]; + right_reg[i] = accum[i]; + } + + left_group = 0; + strcpy(temp, "183063"); + binary_load(accum, temp, strlen(temp)); + if (islarger(left_reg, accum)) { + left_group = 1; + } + strcpy(temp, "820063"); + binary_load(accum, temp, strlen(temp)); + if (islarger(left_reg, accum)) { + left_group = 2; + } + strcpy(temp, "1000775"); + binary_load(accum, temp, strlen(temp)); + if (islarger(left_reg, accum)) { + left_group = 3; + } + strcpy(temp, "1491020"); + binary_load(accum, temp, strlen(temp)); + if (islarger(left_reg, accum)) { + left_group = 4; + } + strcpy(temp, "1979844"); + binary_load(accum, temp, strlen(temp)); + if (islarger(left_reg, accum)) { + left_group = 5; + } + strcpy(temp, "1996938"); + binary_load(accum, temp, strlen(temp)); + if (islarger(left_reg, accum)) { + left_group = 6; + } + right_group = 0; + strcpy(temp, "183063"); + binary_load(accum, temp, strlen(temp)); + if (islarger(right_reg, accum)) { + right_group = 1; + } + strcpy(temp, "820063"); + binary_load(accum, temp, strlen(temp)); + if (islarger(right_reg, accum)) { + right_group = 2; + } + strcpy(temp, "1000775"); + binary_load(accum, temp, strlen(temp)); + if (islarger(right_reg, accum)) { + right_group = 3; + } + strcpy(temp, "1491020"); + binary_load(accum, temp, strlen(temp)); + if (islarger(right_reg, accum)) { + right_group = 4; + } + strcpy(temp, "1979844"); + binary_load(accum, temp, strlen(temp)); + if (islarger(right_reg, accum)) { + right_group = 5; + } + strcpy(temp, "1996938"); + binary_load(accum, temp, strlen(temp)); + if (islarger(right_reg, accum)) { + right_group = 6; + } + + switch (left_group) { + case 1: strcpy(temp, "183064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 2: strcpy(temp, "820064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 3: strcpy(temp, "1000776"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 4: strcpy(temp, "1491021"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 5: strcpy(temp, "1979845"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + case 6: strcpy(temp, "1996939"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(left_reg, accum); + break; + } + + switch (right_group) { + case 1: strcpy(temp, "183064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 2: strcpy(temp, "820064"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 3: strcpy(temp, "1000776"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 4: strcpy(temp, "1491021"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 5: strcpy(temp, "1979845"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + case 6: strcpy(temp, "1996939"); + binary_load(accum, temp, strlen(temp)); + binary_subtract(right_reg, accum); + break; + } + + left_character = 0; + right_character = 0; + mask = 0x800000; + for (i = 23; i >= 0; i--) { + if (left_reg[i] == 1) { + left_character += mask; + } + if (right_reg[i] == 1) { + right_character += mask; + } + mask = mask >> 1; + } + + left_odd = left_character / t_even_ltd[left_group]; + left_even = left_character % t_even_ltd[left_group]; + right_odd = right_character / t_even_ltd[right_group]; + right_even = right_character % t_even_ltd[right_group]; + + getRSSwidths(left_odd, modules_odd_ltd[left_group], 7, widest_odd_ltd[left_group], 1); + left_widths[0] = widths[0]; + left_widths[2] = widths[1]; + left_widths[4] = widths[2]; + left_widths[6] = widths[3]; + left_widths[8] = widths[4]; + left_widths[10] = widths[5]; + left_widths[12] = widths[6]; + getRSSwidths(left_even, modules_even_ltd[left_group], 7, widest_even_ltd[left_group], 0); + left_widths[1] = widths[0]; + left_widths[3] = widths[1]; + left_widths[5] = widths[2]; + left_widths[7] = widths[3]; + left_widths[9] = widths[4]; + left_widths[11] = widths[5]; + left_widths[13] = widths[6]; + getRSSwidths(right_odd, modules_odd_ltd[right_group], 7, widest_odd_ltd[right_group], 1); + right_widths[0] = widths[0]; + right_widths[2] = widths[1]; + right_widths[4] = widths[2]; + right_widths[6] = widths[3]; + right_widths[8] = widths[4]; + right_widths[10] = widths[5]; + right_widths[12] = widths[6]; + getRSSwidths(right_even, modules_even_ltd[right_group], 7, widest_even_ltd[right_group], 0); + right_widths[1] = widths[0]; + right_widths[3] = widths[1]; + right_widths[5] = widths[2]; + right_widths[7] = widths[3]; + right_widths[9] = widths[4]; + right_widths[11] = widths[5]; + right_widths[13] = widths[6]; + + checksum = 0; + /* Calculate the checksum */ + for (i = 0; i < 14; i++) { + checksum += checksum_weight_ltd[i] * left_widths[i]; + checksum += checksum_weight_ltd[i + 14] * right_widths[i]; + } + checksum %= 89; + + for (i = 0; i < 14; i++) { + check_elements[i] = finder_pattern_ltd[i + (checksum * 14)]; + } + + total_widths[0] = 1; + total_widths[1] = 1; + total_widths[44] = 1; + total_widths[45] = 1; + for (i = 0; i < 14; i++) { + total_widths[i + 2] = left_widths[i]; + total_widths[i + 16] = check_elements[i]; + total_widths[i + 30] = right_widths[i]; + } + + writer = 0; + latch = '0'; + for (i = 0; i < 46; i++) { + for (j = 0; j < total_widths[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } else { + unset_module(symbol, symbol->rows, writer); + } + writer++; + } + latch = (latch == '1' ? '0' : '1'); + } + if (symbol->width < writer) { + symbol->width = writer; + } + symbol->rows = symbol->rows + 1; + + /* add separator pattern if composite symbol */ + if (symbol->symbology == BARCODE_RSS_LTD_CC) { + for (i = 4; i < 70; i++) { + if (!(module_is_set(symbol, separator_row + 1, i))) { + set_module(symbol, separator_row, i); + } + } + } + + /* Calculate check digit from Annex A and place human readable text */ + + check_digit = 0; + count = 0; + + ustrcpy(symbol->text, (unsigned char*) "(01)"); + for (i = 0; i < 14; i++) { + hrt[i] = '0'; + } + for (i = 0; i < src_len; i++) { + hrt[12 - i] = source[src_len - i - 1]; + } + + for (i = 0; i < 13; i++) { + count += ctoi(hrt[i]); + + if (!(i & 1)) { + count += 2 * (ctoi(hrt[i])); + } + } + + check_digit = 10 - (count % 10); + if (check_digit == 10) { + check_digit = 0; + } + + hrt[13] = itoc(check_digit); + hrt[14] = '\0'; + + strcat((char*) symbol->text, hrt); + + set_minimum_height(symbol, 10); + + return error_number; +} + +/* Attempts to apply encoding rules from secions 7.2.5.5.1 to 7.2.5.5.3 + * of ISO/IEC 24724:2006 */ +int general_rules(char field[], char type[]) { + + int block[2][200], block_count, i, j, k; + char current, next, last; + + block_count = 0; + + block[0][block_count] = 1; + block[1][block_count] = type[0]; + + for (i = 1; i < strlen(type); i++) { + current = type[i]; + last = type[i - 1]; + + if (current == last) { + block[0][block_count] = block[0][block_count] + 1; + } else { + block_count++; + block[0][block_count] = 1; + block[1][block_count] = type[i]; + } + } + + block_count++; + + for (i = 0; i < block_count; i++) { + current = block[1][i]; + next = (block[1][i + 1] & 0xFF); + + if ((current == ISOIEC) && (i != (block_count - 1))) { + if ((next == ANY_ENC) && (block[0][i + 1] >= 4)) { + block[1][i + 1] = NUMERIC; + } + if ((next == ANY_ENC) && (block[0][i + 1] < 4)) { + block[1][i + 1] = ISOIEC; + } + if ((next == ALPHA_OR_ISO) && (block[0][i + 1] >= 5)) { + block[1][i + 1] = ALPHA; + } + if ((next == ALPHA_OR_ISO) && (block[0][i + 1] < 5)) { + block[1][i + 1] = ISOIEC; + } + } + + if (current == ALPHA_OR_ISO) { + block[1][i] = ALPHA; + current = ALPHA; + } + + if ((current == ALPHA) && (i != (block_count - 1))) { + if ((next == ANY_ENC) && (block[0][i + 1] >= 6)) { + block[1][i + 1] = NUMERIC; + } + if ((next == ANY_ENC) && (block[0][i + 1] < 6)) { + if ((i == block_count - 2) && (block[0][i + 1] >= 4)) { + block[1][i + 1] = NUMERIC; + } else { + block[1][i + 1] = ALPHA; + } + } + } + + if (current == ANY_ENC) { + block[1][i] = NUMERIC; + } + } + + if (block_count > 1) { + i = 1; + while (i < block_count) { + if (block[1][i - 1] == block[1][i]) { + /* bring together */ + block[0][i - 1] = block[0][i - 1] + block[0][i]; + j = i + 1; + + /* decreace the list */ + while (j < block_count) { + block[0][j - 1] = block[0][j]; + block[1][j - 1] = block[1][j]; + j++; + } + block_count--; + i--; + } + i++; + } + } + + for (i = 0; i < block_count - 1; i++) { + if ((block[1][i] == NUMERIC) && (block[0][i] & 1)) { + /* Odd size numeric block */ + block[0][i] = block[0][i] - 1; + block[0][i + 1] = block[0][i + 1] + 1; + } + } + + j = 0; + for (i = 0; i < block_count; i++) { + for (k = 0; k < block[0][i]; k++) { + type[j] = block[1][i]; + j++; + } + } + + if ((block[1][block_count - 1] == NUMERIC) && (block[0][block_count - 1] & 1)) { + /* If the last block is numeric and an odd size, further + processing needs to be done outside this procedure */ + return 1; + } else { + return 0; + } +} + +/* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */ +int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) { + int encoding_method, i, j, read_posn, latch, debug = symbol->debug, last_mode = ISOIEC; + int symbol_characters, characters_per_row; +#ifndef _MSC_VER + char general_field[strlen(source) + 1], general_field_type[strlen(source) + 1]; +#else + char* general_field = (char*) _alloca(strlen(source) + 1); + char* general_field_type = (char*) _alloca(strlen(source) + 1); +#endif + int remainder, d1, d2; + char padstring[40]; + + read_posn = 0; + + /* Decide whether a compressed data field is required and if so what + method to use - method 2 = no compressed data field */ + + if ((strlen(source) >= 16) && ((source[0] == '0') && (source[1] == '1'))) { + /* (01) and other AIs */ + encoding_method = 1; + if (debug) printf("Choosing Method 1\n"); + } else { + /* any AIs */ + encoding_method = 2; + if (debug) printf("Choosing Mehod 2\n"); + } + + if (((strlen(source) >= 20) && (encoding_method == 1)) && ((source[2] == '9') && (source[16] == '3'))) { + /* Possibly encoding method > 2 */ + if (debug) printf("Checking for other methods\n"); + + if ((strlen(source) >= 26) && (source[17] == '1')) { + /* Methods 3, 7, 9, 11 and 13 */ + + if (source[18] == '0') { + /* (01) and (310x) */ + char weight_str[7]; + float weight; /* In kilos */ + + for (i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + + if (weight_str[0] == '0') { /* Maximum weight = 99999 */ + + + encoding_method = 7; + + if ((source[19] == '3') && (strlen(source) == 26)) { + /* (01) and (3103) */ + weight = atof(weight_str) / 1000.0; + + if (weight <= 32.767) { + encoding_method = 3; + } + } + + if (strlen(source) == 34) { + if ((source[26] == '1') && (source[27] == '1')) { + /* (01), (310x) and (11) - metric weight and production date */ + encoding_method = 7; + } + + if ((source[26] == '1') && (source[27] == '3')) { + /* (01), (310x) and (13) - metric weight and packaging date */ + encoding_method = 9; + } + + if ((source[26] == '1') && (source[27] == '5')) { + /* (01), (310x) and (15) - metric weight and "best before" date */ + encoding_method = 11; + } + + if ((source[26] == '1') && (source[27] == '7')) { + /* (01), (310x) and (17) - metric weight and expiration date */ + encoding_method = 13; + } + } + } + } + if (debug) printf("Now using method %d\n", encoding_method); + } + + if ((strlen(source) >= 26) && (source[17] == '2')) { + /* Methods 4, 8, 10, 12 and 14 */ + + if (source[18] == '0') { + /* (01) and (320x) */ + char weight_str[7]; + float weight; /* In pounds */ + + for (i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + + if (weight_str[0] == '0') { /* Maximum weight = 99999 */ + + encoding_method = 8; + + if (((source[19] == '2') || (source[19] == '3')) && (strlen(source) == 26)) { + /* (01) and (3202)/(3203) */ + + if (source[19] == '3') { + weight = (float) (atof(weight_str) / 1000.0F); + if (weight <= 22.767) { + encoding_method = 4; + } + } else { + weight = (float) (atof(weight_str) / 100.0F); + if (weight <= 99.99) { + encoding_method = 4; + } + } + + } + + if (strlen(source) == 34) { + if ((source[26] == '1') && (source[27] == '1')) { + /* (01), (320x) and (11) - English weight and production date */ + encoding_method = 8; + } + + if ((source[26] == '1') && (source[27] == '3')) { + /* (01), (320x) and (13) - English weight and packaging date */ + encoding_method = 10; + } + + if ((source[26] == '1') && (source[27] == '5')) { + /* (01), (320x) and (15) - English weight and "best before" date */ + encoding_method = 12; + } + + if ((source[26] == '1') && (source[27] == '7')) { + /* (01), (320x) and (17) - English weight and expiration date */ + encoding_method = 14; + } + } + } + } + if (debug) printf("Now using method %d\n", encoding_method); + + } + + if (source[17] == '9') { + /* Methods 5 and 6 */ + if ((source[18] == '2') && ((source[19] >= '0') && (source[19] <= '3'))) { + /* (01) and (392x) */ + encoding_method = 5; + } + if ((source[18] == '3') && ((source[19] >= '0') && (source[19] <= '3'))) { + /* (01) and (393x) */ + encoding_method = 6; + } + if (debug) printf("Now using method %d\n", encoding_method); + } + } + + switch (encoding_method) { /* Encoding method - Table 10 */ + case 1: strcat(binary_string, "1XX"); + read_posn = 16; + break; + case 2: strcat(binary_string, "00XX"); + read_posn = 0; + break; + case 3: // 0100 + case 4: // 0101 + bin_append(4 + (encoding_method - 3), 4, binary_string); + read_posn = strlen(source); + break; + case 5: strcat(binary_string, "01100XX"); + read_posn = 20; + break; + case 6: strcat(binary_string, "01101XX"); + read_posn = 23; + break; + default: /* modes 7 to 14 */ + bin_append(56 + (encoding_method - 7), 7, binary_string); + read_posn = strlen(source); + break; + } + if (debug) printf("Setting binary = %s\n", binary_string); + + /* Variable length symbol bit field is just given a place holder (XX) + for the time being */ + + /* Verify that the data to be placed in the compressed data field is all + numeric data before carrying out compression */ + for (i = 0; i < read_posn; i++) { + if ((source[i] < '0') || (source[i] > '9')) { + if ((source[i] != '[') && (source[i] != ']')) { + /* Something is wrong */ + strcpy(symbol->errtxt, "385: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + } + } + + /* Now encode the compressed data field */ + + if (debug) printf("Proceeding to encode data\n"); + if (encoding_method == 1) { + /* Encoding method field "1" - general item identification data */ + char group[4]; + + group[0] = source[2]; + group[1] = '\0'; + + bin_append(atoi(group), 4, binary_string); + + for (i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + + bin_append(atoi(group), 10, binary_string); + } + } + + if ((encoding_method == 3) || (encoding_method == 4)) { + /* Encoding method field "0100" - variable weight item + (0,001 kilogram icrements) */ + /* Encoding method field "0101" - variable weight item (0,01 or + 0,001 pound increment) */ + char group[4]; + char weight_str[7]; + + for (i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + + bin_append(atoi(group), 10, binary_string); + } + + for (i = 0; i < 6; i++) { + weight_str[i] = source[20 + i]; + } + weight_str[6] = '\0'; + + if ((encoding_method == 4) && (source[19] == '3')) { + bin_append(atoi(weight_str) + 10000, 15, binary_string); + } else { + bin_append(atoi(weight_str), 15, binary_string); + } + } + + if ((encoding_method == 5) || (encoding_method == 6)) { + /* Encoding method "01100" - variable measure item and price */ + /* Encoding method "01101" - variable measure item and price with ISO 4217 + Currency Code */ + + char group[4]; + + for (i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + + bin_append(atoi(group), 10, binary_string); + } + + bin_append(source[19] - '0', 2, binary_string); + + if (encoding_method == 6) { + char currency_str[5]; + + for (i = 0; i < 3; i++) { + currency_str[i] = source[20 + i]; + } + currency_str[3] = '\0'; + + bin_append(atoi(currency_str), 10, binary_string); + } + } + + if ((encoding_method >= 7) && (encoding_method <= 14)) { + /* Encoding method fields "0111000" through "0111111" - variable + weight item plus date */ + char group[4]; + int group_val; + char weight_str[8]; + char date_str[4]; + + for (i = 1; i < 5; i++) { + group[0] = source[(i * 3)]; + group[1] = source[(i * 3) + 1]; + group[2] = source[(i * 3) + 2]; + group[3] = '\0'; + + bin_append(atoi(group), 10, binary_string); + } + + weight_str[0] = source[19]; + + for (i = 0; i < 5; i++) { + weight_str[i + 1] = source[21 + i]; + } + weight_str[6] = '\0'; + + bin_append(atoi(weight_str), 20, binary_string); + + if (strlen(source) == 34) { + /* Date information is included */ + date_str[0] = source[28]; + date_str[1] = source[29]; + date_str[2] = '\0'; + group_val = atoi(date_str) * 384; + + date_str[0] = source[30]; + date_str[1] = source[31]; + group_val += (atoi(date_str) - 1) * 32; + + date_str[0] = source[32]; + date_str[1] = source[33]; + group_val += atoi(date_str); + } else { + group_val = 38400; + } + + bin_append(group_val, 16, binary_string); + } + + /* The compressed data field has been processed if appropriate - the + rest of the data (if any) goes into a general-purpose data compaction field */ + + j = 0; + for (i = read_posn; i < strlen(source); i++) { + general_field[j] = source[i]; + j++; + } + general_field[j] = '\0'; + if (debug) printf("General field data = %s\n", general_field); + + latch = 0; + for (i = 0; i < strlen(general_field); i++) { + /* Table 13 - ISO/IEC 646 encodation */ + if ((general_field[i] < ' ') || (general_field[i] > 'z')) { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } else { + general_field_type[i] = ISOIEC; + } + + if (general_field[i] == '#') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == '$') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == '@') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == 92) { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == '^') { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + if (general_field[i] == 96) { + general_field_type[i] = INVALID_CHAR; + latch = 1; + } + + /* Table 12 - Alphanumeric encodation */ + if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '*') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == ',') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '-') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '.') { + general_field_type[i] = ALPHA_OR_ISO; + } + if (general_field[i] == '/') { + general_field_type[i] = ALPHA_OR_ISO; + } + + /* Numeric encodation */ + if ((general_field[i] >= '0') && (general_field[i] <= '9')) { + general_field_type[i] = ANY_ENC; + } + if (general_field[i] == '[') { + /* FNC1 can be encoded in any system */ + general_field_type[i] = ANY_ENC; + } + } + + general_field_type[strlen(general_field)] = '\0'; + if (debug) printf("General field type: %s\n", general_field_type); + + if (latch == 1) { + /* Invalid characters in input data */ + strcpy(symbol->errtxt, "386: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + + for (i = 0; i < strlen(general_field); i++) { + if ((general_field_type[i] == ISOIEC) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ISOIEC; + } + } + + for (i = 0; i < strlen(general_field); i++) { + if ((general_field_type[i] == ALPHA_OR_ISO) && (general_field[i + 1] == '[')) { + general_field_type[i + 1] = ALPHA_OR_ISO; + } + } + + latch = general_rules(general_field, general_field_type); + if (debug) printf("General field type: %s\n", general_field_type); + + last_mode = NUMERIC; + + /* Set initial mode if not NUMERIC */ + if (general_field_type[0] == ALPHA) { + bin_append(0, 4, binary_string); /* Alphanumeric latch */ + last_mode = ALPHA; + } + if (general_field_type[0] == ISOIEC) { + bin_append(0, 4, binary_string); /* Alphanumeric latch */ + bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */ + last_mode = ISOIEC; + } + + i = 0; + do { + if (debug) printf("Processing character %d ", i); + switch (general_field_type[i]) { + case NUMERIC: + if (debug) printf("as NUMERIC:"); + + if (last_mode != NUMERIC) { + bin_append(0, 3, binary_string); /* Numeric latch */ + if (debug) printf("\n"); + } + + if (debug) printf(" %c%c > ", general_field[i], general_field[i + 1]); + if (general_field[i] != '[') { + d1 = ctoi(general_field[i]); + } else { + d1 = 10; + } + + if (general_field[i + 1] != '[') { + d2 = ctoi(general_field[i + 1]); + } else { + d2 = 10; + } + + bin_append((11 * d1) + d2 + 8, 7, binary_string); + + i += 2; + if (debug) printf("\n"); + last_mode = NUMERIC; + break; + + case ALPHA: + if (debug) printf("as ALPHA\n"); + if (i != 0) { + if (last_mode == NUMERIC) { + bin_append(0, 4, binary_string); /* Alphanumeric latch */ + } + if (last_mode == ISOIEC) { + bin_append(4, 5, binary_string); /* Alphanumeric latch */ + } + } + + if ((general_field[i] >= '0') && (general_field[i] <= '9')) { + bin_append(general_field[i] - 43, 5, binary_string); + } + + if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + bin_append(general_field[i] - 33, 6, binary_string); + } + + last_mode = ALPHA; + + if (general_field[i] == '[') { + bin_append(15, 5, binary_string); + last_mode = NUMERIC; + } /* FNC1/Numeric latch */ + + if (general_field[i] == '*') bin_append(58, 6, binary_string); /* asterisk */ + if (general_field[i] == ',') bin_append(59, 6, binary_string); /* comma */ + if (general_field[i] == '-') bin_append(60, 6, binary_string); /* minus or hyphen */ + if (general_field[i] == '.') bin_append(61, 6, binary_string); /* period or full stop */ + if (general_field[i] == '/') bin_append(62, 6, binary_string); /* slash or solidus */ + + i++; + break; + + case ISOIEC: + if (debug) printf("as ISOIEC\n"); + if (i != 0) { + if (last_mode == NUMERIC) { + bin_append(0, 4, binary_string); /* Alphanumeric latch */ + bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */ + } + if (last_mode == ALPHA) { + bin_append(4, 5, binary_string); /* ISO/IEC 646 latch */ + } + } + + if ((general_field[i] >= '0') && (general_field[i] <= '9')) { + bin_append(general_field[i] - 43, 5, binary_string); + } + + if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) { + bin_append(general_field[i] - 1, 7, binary_string); + } + + if ((general_field[i] >= 'a') && (general_field[i] <= 'z')) { + bin_append(general_field[i] - 7, 7, binary_string); + } + last_mode = ISOIEC; + + if (general_field[i] == '[') { + bin_append(15, 5, binary_string); + last_mode = NUMERIC; + } /* FNC1/Numeric latch */ + + if (general_field[i] == '!') bin_append(232, 8, binary_string); /* exclamation mark */ + if (general_field[i] == 34) bin_append(233, 8, binary_string); /* quotation mark */ + if (general_field[i] == 37) bin_append(234, 8, binary_string); /* percent sign */ + if (general_field[i] == '&') bin_append(235, 8, binary_string); /* ampersand */ + if (general_field[i] == 39) bin_append(236, 8, binary_string); /* apostrophe */ + if (general_field[i] == '(') bin_append(237, 8, binary_string); /* left parenthesis */ + if (general_field[i] == ')') bin_append(238, 8, binary_string); /* right parenthesis */ + if (general_field[i] == '*') bin_append(239, 8, binary_string); /* asterisk */ + if (general_field[i] == '+') bin_append(240, 8, binary_string); /* plus sign */ + if (general_field[i] == ',') bin_append(241, 8, binary_string); /* comma */ + if (general_field[i] == '-') bin_append(242, 8, binary_string); /* minus or hyphen */ + if (general_field[i] == '.') bin_append(243, 8, binary_string); /* period or full stop */ + if (general_field[i] == '/') bin_append(244, 8, binary_string); /* slash or solidus */ + if (general_field[i] == ':') bin_append(245, 8, binary_string); /* colon */ + if (general_field[i] == ';') bin_append(246, 8, binary_string); /* semicolon */ + if (general_field[i] == '<') bin_append(247, 8, binary_string); /* less-than sign */ + if (general_field[i] == '=') bin_append(248, 8, binary_string); /* equals sign */ + if (general_field[i] == '>') bin_append(249, 8, binary_string); /* greater-than sign */ + if (general_field[i] == '?') bin_append(250, 8, binary_string); /* question mark */ + if (general_field[i] == '_') bin_append(251, 8, binary_string); /* underline or low line */ + if (general_field[i] == ' ') bin_append(252, 8, binary_string); /* space */ + + i++; + break; + } + } while (i + latch < strlen(general_field)); + if (debug) printf("Resultant binary = %s\n", binary_string); + if (debug) printf("\tLength: %d\n", (int) strlen(binary_string)); + + remainder = 12 - (strlen(binary_string) % 12); + if (remainder == 12) { + remainder = 0; + } + symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1; + + if ((symbol->symbology == BARCODE_RSS_EXPSTACK) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) { + characters_per_row = symbol->option_2 * 2; + + if ((characters_per_row < 2) || (characters_per_row > 20)) { + characters_per_row = 4; + } + + if ((symbol_characters % characters_per_row) == 1) { + symbol_characters++; + } + + if (symbol_characters < 4) { + symbol_characters = 4; + } + } + + if (symbol_characters < 3) { + symbol_characters = 3; + } + + remainder = (12 * (symbol_characters - 1)) - strlen(binary_string); + + if (latch == 1) { + /* There is still one more numeric digit to encode */ + if (debug) printf("Adding extra (odd) numeric digit\n"); + + if (last_mode == NUMERIC) { + if ((remainder >= 4) && (remainder <= 6)) { + bin_append(ctoi(general_field[i]) + 1, 4, binary_string); + } else { + d1 = ctoi(general_field[i]); + d2 = 10; + + bin_append((11 * d1) + d2 + 8, 7, binary_string); + } + } else { + bin_append(general_field[i] - 43, 5, binary_string); + } + + remainder = 12 - (strlen(binary_string) % 12); + if (remainder == 12) { + remainder = 0; + } + symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1; + + if ((symbol->symbology == BARCODE_RSS_EXPSTACK) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) { + characters_per_row = symbol->option_2 * 2; + + if ((characters_per_row < 2) || (characters_per_row > 20)) { + characters_per_row = 4; + } + + if ((symbol_characters % characters_per_row) == 1) { + symbol_characters++; + } + + if (symbol_characters < 4) { + symbol_characters = 4; + } + } + + if (symbol_characters < 3) { + symbol_characters = 3; + } + + remainder = (12 * (symbol_characters - 1)) - strlen(binary_string); + + if (debug) printf("Resultant binary = %s\n", binary_string); + if (debug) printf("\tLength: %d\n", (int) strlen(binary_string)); + } + + if (strlen(binary_string) > 252) { + strcpy(symbol->errtxt, "387: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + + /* Now add padding to binary string (7.2.5.5.4) */ + i = remainder; + if ((strlen(general_field) != 0) && (last_mode == NUMERIC)) { + strcpy(padstring, "0000"); + i -= 4; + } else { + strcpy(padstring, ""); + } + for (; i > 0; i -= 5) { + strcat(padstring, "00100"); + } + + padstring[remainder] = '\0'; + strcat(binary_string, padstring); + + /* Patch variable length symbol bit field */ + d1 = symbol_characters & 1; + + if (symbol_characters <= 14) { + d2 = 0; + } else { + d2 = 1; + } + + if (encoding_method == 1) { + binary_string[2] = d1 ? '1' : '0'; + binary_string[3] = d2 ? '1' : '0'; + } + if (encoding_method == 2) { + binary_string[3] = d1 ? '1' : '0'; + binary_string[4] = d2 ? '1' : '0'; + } + if ((encoding_method == 5) || (encoding_method == 6)) { + binary_string[6] = d1 ? '1' : '0'; + binary_string[7] = d2 ? '1' : '0'; + } + if (debug) printf("Resultant binary = %s\n", binary_string); + if (debug) printf("\tLength: %d\n", (int) strlen(binary_string)); + return 0; +} + +/* GS1 DataBar Expanded */ +int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) { + int i, j, k, p, data_chars, vs[21], group[21], v_odd[21], v_even[21]; + char substring[21][14], latch; + int char_widths[21][8], checksum, check_widths[8], c_group; + int check_char, c_odd, c_even, elements[235], pattern_width, reader, writer; + int row, elements_in_sub, special_case_row, left_to_right; + int codeblocks, sub_elements[235], stack_rows, current_row, current_block; + int separator_row; +#ifndef _MSC_VER + char reduced[src_len + 1], binary_string[(7 * src_len) + 1]; +#else + char* reduced = (char*) _alloca(src_len + 1); + char* binary_string = (char*) _alloca((7 * src_len) + 1); +#endif + + separator_row = 0; + reader = 0; + + if (symbol->input_mode != GS1_MODE) { + /* GS1 data has not been verified yet */ + i = gs1_verify(symbol, source, src_len, reduced); + if (i != 0) { + return i; + } + } + + if ((symbol->symbology == BARCODE_RSS_EXP_CC) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) { + /* make space for a composite separator pattern */ + separator_row = symbol->rows; + symbol->row_height[separator_row] = 1; + symbol->rows += 1; + } + + strcpy(binary_string, ""); + + if (symbol->option_1 == 2) { + strcat(binary_string, "1"); + } else { + strcat(binary_string, "0"); + } + + i = rss_binary_string(symbol, reduced, binary_string); + if (i != 0) { + return i; + } + + data_chars = strlen(binary_string) / 12; + + for (i = 0; i < data_chars; i++) { + for (j = 0; j < 12; j++) { + substring[i][j] = binary_string[(i * 12) + j]; + } + substring[i][12] = '\0'; + } + + for (i = 0; i < data_chars; i++) { + vs[i] = 0; + for (p = 0; p < 12; p++) { + if (substring[i][p] == '1') { + vs[i] += (0x800 >> p); + } + } + } + + for (i = 0; i < data_chars; i++) { + if (vs[i] <= 347) { + group[i] = 1; + } + if ((vs[i] >= 348) && (vs[i] <= 1387)) { + group[i] = 2; + } + if ((vs[i] >= 1388) && (vs[i] <= 2947)) { + group[i] = 3; + } + if ((vs[i] >= 2948) && (vs[i] <= 3987)) { + group[i] = 4; + } + if (vs[i] >= 3988) { + group[i] = 5; + } + v_odd[i] = (vs[i] - g_sum_exp[group[i] - 1]) / t_even_exp[group[i] - 1]; + v_even[i] = (vs[i] - g_sum_exp[group[i] - 1]) % t_even_exp[group[i] - 1]; + + getRSSwidths(v_odd[i], modules_odd_exp[group[i] - 1], 4, widest_odd_exp[group[i] - 1], 0); + char_widths[i][0] = widths[0]; + char_widths[i][2] = widths[1]; + char_widths[i][4] = widths[2]; + char_widths[i][6] = widths[3]; + getRSSwidths(v_even[i], modules_even_exp[group[i] - 1], 4, widest_even_exp[group[i] - 1], 1); + char_widths[i][1] = widths[0]; + char_widths[i][3] = widths[1]; + char_widths[i][5] = widths[2]; + char_widths[i][7] = widths[3]; + } + + /* 7.2.6 Check character */ + /* The checksum value is equal to the mod 211 residue of the weighted sum of the widths of the + elements in the data characters. */ + checksum = 0; + for (i = 0; i < data_chars; i++) { + row = weight_rows[(((data_chars - 2) / 2) * 21) + i]; + for (j = 0; j < 8; j++) { + checksum += (char_widths[i][j] * checksum_weight_exp[(row * 8) + j]); + + } + } + + check_char = (211 * ((data_chars + 1) - 4)) + (checksum % 211); + + if (check_char <= 347) { + c_group = 1; + } + if ((check_char >= 348) && (check_char <= 1387)) { + c_group = 2; + } + if ((check_char >= 1388) && (check_char <= 2947)) { + c_group = 3; + } + if ((check_char >= 2948) && (check_char <= 3987)) { + c_group = 4; + } + if (check_char >= 3988) { + c_group = 5; + } + + c_odd = (check_char - g_sum_exp[c_group - 1]) / t_even_exp[c_group - 1]; + c_even = (check_char - g_sum_exp[c_group - 1]) % t_even_exp[c_group - 1]; + + getRSSwidths(c_odd, modules_odd_exp[c_group - 1], 4, widest_odd_exp[c_group - 1], 0); + check_widths[0] = widths[0]; + check_widths[2] = widths[1]; + check_widths[4] = widths[2]; + check_widths[6] = widths[3]; + getRSSwidths(c_even, modules_even_exp[c_group - 1], 4, widest_even_exp[c_group - 1], 1); + check_widths[1] = widths[0]; + check_widths[3] = widths[1]; + check_widths[5] = widths[2]; + check_widths[7] = widths[3]; + + /* Initialise element array */ + pattern_width = ((((data_chars + 1) / 2) + ((data_chars + 1) & 1)) * 5) + ((data_chars + 1) * 8) + 4; + for (i = 0; i < pattern_width; i++) { + elements[i] = 0; + } + + /* Put finder patterns in element array */ + for (i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) & 1)); i++) { + k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 1) * 11) + i; + for (j = 0; j < 5; j++) { + elements[(21 * i) + j + 10] = finder_pattern_exp[((finder_sequence[k] - 1) * 5) + j]; + } + } + + /* Put check character in element array */ + for (i = 0; i < 8; i++) { + elements[i + 2] = check_widths[i]; + } + + /* Put forward reading data characters in element array */ + for (i = 1; i < data_chars; i += 2) { + for (j = 0; j < 8; j++) { + elements[(((i - 1) / 2) * 21) + 23 + j] = char_widths[i][j]; + } + } + + /* Put reversed data characters in element array */ + for (i = 0; i < data_chars; i += 2) { + for (j = 0; j < 8; j++) { + elements[((i / 2) * 21) + 15 + j] = char_widths[i][7 - j]; + } + } + + if ((symbol->symbology == BARCODE_RSS_EXP) || (symbol->symbology == BARCODE_RSS_EXP_CC)) { + /* Copy elements into symbol */ + + elements[0] = 1; // left guard + elements[1] = 1; + + elements[pattern_width - 2] = 1; // right guard + elements[pattern_width - 1] = 1; + + writer = 0; + latch = '0'; + for (i = 0; i < pattern_width; i++) { + for (j = 0; j < elements[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } else { + unset_module(symbol, symbol->rows, writer); + } + writer++; + } + if (latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if (symbol->width < writer) { + symbol->width = writer; + } + symbol->rows = symbol->rows + 1; + if (symbol->symbology == BARCODE_RSS_EXP_CC) { + for (j = 4; j < (symbol->width - 4); j++) { + if (module_is_set(symbol, separator_row + 1, j)) { + unset_module(symbol, separator_row, j); + } else { + set_module(symbol, separator_row, j); + } + } + /* finder bar adjustment */ + for (j = 0; j < (writer / 49); j++) { + k = (49 * j) + 18; + for (i = 0; i < 15; i++) { + if ((!(module_is_set(symbol, separator_row + 1, i + k - 1))) && + (!(module_is_set(symbol, separator_row + 1, i + k))) && + module_is_set(symbol, separator_row, i + k - 1)) { + unset_module(symbol, separator_row, i + k); + } + } + } + } + + /* Add human readable text */ + for (i = 0; i <= src_len; i++) { + if ((source[i] != '[') && (source[i] != ']')) { + symbol->text[i] = source[i]; + } else { + if (source[i] == '[') { + symbol->text[i] = '('; + } + if (source[i] == ']') { + symbol->text[i] = ')'; + } + } + } + + } else { + /* RSS Expanded Stacked */ + + /* Bug corrected: Character missing for message + * [01]90614141999996[10]1234222222222221 + * Patch by Daniel Frede + */ + codeblocks = (data_chars + 1) / 2 + ((data_chars + 1) % 2); + + + if ((symbol->option_2 < 1) || (symbol->option_2 > 10)) { + symbol->option_2 = 2; + } + if ((symbol->option_1 == 2) && (symbol->option_2 == 1)) { + /* "There shall be a minimum of four symbol characters in the + first row of an RSS Expanded Stacked symbol when it is the linear + component of an EAN.UCC Composite symbol." */ + symbol->option_2 = 2; + } + + stack_rows = codeblocks / symbol->option_2; + if (codeblocks % symbol->option_2 > 0) { + stack_rows++; + } + + current_block = 0; + for (current_row = 1; current_row <= stack_rows; current_row++) { + for (i = 0; i < 235; i++) { + sub_elements[i] = 0; + } + special_case_row = 0; + + /* Row Start */ + sub_elements[0] = 1; // left guard + sub_elements[1] = 1; + elements_in_sub = 2; + + /* Row Data */ + reader = 0; + do { + if (((symbol->option_2 & 1) || (current_row & 1)) || + ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) && + (((current_row * symbol->option_2) - codeblocks) & 1))) { + /* left to right */ + left_to_right = 1; + i = 2 + (current_block * 21); + for (j = 0; j < 21; j++) { + if ((i + j) < pattern_width) { + sub_elements[j + (reader * 21) + 2] = elements[i + j]; + } + elements_in_sub++; + } + } else { + /* right to left */ + left_to_right = 0; + i = 2 + (((current_row * symbol->option_2) - reader - 1) * 21); + for (j = 0; j < 21; j++) { + if ((i + j) < pattern_width) { + sub_elements[(20 - j) + (reader * 21) + 2] = elements[i + j]; + } + elements_in_sub++; + } + } + reader++; + current_block++; + } while ((reader < symbol->option_2) && (current_block < codeblocks)); + + /* Row Stop */ + sub_elements[elements_in_sub] = 1; // right guard + sub_elements[elements_in_sub + 1] = 1; + elements_in_sub += 2; + + latch = current_row & 1 ? '0' : '1'; + + if ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) && + ((current_row & 1) == 0) && ((symbol->option_2 & 1) == 0)) { + /* Special case bottom row */ + special_case_row = 1; + sub_elements[0] = 2; + latch = '0'; + } + + writer = 0; + for (i = 0; i < elements_in_sub; i++) { + for (j = 0; j < sub_elements[i]; j++) { + if (latch == '1') { + set_module(symbol, symbol->rows, writer); + } else { + unset_module(symbol, symbol->rows, writer); + } + writer++; + } + if (latch == '1') { + latch = '0'; + } else { + latch = '1'; + } + } + if (symbol->width < writer) { + symbol->width = writer; + } + + if (current_row != 1) { + /* middle separator pattern (above current row) */ + for (j = 5; j < (49 * symbol->option_2); j += 2) { + set_module(symbol, symbol->rows - 2, j); + } + symbol->row_height[symbol->rows - 2] = 1; + /* bottom separator pattern (above current row) */ + for (j = 4; j < (writer - 4); j++) { + if (module_is_set(symbol, symbol->rows, j)) { + unset_module(symbol, symbol->rows - 1, j); + } else { + set_module(symbol, symbol->rows - 1, j); + } + } + symbol->row_height[symbol->rows - 1] = 1; + /* finder bar adjustment */ + for (j = 0; j < reader; j++) { + k = (49 * j) + 18 + special_case_row; + if (left_to_right) { + for (i = 0; i < 15; i++) { + if ((!(module_is_set(symbol, symbol->rows, i + k - 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows - 1, i + k - 1)) { + unset_module(symbol, symbol->rows - 1, i + k); + } + } + } else { + if ((current_row == stack_rows) && (data_chars % 2 == 0)) { + k -= 18; + } + for (i = 14; i >= 0; i--) { + if ((!(module_is_set(symbol, symbol->rows, i + k + 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows - 1, i + k + 1)) { + unset_module(symbol, symbol->rows - 1, i + k); + } + } + } + } + } + + if (current_row != stack_rows) { + /* top separator pattern (below current row) */ + for (j = 4; j < (writer - 4); j++) { + if (module_is_set(symbol, symbol->rows, j)) { + unset_module(symbol, symbol->rows + 1, j); + } else { + set_module(symbol, symbol->rows + 1, j); + } + } + symbol->row_height[symbol->rows + 1] = 1; + /* finder bar adjustment */ + for (j = 0; j < reader; j++) { + k = (49 * j) + 18; + if (left_to_right) { + for (i = 0; i < 15; i++) { + if ((!(module_is_set(symbol, symbol->rows, i + k - 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows + 1, i + k - 1)) { + unset_module(symbol, symbol->rows + 1, i + k); + } + } + } else { + for (i = 14; i >= 0; i--) { + if ((!(module_is_set(symbol, symbol->rows, i + k + 1))) && + (!(module_is_set(symbol, symbol->rows, i + k))) && + module_is_set(symbol, symbol->rows + 1, i + k + 1)) { + unset_module(symbol, symbol->rows + 1, i + k); + } + } + } + } + } + + symbol->rows = symbol->rows + 4; + } + symbol->rows = symbol->rows - 3; + if (symbol->symbology == BARCODE_RSS_EXPSTACK_CC) { + for (j = 4; j < (symbol->width - 4); j++) { + if (module_is_set(symbol, separator_row + 1, j)) { + unset_module(symbol, separator_row, j); + } else { + set_module(symbol, separator_row, j); + } + } + /* finder bar adjustment */ + for (j = 0; j < reader; j++) { + k = (49 * j) + 18; + for (i = 0; i < 15; i++) { + if ((!(module_is_set(symbol, separator_row + 1, i + k - 1))) && + (!(module_is_set(symbol, separator_row + 1, i + k))) && + module_is_set(symbol, separator_row, i + k - 1)) { + unset_module(symbol, separator_row, i + k); + } + } + } + } + + } + + for (i = 0; i < symbol->rows; i++) { + if (symbol->row_height[i] == 0) { + symbol->row_height[i] = 34; + } + } + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/rss.h b/3rdparty/zint-2.6.1/backend/rss.h new file mode 100644 index 0000000..ae47d99 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/rss.h @@ -0,0 +1,298 @@ +/* rss.h - Data tables for Reduced Space Symbology */ + +/* + libzint - the open source barcode library + Copyright (C) 2007-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define NUMERIC 110 +#define ALPHA 97 +#define ISOIEC 105 +#define INVALID_CHAR 100 +#define ANY_ENC 120 +#define ALPHA_OR_ISO 121 + +/* RSS-14 Tables */ +static const unsigned short int g_sum_table[9] = { + 0, 161, 961, 2015, 2715, 0, 336, 1036, 1516 +}; + +static const char t_table[9] = { + 1, 10, 34, 70, 126, 4, 20, 48, 81 +}; + +static const char modules_odd[9] = { + 12, 10, 8, 6, 4, 5, 7, 9, 11 +}; + +static const char modules_even[9] = { + 4, 6, 8, 10, 12, 10, 8, 6, 4 +}; + +static const char widest_odd[9] = { + 8, 6, 4, 3, 1, 2, 4, 6, 8 +}; + +static const char widest_even[9] = { + 1, 3, 5, 6, 8, 7, 5, 3, 1 +}; + +static int widths[8]; +static const char finder_pattern[45] = { + 3, 8, 2, 1, 1, + 3, 5, 5, 1, 1, + 3, 3, 7, 1, 1, + 3, 1, 9, 1, 1, + 2, 7, 4, 1, 1, + 2, 5, 6, 1, 1, + 2, 3, 8, 1, 1, + 1, 5, 7, 1, 1, + 1, 3, 9, 1, 1 +}; + +static const char checksum_weight[32] = { + /* Table 5 */ + 1, 3, 9, 27, 2, 6, 18, 54, + 4, 12, 36, 29, 8, 24, 72, 58, + 16, 48, 65, 37, 32, 17, 51, 74, + 64, 34, 23, 69, 49, 68, 46, 59 +}; + +/* RSS Limited Tables */ +static const unsigned short int t_even_ltd[7] = { + 28, 728, 6454, 203, 2408, 1, 16632 +}; + +static const char modules_odd_ltd[7] = { + 17, 13, 9, 15, 11, 19, 7 +}; + +static const char modules_even_ltd[7] = { + 9, 13, 17, 11, 15, 7, 19 +}; + +static const char widest_odd_ltd[7] = { + 6, 5, 3, 5, 4, 8, 1 +}; + +static const char widest_even_ltd[7] = { + 3, 4, 6, 4, 5, 1, 8 +}; + +static const char checksum_weight_ltd[28] = { + /* Table 7 */ + 1, 3, 9, 27, 81, 65, 17, 51, 64, 14, 42, 37, 22, 66, + 20, 60, 2, 6, 18, 54, 73, 41, 34, 13, 39, 28, 84, 74 +}; + +static const char finder_pattern_ltd[1246] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, + 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 3, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, + 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, + 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, + 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, + 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, + 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, + 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1 +}; + +/* RSS Expanded Tables */ +static const unsigned short int g_sum_exp[5] = { + 0, 348, 1388, 2948, 3988 +}; + +static const unsigned short int t_even_exp[5] = { + 4, 20, 52, 104, 204 +}; + +static const char modules_odd_exp[5] = { + 12, 10, 8, 6, 4 +}; + +static const char modules_even_exp[5] = { + 5, 7, 9, 11, 13 +}; + +static const char widest_odd_exp[5] = { + 7, 5, 4, 3, 1 +}; + +static const char widest_even_exp[5] = { + 2, 4, 5, 6, 8 +}; + +static const unsigned short int checksum_weight_exp[184] = { + /* Table 14 */ + 1, 3, 9, 27, 81, 32, 96, 77, + 20, 60, 180, 118, 143, 7, 21, 63, + 189, 145, 13, 39, 117, 140, 209, 205, + 193, 157, 49, 147, 19, 57, 171, 91, + 62, 186, 136, 197, 169, 85, 44, 132, + 185, 133, 188, 142, 4, 12, 36, 108, + 113, 128, 173, 97, 80, 29, 87, 50, + 150, 28, 84, 41, 123, 158, 52, 156, + 46, 138, 203, 187, 139, 206, 196, 166, + 76, 17, 51, 153, 37, 111, 122, 155, + 43, 129, 176, 106, 107, 110, 119, 146, + 16, 48, 144, 10, 30, 90, 59, 177, + 109, 116, 137, 200, 178, 112, 125, 164, + 70, 210, 208, 202, 184, 130, 179, 115, + 134, 191, 151, 31, 93, 68, 204, 190, + 148, 22, 66, 198, 172, 94, 71, 2, + 6, 18, 54, 162, 64, 192, 154, 40, + 120, 149, 25, 75, 14, 42, 126, 167, + 79, 26, 78, 23, 69, 207, 199, 175, + 103, 98, 83, 38, 114, 131, 182, 124, + 161, 61, 183, 127, 170, 88, 53, 159, + 55, 165, 73, 8, 24, 72, 5, 15, + 45, 135, 194, 160, 58, 174, 100, 89 +}; + +static const char finder_pattern_exp[60] = { + /* Table 15 */ + 1, 8, 4, 1, 1, + 1, 1, 4, 8, 1, + 3, 6, 4, 1, 1, + 1, 1, 4, 6, 3, + 3, 4, 6, 1, 1, + 1, 1, 6, 4, 3, + 3, 2, 8, 1, 1, + 1, 1, 8, 2, 3, + 2, 6, 5, 1, 1, + 1, 1, 5, 6, 2, + 2, 2, 9, 1, 1, + 1, 1, 9, 2, 2 +}; + +static const char finder_sequence[198] = { + /* Table 16 */ + 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 6, 3, 8, 0, 0, 0, 0, 0, 0, 0, + 1, 10, 3, 8, 5, 0, 0, 0, 0, 0, 0, + 1, 10, 3, 8, 7, 12, 0, 0, 0, 0, 0, + 1, 10, 3, 8, 9, 12, 11, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 10, 9, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 0, + 1, 2, 3, 4, 5, 8, 7, 10, 9, 12, 11 +}; + +static const char weight_rows[210] = { + 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 10, 3, 4, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 3, 4, 13, 14, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 3, 4, 13, 14, 11, 12, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 18, 3, 4, 13, 14, 15, 16, 21, 22, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 15, 16, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 21, 22, 19, 20 +}; diff --git a/3rdparty/zint-2.6.1/backend/sjis.h b/3rdparty/zint-2.6.1/backend/sjis.h new file mode 100644 index 0000000..629d3e1 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/sjis.h @@ -0,0 +1,6886 @@ +/* sjis.h - Unicode to Shift JIS lookup table + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +/* Derived from : +## Shift_JIS (JIS X 0208:1997 Appendix 1) vs Unicode mapping table +## +## Date: 06 Mar 2002 06:01:22 GMT +## License: +## Copyright (C) 2001 earthian@tama.or.jp, All Rights Reserved. +## Copyright (C) 2001 I'O, All Rights Reserved. +## You can use, modify, distribute this table freely. + */ + +static const unsigned short int sjis_lookup[] = { + 0x005C, 0x815F, // REVERSE SOLIDUS + 0x00A2, 0x8191, // CENT SIGN + 0x00A3, 0x8192, // POUND SIGN + 0x00A7, 0x8198, // SECTION SIGN + 0x00A8, 0x814E, // DIAERESIS + 0x00AC, 0x81CA, // NOT SIGN + 0x00B0, 0x818B, // DEGREE SIGN + 0x00B1, 0x817D, // PLUS-MINUS SIGN + 0x00B4, 0x814C, // ACUTE ACCENT + 0x00B6, 0x81F7, // PILCROW SIGN + 0x00D7, 0x817E, // MULTIPLICATION SIGN + 0x00F7, 0x8180, // DIVISION SIGN + 0x0391, 0x839F, // GREEK CAPITAL LETTER ALPHA + 0x0392, 0x83A0, // GREEK CAPITAL LETTER BETA + 0x0393, 0x83A1, // GREEK CAPITAL LETTER GAMMA + 0x0394, 0x83A2, // GREEK CAPITAL LETTER DELTA + 0x0395, 0x83A3, // GREEK CAPITAL LETTER EPSILON + 0x0396, 0x83A4, // GREEK CAPITAL LETTER ZETA + 0x0397, 0x83A5, // GREEK CAPITAL LETTER ETA + 0x0398, 0x83A6, // GREEK CAPITAL LETTER THETA + 0x0399, 0x83A7, // GREEK CAPITAL LETTER IOTA + 0x039A, 0x83A8, // GREEK CAPITAL LETTER KAPPA + 0x039B, 0x83A9, // GREEK CAPITAL LETTER LAMDA + 0x039C, 0x83AA, // GREEK CAPITAL LETTER MU + 0x039D, 0x83AB, // GREEK CAPITAL LETTER NU + 0x039E, 0x83AC, // GREEK CAPITAL LETTER XI + 0x039F, 0x83AD, // GREEK CAPITAL LETTER OMICRON + 0x03A0, 0x83AE, // GREEK CAPITAL LETTER PI + 0x03A1, 0x83AF, // GREEK CAPITAL LETTER RHO + 0x03A3, 0x83B0, // GREEK CAPITAL LETTER SIGMA + 0x03A4, 0x83B1, // GREEK CAPITAL LETTER TAU + 0x03A5, 0x83B2, // GREEK CAPITAL LETTER UPSILON + 0x03A6, 0x83B3, // GREEK CAPITAL LETTER PHI + 0x03A7, 0x83B4, // GREEK CAPITAL LETTER CHI + 0x03A8, 0x83B5, // GREEK CAPITAL LETTER PSI + 0x03A9, 0x83B6, // GREEK CAPITAL LETTER OMEGA + 0x03B1, 0x83BF, // GREEK SMALL LETTER ALPHA + 0x03B2, 0x83C0, // GREEK SMALL LETTER BETA + 0x03B3, 0x83C1, // GREEK SMALL LETTER GAMMA + 0x03B4, 0x83C2, // GREEK SMALL LETTER DELTA + 0x03B5, 0x83C3, // GREEK SMALL LETTER EPSILON + 0x03B6, 0x83C4, // GREEK SMALL LETTER ZETA + 0x03B7, 0x83C5, // GREEK SMALL LETTER ETA + 0x03B8, 0x83C6, // GREEK SMALL LETTER THETA + 0x03B9, 0x83C7, // GREEK SMALL LETTER IOTA + 0x03BA, 0x83C8, // GREEK SMALL LETTER KAPPA + 0x03BB, 0x83C9, // GREEK SMALL LETTER LAMDA + 0x03BC, 0x83CA, // GREEK SMALL LETTER MU + 0x03BD, 0x83CB, // GREEK SMALL LETTER NU + 0x03BE, 0x83CC, // GREEK SMALL LETTER XI + 0x03BF, 0x83CD, // GREEK SMALL LETTER OMICRON + 0x03C0, 0x83CE, // GREEK SMALL LETTER PI + 0x03C1, 0x83CF, // GREEK SMALL LETTER RHO + 0x03C3, 0x83D0, // GREEK SMALL LETTER SIGMA + 0x03C4, 0x83D1, // GREEK SMALL LETTER TAU + 0x03C5, 0x83D2, // GREEK SMALL LETTER UPSILON + 0x03C6, 0x83D3, // GREEK SMALL LETTER PHI + 0x03C7, 0x83D4, // GREEK SMALL LETTER CHI + 0x03C8, 0x83D5, // GREEK SMALL LETTER PSI + 0x03C9, 0x83D6, // GREEK SMALL LETTER OMEGA + 0x0401, 0x8446, // CYRILLIC CAPITAL LETTER IO + 0x0410, 0x8440, // CYRILLIC CAPITAL LETTER A + 0x0411, 0x8441, // CYRILLIC CAPITAL LETTER BE + 0x0412, 0x8442, // CYRILLIC CAPITAL LETTER VE + 0x0413, 0x8443, // CYRILLIC CAPITAL LETTER GHE + 0x0414, 0x8444, // CYRILLIC CAPITAL LETTER DE + 0x0415, 0x8445, // CYRILLIC CAPITAL LETTER IE + 0x0416, 0x8447, // CYRILLIC CAPITAL LETTER ZHE + 0x0417, 0x8448, // CYRILLIC CAPITAL LETTER ZE + 0x0418, 0x8449, // CYRILLIC CAPITAL LETTER I + 0x0419, 0x844A, // CYRILLIC CAPITAL LETTER SHORT I + 0x041A, 0x844B, // CYRILLIC CAPITAL LETTER KA + 0x041B, 0x844C, // CYRILLIC CAPITAL LETTER EL + 0x041C, 0x844D, // CYRILLIC CAPITAL LETTER EM + 0x041D, 0x844E, // CYRILLIC CAPITAL LETTER EN + 0x041E, 0x844F, // CYRILLIC CAPITAL LETTER O + 0x041F, 0x8450, // CYRILLIC CAPITAL LETTER PE + 0x0420, 0x8451, // CYRILLIC CAPITAL LETTER ER + 0x0421, 0x8452, // CYRILLIC CAPITAL LETTER ES + 0x0422, 0x8453, // CYRILLIC CAPITAL LETTER TE + 0x0423, 0x8454, // CYRILLIC CAPITAL LETTER U + 0x0424, 0x8455, // CYRILLIC CAPITAL LETTER EF + 0x0425, 0x8456, // CYRILLIC CAPITAL LETTER HA + 0x0426, 0x8457, // CYRILLIC CAPITAL LETTER TSE + 0x0427, 0x8458, // CYRILLIC CAPITAL LETTER CHE + 0x0428, 0x8459, // CYRILLIC CAPITAL LETTER SHA + 0x0429, 0x845A, // CYRILLIC CAPITAL LETTER SHCHA + 0x042B, 0x845C, // CYRILLIC CAPITAL LETTER YERU + 0x042C, 0x845D, // CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042D, 0x845E, // CYRILLIC CAPITAL LETTER E + 0x042E, 0x845F, // CYRILLIC CAPITAL LETTER YU + 0x042F, 0x8460, // CYRILLIC CAPITAL LETTER YA + 0x0430, 0x8470, // CYRILLIC SMALL LETTER A + 0x0431, 0x8471, // CYRILLIC SMALL LETTER BE + 0x0432, 0x8472, // CYRILLIC SMALL LETTER VE + 0x0433, 0x8473, // CYRILLIC SMALL LETTER GHE + 0x0434, 0x8474, // CYRILLIC SMALL LETTER DE + 0x0435, 0x8475, // CYRILLIC SMALL LETTER IE + 0x0436, 0x8477, // CYRILLIC SMALL LETTER ZHE + 0x0437, 0x8478, // CYRILLIC SMALL LETTER ZE + 0x0438, 0x8479, // CYRILLIC SMALL LETTER I + 0x0439, 0x847A, // CYRILLIC SMALL LETTER SHORT I + 0x043A, 0x847B, // CYRILLIC SMALL LETTER KA + 0x043B, 0x847C, // CYRILLIC SMALL LETTER EL + 0x043C, 0x847D, // CYRILLIC SMALL LETTER EM + 0x043D, 0x847E, // CYRILLIC SMALL LETTER EN + 0x043E, 0x8480, // CYRILLIC SMALL LETTER O + 0x043F, 0x8481, // CYRILLIC SMALL LETTER PE + 0x0440, 0x8482, // CYRILLIC SMALL LETTER ER + 0x0441, 0x8483, // CYRILLIC SMALL LETTER ES + 0x0442, 0x8484, // CYRILLIC SMALL LETTER TE + 0x0443, 0x8485, // CYRILLIC SMALL LETTER U + 0x0444, 0x8486, // CYRILLIC SMALL LETTER EF + 0x0445, 0x8487, // CYRILLIC SMALL LETTER HA + 0x0446, 0x8488, // CYRILLIC SMALL LETTER TSE + 0x0447, 0x8489, // CYRILLIC SMALL LETTER CHE + 0x0448, 0x848A, // CYRILLIC SMALL LETTER SHA + 0x0449, 0x848B, // CYRILLIC SMALL LETTER SHCHA + 0x044A, 0x848C, // CYRILLIC SMALL LETTER HARD SIGN + 0x044B, 0x848D, // CYRILLIC SMALL LETTER YERU + 0x044C, 0x848E, // CYRILLIC SMALL LETTER SOFT SIGN + 0x044D, 0x848F, // CYRILLIC SMALL LETTER E + 0x044E, 0x8490, // CYRILLIC SMALL LETTER YU + 0x044F, 0x8491, // CYRILLIC SMALL LETTER YA + 0x0451, 0x8476, // CYRILLIC SMALL LETTER IO + 0x2010, 0x815D, // HYPHEN + 0x2014, 0x815C, // EM DASH + 0x2016, 0x8161, // DOUBLE VERTICAL LINE + 0x2018, 0x8165, // LEFT SINGLE QUOTATION MARK + 0x2019, 0x8166, // RIGHT SINGLE QUOTATION MARK + 0x201C, 0x8167, // LEFT DOUBLE QUOTATION MARK + 0x201D, 0x8168, // RIGHT DOUBLE QUOTATION MARK + 0x2020, 0x81F5, // DAGGER + 0x2021, 0x81F6, // DOUBLE DAGGER + 0x2025, 0x8164, // TWO DOT LEADER + 0x2026, 0x8163, // HORIZONTAL ELLIPSIS + 0x2030, 0x81F1, // PER MILLE SIGN + 0x2032, 0x818C, // PRIME + 0x2033, 0x818D, // DOUBLE PRIME + 0x203B, 0x81A6, // REFERENCE MARK + 0x2103, 0x818E, // DEGREE CELSIUS + 0x212B, 0x81F0, // ANGSTROM SIGN + 0x2190, 0x81A9, // LEFTWARDS ARROW + 0x2191, 0x81AA, // UPWARDS ARROW + 0x2192, 0x81A8, // RIGHTWARDS ARROW + 0x2193, 0x81AB, // DOWNWARDS ARROW + 0x21D2, 0x81CB, // RIGHTWARDS DOUBLE ARROW + 0x21D4, 0x81CC, // LEFT RIGHT DOUBLE ARROW + 0x2200, 0x81CD, // FOR ALL + 0x2202, 0x81DD, // PARTIAL DIFFERENTIAL + 0x2203, 0x81CE, // THERE EXISTS + 0x2207, 0x81DE, // NABLA + 0x2208, 0x81B8, // ELEMENT OF + 0x220B, 0x81B9, // CONTAINS AS MEMBER + 0x2212, 0x817C, // MINUS SIGN + 0x221A, 0x81E3, // SQUARE ROOT + 0x221D, 0x81E5, // PROPORTIONAL TO + 0x221E, 0x8187, // INFINITY + 0x2220, 0x81DA, // ANGLE + 0x2227, 0x81C8, // LOGICAL AND + 0x2228, 0x81C9, // LOGICAL OR + 0x2229, 0x81BF, // INTERSECTION + 0x222A, 0x81BE, // UNION + 0x222B, 0x81E7, // INTEGRAL + 0x222C, 0x81E8, // DOUBLE INTEGRAL + 0x2234, 0x8188, // THEREFORE + 0x2235, 0x81E6, // BECAUSE + 0x223D, 0x81E4, // REVERSED TILDE + 0x2252, 0x81E0, // APPROXIMATELY EQUAL TO OR THE IMAGE OF + 0x2260, 0x8182, // NOT EQUAL TO + 0x2261, 0x81DF, // IDENTICAL TO + 0x2266, 0x8185, // LESS-THAN OVER EQUAL TO + 0x2267, 0x8186, // GREATER-THAN OVER EQUAL TO + 0x226A, 0x81E1, // MUCH LESS-THAN + 0x226B, 0x81E2, // MUCH GREATER-THAN + 0x2282, 0x81BC, // SUBSET OF + 0x2283, 0x81BD, // SUPERSET OF + 0x2286, 0x81BA, // SUBSET OF OR EQUAL TO + 0x2287, 0x81BB, // SUPERSET OF OR EQUAL TO + 0x22A5, 0x81DB, // UP TACK + 0x2312, 0x81DC, // ARC + 0x2500, 0x849F, // BOX DRAWINGS LIGHT HORIZONTAL + 0x2501, 0x84AA, // BOX DRAWINGS HEAVY HORIZONTAL + 0x2502, 0x84A0, // BOX DRAWINGS LIGHT VERTICAL + 0x2503, 0x84AB, // BOX DRAWINGS HEAVY VERTICAL + 0x250C, 0x84A1, // BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x250F, 0x84AC, // BOX DRAWINGS HEAVY DOWN AND RIGHT + 0x2510, 0x84A2, // BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2513, 0x84AD, // BOX DRAWINGS HEAVY DOWN AND LEFT + 0x2514, 0x84A4, // BOX DRAWINGS LIGHT UP AND RIGHT + 0x2517, 0x84AF, // BOX DRAWINGS HEAVY UP AND RIGHT + 0x2518, 0x84A3, // BOX DRAWINGS LIGHT UP AND LEFT + 0x251B, 0x84AE, // BOX DRAWINGS HEAVY UP AND LEFT + 0x251C, 0x84A5, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x251D, 0x84BA, // BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + 0x2520, 0x84B5, // BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + 0x2523, 0x84B0, // BOX DRAWINGS HEAVY VERTICAL AND RIGHT + 0x2524, 0x84A7, // BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x2525, 0x84BC, // BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + 0x2528, 0x84B7, // BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + 0x252B, 0x84B2, // BOX DRAWINGS HEAVY VERTICAL AND LEFT + 0x252C, 0x84A6, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x252F, 0x84B6, // BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + 0x2530, 0x84BB, // BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + 0x2533, 0x84B1, // BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + 0x2534, 0x84A8, // BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x2537, 0x84B8, // BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + 0x2538, 0x84BD, // BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + 0x253B, 0x84B3, // BOX DRAWINGS HEAVY UP AND HORIZONTAL + 0x253C, 0x84A9, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x253F, 0x84B9, // BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + 0x2542, 0x84BE, // BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + 0x254B, 0x84B4, // BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + 0x25A0, 0x81A1, // BLACK SQUARE + 0x25A1, 0x81A0, // WHITE SQUARE + 0x25B2, 0x81A3, // BLACK UP-POINTING TRIANGLE + 0x25B3, 0x81A2, // WHITE UP-POINTING TRIANGLE + 0x25BC, 0x81A5, // BLACK DOWN-POINTING TRIANGLE + 0x25BD, 0x81A4, // WHITE DOWN-POINTING TRIANGLE + 0x25C6, 0x819F, // BLACK DIAMOND + 0x25C7, 0x819E, // WHITE DIAMOND + 0x25CB, 0x819B, // WHITE CIRCLE + 0x25CE, 0x819D, // BULLSEYE + 0x25CF, 0x819C, // BLACK CIRCLE + 0x25EF, 0x81FC, // LARGE CIRCLE + 0x2605, 0x819A, // BLACK STAR + 0x2606, 0x8199, // WHITE STAR + 0x2640, 0x818A, // FEMALE SIGN + 0x2642, 0x8189, // MALE SIGN + 0x266A, 0x81F4, // EIGHTH NOTE + 0x266D, 0x81F3, // MUSIC FLAT SIGN + 0x266F, 0x81F2, // MUSIC SHARP SIGN + 0x3000, 0x8140, // IDEOGRAPHIC SPACE + 0x3001, 0x8141, // IDEOGRAPHIC COMMA + 0x3002, 0x8142, // IDEOGRAPHIC FULL STOP + 0x3003, 0x8156, // DITTO MARK + 0x3005, 0x8158, // IDEOGRAPHIC ITERATION MARK + 0x3006, 0x8159, // IDEOGRAPHIC CLOSING MARK + 0x3007, 0x815A, // IDEOGRAPHIC NUMBER ZERO + 0x3008, 0x8171, // LEFT ANGLE BRACKET + 0x3009, 0x8172, // RIGHT ANGLE BRACKET + 0x300A, 0x8173, // LEFT DOUBLE ANGLE BRACKET + 0x300B, 0x8174, // RIGHT DOUBLE ANGLE BRACKET + 0x300C, 0x8175, // LEFT CORNER BRACKET + 0x300D, 0x8176, // RIGHT CORNER BRACKET + 0x300E, 0x8177, // LEFT WHITE CORNER BRACKET + 0x300F, 0x8178, // RIGHT WHITE CORNER BRACKET + 0x3010, 0x8179, // LEFT BLACK LENTICULAR BRACKET + 0x3011, 0x817A, // RIGHT BLACK LENTICULAR BRACKET + 0x3012, 0x81A7, // POSTAL MARK + 0x3013, 0x81AC, // GETA MARK + 0x3014, 0x816B, // LEFT TORTOISE SHELL BRACKET + 0x3015, 0x816C, // RIGHT TORTOISE SHELL BRACKET + 0x301C, 0x8160, // WAVE DASH + 0x3041, 0x829F, // HIRAGANA LETTER SMALL A + 0x3042, 0x82A0, // HIRAGANA LETTER A + 0x3043, 0x82A1, // HIRAGANA LETTER SMALL I + 0x3044, 0x82A2, // HIRAGANA LETTER I + 0x3045, 0x82A3, // HIRAGANA LETTER SMALL U + 0x3046, 0x82A4, // HIRAGANA LETTER U + 0x3047, 0x82A5, // HIRAGANA LETTER SMALL E + 0x3048, 0x82A6, // HIRAGANA LETTER E + 0x3049, 0x82A7, // HIRAGANA LETTER SMALL O + 0x304A, 0x82A8, // HIRAGANA LETTER O + 0x304B, 0x82A9, // HIRAGANA LETTER KA + 0x304C, 0x82AA, // HIRAGANA LETTER GA + 0x304D, 0x82AB, // HIRAGANA LETTER KI + 0x304E, 0x82AC, // HIRAGANA LETTER GI + 0x304F, 0x82AD, // HIRAGANA LETTER KU + 0x3050, 0x82AE, // HIRAGANA LETTER GU + 0x3051, 0x82AF, // HIRAGANA LETTER KE + 0x3052, 0x82B0, // HIRAGANA LETTER GE + 0x3053, 0x82B1, // HIRAGANA LETTER KO + 0x3054, 0x82B2, // HIRAGANA LETTER GO + 0x3055, 0x82B3, // HIRAGANA LETTER SA + 0x3056, 0x82B4, // HIRAGANA LETTER ZA + 0x3057, 0x82B5, // HIRAGANA LETTER SI + 0x3058, 0x82B6, // HIRAGANA LETTER ZI + 0x3059, 0x82B7, // HIRAGANA LETTER SU + 0x305A, 0x82B8, // HIRAGANA LETTER ZU + 0x305B, 0x82B9, // HIRAGANA LETTER SE + 0x305C, 0x82BA, // HIRAGANA LETTER ZE + 0x305D, 0x82BB, // HIRAGANA LETTER SO + 0x305E, 0x82BC, // HIRAGANA LETTER ZO + 0x305F, 0x82BD, // HIRAGANA LETTER TA + 0x3060, 0x82BE, // HIRAGANA LETTER DA + 0x3061, 0x82BF, // HIRAGANA LETTER TI + 0x3062, 0x82C0, // HIRAGANA LETTER DI + 0x3063, 0x82C1, // HIRAGANA LETTER SMALL TU + 0x3064, 0x82C2, // HIRAGANA LETTER TU + 0x3065, 0x82C3, // HIRAGANA LETTER DU + 0x3066, 0x82C4, // HIRAGANA LETTER TE + 0x3067, 0x82C5, // HIRAGANA LETTER DE + 0x3068, 0x82C6, // HIRAGANA LETTER TO + 0x3069, 0x82C7, // HIRAGANA LETTER DO + 0x306A, 0x82C8, // HIRAGANA LETTER NA + 0x306B, 0x82C9, // HIRAGANA LETTER NI + 0x306C, 0x82CA, // HIRAGANA LETTER NU + 0x306D, 0x82CB, // HIRAGANA LETTER NE + 0x306E, 0x82CC, // HIRAGANA LETTER NO + 0x306F, 0x82CD, // HIRAGANA LETTER HA + 0x3070, 0x82CE, // HIRAGANA LETTER BA + 0x3071, 0x82CF, // HIRAGANA LETTER PA + 0x3072, 0x82D0, // HIRAGANA LETTER HI + 0x3073, 0x82D1, // HIRAGANA LETTER BI + 0x3074, 0x82D2, // HIRAGANA LETTER PI + 0x3075, 0x82D3, // HIRAGANA LETTER HU + 0x3076, 0x82D4, // HIRAGANA LETTER BU + 0x3077, 0x82D5, // HIRAGANA LETTER PU + 0x3078, 0x82D6, // HIRAGANA LETTER HE + 0x3079, 0x82D7, // HIRAGANA LETTER BE + 0x307A, 0x82D8, // HIRAGANA LETTER PE + 0x307B, 0x82D9, // HIRAGANA LETTER HO + 0x307C, 0x82DA, // HIRAGANA LETTER BO + 0x307D, 0x82DB, // HIRAGANA LETTER PO + 0x307E, 0x82DC, // HIRAGANA LETTER MA + 0x307F, 0x82DD, // HIRAGANA LETTER MI + 0x3080, 0x82DE, // HIRAGANA LETTER MU + 0x3081, 0x82DF, // HIRAGANA LETTER ME + 0x3082, 0x82E0, // HIRAGANA LETTER MO + 0x3083, 0x82E1, // HIRAGANA LETTER SMALL YA + 0x3084, 0x82E2, // HIRAGANA LETTER YA + 0x3085, 0x82E3, // HIRAGANA LETTER SMALL YU + 0x3086, 0x82E4, // HIRAGANA LETTER YU + 0x3087, 0x82E5, // HIRAGANA LETTER SMALL YO + 0x3088, 0x82E6, // HIRAGANA LETTER YO + 0x3089, 0x82E7, // HIRAGANA LETTER RA + 0x308A, 0x82E8, // HIRAGANA LETTER RI + 0x308B, 0x82E9, // HIRAGANA LETTER RU + 0x308C, 0x82EA, // HIRAGANA LETTER RE + 0x308D, 0x82EB, // HIRAGANA LETTER RO + 0x308E, 0x82EC, // HIRAGANA LETTER SMALL WA + 0x308F, 0x82ED, // HIRAGANA LETTER WA + 0x3090, 0x82EE, // HIRAGANA LETTER WI + 0x3091, 0x82EF, // HIRAGANA LETTER WE + 0x3092, 0x82F0, // HIRAGANA LETTER WO + 0x3093, 0x82F1, // HIRAGANA LETTER N + 0x309B, 0x814A, // KATAKANA-HIRAGANA VOICED SOUND MARK + 0x309C, 0x814B, // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + 0x309D, 0x8154, // HIRAGANA ITERATION MARK + 0x309E, 0x8155, // HIRAGANA VOICED ITERATION MARK + 0x30A1, 0x8340, // KATAKANA LETTER SMALL A + 0x30A2, 0x8341, // KATAKANA LETTER A + 0x30A3, 0x8342, // KATAKANA LETTER SMALL I + 0x30A4, 0x8343, // KATAKANA LETTER I + 0x30A5, 0x8344, // KATAKANA LETTER SMALL U + 0x30A6, 0x8345, // KATAKANA LETTER U + 0x30A7, 0x8346, // KATAKANA LETTER SMALL E + 0x30A8, 0x8347, // KATAKANA LETTER E + 0x30A9, 0x8348, // KATAKANA LETTER SMALL O + 0x30AA, 0x8349, // KATAKANA LETTER O + 0x30AB, 0x834A, // KATAKANA LETTER KA + 0x30AC, 0x834B, // KATAKANA LETTER GA + 0x30AD, 0x834C, // KATAKANA LETTER KI + 0x30AE, 0x834D, // KATAKANA LETTER GI + 0x30AF, 0x834E, // KATAKANA LETTER KU + 0x30B0, 0x834F, // KATAKANA LETTER GU + 0x30B1, 0x8350, // KATAKANA LETTER KE + 0x30B2, 0x8351, // KATAKANA LETTER GE + 0x30B3, 0x8352, // KATAKANA LETTER KO + 0x30B4, 0x8353, // KATAKANA LETTER GO + 0x30B5, 0x8354, // KATAKANA LETTER SA + 0x30B6, 0x8355, // KATAKANA LETTER ZA + 0x30B7, 0x8356, // KATAKANA LETTER SI + 0x30B8, 0x8357, // KATAKANA LETTER ZI + 0x30B9, 0x8358, // KATAKANA LETTER SU + 0x30BA, 0x8359, // KATAKANA LETTER ZU + 0x30BB, 0x835A, // KATAKANA LETTER SE + 0x30BD, 0x835C, // KATAKANA LETTER SO + 0x30BE, 0x835D, // KATAKANA LETTER ZO + 0x30BF, 0x835E, // KATAKANA LETTER TA + 0x30C0, 0x835F, // KATAKANA LETTER DA + 0x30C1, 0x8360, // KATAKANA LETTER TI + 0x30C2, 0x8361, // KATAKANA LETTER DI + 0x30C3, 0x8362, // KATAKANA LETTER SMALL TU + 0x30C4, 0x8363, // KATAKANA LETTER TU + 0x30C5, 0x8364, // KATAKANA LETTER DU + 0x30C6, 0x8365, // KATAKANA LETTER TE + 0x30C7, 0x8366, // KATAKANA LETTER DE + 0x30C8, 0x8367, // KATAKANA LETTER TO + 0x30C9, 0x8368, // KATAKANA LETTER DO + 0x30CA, 0x8369, // KATAKANA LETTER NA + 0x30CB, 0x836A, // KATAKANA LETTER NI + 0x30CC, 0x836B, // KATAKANA LETTER NU + 0x30CD, 0x836C, // KATAKANA LETTER NE + 0x30CE, 0x836D, // KATAKANA LETTER NO + 0x30CF, 0x836E, // KATAKANA LETTER HA + 0x30D0, 0x836F, // KATAKANA LETTER BA + 0x30D1, 0x8370, // KATAKANA LETTER PA + 0x30D2, 0x8371, // KATAKANA LETTER HI + 0x30D3, 0x8372, // KATAKANA LETTER BI + 0x30D4, 0x8373, // KATAKANA LETTER PI + 0x30D5, 0x8374, // KATAKANA LETTER HU + 0x30D6, 0x8375, // KATAKANA LETTER BU + 0x30D7, 0x8376, // KATAKANA LETTER PU + 0x30D8, 0x8377, // KATAKANA LETTER HE + 0x30D9, 0x8378, // KATAKANA LETTER BE + 0x30DA, 0x8379, // KATAKANA LETTER PE + 0x30DB, 0x837A, // KATAKANA LETTER HO + 0x30DC, 0x837B, // KATAKANA LETTER BO + 0x30DD, 0x837C, // KATAKANA LETTER PO + 0x30DE, 0x837D, // KATAKANA LETTER MA + 0x30DF, 0x837E, // KATAKANA LETTER MI + 0x30E0, 0x8380, // KATAKANA LETTER MU + 0x30E1, 0x8381, // KATAKANA LETTER ME + 0x30E2, 0x8382, // KATAKANA LETTER MO + 0x30E3, 0x8383, // KATAKANA LETTER SMALL YA + 0x30E4, 0x8384, // KATAKANA LETTER YA + 0x30E5, 0x8385, // KATAKANA LETTER SMALL YU + 0x30E6, 0x8386, // KATAKANA LETTER YU + 0x30E7, 0x8387, // KATAKANA LETTER SMALL YO + 0x30E8, 0x8388, // KATAKANA LETTER YO + 0x30E9, 0x8389, // KATAKANA LETTER RA + 0x30EA, 0x838A, // KATAKANA LETTER RI + 0x30EB, 0x838B, // KATAKANA LETTER RU + 0x30EC, 0x838C, // KATAKANA LETTER RE + 0x30ED, 0x838D, // KATAKANA LETTER RO + 0x30EE, 0x838E, // KATAKANA LETTER SMALL WA + 0x30EF, 0x838F, // KATAKANA LETTER WA + 0x30F0, 0x8390, // KATAKANA LETTER WI + 0x30F1, 0x8391, // KATAKANA LETTER WE + 0x30F2, 0x8392, // KATAKANA LETTER WO + 0x30F3, 0x8393, // KATAKANA LETTER N + 0x30F4, 0x8394, // KATAKANA LETTER VU + 0x30F5, 0x8395, // KATAKANA LETTER SMALL KA + 0x30F6, 0x8396, // KATAKANA LETTER SMALL KE + 0x30FB, 0x8145, // KATAKANA MIDDLE DOT + 0x30FD, 0x8152, // KATAKANA ITERATION MARK + 0x30FE, 0x8153, // KATAKANA VOICED ITERATION MARK + 0x4E00, 0x88EA, // + 0x4E01, 0x929A, // + 0x4E03, 0x8EB5, // + 0x4E07, 0x969C, // + 0x4E08, 0x8FE4, // + 0x4E09, 0x8E4F, // + 0x4E0A, 0x8FE3, // + 0x4E0B, 0x89BA, // + 0x4E0D, 0x9573, // + 0x4E0E, 0x975E, // + 0x4E10, 0x98A0, // + 0x4E11, 0x894E, // + 0x4E14, 0x8A8E, // + 0x4E15, 0x98A1, // + 0x4E16, 0x90A2, // + 0x4E17, 0x99C0, // + 0x4E18, 0x8B75, // + 0x4E19, 0x95B8, // + 0x4E1E, 0x8FE5, // + 0x4E21, 0x97BC, // + 0x4E26, 0x95C0, // + 0x4E2A, 0x98A2, // + 0x4E2D, 0x9286, // + 0x4E31, 0x98A3, // + 0x4E32, 0x8BF8, // + 0x4E36, 0x98A4, // + 0x4E38, 0x8ADB, // + 0x4E39, 0x924F, // + 0x4E3B, 0x8EE5, // + 0x4E3C, 0x98A5, // + 0x4E3F, 0x98A6, // + 0x4E42, 0x98A7, // + 0x4E43, 0x9454, // + 0x4E45, 0x8B76, // + 0x4E4B, 0x9456, // + 0x4E4D, 0x93E1, // + 0x4E4E, 0x8CC1, // + 0x4E4F, 0x9652, // + 0x4E55, 0xE568, // + 0x4E56, 0x98A8, // + 0x4E57, 0x8FE6, // + 0x4E58, 0x98A9, // + 0x4E59, 0x89B3, // + 0x4E5D, 0x8BE3, // + 0x4E5E, 0x8CEE, // + 0x4E5F, 0x96E7, // + 0x4E62, 0x9BA4, // + 0x4E71, 0x9790, // + 0x4E73, 0x93FB, // + 0x4E7E, 0x8AA3, // + 0x4E80, 0x8B54, // + 0x4E82, 0x98AA, // + 0x4E85, 0x98AB, // + 0x4E86, 0x97B9, // + 0x4E88, 0x975C, // + 0x4E89, 0x9188, // + 0x4E8A, 0x98AD, // + 0x4E8B, 0x8E96, // + 0x4E8C, 0x93F1, // + 0x4E8E, 0x98B0, // + 0x4E91, 0x895D, // + 0x4E92, 0x8CDD, // + 0x4E94, 0x8CDC, // + 0x4E95, 0x88E4, // + 0x4E98, 0x986A, // + 0x4E99, 0x9869, // + 0x4E9B, 0x8DB1, // + 0x4E9C, 0x889F, // + 0x4E9E, 0x98B1, // + 0x4E9F, 0x98B2, // + 0x4EA0, 0x98B3, // + 0x4EA1, 0x9653, // + 0x4EA2, 0x98B4, // + 0x4EA4, 0x8CF0, // + 0x4EA5, 0x88E5, // + 0x4EA6, 0x9692, // + 0x4EA8, 0x8B9C, // + 0x4EAB, 0x8B9D, // + 0x4EAC, 0x8B9E, // + 0x4EAD, 0x92E0, // + 0x4EAE, 0x97BA, // + 0x4EB0, 0x98B5, // + 0x4EB3, 0x98B6, // + 0x4EB6, 0x98B7, // + 0x4EBA, 0x906C, // + 0x4EC0, 0x8F59, // + 0x4EC1, 0x906D, // + 0x4EC2, 0x98BC, // + 0x4EC4, 0x98BA, // + 0x4EC6, 0x98BB, // + 0x4EC7, 0x8B77, // + 0x4ECA, 0x8DA1, // + 0x4ECB, 0x89EE, // + 0x4ECD, 0x98B9, // + 0x4ECE, 0x98B8, // + 0x4ECF, 0x95A7, // + 0x4ED4, 0x8E65, // + 0x4ED5, 0x8E64, // + 0x4ED6, 0x91BC, // + 0x4ED7, 0x98BD, // + 0x4ED8, 0x9574, // + 0x4ED9, 0x90E5, // + 0x4EDD, 0x8157, // + 0x4EDE, 0x98BE, // + 0x4EDF, 0x98C0, // + 0x4EE3, 0x91E3, // + 0x4EE4, 0x97DF, // + 0x4EE5, 0x88C8, // + 0x4EED, 0x98BF, // + 0x4EEE, 0x89BC, // + 0x4EF0, 0x8BC2, // + 0x4EF2, 0x9287, // + 0x4EF6, 0x8C8F, // + 0x4EF7, 0x98C1, // + 0x4EFB, 0x9443, // + 0x4F01, 0x8AE9, // + 0x4F09, 0x98C2, // + 0x4F0A, 0x88C9, // + 0x4F0D, 0x8CDE, // + 0x4F0E, 0x8AEA, // + 0x4F0F, 0x959A, // + 0x4F10, 0x94B0, // + 0x4F11, 0x8B78, // + 0x4F1A, 0x89EF, // + 0x4F1C, 0x98E5, // + 0x4F1D, 0x9360, // + 0x4F2F, 0x948C, // + 0x4F30, 0x98C4, // + 0x4F34, 0x94BA, // + 0x4F36, 0x97E0, // + 0x4F38, 0x904C, // + 0x4F3A, 0x8E66, // + 0x4F3C, 0x8E97, // + 0x4F3D, 0x89BE, // + 0x4F43, 0x92CF, // + 0x4F46, 0x9241, // + 0x4F47, 0x98C8, // + 0x4F4D, 0x88CA, // + 0x4F4E, 0x92E1, // + 0x4F4F, 0x8F5A, // + 0x4F50, 0x8DB2, // + 0x4F51, 0x9743, // + 0x4F53, 0x91CC, // + 0x4F55, 0x89BD, // + 0x4F57, 0x98C7, // + 0x4F59, 0x975D, // + 0x4F5A, 0x98C3, // + 0x4F5B, 0x98C5, // + 0x4F5C, 0x8DEC, // + 0x4F5D, 0x98C6, // + 0x4F5E, 0x9B43, // + 0x4F69, 0x98CE, // + 0x4F6F, 0x98D1, // + 0x4F70, 0x98CF, // + 0x4F73, 0x89C0, // + 0x4F75, 0x95B9, // + 0x4F76, 0x98C9, // + 0x4F7B, 0x98CD, // + 0x4F7C, 0x8CF1, // + 0x4F7F, 0x8E67, // + 0x4F83, 0x8AA4, // + 0x4F86, 0x98D2, // + 0x4F88, 0x98CA, // + 0x4F8B, 0x97E1, // + 0x4F8D, 0x8E98, // + 0x4F8F, 0x98CB, // + 0x4F91, 0x98D0, // + 0x4F96, 0x98D3, // + 0x4F98, 0x98CC, // + 0x4F9B, 0x8B9F, // + 0x4F9D, 0x88CB, // + 0x4FA0, 0x8BA0, // + 0x4FA1, 0x89BF, // + 0x4FAB, 0x9B44, // + 0x4FAD, 0x9699, // + 0x4FAE, 0x958E, // + 0x4FAF, 0x8CF2, // + 0x4FB5, 0x904E, // + 0x4FB6, 0x97B5, // + 0x4FBF, 0x95D6, // + 0x4FC2, 0x8C57, // + 0x4FC3, 0x91A3, // + 0x4FC4, 0x89E2, // + 0x4FCA, 0x8F72, // + 0x4FCE, 0x98D7, // + 0x4FD0, 0x98DC, // + 0x4FD1, 0x98DA, // + 0x4FD4, 0x98D5, // + 0x4FD7, 0x91AD, // + 0x4FD8, 0x98D8, // + 0x4FDA, 0x98DB, // + 0x4FDB, 0x98D9, // + 0x4FDD, 0x95DB, // + 0x4FDF, 0x98D6, // + 0x4FE1, 0x904D, // + 0x4FE3, 0x9693, // + 0x4FE4, 0x98DD, // + 0x4FE5, 0x98DE, // + 0x4FEE, 0x8F43, // + 0x4FEF, 0x98EB, // + 0x4FF3, 0x946F, // + 0x4FF5, 0x9555, // + 0x4FF6, 0x98E6, // + 0x4FF8, 0x95EE, // + 0x4FFA, 0x89B4, // + 0x4FFE, 0x98EA, // + 0x5005, 0x98E4, // + 0x5006, 0x98ED, // + 0x5009, 0x9171, // + 0x500B, 0x8CC2, // + 0x500D, 0x947B, // + 0x500F, 0xE0C5, // + 0x5011, 0x98EC, // + 0x5012, 0x937C, // + 0x5014, 0x98E1, // + 0x5016, 0x8CF4, // + 0x5019, 0x8CF3, // + 0x501A, 0x98DF, // + 0x501F, 0x8ED8, // + 0x5021, 0x98E7, // + 0x5023, 0x95ED, // + 0x5024, 0x926C, // + 0x5025, 0x98E3, // + 0x5026, 0x8C91, // + 0x5028, 0x98E0, // + 0x5029, 0x98E8, // + 0x502A, 0x98E2, // + 0x502B, 0x97CF, // + 0x502C, 0x98E9, // + 0x502D, 0x9860, // + 0x5036, 0x8BE4, // + 0x5039, 0x8C90, // + 0x5043, 0x98EE, // + 0x5047, 0x98EF, // + 0x5048, 0x98F3, // + 0x5049, 0x88CC, // + 0x504F, 0x95CE, // + 0x5050, 0x98F2, // + 0x5055, 0x98F1, // + 0x5056, 0x98F5, // + 0x505A, 0x98F4, // + 0x505C, 0x92E2, // + 0x5065, 0x8C92, // + 0x506C, 0x98F6, // + 0x5072, 0x8EC3, // + 0x5074, 0x91A4, // + 0x5075, 0x92E3, // + 0x5076, 0x8BF4, // + 0x5078, 0x98F7, // + 0x507D, 0x8B55, // + 0x5080, 0x98F8, // + 0x5085, 0x98FA, // + 0x508D, 0x9654, // + 0x5091, 0x8C86, // + 0x5098, 0x8E50, // + 0x5099, 0x94F5, // + 0x509A, 0x98F9, // + 0x50AC, 0x8DC3, // + 0x50AD, 0x9762, // + 0x50B2, 0x98FC, // + 0x50B3, 0x9942, // + 0x50B4, 0x98FB, // + 0x50B5, 0x8DC2, // + 0x50B7, 0x8F9D, // + 0x50BE, 0x8C58, // + 0x50C2, 0x9943, // + 0x50C5, 0x8BCD, // + 0x50C9, 0x9940, // + 0x50CA, 0x9941, // + 0x50CD, 0x93AD, // + 0x50CF, 0x919C, // + 0x50D1, 0x8BA1, // + 0x50D5, 0x966C, // + 0x50D6, 0x9944, // + 0x50DA, 0x97BB, // + 0x50DE, 0x9945, // + 0x50E3, 0x9948, // + 0x50E5, 0x9946, // + 0x50E7, 0x916D, // + 0x50ED, 0x9947, // + 0x50EE, 0x9949, // + 0x50F5, 0x994B, // + 0x50F9, 0x994A, // + 0x50FB, 0x95C6, // + 0x5100, 0x8B56, // + 0x5101, 0x994D, // + 0x5102, 0x994E, // + 0x5104, 0x89AD, // + 0x5109, 0x994C, // + 0x5112, 0x8EF2, // + 0x5114, 0x9951, // + 0x5115, 0x9950, // + 0x5116, 0x994F, // + 0x5118, 0x98D4, // + 0x511A, 0x9952, // + 0x511F, 0x8F9E, // + 0x5121, 0x9953, // + 0x512A, 0x9744, // + 0x5132, 0x96D7, // + 0x5137, 0x9955, // + 0x513A, 0x9954, // + 0x513B, 0x9957, // + 0x513C, 0x9956, // + 0x513F, 0x9958, // + 0x5140, 0x9959, // + 0x5141, 0x88F2, // + 0x5143, 0x8CB3, // + 0x5144, 0x8C5A, // + 0x5146, 0x929B, // + 0x5147, 0x8BA2, // + 0x5148, 0x90E6, // + 0x5149, 0x8CF5, // + 0x514B, 0x8D8E, // + 0x514D, 0x96C6, // + 0x514E, 0x9365, // + 0x5150, 0x8E99, // + 0x5152, 0x995A, // + 0x5154, 0x995C, // + 0x515A, 0x937D, // + 0x515C, 0x8A95, // + 0x5162, 0x995D, // + 0x5165, 0x93FC, // + 0x5168, 0x9153, // + 0x5169, 0x995F, // + 0x516A, 0x9960, // + 0x516B, 0x94AA, // + 0x516C, 0x8CF6, // + 0x516D, 0x985A, // + 0x516E, 0x9961, // + 0x5171, 0x8BA4, // + 0x5175, 0x95BA, // + 0x5176, 0x91B4, // + 0x5177, 0x8BEF, // + 0x5178, 0x9354, // + 0x517C, 0x8C93, // + 0x5180, 0x9962, // + 0x5182, 0x9963, // + 0x5185, 0x93E0, // + 0x5186, 0x897E, // + 0x5189, 0x9966, // + 0x518A, 0x8DFB, // + 0x518C, 0x9965, // + 0x518D, 0x8DC4, // + 0x518F, 0x9967, // + 0x5190, 0xE3EC, // + 0x5191, 0x9968, // + 0x5192, 0x9660, // + 0x5193, 0x9969, // + 0x5195, 0x996A, // + 0x5196, 0x996B, // + 0x5197, 0x8FE7, // + 0x5199, 0x8ECA, // + 0x51A0, 0x8AA5, // + 0x51A2, 0x996E, // + 0x51A4, 0x996C, // + 0x51A5, 0x96BB, // + 0x51A6, 0x996D, // + 0x51A8, 0x9579, // + 0x51A9, 0x996F, // + 0x51AA, 0x9970, // + 0x51AB, 0x9971, // + 0x51AC, 0x937E, // + 0x51B0, 0x9975, // + 0x51B1, 0x9973, // + 0x51B2, 0x9974, // + 0x51B3, 0x9972, // + 0x51B4, 0x8DE1, // + 0x51B5, 0x9976, // + 0x51B6, 0x96E8, // + 0x51B7, 0x97E2, // + 0x51BD, 0x9977, // + 0x51C4, 0x90A6, // + 0x51C5, 0x9978, // + 0x51C6, 0x8F79, // + 0x51C9, 0x9979, // + 0x51CB, 0x929C, // + 0x51CC, 0x97BD, // + 0x51CD, 0x9380, // + 0x51D6, 0x99C3, // + 0x51DB, 0x997A, // + 0x51DC, 0xEAA3, // + 0x51DD, 0x8BC3, // + 0x51E0, 0x997B, // + 0x51E1, 0x967D, // + 0x51E6, 0x8F88, // + 0x51E7, 0x91FA, // + 0x51E9, 0x997D, // + 0x51EA, 0x93E2, // + 0x51ED, 0x997E, // + 0x51F0, 0x9980, // + 0x51F1, 0x8A4D, // + 0x51F5, 0x9981, // + 0x51F6, 0x8BA5, // + 0x51F8, 0x93CA, // + 0x51F9, 0x899A, // + 0x51FA, 0x8F6F, // + 0x51FD, 0x949F, // + 0x51FE, 0x9982, // + 0x5200, 0x9381, // + 0x5203, 0x906E, // + 0x5204, 0x9983, // + 0x5206, 0x95AA, // + 0x5207, 0x90D8, // + 0x5208, 0x8AA0, // + 0x520A, 0x8AA7, // + 0x520B, 0x9984, // + 0x520E, 0x9986, // + 0x5211, 0x8C59, // + 0x5214, 0x9985, // + 0x5217, 0x97F1, // + 0x521D, 0x8F89, // + 0x5224, 0x94BB, // + 0x5225, 0x95CA, // + 0x5227, 0x9987, // + 0x5229, 0x9798, // + 0x522A, 0x9988, // + 0x522E, 0x9989, // + 0x5230, 0x939E, // + 0x5233, 0x998A, // + 0x5236, 0x90A7, // + 0x5237, 0x8DFC, // + 0x5238, 0x8C94, // + 0x5239, 0x998B, // + 0x523A, 0x8E68, // + 0x523B, 0x8D8F, // + 0x5243, 0x92E4, // + 0x5244, 0x998D, // + 0x5247, 0x91A5, // + 0x524A, 0x8DED, // + 0x524B, 0x998E, // + 0x524C, 0x998F, // + 0x524D, 0x914F, // + 0x524F, 0x998C, // + 0x5254, 0x9991, // + 0x5256, 0x9655, // + 0x525B, 0x8D84, // + 0x525E, 0x9990, // + 0x5263, 0x8C95, // + 0x5264, 0x8DDC, // + 0x5265, 0x948D, // + 0x5269, 0x9994, // + 0x526A, 0x9992, // + 0x526F, 0x959B, // + 0x5270, 0x8FE8, // + 0x5271, 0x999B, // + 0x5272, 0x8A84, // + 0x5273, 0x9995, // + 0x5274, 0x9993, // + 0x5275, 0x916E, // + 0x527D, 0x9997, // + 0x527F, 0x9996, // + 0x5283, 0x8A63, // + 0x5287, 0x8C80, // + 0x5288, 0x999C, // + 0x5289, 0x97AB, // + 0x528D, 0x9998, // + 0x5291, 0x999D, // + 0x5292, 0x999A, // + 0x5294, 0x9999, // + 0x529B, 0x97CD, // + 0x529F, 0x8CF7, // + 0x52A0, 0x89C1, // + 0x52A3, 0x97F2, // + 0x52A9, 0x8F95, // + 0x52AA, 0x9377, // + 0x52AB, 0x8D85, // + 0x52AC, 0x99A0, // + 0x52AD, 0x99A1, // + 0x52B1, 0x97E3, // + 0x52B4, 0x984A, // + 0x52B5, 0x99A3, // + 0x52B9, 0x8CF8, // + 0x52BC, 0x99A2, // + 0x52BE, 0x8A4E, // + 0x52C1, 0x99A4, // + 0x52C3, 0x9675, // + 0x52C5, 0x92BA, // + 0x52C7, 0x9745, // + 0x52C9, 0x95D7, // + 0x52CD, 0x99A5, // + 0x52D2, 0xE8D3, // + 0x52D5, 0x93AE, // + 0x52D7, 0x99A6, // + 0x52D8, 0x8AA8, // + 0x52D9, 0x96B1, // + 0x52DD, 0x8F9F, // + 0x52DE, 0x99A7, // + 0x52DF, 0x95E5, // + 0x52E0, 0x99AB, // + 0x52E2, 0x90A8, // + 0x52E3, 0x99A8, // + 0x52E4, 0x8BCE, // + 0x52E6, 0x99A9, // + 0x52E7, 0x8AA9, // + 0x52F2, 0x8C4D, // + 0x52F3, 0x99AC, // + 0x52F5, 0x99AD, // + 0x52F8, 0x99AE, // + 0x52F9, 0x99AF, // + 0x52FA, 0x8ED9, // + 0x52FE, 0x8CF9, // + 0x52FF, 0x96DC, // + 0x5301, 0x96E6, // + 0x5302, 0x93F5, // + 0x5305, 0x95EF, // + 0x5306, 0x99B0, // + 0x5308, 0x99B1, // + 0x530D, 0x99B3, // + 0x530F, 0x99B5, // + 0x5310, 0x99B4, // + 0x5315, 0x99B6, // + 0x5316, 0x89BB, // + 0x5317, 0x966B, // + 0x5319, 0x8DFA, // + 0x531A, 0x99B7, // + 0x531D, 0x9178, // + 0x5320, 0x8FA0, // + 0x5321, 0x8BA7, // + 0x5323, 0x99B8, // + 0x532A, 0x94D9, // + 0x532F, 0x99B9, // + 0x5331, 0x99BA, // + 0x5333, 0x99BB, // + 0x5338, 0x99BC, // + 0x5339, 0x9543, // + 0x533A, 0x8BE6, // + 0x533B, 0x88E3, // + 0x533F, 0x93BD, // + 0x5340, 0x99BD, // + 0x5341, 0x8F5C, // + 0x5343, 0x90E7, // + 0x5345, 0x99BF, // + 0x5346, 0x99BE, // + 0x5347, 0x8FA1, // + 0x5348, 0x8CDF, // + 0x5349, 0x99C1, // + 0x534A, 0x94BC, // + 0x534D, 0x99C2, // + 0x5351, 0x94DA, // + 0x5352, 0x91B2, // + 0x5353, 0x91EC, // + 0x5354, 0x8BA6, // + 0x5357, 0x93EC, // + 0x5358, 0x9250, // + 0x535A, 0x948E, // + 0x535C, 0x966D, // + 0x535E, 0x99C4, // + 0x5360, 0x90E8, // + 0x5366, 0x8C54, // + 0x5369, 0x99C5, // + 0x536E, 0x99C6, // + 0x536F, 0x894B, // + 0x5370, 0x88F3, // + 0x5371, 0x8AEB, // + 0x5373, 0x91A6, // + 0x5374, 0x8B70, // + 0x5375, 0x9791, // + 0x5377, 0x99C9, // + 0x5378, 0x89B5, // + 0x537B, 0x99C8, // + 0x537F, 0x8BA8, // + 0x5382, 0x99CA, // + 0x5384, 0x96EF, // + 0x5396, 0x99CB, // + 0x5398, 0x97D0, // + 0x539A, 0x8CFA, // + 0x539F, 0x8CB4, // + 0x53A0, 0x99CC, // + 0x53A5, 0x99CE, // + 0x53A6, 0x99CD, // + 0x53A8, 0x907E, // + 0x53A9, 0x8958, // + 0x53AD, 0x897D, // + 0x53AE, 0x99CF, // + 0x53B0, 0x99D0, // + 0x53B3, 0x8CB5, // + 0x53B6, 0x99D1, // + 0x53BB, 0x8B8E, // + 0x53C2, 0x8E51, // + 0x53C3, 0x99D2, // + 0x53C8, 0x9694, // + 0x53C9, 0x8DB3, // + 0x53CA, 0x8B79, // + 0x53CB, 0x9746, // + 0x53CC, 0x916F, // + 0x53CD, 0x94BD, // + 0x53CE, 0x8EFB, // + 0x53D4, 0x8F66, // + 0x53D6, 0x8EE6, // + 0x53D7, 0x8EF3, // + 0x53D9, 0x8F96, // + 0x53DB, 0x94BE, // + 0x53DF, 0x99D5, // + 0x53E1, 0x8962, // + 0x53E2, 0x9170, // + 0x53E3, 0x8CFB, // + 0x53E4, 0x8CC3, // + 0x53E5, 0x8BE5, // + 0x53E8, 0x99D9, // + 0x53E9, 0x9240, // + 0x53EA, 0x91FC, // + 0x53EB, 0x8BA9, // + 0x53EC, 0x8FA2, // + 0x53ED, 0x99DA, // + 0x53EE, 0x99D8, // + 0x53EF, 0x89C2, // + 0x53F0, 0x91E4, // + 0x53F1, 0x8EB6, // + 0x53F2, 0x8E6A, // + 0x53F3, 0x8945, // + 0x53F6, 0x8A90, // + 0x53F7, 0x8D86, // + 0x53F8, 0x8E69, // + 0x53FA, 0x99DB, // + 0x5401, 0x99DC, // + 0x5403, 0x8B68, // + 0x5404, 0x8A65, // + 0x5408, 0x8D87, // + 0x5409, 0x8B67, // + 0x540A, 0x92DD, // + 0x540B, 0x8944, // + 0x540C, 0x93AF, // + 0x540D, 0x96BC, // + 0x540E, 0x8D40, // + 0x540F, 0x9799, // + 0x5410, 0x9366, // + 0x5411, 0x8CFC, // + 0x541B, 0x8C4E, // + 0x541D, 0x99E5, // + 0x541F, 0x8BE1, // + 0x5420, 0x9669, // + 0x5426, 0x94DB, // + 0x5429, 0x99E4, // + 0x542B, 0x8ADC, // + 0x542C, 0x99DF, // + 0x542D, 0x99E0, // + 0x542E, 0x99E2, // + 0x5436, 0x99E3, // + 0x5438, 0x8B7A, // + 0x5439, 0x9081, // + 0x543B, 0x95AB, // + 0x543C, 0x99E1, // + 0x543D, 0x99DD, // + 0x543E, 0x8CE1, // + 0x5440, 0x99DE, // + 0x5442, 0x9843, // + 0x5446, 0x95F0, // + 0x5448, 0x92E6, // + 0x5449, 0x8CE0, // + 0x544A, 0x8D90, // + 0x544E, 0x99E6, // + 0x5451, 0x93DB, // + 0x545F, 0x99EA, // + 0x5468, 0x8EFC, // + 0x546A, 0x8EF4, // + 0x5470, 0x99ED, // + 0x5471, 0x99EB, // + 0x5473, 0x96A1, // + 0x5475, 0x99E8, // + 0x5476, 0x99F1, // + 0x5477, 0x99EC, // + 0x547B, 0x99EF, // + 0x547C, 0x8CC4, // + 0x547D, 0x96BD, // + 0x5480, 0x99F0, // + 0x5484, 0x99F2, // + 0x5486, 0x99F4, // + 0x548B, 0x8DEE, // + 0x548C, 0x9861, // + 0x548E, 0x99E9, // + 0x548F, 0x99E7, // + 0x5490, 0x99F3, // + 0x5492, 0x99EE, // + 0x54A2, 0x99F6, // + 0x54A4, 0x9A42, // + 0x54A5, 0x99F8, // + 0x54A8, 0x99FC, // + 0x54AB, 0x9A40, // + 0x54AC, 0x99F9, // + 0x54AF, 0x9A5D, // + 0x54B2, 0x8DE7, // + 0x54B3, 0x8A50, // + 0x54B8, 0x99F7, // + 0x54BC, 0x9A44, // + 0x54BD, 0x88F4, // + 0x54BE, 0x9A43, // + 0x54C0, 0x88A3, // + 0x54C1, 0x9569, // + 0x54C2, 0x9A41, // + 0x54C4, 0x99FA, // + 0x54C7, 0x99F5, // + 0x54C8, 0x99FB, // + 0x54C9, 0x8DC6, // + 0x54D8, 0x9A45, // + 0x54E1, 0x88F5, // + 0x54E2, 0x9A4E, // + 0x54E5, 0x9A46, // + 0x54E6, 0x9A47, // + 0x54E8, 0x8FA3, // + 0x54E9, 0x9689, // + 0x54ED, 0x9A4C, // + 0x54EE, 0x9A4B, // + 0x54F2, 0x934E, // + 0x54FA, 0x9A4D, // + 0x54FD, 0x9A4A, // + 0x5504, 0x8953, // + 0x5506, 0x8DB4, // + 0x5507, 0x904F, // + 0x550F, 0x9A48, // + 0x5510, 0x9382, // + 0x5514, 0x9A49, // + 0x5516, 0x88A0, // + 0x552E, 0x9A53, // + 0x552F, 0x9742, // + 0x5531, 0x8FA5, // + 0x5533, 0x9A59, // + 0x5538, 0x9A58, // + 0x5539, 0x9A4F, // + 0x553E, 0x91C1, // + 0x5540, 0x9A50, // + 0x5544, 0x91ED, // + 0x5545, 0x9A55, // + 0x5546, 0x8FA4, // + 0x554C, 0x9A52, // + 0x554F, 0x96E2, // + 0x5556, 0x9A56, // + 0x5557, 0x9A57, // + 0x555C, 0x9A54, // + 0x555D, 0x9A5A, // + 0x5563, 0x9A51, // + 0x557B, 0x9A60, // + 0x557C, 0x9A65, // + 0x557E, 0x9A61, // + 0x5580, 0x9A5C, // + 0x5583, 0x9A66, // + 0x5584, 0x9150, // + 0x5587, 0x9A68, // + 0x5589, 0x8D41, // + 0x558A, 0x9A5E, // + 0x558B, 0x929D, // + 0x5598, 0x9A62, // + 0x559A, 0x8AAB, // + 0x559C, 0x8AEC, // + 0x559D, 0x8A85, // + 0x559E, 0x9A63, // + 0x559F, 0x9A5F, // + 0x55A7, 0x8C96, // + 0x55A8, 0x9A69, // + 0x55A9, 0x9A67, // + 0x55AA, 0x9172, // + 0x55AB, 0x8B69, // + 0x55AC, 0x8BAA, // + 0x55AE, 0x9A64, // + 0x55B0, 0x8BF2, // + 0x55B6, 0x8963, // + 0x55C4, 0x9A6D, // + 0x55C5, 0x9A6B, // + 0x55C7, 0x9AA5, // + 0x55D4, 0x9A70, // + 0x55DA, 0x9A6A, // + 0x55DC, 0x9A6E, // + 0x55DF, 0x9A6C, // + 0x55E3, 0x8E6B, // + 0x55E4, 0x9A6F, // + 0x55F7, 0x9A72, // + 0x55F9, 0x9A77, // + 0x55FD, 0x9A75, // + 0x55FE, 0x9A74, // + 0x5606, 0x9251, // + 0x5609, 0x89C3, // + 0x5614, 0x9A71, // + 0x5616, 0x9A73, // + 0x5617, 0x8FA6, // + 0x5618, 0x8952, // + 0x561B, 0x9A76, // + 0x5629, 0x89DC, // + 0x562F, 0x9A82, // + 0x5631, 0x8FFA, // + 0x5632, 0x9A7D, // + 0x5634, 0x9A7B, // + 0x5636, 0x9A7C, // + 0x5638, 0x9A7E, // + 0x5642, 0x895C, // + 0x564C, 0x9158, // + 0x564E, 0x9A78, // + 0x5650, 0x9A79, // + 0x565B, 0x8A9A, // + 0x5664, 0x9A81, // + 0x5668, 0x8AED, // + 0x566A, 0x9A84, // + 0x566B, 0x9A80, // + 0x566C, 0x9A83, // + 0x5674, 0x95AC, // + 0x5678, 0x93D3, // + 0x567A, 0x94B6, // + 0x5680, 0x9A86, // + 0x5686, 0x9A85, // + 0x5687, 0x8A64, // + 0x568A, 0x9A87, // + 0x568F, 0x9A8A, // + 0x5694, 0x9A89, // + 0x56A0, 0x9A88, // + 0x56A2, 0x9458, // + 0x56A5, 0x9A8B, // + 0x56AE, 0x9A8C, // + 0x56B4, 0x9A8E, // + 0x56B6, 0x9A8D, // + 0x56BC, 0x9A90, // + 0x56C0, 0x9A93, // + 0x56C1, 0x9A91, // + 0x56C2, 0x9A8F, // + 0x56C3, 0x9A92, // + 0x56C8, 0x9A94, // + 0x56CE, 0x9A95, // + 0x56D1, 0x9A96, // + 0x56D3, 0x9A97, // + 0x56D7, 0x9A98, // + 0x56D8, 0x9964, // + 0x56DA, 0x8EFA, // + 0x56DB, 0x8E6C, // + 0x56DE, 0x89F1, // + 0x56E0, 0x88F6, // + 0x56E3, 0x9263, // + 0x56EE, 0x9A99, // + 0x56F0, 0x8DA2, // + 0x56F2, 0x88CD, // + 0x56F3, 0x907D, // + 0x56F9, 0x9A9A, // + 0x56FA, 0x8CC5, // + 0x56FD, 0x8D91, // + 0x56FF, 0x9A9C, // + 0x5700, 0x9A9B, // + 0x5703, 0x95DE, // + 0x5704, 0x9A9D, // + 0x5708, 0x9A9F, // + 0x5709, 0x9A9E, // + 0x570B, 0x9AA0, // + 0x570D, 0x9AA1, // + 0x570F, 0x8C97, // + 0x5712, 0x8980, // + 0x5713, 0x9AA2, // + 0x5716, 0x9AA4, // + 0x5718, 0x9AA3, // + 0x571C, 0x9AA6, // + 0x571F, 0x9379, // + 0x5726, 0x9AA7, // + 0x5727, 0x88B3, // + 0x5728, 0x8DDD, // + 0x572D, 0x8C5C, // + 0x5730, 0x926E, // + 0x5737, 0x9AA8, // + 0x5738, 0x9AA9, // + 0x573B, 0x9AAB, // + 0x5740, 0x9AAC, // + 0x5742, 0x8DE2, // + 0x5747, 0x8BCF, // + 0x574A, 0x9656, // + 0x574E, 0x9AAA, // + 0x574F, 0x9AAD, // + 0x5750, 0x8DBF, // + 0x5751, 0x8D42, // + 0x5761, 0x9AB1, // + 0x5764, 0x8DA3, // + 0x5766, 0x9252, // + 0x5769, 0x9AAE, // + 0x576A, 0x92D8, // + 0x577F, 0x9AB2, // + 0x5782, 0x9082, // + 0x5788, 0x9AB0, // + 0x5789, 0x9AB3, // + 0x578B, 0x8C5E, // + 0x5793, 0x9AB4, // + 0x57A0, 0x9AB5, // + 0x57A2, 0x8D43, // + 0x57A3, 0x8A5F, // + 0x57A4, 0x9AB7, // + 0x57AA, 0x9AB8, // + 0x57B0, 0x9AB9, // + 0x57B3, 0x9AB6, // + 0x57C0, 0x9AAF, // + 0x57C3, 0x9ABA, // + 0x57C6, 0x9ABB, // + 0x57CB, 0x9684, // + 0x57CE, 0x8FE9, // + 0x57D2, 0x9ABD, // + 0x57D3, 0x9ABE, // + 0x57D4, 0x9ABC, // + 0x57D6, 0x9AC0, // + 0x57DC, 0x9457, // + 0x57DF, 0x88E6, // + 0x57E0, 0x9575, // + 0x57E3, 0x9AC1, // + 0x57F4, 0x8FFB, // + 0x57F7, 0x8EB7, // + 0x57F9, 0x947C, // + 0x57FA, 0x8AEE, // + 0x57FC, 0x8DE9, // + 0x5800, 0x9678, // + 0x5802, 0x93B0, // + 0x5805, 0x8C98, // + 0x5806, 0x91CD, // + 0x580A, 0x9ABF, // + 0x580B, 0x9AC2, // + 0x5815, 0x91C2, // + 0x5819, 0x9AC3, // + 0x581D, 0x9AC4, // + 0x5821, 0x9AC6, // + 0x5824, 0x92E7, // + 0x582A, 0x8AAC, // + 0x582F, 0xEA9F, // + 0x5830, 0x8981, // + 0x5831, 0x95F1, // + 0x5834, 0x8FEA, // + 0x5835, 0x9367, // + 0x583A, 0x8DE4, // + 0x583D, 0x9ACC, // + 0x5840, 0x95BB, // + 0x5841, 0x97DB, // + 0x584A, 0x89F2, // + 0x584B, 0x9AC8, // + 0x5851, 0x9159, // + 0x5852, 0x9ACB, // + 0x5854, 0x9383, // + 0x5857, 0x9368, // + 0x5858, 0x9384, // + 0x5859, 0x94B7, // + 0x585A, 0x92CB, // + 0x585E, 0x8DC7, // + 0x5862, 0x9AC7, // + 0x5869, 0x8996, // + 0x586B, 0x9355, // + 0x5870, 0x9AC9, // + 0x5872, 0x9AC5, // + 0x5875, 0x906F, // + 0x5879, 0x9ACD, // + 0x587E, 0x8F6D, // + 0x5883, 0x8BAB, // + 0x5885, 0x9ACE, // + 0x5893, 0x95E6, // + 0x5897, 0x919D, // + 0x589C, 0x92C4, // + 0x589F, 0x9AD0, // + 0x58A8, 0x966E, // + 0x58AB, 0x9AD1, // + 0x58AE, 0x9AD6, // + 0x58B3, 0x95AD, // + 0x58B8, 0x9AD5, // + 0x58B9, 0x9ACF, // + 0x58BA, 0x9AD2, // + 0x58BB, 0x9AD4, // + 0x58BE, 0x8DA4, // + 0x58C1, 0x95C7, // + 0x58C5, 0x9AD7, // + 0x58C7, 0x9264, // + 0x58CA, 0x89F3, // + 0x58CC, 0x8FEB, // + 0x58D1, 0x9AD9, // + 0x58D3, 0x9AD8, // + 0x58D5, 0x8D88, // + 0x58D7, 0x9ADA, // + 0x58D8, 0x9ADC, // + 0x58D9, 0x9ADB, // + 0x58DC, 0x9ADE, // + 0x58DE, 0x9AD3, // + 0x58DF, 0x9AE0, // + 0x58E4, 0x9ADF, // + 0x58E5, 0x9ADD, // + 0x58EB, 0x8E6D, // + 0x58EC, 0x9070, // + 0x58EE, 0x9173, // + 0x58EF, 0x9AE1, // + 0x58F0, 0x90BA, // + 0x58F1, 0x88EB, // + 0x58F2, 0x9484, // + 0x58F7, 0x92D9, // + 0x58F9, 0x9AE3, // + 0x58FA, 0x9AE2, // + 0x58FB, 0x9AE4, // + 0x58FC, 0x9AE5, // + 0x58FD, 0x9AE6, // + 0x5902, 0x9AE7, // + 0x5909, 0x95CF, // + 0x590A, 0x9AE8, // + 0x590F, 0x89C4, // + 0x5910, 0x9AE9, // + 0x5916, 0x8A4F, // + 0x5918, 0x99C7, // + 0x5919, 0x8F67, // + 0x591A, 0x91BD, // + 0x591B, 0x9AEA, // + 0x591C, 0x96E9, // + 0x5922, 0x96B2, // + 0x5925, 0x9AEC, // + 0x5927, 0x91E5, // + 0x5929, 0x9356, // + 0x592A, 0x91BE, // + 0x592B, 0x9576, // + 0x592C, 0x9AED, // + 0x592D, 0x9AEE, // + 0x592E, 0x899B, // + 0x5931, 0x8EB8, // + 0x5932, 0x9AEF, // + 0x5937, 0x88CE, // + 0x5938, 0x9AF0, // + 0x593E, 0x9AF1, // + 0x5944, 0x8982, // + 0x5947, 0x8AEF, // + 0x5948, 0x93DE, // + 0x5949, 0x95F2, // + 0x594E, 0x9AF5, // + 0x594F, 0x9174, // + 0x5950, 0x9AF4, // + 0x5951, 0x8C5F, // + 0x5954, 0x967A, // + 0x5955, 0x9AF3, // + 0x5957, 0x9385, // + 0x5958, 0x9AF7, // + 0x595A, 0x9AF6, // + 0x5960, 0x9AF9, // + 0x5962, 0x9AF8, // + 0x5965, 0x899C, // + 0x5967, 0x9AFA, // + 0x5968, 0x8FA7, // + 0x5969, 0x9AFC, // + 0x596A, 0x9244, // + 0x596C, 0x9AFB, // + 0x596E, 0x95B1, // + 0x5973, 0x8F97, // + 0x5974, 0x937A, // + 0x5978, 0x9B40, // + 0x597D, 0x8D44, // + 0x5981, 0x9B41, // + 0x5982, 0x9440, // + 0x5983, 0x94DC, // + 0x5984, 0x96CF, // + 0x598A, 0x9444, // + 0x598D, 0x9B4A, // + 0x5993, 0x8B57, // + 0x5996, 0x9764, // + 0x5999, 0x96AD, // + 0x599B, 0x9BAA, // + 0x599D, 0x9B42, // + 0x59A3, 0x9B45, // + 0x59A5, 0x91C3, // + 0x59A8, 0x9657, // + 0x59AC, 0x9369, // + 0x59B2, 0x9B46, // + 0x59B9, 0x9685, // + 0x59BB, 0x8DC8, // + 0x59BE, 0x8FA8, // + 0x59C6, 0x9B47, // + 0x59C9, 0x8E6F, // + 0x59CB, 0x8E6E, // + 0x59D0, 0x88B7, // + 0x59D1, 0x8CC6, // + 0x59D3, 0x90A9, // + 0x59D4, 0x88CF, // + 0x59D9, 0x9B4B, // + 0x59DA, 0x9B4C, // + 0x59DC, 0x9B49, // + 0x59E5, 0x8957, // + 0x59E6, 0x8AAD, // + 0x59E8, 0x9B48, // + 0x59EA, 0x96C3, // + 0x59EB, 0x9550, // + 0x59F6, 0x88A6, // + 0x59FB, 0x88F7, // + 0x59FF, 0x8E70, // + 0x5A01, 0x88D0, // + 0x5A03, 0x88A1, // + 0x5A09, 0x9B51, // + 0x5A11, 0x9B4F, // + 0x5A18, 0x96BA, // + 0x5A1A, 0x9B52, // + 0x5A1C, 0x9B50, // + 0x5A1F, 0x9B4E, // + 0x5A20, 0x9050, // + 0x5A25, 0x9B4D, // + 0x5A29, 0x95D8, // + 0x5A2F, 0x8CE2, // + 0x5A35, 0x9B56, // + 0x5A36, 0x9B57, // + 0x5A3C, 0x8FA9, // + 0x5A40, 0x9B53, // + 0x5A41, 0x984B, // + 0x5A46, 0x946B, // + 0x5A49, 0x9B55, // + 0x5A5A, 0x8DA5, // + 0x5A62, 0x9B58, // + 0x5A66, 0x9577, // + 0x5A6A, 0x9B59, // + 0x5A6C, 0x9B54, // + 0x5A7F, 0x96B9, // + 0x5A92, 0x947D, // + 0x5A9A, 0x9B5A, // + 0x5A9B, 0x9551, // + 0x5ABD, 0x9B5F, // + 0x5ABE, 0x9B5C, // + 0x5AC1, 0x89C5, // + 0x5AC2, 0x9B5E, // + 0x5AC9, 0x8EB9, // + 0x5ACB, 0x9B5D, // + 0x5ACC, 0x8C99, // + 0x5AD0, 0x9B6B, // + 0x5AD6, 0x9B64, // + 0x5AD7, 0x9B61, // + 0x5AE1, 0x9284, // + 0x5AE3, 0x9B60, // + 0x5AE6, 0x9B62, // + 0x5AE9, 0x9B63, // + 0x5AFA, 0x9B65, // + 0x5AFB, 0x9B66, // + 0x5B09, 0x8AF0, // + 0x5B0B, 0x9B68, // + 0x5B0C, 0x9B67, // + 0x5B16, 0x9B69, // + 0x5B22, 0x8FEC, // + 0x5B2A, 0x9B6C, // + 0x5B2C, 0x92DA, // + 0x5B30, 0x8964, // + 0x5B32, 0x9B6A, // + 0x5B36, 0x9B6D, // + 0x5B3E, 0x9B6E, // + 0x5B40, 0x9B71, // + 0x5B43, 0x9B6F, // + 0x5B45, 0x9B70, // + 0x5B50, 0x8E71, // + 0x5B51, 0x9B72, // + 0x5B54, 0x8D45, // + 0x5B55, 0x9B73, // + 0x5B57, 0x8E9A, // + 0x5B58, 0x91B6, // + 0x5B5A, 0x9B74, // + 0x5B5B, 0x9B75, // + 0x5B5C, 0x8E79, // + 0x5B5D, 0x8D46, // + 0x5B5F, 0x96D0, // + 0x5B63, 0x8B47, // + 0x5B64, 0x8CC7, // + 0x5B65, 0x9B76, // + 0x5B66, 0x8A77, // + 0x5B69, 0x9B77, // + 0x5B6B, 0x91B7, // + 0x5B70, 0x9B78, // + 0x5B71, 0x9BA1, // + 0x5B73, 0x9B79, // + 0x5B75, 0x9B7A, // + 0x5B78, 0x9B7B, // + 0x5B7A, 0x9B7D, // + 0x5B80, 0x9B7E, // + 0x5B83, 0x9B80, // + 0x5B85, 0x91EE, // + 0x5B87, 0x8946, // + 0x5B88, 0x8EE7, // + 0x5B89, 0x88C0, // + 0x5B8B, 0x9176, // + 0x5B8C, 0x8AAE, // + 0x5B8D, 0x8EB3, // + 0x5B8F, 0x8D47, // + 0x5B95, 0x9386, // + 0x5B97, 0x8F40, // + 0x5B98, 0x8AAF, // + 0x5B99, 0x9288, // + 0x5B9A, 0x92E8, // + 0x5B9B, 0x88B6, // + 0x5B9C, 0x8B58, // + 0x5B9D, 0x95F3, // + 0x5B9F, 0x8EC0, // + 0x5BA2, 0x8B71, // + 0x5BA3, 0x90E9, // + 0x5BA4, 0x8EBA, // + 0x5BA5, 0x9747, // + 0x5BA6, 0x9B81, // + 0x5BAE, 0x8B7B, // + 0x5BB0, 0x8DC9, // + 0x5BB3, 0x8A51, // + 0x5BB4, 0x8983, // + 0x5BB5, 0x8FAA, // + 0x5BB6, 0x89C6, // + 0x5BB8, 0x9B82, // + 0x5BB9, 0x9765, // + 0x5BBF, 0x8F68, // + 0x5BC2, 0x8EE2, // + 0x5BC3, 0x9B83, // + 0x5BC4, 0x8AF1, // + 0x5BC5, 0x93D0, // + 0x5BC6, 0x96A7, // + 0x5BC7, 0x9B84, // + 0x5BC9, 0x9B85, // + 0x5BCC, 0x9578, // + 0x5BD0, 0x9B87, // + 0x5BD2, 0x8AA6, // + 0x5BD3, 0x8BF5, // + 0x5BD4, 0x9B86, // + 0x5BDB, 0x8AB0, // + 0x5BDD, 0x9051, // + 0x5BDE, 0x9B8B, // + 0x5BDF, 0x8E40, // + 0x5BE1, 0x89C7, // + 0x5BE2, 0x9B8A, // + 0x5BE4, 0x9B88, // + 0x5BE5, 0x9B8C, // + 0x5BE6, 0x9B89, // + 0x5BE7, 0x944A, // + 0x5BE8, 0x9ECB, // + 0x5BE9, 0x9052, // + 0x5BEB, 0x9B8D, // + 0x5BEE, 0x97BE, // + 0x5BF0, 0x9B8E, // + 0x5BF3, 0x9B90, // + 0x5BF5, 0x929E, // + 0x5BF6, 0x9B8F, // + 0x5BF8, 0x90A1, // + 0x5BFA, 0x8E9B, // + 0x5BFE, 0x91CE, // + 0x5BFF, 0x8EF5, // + 0x5C01, 0x9595, // + 0x5C02, 0x90EA, // + 0x5C04, 0x8ECB, // + 0x5C05, 0x9B91, // + 0x5C06, 0x8FAB, // + 0x5C07, 0x9B92, // + 0x5C08, 0x9B93, // + 0x5C09, 0x88D1, // + 0x5C0A, 0x91B8, // + 0x5C0B, 0x9071, // + 0x5C0D, 0x9B94, // + 0x5C0E, 0x93B1, // + 0x5C0F, 0x8FAC, // + 0x5C11, 0x8FAD, // + 0x5C13, 0x9B95, // + 0x5C16, 0x90EB, // + 0x5C1A, 0x8FAE, // + 0x5C20, 0x9B96, // + 0x5C22, 0x9B97, // + 0x5C24, 0x96DE, // + 0x5C28, 0x9B98, // + 0x5C2D, 0x8BC4, // + 0x5C31, 0x8F41, // + 0x5C38, 0x9B99, // + 0x5C39, 0x9B9A, // + 0x5C3A, 0x8EDA, // + 0x5C3B, 0x904B, // + 0x5C3C, 0x93F2, // + 0x5C3D, 0x9073, // + 0x5C3E, 0x94F6, // + 0x5C3F, 0x9441, // + 0x5C40, 0x8BC7, // + 0x5C41, 0x9B9B, // + 0x5C45, 0x8B8F, // + 0x5C46, 0x9B9C, // + 0x5C48, 0x8BFC, // + 0x5C4A, 0x93CD, // + 0x5C4B, 0x89AE, // + 0x5C4D, 0x8E72, // + 0x5C4E, 0x9B9D, // + 0x5C4F, 0x9BA0, // + 0x5C50, 0x9B9F, // + 0x5C51, 0x8BFB, // + 0x5C53, 0x9B9E, // + 0x5C55, 0x9357, // + 0x5C5E, 0x91AE, // + 0x5C60, 0x936A, // + 0x5C61, 0x8EC6, // + 0x5C64, 0x9177, // + 0x5C65, 0x979A, // + 0x5C6C, 0x9BA2, // + 0x5C6E, 0x9BA3, // + 0x5C6F, 0x93D4, // + 0x5C71, 0x8E52, // + 0x5C76, 0x9BA5, // + 0x5C79, 0x9BA6, // + 0x5C8C, 0x9BA7, // + 0x5C90, 0x8AF2, // + 0x5C91, 0x9BA8, // + 0x5C94, 0x9BA9, // + 0x5CA1, 0x89AA, // + 0x5CA8, 0x915A, // + 0x5CA9, 0x8AE2, // + 0x5CAB, 0x9BAB, // + 0x5CAC, 0x96A6, // + 0x5CB1, 0x91D0, // + 0x5CB3, 0x8A78, // + 0x5CB6, 0x9BAD, // + 0x5CB7, 0x9BAF, // + 0x5CB8, 0x8ADD, // + 0x5CBB, 0x9BAC, // + 0x5CBC, 0x9BAE, // + 0x5CBE, 0x9BB1, // + 0x5CC5, 0x9BB0, // + 0x5CC7, 0x9BB2, // + 0x5CD9, 0x9BB3, // + 0x5CE0, 0x93BB, // + 0x5CE1, 0x8BAC, // + 0x5CE8, 0x89E3, // + 0x5CE9, 0x9BB4, // + 0x5CEA, 0x9BB9, // + 0x5CED, 0x9BB7, // + 0x5CEF, 0x95F5, // + 0x5CF0, 0x95F4, // + 0x5CF6, 0x9387, // + 0x5CFA, 0x9BB6, // + 0x5CFB, 0x8F73, // + 0x5CFD, 0x9BB5, // + 0x5D07, 0x9092, // + 0x5D0B, 0x9BBA, // + 0x5D0E, 0x8DE8, // + 0x5D11, 0x9BC0, // + 0x5D14, 0x9BC1, // + 0x5D15, 0x9BBB, // + 0x5D16, 0x8A52, // + 0x5D17, 0x9BBC, // + 0x5D18, 0x9BC5, // + 0x5D19, 0x9BC4, // + 0x5D1A, 0x9BC3, // + 0x5D1B, 0x9BBF, // + 0x5D1F, 0x9BBE, // + 0x5D22, 0x9BC2, // + 0x5D29, 0x95F6, // + 0x5D4B, 0x9BC9, // + 0x5D4C, 0x9BC6, // + 0x5D4E, 0x9BC8, // + 0x5D50, 0x9792, // + 0x5D52, 0x9BC7, // + 0x5D5C, 0x9BBD, // + 0x5D69, 0x9093, // + 0x5D6C, 0x9BCA, // + 0x5D6F, 0x8DB5, // + 0x5D73, 0x9BCB, // + 0x5D76, 0x9BCC, // + 0x5D82, 0x9BCF, // + 0x5D84, 0x9BCE, // + 0x5D87, 0x9BCD, // + 0x5D8B, 0x9388, // + 0x5D8C, 0x9BB8, // + 0x5D90, 0x9BD5, // + 0x5D9D, 0x9BD1, // + 0x5DA2, 0x9BD0, // + 0x5DAC, 0x9BD2, // + 0x5DAE, 0x9BD3, // + 0x5DB7, 0x9BD6, // + 0x5DBA, 0x97E4, // + 0x5DBC, 0x9BD7, // + 0x5DBD, 0x9BD4, // + 0x5DC9, 0x9BD8, // + 0x5DCC, 0x8ADE, // + 0x5DCD, 0x9BD9, // + 0x5DD2, 0x9BDB, // + 0x5DD3, 0x9BDA, // + 0x5DD6, 0x9BDC, // + 0x5DDB, 0x9BDD, // + 0x5DDD, 0x90EC, // + 0x5DDE, 0x8F42, // + 0x5DE1, 0x8F84, // + 0x5DE3, 0x9183, // + 0x5DE5, 0x8D48, // + 0x5DE6, 0x8DB6, // + 0x5DE7, 0x8D49, // + 0x5DE8, 0x8B90, // + 0x5DEB, 0x9BDE, // + 0x5DEE, 0x8DB7, // + 0x5DF1, 0x8CC8, // + 0x5DF2, 0x9BDF, // + 0x5DF3, 0x96A4, // + 0x5DF4, 0x9462, // + 0x5DF5, 0x9BE0, // + 0x5DF7, 0x8D4A, // + 0x5DFB, 0x8AAA, // + 0x5DFD, 0x9246, // + 0x5DFE, 0x8BD0, // + 0x5E02, 0x8E73, // + 0x5E03, 0x957A, // + 0x5E06, 0x94BF, // + 0x5E0B, 0x9BE1, // + 0x5E0C, 0x8AF3, // + 0x5E11, 0x9BE4, // + 0x5E16, 0x929F, // + 0x5E19, 0x9BE3, // + 0x5E1A, 0x9BE2, // + 0x5E1B, 0x9BE5, // + 0x5E1D, 0x92E9, // + 0x5E25, 0x9083, // + 0x5E2B, 0x8E74, // + 0x5E2D, 0x90C8, // + 0x5E2F, 0x91D1, // + 0x5E30, 0x8B41, // + 0x5E33, 0x92A0, // + 0x5E36, 0x9BE6, // + 0x5E37, 0x9BE7, // + 0x5E38, 0x8FED, // + 0x5E3D, 0x9658, // + 0x5E40, 0x9BEA, // + 0x5E43, 0x9BE9, // + 0x5E44, 0x9BE8, // + 0x5E45, 0x959D, // + 0x5E47, 0x9BF1, // + 0x5E4C, 0x9679, // + 0x5E4E, 0x9BEB, // + 0x5E54, 0x9BED, // + 0x5E55, 0x968B, // + 0x5E57, 0x9BEC, // + 0x5E5F, 0x9BEE, // + 0x5E61, 0x94A6, // + 0x5E62, 0x9BEF, // + 0x5E63, 0x95BC, // + 0x5E64, 0x9BF0, // + 0x5E72, 0x8AB1, // + 0x5E73, 0x95BD, // + 0x5E74, 0x944E, // + 0x5E75, 0x9BF2, // + 0x5E76, 0x9BF3, // + 0x5E78, 0x8D4B, // + 0x5E79, 0x8AB2, // + 0x5E7A, 0x9BF4, // + 0x5E7B, 0x8CB6, // + 0x5E7C, 0x9763, // + 0x5E7D, 0x9748, // + 0x5E7E, 0x8AF4, // + 0x5E7F, 0x9BF6, // + 0x5E81, 0x92A1, // + 0x5E83, 0x8D4C, // + 0x5E84, 0x8FAF, // + 0x5E87, 0x94DD, // + 0x5E8A, 0x8FB0, // + 0x5E8F, 0x8F98, // + 0x5E95, 0x92EA, // + 0x5E96, 0x95F7, // + 0x5E97, 0x9358, // + 0x5E9A, 0x8D4D, // + 0x5E9C, 0x957B, // + 0x5EA0, 0x9BF7, // + 0x5EA6, 0x9378, // + 0x5EA7, 0x8DC0, // + 0x5EAB, 0x8CC9, // + 0x5EAD, 0x92EB, // + 0x5EB5, 0x88C1, // + 0x5EB6, 0x8F8E, // + 0x5EB7, 0x8D4E, // + 0x5EB8, 0x9766, // + 0x5EC1, 0x9BF8, // + 0x5EC2, 0x9BF9, // + 0x5EC3, 0x9470, // + 0x5EC8, 0x9BFA, // + 0x5EC9, 0x97F5, // + 0x5ECA, 0x984C, // + 0x5ECF, 0x9BFC, // + 0x5ED0, 0x9BFB, // + 0x5ED3, 0x8A66, // + 0x5ED6, 0x9C40, // + 0x5EDA, 0x9C43, // + 0x5EDB, 0x9C44, // + 0x5EDD, 0x9C42, // + 0x5EDF, 0x955F, // + 0x5EE0, 0x8FB1, // + 0x5EE1, 0x9C46, // + 0x5EE2, 0x9C45, // + 0x5EE3, 0x9C41, // + 0x5EE8, 0x9C47, // + 0x5EE9, 0x9C48, // + 0x5EEC, 0x9C49, // + 0x5EF0, 0x9C4C, // + 0x5EF1, 0x9C4A, // + 0x5EF3, 0x9C4B, // + 0x5EF4, 0x9C4D, // + 0x5EF6, 0x8984, // + 0x5EF7, 0x92EC, // + 0x5EF8, 0x9C4E, // + 0x5EFA, 0x8C9A, // + 0x5EFB, 0x89F4, // + 0x5EFC, 0x9455, // + 0x5EFE, 0x9C4F, // + 0x5EFF, 0x93F9, // + 0x5F01, 0x95D9, // + 0x5F03, 0x9C50, // + 0x5F04, 0x984D, // + 0x5F09, 0x9C51, // + 0x5F0A, 0x95BE, // + 0x5F0B, 0x9C54, // + 0x5F0C, 0x989F, // + 0x5F0D, 0x98AF, // + 0x5F0F, 0x8EAE, // + 0x5F10, 0x93F3, // + 0x5F11, 0x9C55, // + 0x5F13, 0x8B7C, // + 0x5F14, 0x92A2, // + 0x5F15, 0x88F8, // + 0x5F16, 0x9C56, // + 0x5F17, 0x95A4, // + 0x5F18, 0x8D4F, // + 0x5F1B, 0x926F, // + 0x5F1F, 0x92ED, // + 0x5F25, 0x96ED, // + 0x5F26, 0x8CB7, // + 0x5F27, 0x8CCA, // + 0x5F29, 0x9C57, // + 0x5F2D, 0x9C58, // + 0x5F2F, 0x9C5E, // + 0x5F31, 0x8EE3, // + 0x5F35, 0x92A3, // + 0x5F37, 0x8BAD, // + 0x5F38, 0x9C59, // + 0x5F3C, 0x954A, // + 0x5F3E, 0x9265, // + 0x5F41, 0x9C5A, // + 0x5F4A, 0x8BAE, // + 0x5F4C, 0x9C5C, // + 0x5F4E, 0x9C5D, // + 0x5F51, 0x9C5F, // + 0x5F53, 0x9396, // + 0x5F56, 0x9C60, // + 0x5F57, 0x9C61, // + 0x5F59, 0x9C62, // + 0x5F5C, 0x9C53, // + 0x5F5D, 0x9C52, // + 0x5F61, 0x9C63, // + 0x5F62, 0x8C60, // + 0x5F66, 0x9546, // + 0x5F69, 0x8DCA, // + 0x5F6A, 0x9556, // + 0x5F6B, 0x92A4, // + 0x5F6C, 0x956A, // + 0x5F6D, 0x9C64, // + 0x5F70, 0x8FB2, // + 0x5F71, 0x8965, // + 0x5F73, 0x9C65, // + 0x5F77, 0x9C66, // + 0x5F79, 0x96F0, // + 0x5F7C, 0x94DE, // + 0x5F7F, 0x9C69, // + 0x5F80, 0x899D, // + 0x5F81, 0x90AA, // + 0x5F82, 0x9C68, // + 0x5F83, 0x9C67, // + 0x5F84, 0x8C61, // + 0x5F85, 0x91D2, // + 0x5F87, 0x9C6D, // + 0x5F88, 0x9C6B, // + 0x5F8A, 0x9C6A, // + 0x5F8B, 0x97A5, // + 0x5F8C, 0x8CE3, // + 0x5F90, 0x8F99, // + 0x5F91, 0x9C6C, // + 0x5F92, 0x936B, // + 0x5F93, 0x8F5D, // + 0x5F97, 0x93BE, // + 0x5F98, 0x9C70, // + 0x5F99, 0x9C6F, // + 0x5F9E, 0x9C6E, // + 0x5FA0, 0x9C71, // + 0x5FA1, 0x8CE4, // + 0x5FA8, 0x9C72, // + 0x5FA9, 0x959C, // + 0x5FAA, 0x8F7A, // + 0x5FAD, 0x9C73, // + 0x5FAE, 0x94F7, // + 0x5FB3, 0x93BF, // + 0x5FB4, 0x92A5, // + 0x5FB9, 0x934F, // + 0x5FBC, 0x9C74, // + 0x5FBD, 0x8B4A, // + 0x5FC3, 0x9053, // + 0x5FC5, 0x954B, // + 0x5FCC, 0x8AF5, // + 0x5FCD, 0x9445, // + 0x5FD6, 0x9C75, // + 0x5FD7, 0x8E75, // + 0x5FD8, 0x9659, // + 0x5FD9, 0x965A, // + 0x5FDC, 0x899E, // + 0x5FDD, 0x9C7A, // + 0x5FE0, 0x9289, // + 0x5FE4, 0x9C77, // + 0x5FEB, 0x89F5, // + 0x5FF0, 0x9CAB, // + 0x5FF1, 0x9C79, // + 0x5FF5, 0x944F, // + 0x5FF8, 0x9C78, // + 0x5FFB, 0x9C76, // + 0x5FFD, 0x8D9A, // + 0x5FFF, 0x9C7C, // + 0x600E, 0x9C83, // + 0x600F, 0x9C89, // + 0x6010, 0x9C81, // + 0x6012, 0x937B, // + 0x6015, 0x9C86, // + 0x6016, 0x957C, // + 0x6019, 0x9C80, // + 0x601B, 0x9C85, // + 0x601C, 0x97E5, // + 0x601D, 0x8E76, // + 0x6020, 0x91D3, // + 0x6021, 0x9C7D, // + 0x6025, 0x8B7D, // + 0x6026, 0x9C88, // + 0x6027, 0x90AB, // + 0x6028, 0x8985, // + 0x6029, 0x9C82, // + 0x602A, 0x89F6, // + 0x602B, 0x9C87, // + 0x602F, 0x8BAF, // + 0x6031, 0x9C84, // + 0x603A, 0x9C8A, // + 0x6041, 0x9C8C, // + 0x6042, 0x9C96, // + 0x6043, 0x9C94, // + 0x6046, 0x9C91, // + 0x604A, 0x9C90, // + 0x604B, 0x97F6, // + 0x604D, 0x9C92, // + 0x6050, 0x8BB0, // + 0x6052, 0x8D50, // + 0x6055, 0x8F9A, // + 0x6059, 0x9C99, // + 0x605A, 0x9C8B, // + 0x605F, 0x9C8F, // + 0x6060, 0x9C7E, // + 0x6062, 0x89F8, // + 0x6063, 0x9C93, // + 0x6064, 0x9C95, // + 0x6065, 0x9270, // + 0x6068, 0x8DA6, // + 0x6069, 0x89B6, // + 0x606A, 0x9C8D, // + 0x606B, 0x9C98, // + 0x606C, 0x9C97, // + 0x606D, 0x8BB1, // + 0x606F, 0x91A7, // + 0x6070, 0x8A86, // + 0x6075, 0x8C62, // + 0x6077, 0x9C8E, // + 0x6081, 0x9C9A, // + 0x6083, 0x9C9D, // + 0x6084, 0x9C9F, // + 0x6089, 0x8EBB, // + 0x608B, 0x9CA5, // + 0x608C, 0x92EE, // + 0x608D, 0x9C9B, // + 0x6092, 0x9CA3, // + 0x6094, 0x89F7, // + 0x6096, 0x9CA1, // + 0x6097, 0x9CA2, // + 0x609A, 0x9C9E, // + 0x609B, 0x9CA0, // + 0x609F, 0x8CE5, // + 0x60A0, 0x9749, // + 0x60A3, 0x8AB3, // + 0x60A6, 0x8978, // + 0x60A7, 0x9CA4, // + 0x60A9, 0x9459, // + 0x60AA, 0x88AB, // + 0x60B2, 0x94DF, // + 0x60B3, 0x9C7B, // + 0x60B4, 0x9CAA, // + 0x60B5, 0x9CAE, // + 0x60B6, 0x96E3, // + 0x60B8, 0x9CA7, // + 0x60BC, 0x9389, // + 0x60BD, 0x9CAC, // + 0x60C5, 0x8FEE, // + 0x60C6, 0x9CAD, // + 0x60C7, 0x93D5, // + 0x60D1, 0x9866, // + 0x60D3, 0x9CA9, // + 0x60D8, 0x9CAF, // + 0x60DA, 0x8D9B, // + 0x60DC, 0x90C9, // + 0x60DF, 0x88D2, // + 0x60E0, 0x9CA8, // + 0x60E1, 0x9CA6, // + 0x60E3, 0x9179, // + 0x60E7, 0x9C9C, // + 0x60E8, 0x8E53, // + 0x60F0, 0x91C4, // + 0x60F1, 0x9CBB, // + 0x60F3, 0x917A, // + 0x60F4, 0x9CB6, // + 0x60F6, 0x9CB3, // + 0x60F7, 0x9CB4, // + 0x60F9, 0x8EE4, // + 0x60FA, 0x9CB7, // + 0x60FB, 0x9CBA, // + 0x6100, 0x9CB5, // + 0x6101, 0x8F44, // + 0x6103, 0x9CB8, // + 0x6106, 0x9CB2, // + 0x6108, 0x96FA, // + 0x6109, 0x96F9, // + 0x610D, 0x9CBC, // + 0x610E, 0x9CBD, // + 0x610F, 0x88D3, // + 0x6115, 0x9CB1, // + 0x611A, 0x8BF0, // + 0x611B, 0x88A4, // + 0x611F, 0x8AB4, // + 0x6121, 0x9CB9, // + 0x6127, 0x9CC1, // + 0x6128, 0x9CC0, // + 0x612C, 0x9CC5, // + 0x6134, 0x9CC6, // + 0x613C, 0x9CC4, // + 0x613D, 0x9CC7, // + 0x613E, 0x9CBF, // + 0x613F, 0x9CC3, // + 0x6142, 0x9CC8, // + 0x6144, 0x9CC9, // + 0x6147, 0x9CBE, // + 0x6148, 0x8E9C, // + 0x614A, 0x9CC2, // + 0x614B, 0x91D4, // + 0x614C, 0x8D51, // + 0x614D, 0x9CB0, // + 0x614E, 0x9054, // + 0x6153, 0x9CD6, // + 0x6155, 0x95E7, // + 0x6158, 0x9CCC, // + 0x6159, 0x9CCD, // + 0x615A, 0x9CCE, // + 0x615D, 0x9CD5, // + 0x615F, 0x9CD4, // + 0x6162, 0x969D, // + 0x6163, 0x8AB5, // + 0x6165, 0x9CD2, // + 0x6167, 0x8C64, // + 0x6168, 0x8A53, // + 0x616B, 0x9CCF, // + 0x616E, 0x97B6, // + 0x616F, 0x9CD1, // + 0x6170, 0x88D4, // + 0x6171, 0x9CD3, // + 0x6173, 0x9CCA, // + 0x6174, 0x9CD0, // + 0x6175, 0x9CD7, // + 0x6176, 0x8C63, // + 0x6177, 0x9CCB, // + 0x617E, 0x977C, // + 0x6182, 0x974A, // + 0x6187, 0x9CDA, // + 0x618A, 0x9CDE, // + 0x618E, 0x919E, // + 0x6190, 0x97F7, // + 0x6191, 0x9CDF, // + 0x6194, 0x9CDC, // + 0x6196, 0x9CD9, // + 0x6199, 0x9CD8, // + 0x619A, 0x9CDD, // + 0x61A4, 0x95AE, // + 0x61A7, 0x93B2, // + 0x61A9, 0x8C65, // + 0x61AB, 0x9CE0, // + 0x61AC, 0x9CDB, // + 0x61AE, 0x9CE1, // + 0x61B2, 0x8C9B, // + 0x61B6, 0x89AF, // + 0x61BA, 0x9CE9, // + 0x61BE, 0x8AB6, // + 0x61C3, 0x9CE7, // + 0x61C6, 0x9CE8, // + 0x61C7, 0x8DA7, // + 0x61C8, 0x9CE6, // + 0x61C9, 0x9CE4, // + 0x61CA, 0x9CE3, // + 0x61CB, 0x9CEA, // + 0x61CC, 0x9CE2, // + 0x61CD, 0x9CEC, // + 0x61D0, 0x89F9, // + 0x61E3, 0x9CEE, // + 0x61E6, 0x9CED, // + 0x61F2, 0x92A6, // + 0x61F4, 0x9CF1, // + 0x61F6, 0x9CEF, // + 0x61F7, 0x9CE5, // + 0x61F8, 0x8C9C, // + 0x61FA, 0x9CF0, // + 0x61FC, 0x9CF4, // + 0x61FD, 0x9CF3, // + 0x61FE, 0x9CF5, // + 0x61FF, 0x9CF2, // + 0x6200, 0x9CF6, // + 0x6208, 0x9CF7, // + 0x6209, 0x9CF8, // + 0x620A, 0x95E8, // + 0x620C, 0x9CFA, // + 0x620D, 0x9CF9, // + 0x620E, 0x8F5E, // + 0x6210, 0x90AC, // + 0x6211, 0x89E4, // + 0x6212, 0x89FA, // + 0x6214, 0x9CFB, // + 0x6216, 0x88BD, // + 0x621A, 0x90CA, // + 0x621B, 0x9CFC, // + 0x621D, 0xE6C1, // + 0x621E, 0x9D40, // + 0x621F, 0x8C81, // + 0x6221, 0x9D41, // + 0x6226, 0x90ED, // + 0x622A, 0x9D42, // + 0x622E, 0x9D43, // + 0x622F, 0x8B59, // + 0x6230, 0x9D44, // + 0x6232, 0x9D45, // + 0x6233, 0x9D46, // + 0x6234, 0x91D5, // + 0x6238, 0x8CCB, // + 0x623B, 0x96DF, // + 0x6240, 0x8F8A, // + 0x6241, 0x9D47, // + 0x6247, 0x90EE, // + 0x6248, 0xE7BB, // + 0x6249, 0x94E0, // + 0x624B, 0x8EE8, // + 0x624D, 0x8DCB, // + 0x624E, 0x9D48, // + 0x6253, 0x91C5, // + 0x6255, 0x95A5, // + 0x6258, 0x91EF, // + 0x625B, 0x9D4B, // + 0x625E, 0x9D49, // + 0x6260, 0x9D4C, // + 0x6263, 0x9D4A, // + 0x6268, 0x9D4D, // + 0x626E, 0x95AF, // + 0x6271, 0x88B5, // + 0x6276, 0x957D, // + 0x6279, 0x94E1, // + 0x627C, 0x9D4E, // + 0x627E, 0x9D51, // + 0x627F, 0x8FB3, // + 0x6280, 0x8B5A, // + 0x6282, 0x9D4F, // + 0x6283, 0x9D56, // + 0x6284, 0x8FB4, // + 0x6289, 0x9D50, // + 0x628A, 0x9463, // + 0x6291, 0x977D, // + 0x6292, 0x9D52, // + 0x6293, 0x9D53, // + 0x6294, 0x9D57, // + 0x6295, 0x938A, // + 0x6296, 0x9D54, // + 0x6297, 0x8D52, // + 0x6298, 0x90DC, // + 0x629B, 0x9D65, // + 0x629C, 0x94B2, // + 0x629E, 0x91F0, // + 0x62AB, 0x94E2, // + 0x62AC, 0x9DAB, // + 0x62B1, 0x95F8, // + 0x62B5, 0x92EF, // + 0x62B9, 0x9695, // + 0x62BB, 0x9D5A, // + 0x62BC, 0x899F, // + 0x62BD, 0x928A, // + 0x62C2, 0x9D63, // + 0x62C5, 0x9253, // + 0x62C6, 0x9D5D, // + 0x62C7, 0x9D64, // + 0x62C8, 0x9D5F, // + 0x62C9, 0x9D66, // + 0x62CA, 0x9D62, // + 0x62CC, 0x9D61, // + 0x62CD, 0x948F, // + 0x62D0, 0x89FB, // + 0x62D1, 0x9D59, // + 0x62D2, 0x8B91, // + 0x62D3, 0x91F1, // + 0x62D4, 0x9D55, // + 0x62D7, 0x9D58, // + 0x62D8, 0x8D53, // + 0x62D9, 0x90D9, // + 0x62DB, 0x8FB5, // + 0x62DC, 0x9D60, // + 0x62DD, 0x9471, // + 0x62E0, 0x8B92, // + 0x62E1, 0x8A67, // + 0x62EC, 0x8A87, // + 0x62ED, 0x9040, // + 0x62EE, 0x9D68, // + 0x62EF, 0x9D6D, // + 0x62F1, 0x9D69, // + 0x62F3, 0x8C9D, // + 0x62F5, 0x9D6E, // + 0x62F6, 0x8E41, // + 0x62F7, 0x8D89, // + 0x62FE, 0x8F45, // + 0x62FF, 0x9D5C, // + 0x6301, 0x8E9D, // + 0x6302, 0x9D6B, // + 0x6307, 0x8E77, // + 0x6308, 0x9D6C, // + 0x6309, 0x88C2, // + 0x630C, 0x9D67, // + 0x6311, 0x92A7, // + 0x6319, 0x8B93, // + 0x631F, 0x8BB2, // + 0x6327, 0x9D6A, // + 0x6328, 0x88A5, // + 0x632B, 0x8DC1, // + 0x632F, 0x9055, // + 0x633A, 0x92F0, // + 0x633D, 0x94D2, // + 0x633E, 0x9D70, // + 0x633F, 0x917D, // + 0x6349, 0x91A8, // + 0x634C, 0x8E4A, // + 0x634D, 0x9D71, // + 0x634F, 0x9D73, // + 0x6350, 0x9D6F, // + 0x6355, 0x95DF, // + 0x6357, 0x92BB, // + 0x635C, 0x917B, // + 0x6367, 0x95F9, // + 0x6368, 0x8ECC, // + 0x6369, 0x9D80, // + 0x636B, 0x9D7E, // + 0x636E, 0x9098, // + 0x6372, 0x8C9E, // + 0x6376, 0x9D78, // + 0x6377, 0x8FB7, // + 0x637A, 0x93E6, // + 0x637B, 0x9450, // + 0x6380, 0x9D76, // + 0x6383, 0x917C, // + 0x6388, 0x8EF6, // + 0x6389, 0x9D7B, // + 0x638C, 0x8FB6, // + 0x638E, 0x9D75, // + 0x638F, 0x9D7A, // + 0x6392, 0x9472, // + 0x6396, 0x9D74, // + 0x6398, 0x8C40, // + 0x639B, 0x8A7C, // + 0x639F, 0x9D7C, // + 0x63A0, 0x97A9, // + 0x63A1, 0x8DCC, // + 0x63A2, 0x9254, // + 0x63A3, 0x9D79, // + 0x63A5, 0x90DA, // + 0x63A7, 0x8D54, // + 0x63A8, 0x9084, // + 0x63A9, 0x8986, // + 0x63AB, 0x9D77, // + 0x63AC, 0x8B64, // + 0x63B2, 0x8C66, // + 0x63B4, 0x92CD, // + 0x63B5, 0x9D7D, // + 0x63BB, 0x917E, // + 0x63BE, 0x9D81, // + 0x63C0, 0x9D83, // + 0x63C3, 0x91B5, // + 0x63C4, 0x9D89, // + 0x63C6, 0x9D84, // + 0x63C9, 0x9D86, // + 0x63CF, 0x9560, // + 0x63D0, 0x92F1, // + 0x63D2, 0x9D87, // + 0x63D6, 0x974B, // + 0x63DA, 0x9767, // + 0x63DB, 0x8AB7, // + 0x63E1, 0x88AC, // + 0x63E3, 0x9D85, // + 0x63E9, 0x9D82, // + 0x63EE, 0x8AF6, // + 0x63F4, 0x8987, // + 0x63F6, 0x9D88, // + 0x63FA, 0x9768, // + 0x6406, 0x9D8C, // + 0x640D, 0x91B9, // + 0x640F, 0x9D93, // + 0x6413, 0x9D8D, // + 0x6416, 0x9D8A, // + 0x6417, 0x9D91, // + 0x641C, 0x9D72, // + 0x6426, 0x9D8E, // + 0x6428, 0x9D92, // + 0x642C, 0x94C0, // + 0x642D, 0x938B, // + 0x6434, 0x9D8B, // + 0x6436, 0x9D8F, // + 0x643A, 0x8C67, // + 0x643E, 0x8DEF, // + 0x6442, 0x90DB, // + 0x644E, 0x9D97, // + 0x6458, 0x9345, // + 0x6467, 0x9D94, // + 0x6469, 0x9680, // + 0x646F, 0x9D95, // + 0x6476, 0x9D96, // + 0x6478, 0x96CC, // + 0x647A, 0x90A0, // + 0x6483, 0x8C82, // + 0x6488, 0x9D9D, // + 0x6492, 0x8E54, // + 0x6493, 0x9D9A, // + 0x6495, 0x9D99, // + 0x649A, 0x9451, // + 0x649E, 0x93B3, // + 0x64A4, 0x9350, // + 0x64A5, 0x9D9B, // + 0x64A9, 0x9D9C, // + 0x64AB, 0x958F, // + 0x64AD, 0x9464, // + 0x64AE, 0x8E42, // + 0x64B0, 0x90EF, // + 0x64B2, 0x966F, // + 0x64B9, 0x8A68, // + 0x64BB, 0x9DA3, // + 0x64BC, 0x9D9E, // + 0x64C1, 0x9769, // + 0x64C2, 0x9DA5, // + 0x64C5, 0x9DA1, // + 0x64C7, 0x9DA2, // + 0x64CD, 0x9180, // + 0x64D2, 0x9DA0, // + 0x64D4, 0x9D5E, // + 0x64D8, 0x9DA4, // + 0x64DA, 0x9D9F, // + 0x64E0, 0x9DA9, // + 0x64E1, 0x9DAA, // + 0x64E2, 0x9346, // + 0x64E3, 0x9DAC, // + 0x64E6, 0x8E43, // + 0x64E7, 0x9DA7, // + 0x64EF, 0x9DAD, // + 0x64F1, 0x9DA6, // + 0x64F2, 0x9DB1, // + 0x64F4, 0x9DB0, // + 0x64F6, 0x9DAF, // + 0x64FA, 0x9DB2, // + 0x64FD, 0x9DB4, // + 0x64FE, 0x8FEF, // + 0x6500, 0x9DB3, // + 0x6505, 0x9DB7, // + 0x6518, 0x9DB5, // + 0x651C, 0x9DB6, // + 0x651D, 0x9D90, // + 0x6523, 0x9DB9, // + 0x6524, 0x9DB8, // + 0x652A, 0x9D98, // + 0x652B, 0x9DBA, // + 0x652C, 0x9DAE, // + 0x652F, 0x8E78, // + 0x6534, 0x9DBB, // + 0x6535, 0x9DBC, // + 0x6536, 0x9DBE, // + 0x6537, 0x9DBD, // + 0x6538, 0x9DBF, // + 0x6539, 0x89FC, // + 0x653B, 0x8D55, // + 0x653E, 0x95FA, // + 0x653F, 0x90AD, // + 0x6545, 0x8CCC, // + 0x6548, 0x9DC1, // + 0x654D, 0x9DC4, // + 0x654F, 0x9571, // + 0x6551, 0x8B7E, // + 0x6555, 0x9DC3, // + 0x6556, 0x9DC2, // + 0x6557, 0x9473, // + 0x6558, 0x9DC5, // + 0x6559, 0x8BB3, // + 0x655D, 0x9DC7, // + 0x655E, 0x9DC6, // + 0x6562, 0x8AB8, // + 0x6563, 0x8E55, // + 0x6566, 0x93D6, // + 0x656C, 0x8C68, // + 0x6570, 0x9094, // + 0x6572, 0x9DC8, // + 0x6574, 0x90AE, // + 0x6575, 0x9347, // + 0x6577, 0x957E, // + 0x6578, 0x9DC9, // + 0x6582, 0x9DCA, // + 0x6583, 0x9DCB, // + 0x6587, 0x95B6, // + 0x6588, 0x9B7C, // + 0x6589, 0x90C4, // + 0x658C, 0x956B, // + 0x658E, 0x8DD6, // + 0x6590, 0x94E3, // + 0x6591, 0x94C1, // + 0x6597, 0x936C, // + 0x6599, 0x97BF, // + 0x659B, 0x9DCD, // + 0x659C, 0x8ECE, // + 0x659F, 0x9DCE, // + 0x65A1, 0x88B4, // + 0x65A4, 0x8BD2, // + 0x65A5, 0x90CB, // + 0x65A7, 0x9580, // + 0x65AB, 0x9DCF, // + 0x65AC, 0x8E61, // + 0x65AD, 0x9266, // + 0x65AF, 0x8E7A, // + 0x65B0, 0x9056, // + 0x65B7, 0x9DD0, // + 0x65B9, 0x95FB, // + 0x65BC, 0x8997, // + 0x65BD, 0x8E7B, // + 0x65C1, 0x9DD3, // + 0x65C3, 0x9DD1, // + 0x65C4, 0x9DD4, // + 0x65C5, 0x97B7, // + 0x65C6, 0x9DD2, // + 0x65CB, 0x90F9, // + 0x65CC, 0x9DD5, // + 0x65CF, 0x91B0, // + 0x65D2, 0x9DD6, // + 0x65D7, 0x8AF8, // + 0x65D9, 0x9DD8, // + 0x65DB, 0x9DD7, // + 0x65E0, 0x9DD9, // + 0x65E1, 0x9DDA, // + 0x65E2, 0x8AF9, // + 0x65E5, 0x93FA, // + 0x65E6, 0x9255, // + 0x65E7, 0x8B8C, // + 0x65E8, 0x8E7C, // + 0x65E9, 0x9181, // + 0x65EC, 0x8F7B, // + 0x65ED, 0x88AE, // + 0x65F1, 0x9DDB, // + 0x65FA, 0x89A0, // + 0x65FB, 0x9DDF, // + 0x6602, 0x8D56, // + 0x6603, 0x9DDE, // + 0x6606, 0x8DA9, // + 0x6607, 0x8FB8, // + 0x660A, 0x9DDD, // + 0x660C, 0x8FB9, // + 0x660E, 0x96BE, // + 0x660F, 0x8DA8, // + 0x6613, 0x88D5, // + 0x6614, 0x90CC, // + 0x661C, 0x9DE4, // + 0x661F, 0x90AF, // + 0x6620, 0x8966, // + 0x6625, 0x8F74, // + 0x6627, 0x9686, // + 0x6628, 0x8DF0, // + 0x662D, 0x8FBA, // + 0x662F, 0x90A5, // + 0x6634, 0x9DE3, // + 0x6635, 0x9DE1, // + 0x6636, 0x9DE2, // + 0x663C, 0x928B, // + 0x663F, 0x9E45, // + 0x6641, 0x9DE8, // + 0x6642, 0x8E9E, // + 0x6643, 0x8D57, // + 0x6644, 0x9DE6, // + 0x6649, 0x9DE7, // + 0x664B, 0x9057, // + 0x664F, 0x9DE5, // + 0x6652, 0x8E4E, // + 0x665D, 0x9DEA, // + 0x665E, 0x9DE9, // + 0x665F, 0x9DEE, // + 0x6662, 0x9DEF, // + 0x6664, 0x9DEB, // + 0x6666, 0x8A41, // + 0x6667, 0x9DEC, // + 0x6668, 0x9DED, // + 0x6669, 0x94D3, // + 0x666E, 0x9581, // + 0x666F, 0x8C69, // + 0x6670, 0x9DF0, // + 0x6674, 0x90B0, // + 0x6676, 0x8FBB, // + 0x667A, 0x9271, // + 0x6681, 0x8BC5, // + 0x6683, 0x9DF1, // + 0x6684, 0x9DF5, // + 0x6687, 0x89C9, // + 0x6688, 0x9DF2, // + 0x6689, 0x9DF4, // + 0x668E, 0x9DF3, // + 0x6691, 0x8F8B, // + 0x6696, 0x9267, // + 0x6697, 0x88C3, // + 0x6698, 0x9DF6, // + 0x669D, 0x9DF7, // + 0x66A2, 0x92A8, // + 0x66A6, 0x97EF, // + 0x66AB, 0x8E62, // + 0x66AE, 0x95E9, // + 0x66B4, 0x965C, // + 0x66B8, 0x9E41, // + 0x66B9, 0x9DF9, // + 0x66BC, 0x9DFC, // + 0x66BE, 0x9DFB, // + 0x66C1, 0x9DF8, // + 0x66C4, 0x9E40, // + 0x66C7, 0x93DC, // + 0x66C9, 0x9DFA, // + 0x66D6, 0x9E42, // + 0x66D9, 0x8F8C, // + 0x66DA, 0x9E43, // + 0x66DC, 0x976A, // + 0x66DD, 0x9498, // + 0x66E0, 0x9E44, // + 0x66E6, 0x9E46, // + 0x66E9, 0x9E47, // + 0x66F0, 0x9E48, // + 0x66F2, 0x8BC8, // + 0x66F3, 0x8967, // + 0x66F4, 0x8D58, // + 0x66F5, 0x9E49, // + 0x66F7, 0x9E4A, // + 0x66F8, 0x8F91, // + 0x66F9, 0x9182, // + 0x66FC, 0x99D6, // + 0x66FD, 0x915D, // + 0x66FE, 0x915C, // + 0x66FF, 0x91D6, // + 0x6700, 0x8DC5, // + 0x6703, 0x98F0, // + 0x6708, 0x8C8E, // + 0x6709, 0x974C, // + 0x670B, 0x95FC, // + 0x670D, 0x959E, // + 0x670F, 0x9E4B, // + 0x6714, 0x8DF1, // + 0x6715, 0x92BD, // + 0x6716, 0x9E4C, // + 0x6717, 0x984E, // + 0x671B, 0x965D, // + 0x671D, 0x92A9, // + 0x671E, 0x9E4D, // + 0x671F, 0x8AFA, // + 0x6726, 0x9E4E, // + 0x6727, 0x9E4F, // + 0x6728, 0x96D8, // + 0x672A, 0x96A2, // + 0x672B, 0x9696, // + 0x672C, 0x967B, // + 0x672D, 0x8E44, // + 0x672E, 0x9E51, // + 0x6731, 0x8EE9, // + 0x6734, 0x9670, // + 0x6736, 0x9E53, // + 0x6737, 0x9E56, // + 0x6738, 0x9E55, // + 0x673A, 0x8AF7, // + 0x673D, 0x8B80, // + 0x673F, 0x9E52, // + 0x6741, 0x9E54, // + 0x6746, 0x9E57, // + 0x6749, 0x9099, // + 0x674E, 0x979B, // + 0x674F, 0x88C7, // + 0x6750, 0x8DDE, // + 0x6751, 0x91BA, // + 0x6753, 0x8EDB, // + 0x6756, 0x8FF1, // + 0x6759, 0x9E5A, // + 0x675C, 0x936D, // + 0x675E, 0x9E58, // + 0x675F, 0x91A9, // + 0x6760, 0x9E59, // + 0x6761, 0x8FF0, // + 0x6762, 0x96DB, // + 0x6764, 0x9E5C, // + 0x6765, 0x9788, // + 0x676A, 0x9E61, // + 0x676D, 0x8D59, // + 0x676F, 0x9474, // + 0x6770, 0x9E5E, // + 0x6771, 0x938C, // + 0x6772, 0x9DDC, // + 0x6773, 0x9DE0, // + 0x6775, 0x8B6E, // + 0x6777, 0x9466, // + 0x677C, 0x9E60, // + 0x677E, 0x8FBC, // + 0x677F, 0x94C2, // + 0x6785, 0x9E66, // + 0x6787, 0x94F8, // + 0x6789, 0x9E5D, // + 0x678B, 0x9E63, // + 0x678C, 0x9E62, // + 0x6790, 0x90CD, // + 0x6795, 0x968D, // + 0x6797, 0x97D1, // + 0x679A, 0x9687, // + 0x679C, 0x89CA, // + 0x679D, 0x8E7D, // + 0x67A0, 0x9867, // + 0x67A1, 0x9E65, // + 0x67A2, 0x9095, // + 0x67A6, 0x9E64, // + 0x67A9, 0x9E5F, // + 0x67AF, 0x8CCD, // + 0x67B3, 0x9E6B, // + 0x67B4, 0x9E69, // + 0x67B6, 0x89CB, // + 0x67B7, 0x9E67, // + 0x67B8, 0x9E6D, // + 0x67B9, 0x9E73, // + 0x67C1, 0x91C6, // + 0x67C4, 0x95BF, // + 0x67C6, 0x9E75, // + 0x67CA, 0x9541, // + 0x67CE, 0x9E74, // + 0x67CF, 0x9490, // + 0x67D0, 0x965E, // + 0x67D1, 0x8AB9, // + 0x67D3, 0x90F5, // + 0x67D4, 0x8F5F, // + 0x67D8, 0x92D1, // + 0x67DA, 0x974D, // + 0x67DD, 0x9E70, // + 0x67DE, 0x9E6F, // + 0x67E2, 0x9E71, // + 0x67E4, 0x9E6E, // + 0x67E7, 0x9E76, // + 0x67E9, 0x9E6C, // + 0x67EC, 0x9E6A, // + 0x67EE, 0x9E72, // + 0x67EF, 0x9E68, // + 0x67F1, 0x928C, // + 0x67F3, 0x96F6, // + 0x67F4, 0x8EC4, // + 0x67F5, 0x8DF2, // + 0x67FB, 0x8DB8, // + 0x67FE, 0x968F, // + 0x67FF, 0x8A60, // + 0x6802, 0x92CC, // + 0x6803, 0x93C8, // + 0x6804, 0x8968, // + 0x6813, 0x90F0, // + 0x6816, 0x90B2, // + 0x6817, 0x8C49, // + 0x681E, 0x9E78, // + 0x6821, 0x8D5A, // + 0x6822, 0x8A9C, // + 0x6829, 0x9E7A, // + 0x682A, 0x8A94, // + 0x682B, 0x9E81, // + 0x6832, 0x9E7D, // + 0x6834, 0x90F1, // + 0x6838, 0x8A6A, // + 0x6839, 0x8DAA, // + 0x683C, 0x8A69, // + 0x683D, 0x8DCD, // + 0x6840, 0x9E7B, // + 0x6841, 0x8C85, // + 0x6842, 0x8C6A, // + 0x6843, 0x938D, // + 0x6846, 0x9E79, // + 0x6848, 0x88C4, // + 0x684D, 0x9E7C, // + 0x684E, 0x9E7E, // + 0x6850, 0x8BCB, // + 0x6851, 0x8C4B, // + 0x6853, 0x8ABA, // + 0x6854, 0x8B6A, // + 0x6859, 0x9E82, // + 0x685C, 0x8DF7, // + 0x685D, 0x9691, // + 0x685F, 0x8E56, // + 0x6863, 0x9E83, // + 0x6867, 0x954F, // + 0x6874, 0x9E8F, // + 0x6876, 0x89B1, // + 0x6877, 0x9E84, // + 0x687E, 0x9E95, // + 0x687F, 0x9E85, // + 0x6881, 0x97C0, // + 0x6883, 0x9E8C, // + 0x6885, 0x947E, // + 0x688D, 0x9E94, // + 0x688F, 0x9E87, // + 0x6893, 0x88B2, // + 0x6894, 0x9E89, // + 0x689B, 0x9E8B, // + 0x689D, 0x9E8A, // + 0x689F, 0x9E86, // + 0x68A0, 0x9E91, // + 0x68A2, 0x8FBD, // + 0x68A6, 0x9AEB, // + 0x68A7, 0x8CE6, // + 0x68A8, 0x979C, // + 0x68AD, 0x9E88, // + 0x68AF, 0x92F2, // + 0x68B0, 0x8A42, // + 0x68B1, 0x8DAB, // + 0x68B3, 0x9E80, // + 0x68B5, 0x9E90, // + 0x68B6, 0x8A81, // + 0x68B9, 0x9E8E, // + 0x68BA, 0x9E92, // + 0x68BC, 0x938E, // + 0x68C4, 0x8AFC, // + 0x68C6, 0x9EB0, // + 0x68C9, 0x96C7, // + 0x68CA, 0x9E97, // + 0x68CB, 0x8AFB, // + 0x68CD, 0x9E9E, // + 0x68D2, 0x965F, // + 0x68D4, 0x9E9F, // + 0x68D5, 0x9EA1, // + 0x68D7, 0x9EA5, // + 0x68D8, 0x9E99, // + 0x68DA, 0x9249, // + 0x68DF, 0x938F, // + 0x68E0, 0x9EA9, // + 0x68E1, 0x9E9C, // + 0x68E3, 0x9EA6, // + 0x68E7, 0x9EA0, // + 0x68EE, 0x9058, // + 0x68EF, 0x9EAA, // + 0x68F2, 0x90B1, // + 0x68F9, 0x9EA8, // + 0x68FA, 0x8ABB, // + 0x6900, 0x986F, // + 0x6901, 0x9E96, // + 0x6904, 0x9EA4, // + 0x6905, 0x88D6, // + 0x6908, 0x9E98, // + 0x690B, 0x96B8, // + 0x690C, 0x9E9D, // + 0x690D, 0x9041, // + 0x690E, 0x92C5, // + 0x690F, 0x9E93, // + 0x6912, 0x9EA3, // + 0x6919, 0x909A, // + 0x691A, 0x9EAD, // + 0x691B, 0x8A91, // + 0x691C, 0x8C9F, // + 0x6921, 0x9EAF, // + 0x6922, 0x9E9A, // + 0x6923, 0x9EAE, // + 0x6925, 0x9EA7, // + 0x6926, 0x9E9B, // + 0x6928, 0x9EAB, // + 0x692A, 0x9EAC, // + 0x6930, 0x9EBD, // + 0x6934, 0x93CC, // + 0x6936, 0x9EA2, // + 0x6939, 0x9EB9, // + 0x693D, 0x9EBB, // + 0x693F, 0x92D6, // + 0x694A, 0x976B, // + 0x6953, 0x9596, // + 0x6954, 0x9EB6, // + 0x6955, 0x91C8, // + 0x6959, 0x9EBC, // + 0x695A, 0x915E, // + 0x695C, 0x9EB3, // + 0x695D, 0x9EC0, // + 0x695E, 0x9EBF, // + 0x6960, 0x93ED, // + 0x6961, 0x9EBE, // + 0x6962, 0x93E8, // + 0x696A, 0x9EC2, // + 0x696B, 0x9EB5, // + 0x696D, 0x8BC6, // + 0x696E, 0x9EB8, // + 0x696F, 0x8F7C, // + 0x6973, 0x9480, // + 0x6974, 0x9EBA, // + 0x6975, 0x8BC9, // + 0x6977, 0x9EB2, // + 0x6978, 0x9EB4, // + 0x6979, 0x9EB1, // + 0x697C, 0x984F, // + 0x697D, 0x8A79, // + 0x697E, 0x9EB7, // + 0x6981, 0x9EC1, // + 0x6982, 0x8A54, // + 0x698A, 0x8DE5, // + 0x698E, 0x897C, // + 0x6991, 0x9ED2, // + 0x6994, 0x9850, // + 0x6995, 0x9ED5, // + 0x699B, 0x9059, // + 0x699C, 0x9ED4, // + 0x69A0, 0x9ED3, // + 0x69A7, 0x9ED0, // + 0x69AE, 0x9EC4, // + 0x69B1, 0x9EE1, // + 0x69B2, 0x9EC3, // + 0x69B4, 0x9ED6, // + 0x69BB, 0x9ECE, // + 0x69BE, 0x9EC9, // + 0x69BF, 0x9EC6, // + 0x69C1, 0x9EC7, // + 0x69C3, 0x9ECF, // + 0x69C7, 0xEAA0, // + 0x69CA, 0x9ECC, // + 0x69CB, 0x8D5C, // + 0x69CC, 0x92C6, // + 0x69CD, 0x9184, // + 0x69CE, 0x9ECA, // + 0x69D0, 0x9EC5, // + 0x69D3, 0x9EC8, // + 0x69D8, 0x976C, // + 0x69D9, 0x968A, // + 0x69DD, 0x9ECD, // + 0x69DE, 0x9ED7, // + 0x69E7, 0x9EDF, // + 0x69E8, 0x9ED8, // + 0x69EB, 0x9EE5, // + 0x69ED, 0x9EE3, // + 0x69F2, 0x9EDE, // + 0x69F9, 0x9EDD, // + 0x69FB, 0x92CE, // + 0x69FD, 0x9185, // + 0x69FF, 0x9EDB, // + 0x6A02, 0x9ED9, // + 0x6A05, 0x9EE0, // + 0x6A0A, 0x9EE6, // + 0x6A0B, 0x94F3, // + 0x6A0C, 0x9EEC, // + 0x6A12, 0x9EE7, // + 0x6A13, 0x9EEA, // + 0x6A14, 0x9EE4, // + 0x6A17, 0x9294, // + 0x6A19, 0x9557, // + 0x6A1B, 0x9EDA, // + 0x6A1E, 0x9EE2, // + 0x6A1F, 0x8FBE, // + 0x6A21, 0x96CD, // + 0x6A22, 0x9EF6, // + 0x6A23, 0x9EE9, // + 0x6A29, 0x8CA0, // + 0x6A2A, 0x89A1, // + 0x6A2B, 0x8A7E, // + 0x6A2E, 0x9ED1, // + 0x6A35, 0x8FBF, // + 0x6A36, 0x9EEE, // + 0x6A38, 0x9EF5, // + 0x6A39, 0x8EF7, // + 0x6A3A, 0x8A92, // + 0x6A3D, 0x924D, // + 0x6A44, 0x9EEB, // + 0x6A47, 0x9EF0, // + 0x6A48, 0x9EF4, // + 0x6A4B, 0x8BB4, // + 0x6A58, 0x8B6B, // + 0x6A59, 0x9EF2, // + 0x6A5F, 0x8B40, // + 0x6A61, 0x93C9, // + 0x6A62, 0x9EF1, // + 0x6A66, 0x9EF3, // + 0x6A72, 0x9EED, // + 0x6A78, 0x9EEF, // + 0x6A7F, 0x8A80, // + 0x6A80, 0x9268, // + 0x6A84, 0x9EFA, // + 0x6A8D, 0x9EF8, // + 0x6A8E, 0x8CE7, // + 0x6A90, 0x9EF7, // + 0x6A97, 0x9F40, // + 0x6A9C, 0x9E77, // + 0x6AA0, 0x9EF9, // + 0x6AA2, 0x9EFB, // + 0x6AA3, 0x9EFC, // + 0x6AAA, 0x9F4B, // + 0x6AAC, 0x9F47, // + 0x6AAE, 0x9E8D, // + 0x6AB3, 0x9F46, // + 0x6AB8, 0x9F45, // + 0x6ABB, 0x9F42, // + 0x6AC1, 0x9EE8, // + 0x6AC2, 0x9F44, // + 0x6AC3, 0x9F43, // + 0x6AD1, 0x9F49, // + 0x6AD3, 0x9845, // + 0x6ADA, 0x9F4C, // + 0x6ADB, 0x8BF9, // + 0x6ADE, 0x9F48, // + 0x6ADF, 0x9F4A, // + 0x6AE8, 0x94A5, // + 0x6AEA, 0x9F4D, // + 0x6AFA, 0x9F51, // + 0x6AFB, 0x9F4E, // + 0x6B04, 0x9793, // + 0x6B05, 0x9F4F, // + 0x6B0A, 0x9EDC, // + 0x6B12, 0x9F52, // + 0x6B16, 0x9F53, // + 0x6B1D, 0x8954, // + 0x6B1F, 0x9F55, // + 0x6B20, 0x8C87, // + 0x6B21, 0x8E9F, // + 0x6B23, 0x8BD3, // + 0x6B27, 0x89A2, // + 0x6B32, 0x977E, // + 0x6B37, 0x9F57, // + 0x6B38, 0x9F56, // + 0x6B39, 0x9F59, // + 0x6B3A, 0x8B5C, // + 0x6B3D, 0x8BD4, // + 0x6B3E, 0x8ABC, // + 0x6B43, 0x9F5C, // + 0x6B49, 0x9F5D, // + 0x6B4C, 0x89CC, // + 0x6B4E, 0x9256, // + 0x6B50, 0x9F5E, // + 0x6B53, 0x8ABD, // + 0x6B54, 0x9F60, // + 0x6B59, 0x9F5F, // + 0x6B5B, 0x9F61, // + 0x6B5F, 0x9F62, // + 0x6B61, 0x9F63, // + 0x6B62, 0x8E7E, // + 0x6B63, 0x90B3, // + 0x6B64, 0x8D9F, // + 0x6B66, 0x9590, // + 0x6B69, 0x95E0, // + 0x6B6A, 0x9863, // + 0x6B6F, 0x8E95, // + 0x6B73, 0x8DCE, // + 0x6B74, 0x97F0, // + 0x6B78, 0x9F64, // + 0x6B79, 0x9F65, // + 0x6B7B, 0x8E80, // + 0x6B7F, 0x9F66, // + 0x6B80, 0x9F67, // + 0x6B83, 0x9F69, // + 0x6B84, 0x9F68, // + 0x6B86, 0x9677, // + 0x6B89, 0x8F7D, // + 0x6B8A, 0x8EEA, // + 0x6B8B, 0x8E63, // + 0x6B8D, 0x9F6A, // + 0x6B95, 0x9F6C, // + 0x6B96, 0x9042, // + 0x6B98, 0x9F6B, // + 0x6B9E, 0x9F6D, // + 0x6BA4, 0x9F6E, // + 0x6BAA, 0x9F6F, // + 0x6BAB, 0x9F70, // + 0x6BAF, 0x9F71, // + 0x6BB1, 0x9F73, // + 0x6BB2, 0x9F72, // + 0x6BB3, 0x9F74, // + 0x6BB4, 0x89A3, // + 0x6BB5, 0x9269, // + 0x6BB7, 0x9F75, // + 0x6BBA, 0x8E45, // + 0x6BBB, 0x8A6B, // + 0x6BBC, 0x9F76, // + 0x6BBF, 0x9361, // + 0x6BC0, 0x9ACA, // + 0x6BC5, 0x8B42, // + 0x6BC6, 0x9F77, // + 0x6BCB, 0x9F78, // + 0x6BCD, 0x95EA, // + 0x6BCE, 0x9688, // + 0x6BD2, 0x93C5, // + 0x6BD3, 0x9F79, // + 0x6BD4, 0x94E4, // + 0x6BD8, 0x94F9, // + 0x6BDB, 0x96D1, // + 0x6BDF, 0x9F7A, // + 0x6BEB, 0x9F7C, // + 0x6BEC, 0x9F7B, // + 0x6BEF, 0x9F7E, // + 0x6BF3, 0x9F7D, // + 0x6C08, 0x9F81, // + 0x6C0F, 0x8E81, // + 0x6C11, 0x96AF, // + 0x6C13, 0x9F82, // + 0x6C14, 0x9F83, // + 0x6C17, 0x8B43, // + 0x6C1B, 0x9F84, // + 0x6C23, 0x9F86, // + 0x6C24, 0x9F85, // + 0x6C34, 0x9085, // + 0x6C37, 0x9558, // + 0x6C38, 0x8969, // + 0x6C3E, 0x94C3, // + 0x6C40, 0x92F3, // + 0x6C41, 0x8F60, // + 0x6C42, 0x8B81, // + 0x6C4E, 0x94C4, // + 0x6C50, 0x8EAC, // + 0x6C55, 0x9F88, // + 0x6C57, 0x8ABE, // + 0x6C5A, 0x8998, // + 0x6C5D, 0x93F0, // + 0x6C5E, 0x9F87, // + 0x6C5F, 0x8D5D, // + 0x6C60, 0x9272, // + 0x6C62, 0x9F89, // + 0x6C68, 0x9F91, // + 0x6C6A, 0x9F8A, // + 0x6C70, 0x91BF, // + 0x6C72, 0x8B82, // + 0x6C73, 0x9F92, // + 0x6C7A, 0x8C88, // + 0x6C7D, 0x8B44, // + 0x6C7E, 0x9F90, // + 0x6C81, 0x9F8E, // + 0x6C82, 0x9F8B, // + 0x6C83, 0x9780, // + 0x6C88, 0x92BE, // + 0x6C8C, 0x93D7, // + 0x6C8D, 0x9F8C, // + 0x6C90, 0x9F94, // + 0x6C92, 0x9F93, // + 0x6C93, 0x8C42, // + 0x6C96, 0x89AB, // + 0x6C99, 0x8DB9, // + 0x6C9A, 0x9F8D, // + 0x6C9B, 0x9F8F, // + 0x6CA1, 0x9676, // + 0x6CA2, 0x91F2, // + 0x6CAB, 0x9697, // + 0x6CAE, 0x9F9C, // + 0x6CB1, 0x9F9D, // + 0x6CB3, 0x89CD, // + 0x6CB8, 0x95A6, // + 0x6CB9, 0x96FB, // + 0x6CBA, 0x9F9F, // + 0x6CBB, 0x8EA1, // + 0x6CBC, 0x8FC0, // + 0x6CBD, 0x9F98, // + 0x6CBE, 0x9F9E, // + 0x6CBF, 0x8988, // + 0x6CC1, 0x8BB5, // + 0x6CC4, 0x9F95, // + 0x6CC5, 0x9F9A, // + 0x6CC9, 0x90F2, // + 0x6CCA, 0x9491, // + 0x6CCC, 0x94E5, // + 0x6CD3, 0x9F97, // + 0x6CD5, 0x9640, // + 0x6CD7, 0x9F99, // + 0x6CD9, 0x9FA2, // + 0x6CDB, 0x9FA0, // + 0x6CDD, 0x9F9B, // + 0x6CE1, 0x9641, // + 0x6CE2, 0x9467, // + 0x6CE3, 0x8B83, // + 0x6CE5, 0x9344, // + 0x6CE8, 0x928D, // + 0x6CEA, 0x9FA3, // + 0x6CEF, 0x9FA1, // + 0x6CF0, 0x91D7, // + 0x6CF1, 0x9F96, // + 0x6CF3, 0x896A, // + 0x6D0B, 0x976D, // + 0x6D0C, 0x9FAE, // + 0x6D12, 0x9FAD, // + 0x6D17, 0x90F4, // + 0x6D19, 0x9FAA, // + 0x6D1B, 0x978C, // + 0x6D1E, 0x93B4, // + 0x6D1F, 0x9FA4, // + 0x6D25, 0x92C3, // + 0x6D29, 0x896B, // + 0x6D2A, 0x8D5E, // + 0x6D2B, 0x9FA7, // + 0x6D32, 0x8F46, // + 0x6D33, 0x9FAC, // + 0x6D35, 0x9FAB, // + 0x6D36, 0x9FA6, // + 0x6D38, 0x9FA9, // + 0x6D3B, 0x8A88, // + 0x6D3D, 0x9FA8, // + 0x6D3E, 0x9468, // + 0x6D41, 0x97AC, // + 0x6D44, 0x8FF2, // + 0x6D45, 0x90F3, // + 0x6D59, 0x9FB4, // + 0x6D5A, 0x9FB2, // + 0x6D5C, 0x956C, // + 0x6D63, 0x9FAF, // + 0x6D64, 0x9FB1, // + 0x6D66, 0x8959, // + 0x6D69, 0x8D5F, // + 0x6D6A, 0x9851, // + 0x6D6C, 0x8A5C, // + 0x6D6E, 0x9582, // + 0x6D74, 0x9781, // + 0x6D77, 0x8A43, // + 0x6D78, 0x905A, // + 0x6D79, 0x9FB3, // + 0x6D85, 0x9FB8, // + 0x6D88, 0x8FC1, // + 0x6D8C, 0x974F, // + 0x6D8E, 0x9FB5, // + 0x6D93, 0x9FB0, // + 0x6D95, 0x9FB6, // + 0x6D99, 0x97DC, // + 0x6D9B, 0x9393, // + 0x6D9C, 0x93C0, // + 0x6DAF, 0x8A55, // + 0x6DB2, 0x8974, // + 0x6DB5, 0x9FBC, // + 0x6DB8, 0x9FBF, // + 0x6DBC, 0x97C1, // + 0x6DC0, 0x9784, // + 0x6DC5, 0x9FC6, // + 0x6DC6, 0x9FC0, // + 0x6DC7, 0x9FBD, // + 0x6DCB, 0x97D2, // + 0x6DCC, 0x9FC3, // + 0x6DD1, 0x8F69, // + 0x6DD2, 0x9FC5, // + 0x6DD5, 0x9FCA, // + 0x6DD8, 0x9391, // + 0x6DD9, 0x9FC8, // + 0x6DDE, 0x9FC2, // + 0x6DE1, 0x9257, // + 0x6DE4, 0x9FC9, // + 0x6DE6, 0x9FBE, // + 0x6DE8, 0x9FC4, // + 0x6DEA, 0x9FCB, // + 0x6DEB, 0x88FA, // + 0x6DEC, 0x9FC1, // + 0x6DEE, 0x9FCC, // + 0x6DF3, 0x8F7E, // + 0x6DF5, 0x95A3, // + 0x6DF7, 0x8DAC, // + 0x6DF9, 0x9FB9, // + 0x6DFA, 0x9FC7, // + 0x6DFB, 0x9359, // + 0x6E05, 0x90B4, // + 0x6E07, 0x8A89, // + 0x6E08, 0x8DCF, // + 0x6E09, 0x8FC2, // + 0x6E0A, 0x9FBB, // + 0x6E0B, 0x8F61, // + 0x6E13, 0x8C6B, // + 0x6E15, 0x9FBA, // + 0x6E19, 0x9FD0, // + 0x6E1A, 0x8F8D, // + 0x6E1B, 0x8CB8, // + 0x6E1D, 0x9FDF, // + 0x6E1F, 0x9FD9, // + 0x6E20, 0x8B94, // + 0x6E21, 0x936E, // + 0x6E23, 0x9FD4, // + 0x6E24, 0x9FDD, // + 0x6E25, 0x88AD, // + 0x6E26, 0x8951, // + 0x6E29, 0x89B7, // + 0x6E2B, 0x9FD6, // + 0x6E2C, 0x91AA, // + 0x6E2D, 0x9FCD, // + 0x6E2E, 0x9FCF, // + 0x6E2F, 0x8D60, // + 0x6E38, 0x9FE0, // + 0x6E3A, 0x9FDB, // + 0x6E3E, 0x9FD3, // + 0x6E43, 0x9FDA, // + 0x6E4A, 0x96A9, // + 0x6E4D, 0x9FD8, // + 0x6E4E, 0x9FDC, // + 0x6E56, 0x8CCE, // + 0x6E58, 0x8FC3, // + 0x6E5B, 0x9258, // + 0x6E5F, 0x9FD2, // + 0x6E67, 0x974E, // + 0x6E6B, 0x9FD5, // + 0x6E6E, 0x9FCE, // + 0x6E6F, 0x9392, // + 0x6E72, 0x9FD1, // + 0x6E76, 0x9FD7, // + 0x6E7E, 0x9870, // + 0x6E7F, 0x8EBC, // + 0x6E80, 0x969E, // + 0x6E82, 0x9FE1, // + 0x6E8C, 0x94AC, // + 0x6E8F, 0x9FED, // + 0x6E90, 0x8CB9, // + 0x6E96, 0x8F80, // + 0x6E98, 0x9FE3, // + 0x6E9C, 0x97AD, // + 0x6E9D, 0x8D61, // + 0x6E9F, 0x9FF0, // + 0x6EA2, 0x88EC, // + 0x6EA5, 0x9FEE, // + 0x6EAA, 0x9FE2, // + 0x6EAF, 0x9FE8, // + 0x6EB2, 0x9FEA, // + 0x6EB6, 0x976E, // + 0x6EB7, 0x9FE5, // + 0x6EBA, 0x934D, // + 0x6EBD, 0x9FE7, // + 0x6EC2, 0x9FEF, // + 0x6EC4, 0x9FE9, // + 0x6EC5, 0x96C5, // + 0x6EC9, 0x9FE4, // + 0x6ECB, 0x8EA0, // + 0x6ECC, 0x9FFC, // + 0x6ED1, 0x8A8A, // + 0x6ED3, 0x9FE6, // + 0x6ED4, 0x9FEB, // + 0x6ED5, 0x9FEC, // + 0x6EDD, 0x91EA, // + 0x6EDE, 0x91D8, // + 0x6EEC, 0x9FF4, // + 0x6EEF, 0x9FFA, // + 0x6EF2, 0x9FF8, // + 0x6EF4, 0x9348, // + 0x6EF7, 0xE042, // + 0x6EF8, 0x9FF5, // + 0x6EFE, 0x9FF6, // + 0x6EFF, 0x9FDE, // + 0x6F01, 0x8B99, // + 0x6F02, 0x9559, // + 0x6F06, 0x8EBD, // + 0x6F09, 0x8D97, // + 0x6F0F, 0x9852, // + 0x6F11, 0x9FF2, // + 0x6F13, 0xE041, // + 0x6F14, 0x8989, // + 0x6F15, 0x9186, // + 0x6F20, 0x9499, // + 0x6F22, 0x8ABF, // + 0x6F23, 0x97F8, // + 0x6F2B, 0x969F, // + 0x6F2C, 0x92D0, // + 0x6F31, 0x9FF9, // + 0x6F32, 0x9FFB, // + 0x6F38, 0x9151, // + 0x6F3E, 0xE040, // + 0x6F3F, 0x9FF7, // + 0x6F41, 0x9FF1, // + 0x6F45, 0x8AC1, // + 0x6F54, 0x8C89, // + 0x6F58, 0xE04E, // + 0x6F5B, 0xE049, // + 0x6F5C, 0x90F6, // + 0x6F5F, 0x8A83, // + 0x6F64, 0x8F81, // + 0x6F66, 0xE052, // + 0x6F6D, 0xE04B, // + 0x6F6E, 0x92AA, // + 0x6F6F, 0xE048, // + 0x6F70, 0x92D7, // + 0x6F74, 0xE06B, // + 0x6F78, 0xE045, // + 0x6F7A, 0xE044, // + 0x6F7C, 0xE04D, // + 0x6F80, 0xE047, // + 0x6F81, 0xE046, // + 0x6F82, 0xE04C, // + 0x6F84, 0x909F, // + 0x6F86, 0xE043, // + 0x6F8E, 0xE04F, // + 0x6F91, 0xE050, // + 0x6F97, 0x8AC0, // + 0x6FA1, 0xE055, // + 0x6FA3, 0xE054, // + 0x6FA4, 0xE056, // + 0x6FAA, 0xE059, // + 0x6FB1, 0x9362, // + 0x6FB3, 0xE053, // + 0x6FB9, 0xE057, // + 0x6FC0, 0x8C83, // + 0x6FC1, 0x91F7, // + 0x6FC2, 0xE051, // + 0x6FC3, 0x945A, // + 0x6FC6, 0xE058, // + 0x6FD4, 0xE05D, // + 0x6FD8, 0xE05E, // + 0x6FDB, 0xE061, // + 0x6FDF, 0xE05A, // + 0x6FE0, 0x8D8A, // + 0x6FE1, 0x9447, // + 0x6FE4, 0x9FB7, // + 0x6FEB, 0x9794, // + 0x6FEC, 0xE05C, // + 0x6FEE, 0xE060, // + 0x6FEF, 0x91F3, // + 0x6FF1, 0xE05F, // + 0x6FF3, 0xE04A, // + 0x6FF6, 0xE889, // + 0x6FFA, 0xE064, // + 0x6FFE, 0xE068, // + 0x7001, 0xE066, // + 0x7009, 0xE062, // + 0x700B, 0xE063, // + 0x700F, 0xE067, // + 0x7011, 0xE065, // + 0x7015, 0x956D, // + 0x7018, 0xE06D, // + 0x701A, 0xE06A, // + 0x701B, 0xE069, // + 0x701D, 0xE06C, // + 0x701E, 0x93D2, // + 0x701F, 0xE06E, // + 0x7026, 0x9295, // + 0x7027, 0x91EB, // + 0x702C, 0x90A3, // + 0x7030, 0xE06F, // + 0x7032, 0xE071, // + 0x703E, 0xE070, // + 0x704C, 0x9FF3, // + 0x7051, 0xE072, // + 0x7058, 0x93E5, // + 0x7063, 0xE073, // + 0x706B, 0x89CE, // + 0x706F, 0x9394, // + 0x7070, 0x8A44, // + 0x7078, 0x8B84, // + 0x707C, 0x8EDC, // + 0x707D, 0x8DD0, // + 0x7089, 0x9846, // + 0x708A, 0x9086, // + 0x708E, 0x898A, // + 0x7092, 0xE075, // + 0x7099, 0xE074, // + 0x70AC, 0xE078, // + 0x70AD, 0x9259, // + 0x70AE, 0xE07B, // + 0x70AF, 0xE076, // + 0x70B3, 0xE07A, // + 0x70B8, 0xE079, // + 0x70B9, 0x935F, // + 0x70BA, 0x88D7, // + 0x70C8, 0x97F3, // + 0x70CB, 0xE07D, // + 0x70CF, 0x8947, // + 0x70D9, 0xE080, // + 0x70DD, 0xE07E, // + 0x70DF, 0xE07C, // + 0x70F1, 0xE077, // + 0x70F9, 0x9642, // + 0x70FD, 0xE082, // + 0x7109, 0xE081, // + 0x7114, 0x898B, // + 0x7119, 0xE084, // + 0x711A, 0x95B0, // + 0x711C, 0xE083, // + 0x7121, 0x96B3, // + 0x7126, 0x8FC5, // + 0x7136, 0x9152, // + 0x713C, 0x8FC4, // + 0x7149, 0x97F9, // + 0x714C, 0xE08A, // + 0x714E, 0x90F7, // + 0x7155, 0xE086, // + 0x7156, 0xE08B, // + 0x7159, 0x898C, // + 0x7162, 0xE089, // + 0x7164, 0x9481, // + 0x7165, 0xE085, // + 0x7166, 0xE088, // + 0x7167, 0x8FC6, // + 0x7169, 0x94CF, // + 0x716C, 0xE08C, // + 0x716E, 0x8ECF, // + 0x717D, 0x90F8, // + 0x7184, 0xE08F, // + 0x7188, 0xE087, // + 0x718A, 0x8C46, // + 0x718F, 0xE08D, // + 0x7194, 0x976F, // + 0x7195, 0xE090, // + 0x7199, 0xEAA4, // + 0x719F, 0x8F6E, // + 0x71A8, 0xE091, // + 0x71AC, 0xE092, // + 0x71B1, 0x944D, // + 0x71B9, 0xE094, // + 0x71BE, 0xE095, // + 0x71C3, 0x9452, // + 0x71C8, 0x9395, // + 0x71C9, 0xE097, // + 0x71CE, 0xE099, // + 0x71D0, 0x97D3, // + 0x71D2, 0xE096, // + 0x71D4, 0xE098, // + 0x71D5, 0x898D, // + 0x71D7, 0xE093, // + 0x71DF, 0x9A7A, // + 0x71E0, 0xE09A, // + 0x71E5, 0x9187, // + 0x71E6, 0x8E57, // + 0x71E7, 0xE09C, // + 0x71EC, 0xE09B, // + 0x71ED, 0x9043, // + 0x71EE, 0x99D7, // + 0x71F5, 0xE09D, // + 0x71F9, 0xE09F, // + 0x71FB, 0xE08E, // + 0x71FC, 0xE09E, // + 0x71FF, 0xE0A0, // + 0x7206, 0x949A, // + 0x720D, 0xE0A1, // + 0x7210, 0xE0A2, // + 0x721B, 0xE0A3, // + 0x7228, 0xE0A4, // + 0x722A, 0x92DC, // + 0x722C, 0xE0A6, // + 0x722D, 0xE0A5, // + 0x7230, 0xE0A7, // + 0x7232, 0xE0A8, // + 0x7235, 0x8EDD, // + 0x7236, 0x9583, // + 0x723A, 0x96EA, // + 0x723B, 0xE0A9, // + 0x723C, 0xE0AA, // + 0x723D, 0x9175, // + 0x723E, 0x8EA2, // + 0x723F, 0xE0AB, // + 0x7240, 0xE0AC, // + 0x7246, 0xE0AD, // + 0x7247, 0x95D0, // + 0x7248, 0x94C5, // + 0x724B, 0xE0AE, // + 0x724C, 0x9476, // + 0x7252, 0x92AB, // + 0x7258, 0xE0AF, // + 0x7259, 0x89E5, // + 0x725B, 0x8B8D, // + 0x725D, 0x96C4, // + 0x725F, 0x96B4, // + 0x7261, 0x89B2, // + 0x7262, 0x9853, // + 0x7267, 0x9671, // + 0x7269, 0x95A8, // + 0x7272, 0x90B5, // + 0x7274, 0xE0B0, // + 0x7279, 0x93C1, // + 0x727D, 0x8CA1, // + 0x727E, 0xE0B1, // + 0x7280, 0x8DD2, // + 0x7281, 0xE0B3, // + 0x7282, 0xE0B2, // + 0x7287, 0xE0B4, // + 0x7292, 0xE0B5, // + 0x7296, 0xE0B6, // + 0x72A0, 0x8B5D, // + 0x72A2, 0xE0B7, // + 0x72A7, 0xE0B8, // + 0x72AC, 0x8CA2, // + 0x72AF, 0x94C6, // + 0x72B2, 0xE0BA, // + 0x72B6, 0x8FF3, // + 0x72B9, 0xE0B9, // + 0x72C2, 0x8BB6, // + 0x72C3, 0xE0BB, // + 0x72C4, 0xE0BD, // + 0x72C6, 0xE0BC, // + 0x72CE, 0xE0BE, // + 0x72D0, 0x8CCF, // + 0x72D2, 0xE0BF, // + 0x72D7, 0x8BE7, // + 0x72D9, 0x915F, // + 0x72DB, 0x8D9D, // + 0x72E0, 0xE0C1, // + 0x72E1, 0xE0C2, // + 0x72E2, 0xE0C0, // + 0x72E9, 0x8EEB, // + 0x72EC, 0x93C6, // + 0x72ED, 0x8BB7, // + 0x72F7, 0xE0C4, // + 0x72F8, 0x924B, // + 0x72F9, 0xE0C3, // + 0x72FC, 0x9854, // + 0x72FD, 0x9482, // + 0x730A, 0xE0C7, // + 0x7316, 0xE0C9, // + 0x7317, 0xE0C6, // + 0x731B, 0x96D2, // + 0x731C, 0xE0C8, // + 0x731D, 0xE0CA, // + 0x731F, 0x97C2, // + 0x7325, 0xE0CE, // + 0x7329, 0xE0CD, // + 0x732A, 0x9296, // + 0x732B, 0x944C, // + 0x732E, 0x8CA3, // + 0x732F, 0xE0CC, // + 0x7334, 0xE0CB, // + 0x7336, 0x9750, // + 0x7337, 0x9751, // + 0x733E, 0xE0CF, // + 0x733F, 0x898E, // + 0x7344, 0x8D96, // + 0x7345, 0x8E82, // + 0x734E, 0xE0D0, // + 0x734F, 0xE0D1, // + 0x7357, 0xE0D3, // + 0x7363, 0x8F62, // + 0x7368, 0xE0D5, // + 0x736A, 0xE0D4, // + 0x7370, 0xE0D6, // + 0x7372, 0x8A6C, // + 0x7375, 0xE0D8, // + 0x7378, 0xE0D7, // + 0x737A, 0xE0DA, // + 0x737B, 0xE0D9, // + 0x7384, 0x8CBA, // + 0x7387, 0x97A6, // + 0x7389, 0x8BCA, // + 0x738B, 0x89A4, // + 0x7396, 0x8BE8, // + 0x73A9, 0x8ADF, // + 0x73B2, 0x97E6, // + 0x73B3, 0xE0DC, // + 0x73BB, 0xE0DE, // + 0x73C0, 0xE0DF, // + 0x73C2, 0x89CF, // + 0x73C8, 0xE0DB, // + 0x73CA, 0x8E58, // + 0x73CD, 0x92BF, // + 0x73CE, 0xE0DD, // + 0x73DE, 0xE0E2, // + 0x73E0, 0x8EEC, // + 0x73E5, 0xE0E0, // + 0x73EA, 0x8C5D, // + 0x73ED, 0x94C7, // + 0x73EE, 0xE0E1, // + 0x73F1, 0xE0FC, // + 0x73F8, 0xE0E7, // + 0x73FE, 0x8CBB, // + 0x7403, 0x8B85, // + 0x7405, 0xE0E4, // + 0x7406, 0x979D, // + 0x7409, 0x97AE, // + 0x7422, 0x91F4, // + 0x7425, 0xE0E6, // + 0x7432, 0xE0E8, // + 0x7433, 0x97D4, // + 0x7434, 0x8BD5, // + 0x7435, 0x94FA, // + 0x7436, 0x9469, // + 0x743A, 0xE0E9, // + 0x743F, 0xE0EB, // + 0x7441, 0xE0EE, // + 0x7455, 0xE0EA, // + 0x7459, 0xE0ED, // + 0x745A, 0x8CE8, // + 0x745B, 0x896C, // + 0x745C, 0xE0EF, // + 0x745E, 0x9090, // + 0x745F, 0xE0EC, // + 0x7460, 0x97DA, // + 0x7463, 0xE0F2, // + 0x7464, 0xEAA2, // + 0x7469, 0xE0F0, // + 0x746A, 0xE0F3, // + 0x746F, 0xE0E5, // + 0x7470, 0xE0F1, // + 0x7473, 0x8DBA, // + 0x7476, 0xE0F4, // + 0x747E, 0xE0F5, // + 0x7483, 0x979E, // + 0x748B, 0xE0F6, // + 0x749E, 0xE0F7, // + 0x74A2, 0xE0E3, // + 0x74A7, 0xE0F8, // + 0x74B0, 0x8AC2, // + 0x74BD, 0x8EA3, // + 0x74CA, 0xE0F9, // + 0x74CF, 0xE0FA, // + 0x74D4, 0xE0FB, // + 0x74DC, 0x895A, // + 0x74E0, 0xE140, // + 0x74E2, 0x955A, // + 0x74E3, 0xE141, // + 0x74E6, 0x8AA2, // + 0x74E7, 0xE142, // + 0x74E9, 0xE143, // + 0x74EE, 0xE144, // + 0x74F0, 0xE146, // + 0x74F1, 0xE147, // + 0x74F2, 0xE145, // + 0x74F6, 0x9572, // + 0x74F7, 0xE149, // + 0x74F8, 0xE148, // + 0x7503, 0xE14B, // + 0x7504, 0xE14A, // + 0x7505, 0xE14C, // + 0x750C, 0xE14D, // + 0x750D, 0xE14F, // + 0x750E, 0xE14E, // + 0x7511, 0x8D99, // + 0x7513, 0xE151, // + 0x7515, 0xE150, // + 0x7518, 0x8AC3, // + 0x751A, 0x9072, // + 0x751E, 0xE152, // + 0x751F, 0x90B6, // + 0x7523, 0x8E59, // + 0x7525, 0x8999, // + 0x7526, 0xE153, // + 0x7528, 0x9770, // + 0x752B, 0x95E1, // + 0x752C, 0xE154, // + 0x7530, 0x9363, // + 0x7531, 0x9752, // + 0x7532, 0x8D62, // + 0x7533, 0x905C, // + 0x7537, 0x926A, // + 0x7538, 0x99B2, // + 0x753A, 0x92AC, // + 0x753B, 0x89E6, // + 0x753C, 0xE155, // + 0x7544, 0xE156, // + 0x7549, 0xE159, // + 0x754A, 0xE158, // + 0x754B, 0x9DC0, // + 0x754C, 0x8A45, // + 0x754D, 0xE157, // + 0x754F, 0x88D8, // + 0x7551, 0x94A8, // + 0x7554, 0x94C8, // + 0x7559, 0x97AF, // + 0x755A, 0xE15C, // + 0x755B, 0xE15A, // + 0x755C, 0x927B, // + 0x755D, 0x90A4, // + 0x7560, 0x94A9, // + 0x7562, 0x954C, // + 0x7564, 0xE15E, // + 0x7565, 0x97AA, // + 0x7566, 0x8C6C, // + 0x7567, 0xE15F, // + 0x7569, 0xE15D, // + 0x756A, 0x94D4, // + 0x756B, 0xE160, // + 0x756D, 0xE161, // + 0x7570, 0x88D9, // + 0x7573, 0x8FF4, // + 0x7574, 0xE166, // + 0x7576, 0xE163, // + 0x7577, 0x93EB, // + 0x7578, 0xE162, // + 0x757F, 0x8B45, // + 0x7582, 0xE169, // + 0x7586, 0xE164, // + 0x7587, 0xE165, // + 0x7589, 0xE168, // + 0x758A, 0xE167, // + 0x758B, 0x9544, // + 0x758E, 0x9161, // + 0x758F, 0x9160, // + 0x7591, 0x8B5E, // + 0x7594, 0xE16A, // + 0x759A, 0xE16B, // + 0x759D, 0xE16C, // + 0x75A3, 0xE16E, // + 0x75A5, 0xE16D, // + 0x75AB, 0x8975, // + 0x75B1, 0xE176, // + 0x75B2, 0x94E6, // + 0x75B3, 0xE170, // + 0x75B5, 0xE172, // + 0x75B8, 0xE174, // + 0x75B9, 0x905D, // + 0x75BC, 0xE175, // + 0x75BD, 0xE173, // + 0x75BE, 0x8EBE, // + 0x75C2, 0xE16F, // + 0x75C3, 0xE171, // + 0x75C5, 0x9561, // + 0x75C7, 0x8FC7, // + 0x75CA, 0xE178, // + 0x75CD, 0xE177, // + 0x75D2, 0xE179, // + 0x75D4, 0x8EA4, // + 0x75D5, 0x8DAD, // + 0x75D8, 0x9397, // + 0x75D9, 0xE17A, // + 0x75DB, 0x92C9, // + 0x75DE, 0xE17C, // + 0x75E2, 0x979F, // + 0x75E3, 0xE17B, // + 0x75E9, 0x9189, // + 0x75F0, 0xE182, // + 0x75F2, 0xE184, // + 0x75F3, 0xE185, // + 0x75F4, 0x9273, // + 0x75FA, 0xE183, // + 0x75FC, 0xE180, // + 0x75FE, 0xE17D, // + 0x75FF, 0xE17E, // + 0x7601, 0xE181, // + 0x7609, 0xE188, // + 0x760B, 0xE186, // + 0x760D, 0xE187, // + 0x761F, 0xE189, // + 0x7620, 0xE18B, // + 0x7621, 0xE18C, // + 0x7622, 0xE18D, // + 0x7624, 0xE18E, // + 0x7627, 0xE18A, // + 0x7630, 0xE190, // + 0x7634, 0xE18F, // + 0x763B, 0xE191, // + 0x7642, 0x97C3, // + 0x7646, 0xE194, // + 0x7647, 0xE192, // + 0x7648, 0xE193, // + 0x764C, 0x8AE0, // + 0x7652, 0x96FC, // + 0x7656, 0x95C8, // + 0x7658, 0xE196, // + 0x765C, 0xE195, // + 0x7661, 0xE197, // + 0x7662, 0xE198, // + 0x7667, 0xE19C, // + 0x7668, 0xE199, // + 0x7669, 0xE19A, // + 0x766A, 0xE19B, // + 0x766C, 0xE19D, // + 0x7670, 0xE19E, // + 0x7672, 0xE19F, // + 0x7676, 0xE1A0, // + 0x7678, 0xE1A1, // + 0x767A, 0x94AD, // + 0x767B, 0x936F, // + 0x767C, 0xE1A2, // + 0x767D, 0x9492, // + 0x767E, 0x9553, // + 0x7680, 0xE1A3, // + 0x7683, 0xE1A4, // + 0x7684, 0x9349, // + 0x7686, 0x8A46, // + 0x7687, 0x8D63, // + 0x7688, 0xE1A5, // + 0x768B, 0xE1A6, // + 0x768E, 0xE1A7, // + 0x7690, 0x8E48, // + 0x7693, 0xE1A9, // + 0x7696, 0xE1A8, // + 0x7699, 0xE1AA, // + 0x769A, 0xE1AB, // + 0x76AE, 0x94E7, // + 0x76B0, 0xE1AC, // + 0x76B4, 0xE1AD, // + 0x76B7, 0xEA89, // + 0x76B8, 0xE1AE, // + 0x76B9, 0xE1AF, // + 0x76BA, 0xE1B0, // + 0x76BF, 0x8E4D, // + 0x76C2, 0xE1B1, // + 0x76C3, 0x9475, // + 0x76C6, 0x967E, // + 0x76C8, 0x896D, // + 0x76CA, 0x8976, // + 0x76CD, 0xE1B2, // + 0x76D2, 0xE1B4, // + 0x76D6, 0xE1B3, // + 0x76D7, 0x9390, // + 0x76DB, 0x90B7, // + 0x76DC, 0x9F58, // + 0x76DE, 0xE1B5, // + 0x76DF, 0x96BF, // + 0x76E1, 0xE1B6, // + 0x76E3, 0x8AC4, // + 0x76E4, 0x94D5, // + 0x76E5, 0xE1B7, // + 0x76E7, 0xE1B8, // + 0x76EA, 0xE1B9, // + 0x76EE, 0x96DA, // + 0x76F2, 0x96D3, // + 0x76F4, 0x92BC, // + 0x76F8, 0x918A, // + 0x76FB, 0xE1BB, // + 0x76FE, 0x8F82, // + 0x7701, 0x8FC8, // + 0x7704, 0xE1BE, // + 0x7707, 0xE1BD, // + 0x7708, 0xE1BC, // + 0x7709, 0x94FB, // + 0x770B, 0x8AC5, // + 0x770C, 0x8CA7, // + 0x771B, 0xE1C4, // + 0x771E, 0xE1C1, // + 0x771F, 0x905E, // + 0x7720, 0x96B0, // + 0x7724, 0xE1C0, // + 0x7725, 0xE1C2, // + 0x7726, 0xE1C3, // + 0x7729, 0xE1BF, // + 0x7737, 0xE1C5, // + 0x7738, 0xE1C6, // + 0x773A, 0x92AD, // + 0x773C, 0x8AE1, // + 0x7740, 0x9285, // + 0x7747, 0xE1C7, // + 0x775A, 0xE1C8, // + 0x775B, 0xE1CB, // + 0x7761, 0x9087, // + 0x7763, 0x93C2, // + 0x7765, 0xE1CC, // + 0x7766, 0x9672, // + 0x7768, 0xE1C9, // + 0x776B, 0xE1CA, // + 0x7779, 0xE1CF, // + 0x777E, 0xE1CE, // + 0x777F, 0xE1CD, // + 0x778B, 0xE1D1, // + 0x778E, 0xE1D0, // + 0x7791, 0xE1D2, // + 0x779E, 0xE1D4, // + 0x77A0, 0xE1D3, // + 0x77A5, 0x95CB, // + 0x77AC, 0x8F75, // + 0x77AD, 0x97C4, // + 0x77B0, 0xE1D5, // + 0x77B3, 0x93B5, // + 0x77B6, 0xE1D6, // + 0x77B9, 0xE1D7, // + 0x77BB, 0xE1DB, // + 0x77BC, 0xE1D9, // + 0x77BD, 0xE1DA, // + 0x77BF, 0xE1D8, // + 0x77C7, 0xE1DC, // + 0x77CD, 0xE1DD, // + 0x77D7, 0xE1DE, // + 0x77DA, 0xE1DF, // + 0x77DB, 0x96B5, // + 0x77DC, 0xE1E0, // + 0x77E2, 0x96EE, // + 0x77E3, 0xE1E1, // + 0x77E5, 0x926D, // + 0x77E7, 0x948A, // + 0x77E9, 0x8BE9, // + 0x77ED, 0x925A, // + 0x77EE, 0xE1E2, // + 0x77EF, 0x8BB8, // + 0x77F3, 0x90CE, // + 0x77FC, 0xE1E3, // + 0x7802, 0x8DBB, // + 0x780C, 0xE1E4, // + 0x7812, 0xE1E5, // + 0x7814, 0x8CA4, // + 0x7815, 0x8DD3, // + 0x7820, 0xE1E7, // + 0x7825, 0x9375, // + 0x7826, 0x8DD4, // + 0x7827, 0x8B6D, // + 0x7832, 0x9643, // + 0x7834, 0x946A, // + 0x783A, 0x9376, // + 0x783F, 0x8D7B, // + 0x7845, 0xE1E9, // + 0x785D, 0x8FC9, // + 0x786B, 0x97B0, // + 0x786C, 0x8D64, // + 0x786F, 0x8CA5, // + 0x7872, 0x94A1, // + 0x7874, 0xE1EB, // + 0x787C, 0xE1ED, // + 0x7881, 0x8CE9, // + 0x7886, 0xE1EC, // + 0x7887, 0x92F4, // + 0x788C, 0xE1EF, // + 0x788D, 0x8A56, // + 0x788E, 0xE1EA, // + 0x7891, 0x94E8, // + 0x7893, 0x894F, // + 0x7895, 0x8DEA, // + 0x7897, 0x9871, // + 0x789A, 0xE1EE, // + 0x78A3, 0xE1F0, // + 0x78A7, 0x95C9, // + 0x78A9, 0x90D7, // + 0x78AA, 0xE1F2, // + 0x78AF, 0xE1F3, // + 0x78B5, 0xE1F1, // + 0x78BA, 0x8A6D, // + 0x78BC, 0xE1F9, // + 0x78BE, 0xE1F8, // + 0x78C1, 0x8EA5, // + 0x78C5, 0xE1FA, // + 0x78C6, 0xE1F5, // + 0x78CA, 0xE1FB, // + 0x78CB, 0xE1F6, // + 0x78D0, 0x94D6, // + 0x78D1, 0xE1F4, // + 0x78D4, 0xE1F7, // + 0x78DA, 0xE241, // + 0x78E7, 0xE240, // + 0x78E8, 0x9681, // + 0x78EC, 0xE1FC, // + 0x78EF, 0x88E9, // + 0x78F4, 0xE243, // + 0x78FD, 0xE242, // + 0x7901, 0x8FCA, // + 0x7907, 0xE244, // + 0x790E, 0x9162, // + 0x7911, 0xE246, // + 0x7912, 0xE245, // + 0x7919, 0xE247, // + 0x7926, 0xE1E6, // + 0x792A, 0xE1E8, // + 0x792B, 0xE249, // + 0x792C, 0xE248, // + 0x793A, 0x8EA6, // + 0x793C, 0x97E7, // + 0x793E, 0x8ED0, // + 0x7940, 0xE24A, // + 0x7941, 0x8C56, // + 0x7947, 0x8B5F, // + 0x7948, 0x8B46, // + 0x7949, 0x8E83, // + 0x7950, 0x9753, // + 0x7953, 0xE250, // + 0x7955, 0xE24F, // + 0x7956, 0x9163, // + 0x7957, 0xE24C, // + 0x795A, 0xE24E, // + 0x795D, 0x8F6A, // + 0x795E, 0x905F, // + 0x795F, 0xE24D, // + 0x7960, 0xE24B, // + 0x7962, 0x9449, // + 0x7965, 0x8FCB, // + 0x796D, 0x8DD5, // + 0x7977, 0x9398, // + 0x797A, 0xE251, // + 0x797F, 0xE252, // + 0x7980, 0xE268, // + 0x7981, 0x8BD6, // + 0x7984, 0x985C, // + 0x7985, 0x9154, // + 0x798A, 0xE253, // + 0x798D, 0x89D0, // + 0x798E, 0x92F5, // + 0x798F, 0x959F, // + 0x799D, 0xE254, // + 0x79A6, 0x8B9A, // + 0x79A7, 0xE255, // + 0x79AA, 0xE257, // + 0x79AE, 0xE258, // + 0x79B0, 0x9448, // + 0x79B3, 0xE259, // + 0x79B9, 0xE25A, // + 0x79BD, 0x8BD7, // + 0x79BE, 0x89D1, // + 0x79BF, 0x93C3, // + 0x79C0, 0x8F47, // + 0x79C1, 0x8E84, // + 0x79C9, 0xE25C, // + 0x79CB, 0x8F48, // + 0x79D1, 0x89C8, // + 0x79D2, 0x9562, // + 0x79D5, 0xE25D, // + 0x79D8, 0x94E9, // + 0x79DF, 0x9164, // + 0x79E1, 0xE260, // + 0x79E3, 0xE261, // + 0x79E4, 0x9489, // + 0x79E6, 0x9060, // + 0x79E7, 0xE25E, // + 0x79E9, 0x9281, // + 0x79EC, 0xE25F, // + 0x79F0, 0x8FCC, // + 0x79FB, 0x88DA, // + 0x7A00, 0x8B48, // + 0x7A08, 0xE262, // + 0x7A0B, 0x92F6, // + 0x7A0D, 0xE263, // + 0x7A0E, 0x90C5, // + 0x7A14, 0x96AB, // + 0x7A17, 0x9542, // + 0x7A18, 0xE264, // + 0x7A19, 0xE265, // + 0x7A1A, 0x9274, // + 0x7A1C, 0x97C5, // + 0x7A1F, 0xE267, // + 0x7A20, 0xE266, // + 0x7A2E, 0x8EED, // + 0x7A31, 0xE269, // + 0x7A32, 0x88EE, // + 0x7A37, 0xE26C, // + 0x7A3B, 0xE26A, // + 0x7A3C, 0x89D2, // + 0x7A3D, 0x8C6D, // + 0x7A3E, 0xE26B, // + 0x7A3F, 0x8D65, // + 0x7A40, 0x8D92, // + 0x7A42, 0x95E4, // + 0x7A43, 0xE26D, // + 0x7A46, 0x9673, // + 0x7A49, 0xE26F, // + 0x7A4D, 0x90CF, // + 0x7A4E, 0x896E, // + 0x7A4F, 0x89B8, // + 0x7A50, 0x88AA, // + 0x7A57, 0xE26E, // + 0x7A61, 0xE270, // + 0x7A62, 0xE271, // + 0x7A63, 0x8FF5, // + 0x7A69, 0xE272, // + 0x7A6B, 0x8A6E, // + 0x7A70, 0xE274, // + 0x7A74, 0x8C8A, // + 0x7A76, 0x8B86, // + 0x7A79, 0xE275, // + 0x7A7A, 0x8BF3, // + 0x7A7D, 0xE276, // + 0x7A7F, 0x90FA, // + 0x7A81, 0x93CB, // + 0x7A83, 0x90DE, // + 0x7A84, 0x8DF3, // + 0x7A88, 0xE277, // + 0x7A92, 0x9282, // + 0x7A93, 0x918B, // + 0x7A95, 0xE279, // + 0x7A96, 0xE27B, // + 0x7A97, 0xE278, // + 0x7A98, 0xE27A, // + 0x7A9F, 0x8C41, // + 0x7AA9, 0xE27C, // + 0x7AAA, 0x8C45, // + 0x7AAE, 0x8B87, // + 0x7AAF, 0x9771, // + 0x7AB0, 0xE27E, // + 0x7AB6, 0xE280, // + 0x7ABA, 0x894D, // + 0x7ABF, 0xE283, // + 0x7AC3, 0x8A96, // + 0x7AC4, 0xE282, // + 0x7AC5, 0xE281, // + 0x7AC7, 0xE285, // + 0x7AC8, 0xE27D, // + 0x7ACA, 0xE286, // + 0x7ACB, 0x97A7, // + 0x7ACD, 0xE287, // + 0x7ACF, 0xE288, // + 0x7AD2, 0x9AF2, // + 0x7AD3, 0xE28A, // + 0x7AD5, 0xE289, // + 0x7AD9, 0xE28B, // + 0x7ADA, 0xE28C, // + 0x7ADC, 0x97B3, // + 0x7ADD, 0xE28D, // + 0x7ADF, 0xE8ED, // + 0x7AE0, 0x8FCD, // + 0x7AE1, 0xE28E, // + 0x7AE2, 0xE28F, // + 0x7AE3, 0x8F76, // + 0x7AE5, 0x93B6, // + 0x7AE6, 0xE290, // + 0x7AEA, 0x9247, // + 0x7AED, 0xE291, // + 0x7AF0, 0xE292, // + 0x7AF6, 0x8BA3, // + 0x7AF8, 0x995E, // + 0x7AF9, 0x927C, // + 0x7AFA, 0x8EB1, // + 0x7AFF, 0x8AC6, // + 0x7B02, 0xE293, // + 0x7B04, 0xE2A0, // + 0x7B06, 0xE296, // + 0x7B08, 0x8B88, // + 0x7B0A, 0xE295, // + 0x7B0B, 0xE2A2, // + 0x7B0F, 0xE294, // + 0x7B11, 0x8FCE, // + 0x7B18, 0xE298, // + 0x7B19, 0xE299, // + 0x7B1B, 0x934A, // + 0x7B1E, 0xE29A, // + 0x7B20, 0x8A7D, // + 0x7B25, 0x9079, // + 0x7B26, 0x9584, // + 0x7B28, 0xE29C, // + 0x7B2C, 0x91E6, // + 0x7B33, 0xE297, // + 0x7B35, 0xE29B, // + 0x7B36, 0xE29D, // + 0x7B39, 0x8DF9, // + 0x7B45, 0xE2A4, // + 0x7B46, 0x954D, // + 0x7B48, 0x94A4, // + 0x7B49, 0x9399, // + 0x7B4B, 0x8BD8, // + 0x7B4C, 0xE2A3, // + 0x7B4D, 0xE2A1, // + 0x7B4F, 0x94B3, // + 0x7B50, 0xE29E, // + 0x7B51, 0x927D, // + 0x7B52, 0x939B, // + 0x7B54, 0x939A, // + 0x7B56, 0x8DF4, // + 0x7B5D, 0xE2B6, // + 0x7B65, 0xE2A6, // + 0x7B67, 0xE2A8, // + 0x7B6C, 0xE2AB, // + 0x7B6E, 0xE2AC, // + 0x7B70, 0xE2A9, // + 0x7B71, 0xE2AA, // + 0x7B74, 0xE2A7, // + 0x7B75, 0xE2A5, // + 0x7B7A, 0xE29F, // + 0x7B86, 0x95CD, // + 0x7B87, 0x89D3, // + 0x7B8B, 0xE2B3, // + 0x7B8D, 0xE2B0, // + 0x7B8F, 0xE2B5, // + 0x7B92, 0xE2B4, // + 0x7B94, 0x9493, // + 0x7B95, 0x96A5, // + 0x7B97, 0x8E5A, // + 0x7B98, 0xE2AE, // + 0x7B99, 0xE2B7, // + 0x7B9A, 0xE2B2, // + 0x7B9C, 0xE2B1, // + 0x7B9D, 0xE2AD, // + 0x7B9F, 0xE2AF, // + 0x7BA1, 0x8AC7, // + 0x7BAA, 0x925C, // + 0x7BAD, 0x90FB, // + 0x7BB1, 0x94A0, // + 0x7BB4, 0xE2BC, // + 0x7BB8, 0x94A2, // + 0x7BC0, 0x90DF, // + 0x7BC1, 0xE2B9, // + 0x7BC4, 0x94CD, // + 0x7BC6, 0xE2BD, // + 0x7BC7, 0x95D1, // + 0x7BC9, 0x927A, // + 0x7BCB, 0xE2B8, // + 0x7BCC, 0xE2BA, // + 0x7BCF, 0xE2BB, // + 0x7BDD, 0xE2BE, // + 0x7BE0, 0x8EC2, // + 0x7BE4, 0x93C4, // + 0x7BE5, 0xE2C3, // + 0x7BE6, 0xE2C2, // + 0x7BE9, 0xE2BF, // + 0x7BED, 0x9855, // + 0x7BF3, 0xE2C8, // + 0x7BF6, 0xE2CC, // + 0x7BF7, 0xE2C9, // + 0x7C00, 0xE2C5, // + 0x7C07, 0xE2C6, // + 0x7C0D, 0xE2CB, // + 0x7C11, 0xE2C0, // + 0x7C12, 0x99D3, // + 0x7C13, 0xE2C7, // + 0x7C14, 0xE2C1, // + 0x7C17, 0xE2CA, // + 0x7C1F, 0xE2D0, // + 0x7C21, 0x8AC8, // + 0x7C23, 0xE2CD, // + 0x7C27, 0xE2CE, // + 0x7C2A, 0xE2CF, // + 0x7C2B, 0xE2D2, // + 0x7C37, 0xE2D1, // + 0x7C38, 0x94F4, // + 0x7C3D, 0xE2D3, // + 0x7C3E, 0x97FA, // + 0x7C3F, 0x95EB, // + 0x7C40, 0xE2D8, // + 0x7C43, 0xE2D5, // + 0x7C4C, 0xE2D4, // + 0x7C4D, 0x90D0, // + 0x7C4F, 0xE2D7, // + 0x7C50, 0xE2D9, // + 0x7C54, 0xE2D6, // + 0x7C56, 0xE2DD, // + 0x7C58, 0xE2DA, // + 0x7C5F, 0xE2DB, // + 0x7C60, 0xE2C4, // + 0x7C64, 0xE2DC, // + 0x7C65, 0xE2DE, // + 0x7C6C, 0xE2DF, // + 0x7C73, 0x95C4, // + 0x7C75, 0xE2E0, // + 0x7C7E, 0x96E0, // + 0x7C81, 0x8BCC, // + 0x7C82, 0x8C48, // + 0x7C83, 0xE2E1, // + 0x7C89, 0x95B2, // + 0x7C8B, 0x9088, // + 0x7C8D, 0x96AE, // + 0x7C90, 0xE2E2, // + 0x7C92, 0x97B1, // + 0x7C95, 0x9494, // + 0x7C97, 0x9165, // + 0x7C98, 0x9453, // + 0x7C9B, 0x8F6C, // + 0x7C9F, 0x88BE, // + 0x7CA1, 0xE2E7, // + 0x7CA2, 0xE2E5, // + 0x7CA4, 0xE2E3, // + 0x7CA5, 0x8A9F, // + 0x7CA7, 0x8FCF, // + 0x7CA8, 0xE2E8, // + 0x7CAB, 0xE2E6, // + 0x7CAD, 0xE2E4, // + 0x7CAE, 0xE2EC, // + 0x7CB1, 0xE2EB, // + 0x7CB2, 0xE2EA, // + 0x7CB3, 0xE2E9, // + 0x7CB9, 0xE2ED, // + 0x7CBD, 0xE2EE, // + 0x7CBE, 0x90B8, // + 0x7CC0, 0xE2EF, // + 0x7CC2, 0xE2F1, // + 0x7CC5, 0xE2F0, // + 0x7CCA, 0x8CD0, // + 0x7CCE, 0x9157, // + 0x7CD2, 0xE2F3, // + 0x7CD6, 0x939C, // + 0x7CD8, 0xE2F2, // + 0x7CDC, 0xE2F4, // + 0x7CDE, 0x95B3, // + 0x7CDF, 0x918C, // + 0x7CE0, 0x8D66, // + 0x7CE2, 0xE2F5, // + 0x7CE7, 0x97C6, // + 0x7CEF, 0xE2F7, // + 0x7CF2, 0xE2F8, // + 0x7CF4, 0xE2F9, // + 0x7CF6, 0xE2FA, // + 0x7CF8, 0x8E85, // + 0x7CFA, 0xE2FB, // + 0x7CFB, 0x8C6E, // + 0x7CFE, 0x8B8A, // + 0x7D00, 0x8B49, // + 0x7D02, 0xE340, // + 0x7D04, 0x96F1, // + 0x7D05, 0x8D67, // + 0x7D06, 0xE2FC, // + 0x7D0A, 0xE343, // + 0x7D0B, 0x96E4, // + 0x7D10, 0x9552, // + 0x7D14, 0x8F83, // + 0x7D15, 0xE342, // + 0x7D17, 0x8ED1, // + 0x7D18, 0x8D68, // + 0x7D19, 0x8E86, // + 0x7D1A, 0x8B89, // + 0x7D1B, 0x95B4, // + 0x7D1C, 0xE341, // + 0x7D20, 0x9166, // + 0x7D21, 0x9661, // + 0x7D22, 0x8DF5, // + 0x7D2B, 0x8E87, // + 0x7D2C, 0x92DB, // + 0x7D2E, 0xE346, // + 0x7D2F, 0x97DD, // + 0x7D30, 0x8DD7, // + 0x7D32, 0xE347, // + 0x7D33, 0x9061, // + 0x7D35, 0xE349, // + 0x7D39, 0x8FD0, // + 0x7D3A, 0x8DAE, // + 0x7D3F, 0xE348, // + 0x7D42, 0x8F49, // + 0x7D43, 0x8CBC, // + 0x7D44, 0x9167, // + 0x7D45, 0xE344, // + 0x7D46, 0xE34A, // + 0x7D4B, 0xE345, // + 0x7D4C, 0x8C6F, // + 0x7D4E, 0xE34D, // + 0x7D4F, 0xE351, // + 0x7D50, 0x8C8B, // + 0x7D56, 0xE34C, // + 0x7D5B, 0xE355, // + 0x7D5E, 0x8D69, // + 0x7D61, 0x978D, // + 0x7D62, 0x88BA, // + 0x7D63, 0xE352, // + 0x7D66, 0x8B8B, // + 0x7D68, 0xE34F, // + 0x7D6E, 0xE350, // + 0x7D71, 0x939D, // + 0x7D72, 0xE34E, // + 0x7D73, 0xE34B, // + 0x7D75, 0x8A47, // + 0x7D76, 0x90E2, // + 0x7D79, 0x8CA6, // + 0x7D7D, 0xE357, // + 0x7D89, 0xE354, // + 0x7D8F, 0xE356, // + 0x7D93, 0xE353, // + 0x7D99, 0x8C70, // + 0x7D9A, 0x91B1, // + 0x7D9B, 0xE358, // + 0x7D9C, 0x918E, // + 0x7D9F, 0xE365, // + 0x7DA2, 0xE361, // + 0x7DAB, 0xE35F, // + 0x7DAC, 0x8EF8, // + 0x7DAD, 0x88DB, // + 0x7DAE, 0xE35A, // + 0x7DAF, 0xE362, // + 0x7DB0, 0xE366, // + 0x7DB1, 0x8D6A, // + 0x7DB2, 0x96D4, // + 0x7DB4, 0x92D4, // + 0x7DB5, 0xE35C, // + 0x7DB8, 0xE364, // + 0x7DBA, 0xE359, // + 0x7DBB, 0x925D, // + 0x7DBD, 0xE35E, // + 0x7DBE, 0x88BB, // + 0x7DBF, 0x96C8, // + 0x7DC7, 0xE35D, // + 0x7DCA, 0x8BD9, // + 0x7DCB, 0x94EA, // + 0x7DCF, 0x918D, // + 0x7DD1, 0x97CE, // + 0x7DD2, 0x8F8F, // + 0x7DD5, 0xE38E, // + 0x7DD8, 0xE367, // + 0x7DDA, 0x90FC, // + 0x7DDC, 0xE363, // + 0x7DDD, 0xE368, // + 0x7DDE, 0xE36A, // + 0x7DE0, 0x92F7, // + 0x7DE1, 0xE36D, // + 0x7DE4, 0xE369, // + 0x7DE8, 0x95D2, // + 0x7DE9, 0x8AC9, // + 0x7DEC, 0x96C9, // + 0x7DEF, 0x88DC, // + 0x7DF2, 0xE36C, // + 0x7DF4, 0x97FB, // + 0x7DFB, 0xE36B, // + 0x7E01, 0x898F, // + 0x7E04, 0x93EA, // + 0x7E05, 0xE36E, // + 0x7E09, 0xE375, // + 0x7E0A, 0xE36F, // + 0x7E0B, 0xE376, // + 0x7E12, 0xE372, // + 0x7E1B, 0x949B, // + 0x7E1E, 0x8EC8, // + 0x7E1F, 0xE374, // + 0x7E21, 0xE371, // + 0x7E22, 0xE377, // + 0x7E23, 0xE370, // + 0x7E26, 0x8F63, // + 0x7E2B, 0x9644, // + 0x7E2E, 0x8F6B, // + 0x7E31, 0xE373, // + 0x7E32, 0xE380, // + 0x7E35, 0xE37B, // + 0x7E37, 0xE37E, // + 0x7E39, 0xE37C, // + 0x7E3A, 0xE381, // + 0x7E3B, 0xE37A, // + 0x7E3D, 0xE360, // + 0x7E3E, 0x90D1, // + 0x7E41, 0x94C9, // + 0x7E43, 0xE37D, // + 0x7E46, 0xE378, // + 0x7E4A, 0x9140, // + 0x7E4B, 0x8C71, // + 0x7E4D, 0x8F4A, // + 0x7E54, 0x9044, // + 0x7E55, 0x9155, // + 0x7E56, 0xE384, // + 0x7E59, 0xE386, // + 0x7E5A, 0xE387, // + 0x7E5D, 0xE383, // + 0x7E5E, 0xE385, // + 0x7E66, 0xE379, // + 0x7E67, 0xE382, // + 0x7E69, 0xE38A, // + 0x7E6A, 0xE389, // + 0x7E6D, 0x969A, // + 0x7E70, 0x8C4A, // + 0x7E79, 0xE388, // + 0x7E7B, 0xE38C, // + 0x7E7C, 0xE38B, // + 0x7E7D, 0xE38F, // + 0x7E7F, 0xE391, // + 0x7E83, 0xE38D, // + 0x7E88, 0xE392, // + 0x7E89, 0xE393, // + 0x7E8C, 0xE394, // + 0x7E8E, 0xE39A, // + 0x7E8F, 0x935A, // + 0x7E90, 0xE396, // + 0x7E92, 0xE395, // + 0x7E93, 0xE397, // + 0x7E94, 0xE398, // + 0x7E96, 0xE399, // + 0x7E9B, 0xE39B, // + 0x7E9C, 0xE39C, // + 0x7F36, 0x8ACA, // + 0x7F38, 0xE39D, // + 0x7F3A, 0xE39E, // + 0x7F45, 0xE39F, // + 0x7F4C, 0xE3A0, // + 0x7F4D, 0xE3A1, // + 0x7F4E, 0xE3A2, // + 0x7F50, 0xE3A3, // + 0x7F51, 0xE3A4, // + 0x7F54, 0xE3A6, // + 0x7F55, 0xE3A5, // + 0x7F58, 0xE3A7, // + 0x7F5F, 0xE3A8, // + 0x7F60, 0xE3A9, // + 0x7F67, 0xE3AC, // + 0x7F68, 0xE3AA, // + 0x7F69, 0xE3AB, // + 0x7F6A, 0x8DDF, // + 0x7F6B, 0x8C72, // + 0x7F6E, 0x9275, // + 0x7F70, 0x94B1, // + 0x7F72, 0x8F90, // + 0x7F75, 0x946C, // + 0x7F77, 0x94EB, // + 0x7F78, 0xE3AD, // + 0x7F79, 0x9CEB, // + 0x7F82, 0xE3AE, // + 0x7F83, 0xE3B0, // + 0x7F85, 0x9785, // + 0x7F86, 0xE3AF, // + 0x7F87, 0xE3B2, // + 0x7F88, 0xE3B1, // + 0x7F8A, 0x9772, // + 0x7F8C, 0xE3B3, // + 0x7F8E, 0x94FC, // + 0x7F94, 0xE3B4, // + 0x7F9A, 0xE3B7, // + 0x7F9D, 0xE3B6, // + 0x7F9E, 0xE3B5, // + 0x7FA3, 0xE3B8, // + 0x7FA4, 0x8C51, // + 0x7FA8, 0x9141, // + 0x7FA9, 0x8B60, // + 0x7FAE, 0xE3BC, // + 0x7FAF, 0xE3B9, // + 0x7FB2, 0xE3BA, // + 0x7FB6, 0xE3BD, // + 0x7FB8, 0xE3BE, // + 0x7FB9, 0xE3BB, // + 0x7FBD, 0x8948, // + 0x7FC1, 0x89A5, // + 0x7FC5, 0xE3C0, // + 0x7FC6, 0xE3C1, // + 0x7FCA, 0xE3C2, // + 0x7FCC, 0x9782, // + 0x7FD2, 0x8F4B, // + 0x7FD4, 0xE3C4, // + 0x7FD5, 0xE3C3, // + 0x7FE0, 0x9089, // + 0x7FE1, 0xE3C5, // + 0x7FE6, 0xE3C6, // + 0x7FE9, 0xE3C7, // + 0x7FEB, 0x8AE3, // + 0x7FF0, 0x8ACB, // + 0x7FF3, 0xE3C8, // + 0x7FF9, 0xE3C9, // + 0x7FFB, 0x967C, // + 0x7FFC, 0x9783, // + 0x8000, 0x9773, // + 0x8001, 0x9856, // + 0x8003, 0x8D6C, // + 0x8004, 0xE3CC, // + 0x8005, 0x8ED2, // + 0x8006, 0xE3CB, // + 0x800B, 0xE3CD, // + 0x800C, 0x8EA7, // + 0x8010, 0x91CF, // + 0x8012, 0xE3CE, // + 0x8015, 0x8D6B, // + 0x8017, 0x96D5, // + 0x8018, 0xE3CF, // + 0x8019, 0xE3D0, // + 0x801C, 0xE3D1, // + 0x8021, 0xE3D2, // + 0x8028, 0xE3D3, // + 0x8033, 0x8EA8, // + 0x8036, 0x96EB, // + 0x803B, 0xE3D5, // + 0x803D, 0x925E, // + 0x803F, 0xE3D4, // + 0x8046, 0xE3D7, // + 0x804A, 0xE3D6, // + 0x8052, 0xE3D8, // + 0x8056, 0x90B9, // + 0x8058, 0xE3D9, // + 0x805A, 0xE3DA, // + 0x805E, 0x95B7, // + 0x805F, 0xE3DB, // + 0x8061, 0x918F, // + 0x8062, 0xE3DC, // + 0x8068, 0xE3DD, // + 0x806F, 0x97FC, // + 0x8070, 0xE3E0, // + 0x8072, 0xE3DF, // + 0x8073, 0xE3DE, // + 0x8074, 0x92AE, // + 0x8076, 0xE3E1, // + 0x8077, 0x9045, // + 0x8079, 0xE3E2, // + 0x807D, 0xE3E3, // + 0x807E, 0x9857, // + 0x807F, 0xE3E4, // + 0x8084, 0xE3E5, // + 0x8085, 0xE3E7, // + 0x8086, 0xE3E6, // + 0x8087, 0x94A3, // + 0x8089, 0x93F7, // + 0x808B, 0x985D, // + 0x808C, 0x94A7, // + 0x8093, 0xE3E9, // + 0x8096, 0x8FD1, // + 0x8098, 0x9549, // + 0x809A, 0xE3EA, // + 0x809B, 0xE3E8, // + 0x809D, 0x8ACC, // + 0x80A1, 0x8CD2, // + 0x80A2, 0x8E88, // + 0x80A5, 0x94EC, // + 0x80A9, 0x8CA8, // + 0x80AA, 0x9662, // + 0x80AC, 0xE3ED, // + 0x80AD, 0xE3EB, // + 0x80AF, 0x8D6D, // + 0x80B1, 0x8D6E, // + 0x80B2, 0x88E7, // + 0x80B4, 0x8DE6, // + 0x80BA, 0x9478, // + 0x80C3, 0x88DD, // + 0x80C4, 0xE3F2, // + 0x80C6, 0x925F, // + 0x80CC, 0x9477, // + 0x80CE, 0x91D9, // + 0x80D6, 0xE3F4, // + 0x80D9, 0xE3F0, // + 0x80DA, 0xE3F3, // + 0x80DB, 0xE3EE, // + 0x80DD, 0xE3F1, // + 0x80DE, 0x9645, // + 0x80E1, 0x8CD3, // + 0x80E4, 0x88FB, // + 0x80E5, 0xE3EF, // + 0x80EF, 0xE3F6, // + 0x80F1, 0xE3F7, // + 0x80F4, 0x93B7, // + 0x80F8, 0x8BB9, // + 0x80FC, 0xE445, // + 0x80FD, 0x945C, // + 0x8102, 0x8E89, // + 0x8105, 0x8BBA, // + 0x8106, 0x90C6, // + 0x8107, 0x9865, // + 0x8108, 0x96AC, // + 0x8109, 0xE3F5, // + 0x810A, 0x90D2, // + 0x811A, 0x8B72, // + 0x811B, 0xE3F8, // + 0x8123, 0xE3FA, // + 0x8129, 0xE3F9, // + 0x812F, 0xE3FB, // + 0x8131, 0x9245, // + 0x8133, 0x945D, // + 0x8139, 0x92AF, // + 0x813E, 0xE442, // + 0x8146, 0xE441, // + 0x814B, 0xE3FC, // + 0x814E, 0x9074, // + 0x8150, 0x9585, // + 0x8151, 0xE444, // + 0x8153, 0xE443, // + 0x8154, 0x8D6F, // + 0x8155, 0x9872, // + 0x815F, 0xE454, // + 0x8165, 0xE448, // + 0x8166, 0xE449, // + 0x816B, 0x8EEE, // + 0x816E, 0xE447, // + 0x8170, 0x8D98, // + 0x8171, 0xE446, // + 0x8174, 0xE44A, // + 0x8178, 0x92B0, // + 0x8179, 0x95A0, // + 0x817A, 0x9142, // + 0x817F, 0x91DA, // + 0x8180, 0xE44E, // + 0x8182, 0xE44F, // + 0x8183, 0xE44B, // + 0x8188, 0xE44C, // + 0x818A, 0xE44D, // + 0x818F, 0x8D70, // + 0x8193, 0xE455, // + 0x8195, 0xE451, // + 0x819A, 0x9586, // + 0x819C, 0x968C, // + 0x819D, 0x9547, // + 0x81A0, 0xE450, // + 0x81A3, 0xE453, // + 0x81A4, 0xE452, // + 0x81A8, 0x9663, // + 0x81A9, 0xE456, // + 0x81B0, 0xE457, // + 0x81B3, 0x9156, // + 0x81B5, 0xE458, // + 0x81B8, 0xE45A, // + 0x81BA, 0xE45E, // + 0x81BE, 0xE459, // + 0x81BF, 0x945E, // + 0x81C0, 0xE45C, // + 0x81C2, 0xE45D, // + 0x81C6, 0x89B0, // + 0x81C8, 0xE464, // + 0x81C9, 0xE45F, // + 0x81CD, 0xE460, // + 0x81D1, 0xE461, // + 0x81D3, 0x919F, // + 0x81D8, 0xE463, // + 0x81D9, 0xE462, // + 0x81DA, 0xE465, // + 0x81DF, 0xE466, // + 0x81E0, 0xE467, // + 0x81E3, 0x9062, // + 0x81E5, 0x89E7, // + 0x81E7, 0xE468, // + 0x81E8, 0x97D5, // + 0x81EA, 0x8EA9, // + 0x81ED, 0x8F4C, // + 0x81F3, 0x8E8A, // + 0x81F4, 0x9276, // + 0x81FA, 0xE469, // + 0x81FB, 0xE46A, // + 0x81FC, 0x8950, // + 0x81FE, 0xE46B, // + 0x8201, 0xE46C, // + 0x8202, 0xE46D, // + 0x8205, 0xE46E, // + 0x8207, 0xE46F, // + 0x8208, 0x8BBB, // + 0x8209, 0x9DA8, // + 0x820A, 0xE470, // + 0x820C, 0x90E3, // + 0x820D, 0xE471, // + 0x820E, 0x8EC9, // + 0x8210, 0xE472, // + 0x8212, 0x98AE, // + 0x8216, 0xE473, // + 0x8217, 0x95DC, // + 0x8218, 0x8ADA, // + 0x821B, 0x9143, // + 0x821C, 0x8F77, // + 0x821E, 0x9591, // + 0x821F, 0x8F4D, // + 0x8229, 0xE474, // + 0x822A, 0x8D71, // + 0x822B, 0xE475, // + 0x822C, 0x94CA, // + 0x822E, 0xE484, // + 0x8233, 0xE477, // + 0x8235, 0x91C7, // + 0x8236, 0x9495, // + 0x8237, 0x8CBD, // + 0x8238, 0xE476, // + 0x8239, 0x9144, // + 0x8240, 0xE478, // + 0x8247, 0x92F8, // + 0x8258, 0xE47A, // + 0x8259, 0xE479, // + 0x825A, 0xE47C, // + 0x825D, 0xE47B, // + 0x825F, 0xE47D, // + 0x8262, 0xE480, // + 0x8264, 0xE47E, // + 0x8266, 0x8ACD, // + 0x8268, 0xE481, // + 0x826A, 0xE482, // + 0x826B, 0xE483, // + 0x826E, 0x8DAF, // + 0x826F, 0x97C7, // + 0x8271, 0xE485, // + 0x8272, 0x9046, // + 0x8276, 0x8990, // + 0x8277, 0xE486, // + 0x8278, 0xE487, // + 0x827E, 0xE488, // + 0x828B, 0x88F0, // + 0x828D, 0xE489, // + 0x8292, 0xE48A, // + 0x8299, 0x9587, // + 0x829D, 0x8EC5, // + 0x829F, 0xE48C, // + 0x82A5, 0x8A48, // + 0x82A6, 0x88B0, // + 0x82AB, 0xE48B, // + 0x82AC, 0xE48E, // + 0x82AD, 0x946D, // + 0x82AF, 0x9063, // + 0x82B1, 0x89D4, // + 0x82B3, 0x9646, // + 0x82B8, 0x8C7C, // + 0x82B9, 0x8BDA, // + 0x82BB, 0xE48D, // + 0x82BD, 0x89E8, // + 0x82C5, 0x8AA1, // + 0x82D1, 0x8991, // + 0x82D2, 0xE492, // + 0x82D3, 0x97E8, // + 0x82D4, 0x91DB, // + 0x82D7, 0x9563, // + 0x82D9, 0xE49E, // + 0x82DB, 0x89D5, // + 0x82DC, 0xE49C, // + 0x82DE, 0xE49A, // + 0x82DF, 0xE491, // + 0x82E1, 0xE48F, // + 0x82E3, 0xE490, // + 0x82E5, 0x8EE1, // + 0x82E6, 0x8BEA, // + 0x82E7, 0x9297, // + 0x82EB, 0x93CF, // + 0x82F1, 0x8970, // + 0x82F3, 0xE494, // + 0x82F4, 0xE493, // + 0x82F9, 0xE499, // + 0x82FA, 0xE495, // + 0x82FB, 0xE498, // + 0x8302, 0x96CE, // + 0x8303, 0xE497, // + 0x8304, 0x89D6, // + 0x8305, 0x8A9D, // + 0x8306, 0xE49B, // + 0x8309, 0xE49D, // + 0x830E, 0x8C73, // + 0x8316, 0xE4A1, // + 0x8317, 0xE4AA, // + 0x8318, 0xE4AB, // + 0x831C, 0x88A9, // + 0x8323, 0xE4B2, // + 0x8328, 0x88EF, // + 0x832B, 0xE4A9, // + 0x832F, 0xE4A8, // + 0x8331, 0xE4A3, // + 0x8332, 0xE4A2, // + 0x8334, 0xE4A0, // + 0x8335, 0xE49F, // + 0x8336, 0x9283, // + 0x8338, 0x91F9, // + 0x8339, 0xE4A5, // + 0x8340, 0xE4A4, // + 0x8345, 0xE4A7, // + 0x8349, 0x9190, // + 0x834A, 0x8C74, // + 0x834F, 0x8960, // + 0x8350, 0xE4A6, // + 0x8352, 0x8D72, // + 0x8358, 0x9191, // + 0x8373, 0xE4B8, // + 0x8375, 0xE4B9, // + 0x8377, 0x89D7, // + 0x837B, 0x89AC, // + 0x837C, 0xE4B6, // + 0x8385, 0xE4AC, // + 0x8387, 0xE4B4, // + 0x8389, 0xE4BB, // + 0x838A, 0xE4B5, // + 0x838E, 0xE4B3, // + 0x8393, 0xE496, // + 0x8396, 0xE4B1, // + 0x839A, 0xE4AD, // + 0x839E, 0x8ACE, // + 0x839F, 0xE4AF, // + 0x83A0, 0xE4BA, // + 0x83A2, 0xE4B0, // + 0x83A8, 0xE4BC, // + 0x83AA, 0xE4AE, // + 0x83AB, 0x949C, // + 0x83B1, 0x9789, // + 0x83B5, 0xE4B7, // + 0x83BD, 0xE4CD, // + 0x83C1, 0xE4C5, // + 0x83C5, 0x909B, // + 0x83CA, 0x8B65, // + 0x83CC, 0x8BDB, // + 0x83CE, 0xE4C0, // + 0x83D3, 0x89D9, // + 0x83D6, 0x8FD2, // + 0x83D8, 0xE4C3, // + 0x83DC, 0x8DD8, // + 0x83DF, 0x9370, // + 0x83E0, 0xE4C8, // + 0x83E9, 0x95EC, // + 0x83EB, 0xE4BF, // + 0x83EF, 0x89D8, // + 0x83F0, 0x8CD4, // + 0x83F1, 0x9548, // + 0x83F2, 0xE4C9, // + 0x83F4, 0xE4BD, // + 0x83F7, 0xE4C6, // + 0x83FB, 0xE4D0, // + 0x83FD, 0xE4C1, // + 0x8403, 0xE4C2, // + 0x8404, 0x93B8, // + 0x8407, 0xE4C7, // + 0x840B, 0xE4C4, // + 0x840C, 0x9647, // + 0x840D, 0xE4CA, // + 0x840E, 0x88DE, // + 0x8413, 0xE4BE, // + 0x8420, 0xE4CC, // + 0x8422, 0xE4CB, // + 0x8429, 0x948B, // + 0x842A, 0xE4D2, // + 0x842C, 0xE4DD, // + 0x8431, 0x8A9E, // + 0x8435, 0xE4E0, // + 0x8438, 0xE4CE, // + 0x843C, 0xE4D3, // + 0x843D, 0x978E, // + 0x8446, 0xE4DC, // + 0x8449, 0x9774, // + 0x844E, 0x97A8, // + 0x8457, 0x9298, // + 0x845B, 0x8A8B, // + 0x8461, 0x9592, // + 0x8462, 0xE4E2, // + 0x8463, 0x939F, // + 0x8466, 0x88AF, // + 0x8469, 0xE4DB, // + 0x846B, 0xE4D7, // + 0x846C, 0x9192, // + 0x846D, 0xE4D1, // + 0x846E, 0xE4D9, // + 0x846F, 0xE4DE, // + 0x8471, 0x944B, // + 0x8475, 0x88A8, // + 0x8477, 0xE4D6, // + 0x8479, 0xE4DF, // + 0x847A, 0x9598, // + 0x8482, 0xE4DA, // + 0x8484, 0xE4D5, // + 0x848B, 0x8FD3, // + 0x8490, 0x8F4E, // + 0x8494, 0x8EAA, // + 0x8499, 0x96D6, // + 0x849C, 0x9566, // + 0x849F, 0xE4E5, // + 0x84A1, 0xE4EE, // + 0x84AD, 0xE4D8, // + 0x84B2, 0x8A97, // + 0x84B8, 0x8FF6, // + 0x84B9, 0xE4E3, // + 0x84BB, 0xE4E8, // + 0x84BC, 0x9193, // + 0x84BF, 0xE4E4, // + 0x84C1, 0xE4EB, // + 0x84C4, 0x927E, // + 0x84C6, 0xE4EC, // + 0x84C9, 0x9775, // + 0x84CA, 0xE4E1, // + 0x84CB, 0x8A57, // + 0x84CD, 0xE4E7, // + 0x84D0, 0xE4EA, // + 0x84D1, 0x96AA, // + 0x84D6, 0xE4ED, // + 0x84D9, 0xE4E6, // + 0x84DA, 0xE4E9, // + 0x84EC, 0x9648, // + 0x84EE, 0x9840, // + 0x84F4, 0xE4F1, // + 0x84FC, 0xE4F8, // + 0x84FF, 0xE4F0, // + 0x8500, 0x8EC1, // + 0x8506, 0xE4CF, // + 0x8511, 0x95CC, // + 0x8513, 0x96A0, // + 0x8514, 0xE4F7, // + 0x8515, 0xE4F6, // + 0x8517, 0xE4F2, // + 0x8518, 0xE4F3, // + 0x851A, 0x8955, // + 0x851F, 0xE4F5, // + 0x8521, 0xE4EF, // + 0x8526, 0x92D3, // + 0x852C, 0xE4F4, // + 0x852D, 0x88FC, // + 0x8535, 0x91A0, // + 0x853D, 0x95C1, // + 0x8540, 0xE4F9, // + 0x8541, 0xE540, // + 0x8543, 0x94D7, // + 0x8548, 0xE4FC, // + 0x8549, 0x8FD4, // + 0x854A, 0x8EC7, // + 0x854B, 0xE542, // + 0x854E, 0x8BBC, // + 0x8555, 0xE543, // + 0x8557, 0x9599, // + 0x8558, 0xE4FB, // + 0x855A, 0xE4D4, // + 0x8563, 0xE4FA, // + 0x8568, 0x986E, // + 0x8569, 0x93A0, // + 0x856A, 0x9593, // + 0x856D, 0xE54A, // + 0x8577, 0xE550, // + 0x857E, 0xE551, // + 0x8580, 0xE544, // + 0x8584, 0x9496, // + 0x8587, 0xE54E, // + 0x8588, 0xE546, // + 0x858A, 0xE548, // + 0x8590, 0xE552, // + 0x8591, 0xE547, // + 0x8594, 0xE54B, // + 0x8597, 0x8992, // + 0x8599, 0x93E3, // + 0x859B, 0xE54C, // + 0x859C, 0xE54F, // + 0x85A4, 0xE545, // + 0x85A6, 0x9145, // + 0x85A8, 0xE549, // + 0x85A9, 0x8E46, // + 0x85AA, 0x9064, // + 0x85AB, 0x8C4F, // + 0x85AC, 0x96F2, // + 0x85AE, 0x96F7, // + 0x85AF, 0x8F92, // + 0x85B9, 0xE556, // + 0x85BA, 0xE554, // + 0x85C1, 0x986D, // + 0x85C9, 0xE553, // + 0x85CD, 0x9795, // + 0x85CF, 0xE555, // + 0x85D0, 0xE557, // + 0x85D5, 0xE558, // + 0x85DD, 0xE559, // + 0x85E4, 0x93A1, // + 0x85E5, 0xE55A, // + 0x85E9, 0x94CB, // + 0x85EA, 0xE54D, // + 0x85F7, 0x8F93, // + 0x85F9, 0xE55C, // + 0x85FA, 0xE561, // + 0x85FB, 0x9194, // + 0x85FE, 0xE560, // + 0x8602, 0xE541, // + 0x8606, 0xE562, // + 0x8607, 0x9168, // + 0x860A, 0xE55D, // + 0x860B, 0xE55F, // + 0x8613, 0xE55E, // + 0x8616, 0x9F50, // + 0x8617, 0x9F41, // + 0x861A, 0xE564, // + 0x8622, 0xE563, // + 0x862D, 0x9796, // + 0x862F, 0xE1BA, // + 0x8630, 0xE565, // + 0x863F, 0xE566, // + 0x864D, 0xE567, // + 0x864E, 0x8CD5, // + 0x8650, 0x8B73, // + 0x8654, 0xE569, // + 0x8655, 0x997C, // + 0x865A, 0x8B95, // + 0x865C, 0x97B8, // + 0x865E, 0x8BF1, // + 0x865F, 0xE56A, // + 0x8667, 0xE56B, // + 0x866B, 0x928E, // + 0x8671, 0xE56C, // + 0x8679, 0x93F8, // + 0x867B, 0x88B8, // + 0x868A, 0x89E1, // + 0x868B, 0xE571, // + 0x868C, 0xE572, // + 0x8693, 0xE56D, // + 0x8695, 0x8E5C, // + 0x86A3, 0xE56E, // + 0x86A4, 0x9461, // + 0x86A9, 0xE56F, // + 0x86AA, 0xE570, // + 0x86AB, 0xE57A, // + 0x86AF, 0xE574, // + 0x86B0, 0xE577, // + 0x86B6, 0xE573, // + 0x86C4, 0xE575, // + 0x86C6, 0xE576, // + 0x86C7, 0x8ED6, // + 0x86C9, 0xE578, // + 0x86CB, 0x9260, // + 0x86CD, 0x8C75, // + 0x86CE, 0x8A61, // + 0x86D4, 0xE57B, // + 0x86D9, 0x8A5E, // + 0x86DB, 0xE581, // + 0x86DE, 0xE57C, // + 0x86DF, 0xE580, // + 0x86E4, 0x94B8, // + 0x86E9, 0xE57D, // + 0x86EC, 0xE57E, // + 0x86ED, 0x9567, // + 0x86EE, 0x94D8, // + 0x86EF, 0xE582, // + 0x86F8, 0x91FB, // + 0x86F9, 0xE58C, // + 0x86FB, 0xE588, // + 0x86FE, 0x89E9, // + 0x8700, 0xE586, // + 0x8702, 0x9649, // + 0x8703, 0xE587, // + 0x8706, 0xE584, // + 0x8708, 0xE585, // + 0x8709, 0xE58A, // + 0x870A, 0xE58D, // + 0x870D, 0xE58B, // + 0x8711, 0xE589, // + 0x8712, 0xE583, // + 0x8718, 0x9277, // + 0x871A, 0xE594, // + 0x871C, 0x96A8, // + 0x8725, 0xE592, // + 0x8729, 0xE593, // + 0x8734, 0xE58E, // + 0x8737, 0xE590, // + 0x873B, 0xE591, // + 0x873F, 0xE58F, // + 0x8749, 0x90E4, // + 0x874B, 0x9858, // + 0x874C, 0xE598, // + 0x874E, 0xE599, // + 0x8753, 0xE59F, // + 0x8755, 0x9049, // + 0x8757, 0xE59B, // + 0x8759, 0xE59E, // + 0x875F, 0xE596, // + 0x8760, 0xE595, // + 0x8763, 0xE5A0, // + 0x8766, 0x89DA, // + 0x8768, 0xE59C, // + 0x876A, 0xE5A1, // + 0x876E, 0xE59D, // + 0x8774, 0xE59A, // + 0x8776, 0x92B1, // + 0x8778, 0xE597, // + 0x877F, 0x9488, // + 0x8782, 0xE5A5, // + 0x878D, 0x975A, // + 0x879F, 0xE5A4, // + 0x87A2, 0xE5A3, // + 0x87AB, 0xE5AC, // + 0x87AF, 0xE5A6, // + 0x87B3, 0xE5AE, // + 0x87BA, 0x9786, // + 0x87BB, 0xE5B1, // + 0x87BD, 0xE5A8, // + 0x87C0, 0xE5A9, // + 0x87C4, 0xE5AD, // + 0x87C6, 0xE5B0, // + 0x87C7, 0xE5AF, // + 0x87CB, 0xE5A7, // + 0x87D0, 0xE5AA, // + 0x87D2, 0xE5BB, // + 0x87E0, 0xE5B4, // + 0x87EF, 0xE5B2, // + 0x87F2, 0xE5B3, // + 0x87F6, 0xE5B8, // + 0x87F7, 0xE5B9, // + 0x87F9, 0x8A49, // + 0x87FB, 0x8B61, // + 0x87FE, 0xE5B7, // + 0x8805, 0xE5A2, // + 0x880D, 0xE5B6, // + 0x880E, 0xE5BA, // + 0x880F, 0xE5B5, // + 0x8811, 0xE5BC, // + 0x8815, 0xE5BE, // + 0x8816, 0xE5BD, // + 0x8821, 0xE5C0, // + 0x8822, 0xE5BF, // + 0x8823, 0xE579, // + 0x8827, 0xE5C4, // + 0x8831, 0xE5C1, // + 0x8836, 0xE5C2, // + 0x8839, 0xE5C3, // + 0x883B, 0xE5C5, // + 0x8840, 0x8C8C, // + 0x8842, 0xE5C7, // + 0x8844, 0xE5C6, // + 0x8846, 0x8F4F, // + 0x884C, 0x8D73, // + 0x884D, 0x9FA5, // + 0x8852, 0xE5C8, // + 0x8853, 0x8F70, // + 0x8857, 0x8A58, // + 0x8859, 0xE5C9, // + 0x885B, 0x8971, // + 0x885D, 0x8FD5, // + 0x885E, 0xE5CA, // + 0x8861, 0x8D74, // + 0x8862, 0xE5CB, // + 0x8863, 0x88DF, // + 0x8868, 0x955C, // + 0x886B, 0xE5CC, // + 0x8870, 0x908A, // + 0x8872, 0xE5D3, // + 0x8875, 0xE5D0, // + 0x8877, 0x928F, // + 0x887D, 0xE5D1, // + 0x887E, 0xE5CE, // + 0x887F, 0x8BDC, // + 0x8881, 0xE5CD, // + 0x8882, 0xE5D4, // + 0x8888, 0x8C55, // + 0x888B, 0x91DC, // + 0x888D, 0xE5DA, // + 0x8892, 0xE5D6, // + 0x8896, 0x91B3, // + 0x8897, 0xE5D5, // + 0x8899, 0xE5D8, // + 0x889E, 0xE5CF, // + 0x88A2, 0xE5D9, // + 0x88A4, 0xE5DB, // + 0x88AB, 0x94ED, // + 0x88AE, 0xE5D7, // + 0x88B0, 0xE5DC, // + 0x88B1, 0xE5DE, // + 0x88B4, 0x8CD1, // + 0x88B5, 0xE5D2, // + 0x88B7, 0x88BF, // + 0x88BF, 0xE5DD, // + 0x88C1, 0x8DD9, // + 0x88C2, 0x97F4, // + 0x88C3, 0xE5DF, // + 0x88C4, 0xE5E0, // + 0x88C5, 0x9195, // + 0x88CF, 0x97A0, // + 0x88D4, 0xE5E1, // + 0x88D5, 0x9754, // + 0x88D8, 0xE5E2, // + 0x88D9, 0xE5E3, // + 0x88DC, 0x95E2, // + 0x88DD, 0xE5E4, // + 0x88DF, 0x8DBE, // + 0x88E1, 0x97A1, // + 0x88E8, 0xE5E9, // + 0x88F2, 0xE5EA, // + 0x88F3, 0x8FD6, // + 0x88F4, 0xE5E8, // + 0x88F8, 0x9787, // + 0x88F9, 0xE5E5, // + 0x88FC, 0xE5E7, // + 0x88FD, 0x90BB, // + 0x88FE, 0x909E, // + 0x8902, 0xE5E6, // + 0x8904, 0xE5EB, // + 0x8907, 0x95A1, // + 0x890A, 0xE5ED, // + 0x890C, 0xE5EC, // + 0x8910, 0x8A8C, // + 0x8912, 0x964A, // + 0x8913, 0xE5EE, // + 0x891D, 0xE5FA, // + 0x891E, 0xE5F0, // + 0x8925, 0xE5F1, // + 0x892A, 0xE5F2, // + 0x892B, 0xE5F3, // + 0x8936, 0xE5F7, // + 0x8938, 0xE5F8, // + 0x893B, 0xE5F6, // + 0x8941, 0xE5F4, // + 0x8943, 0xE5EF, // + 0x8944, 0xE5F5, // + 0x894C, 0xE5F9, // + 0x894D, 0xE8B5, // + 0x8956, 0x89A6, // + 0x895E, 0xE5FC, // + 0x895F, 0x8BDD, // + 0x8960, 0xE5FB, // + 0x8964, 0xE641, // + 0x8966, 0xE640, // + 0x896A, 0xE643, // + 0x896D, 0xE642, // + 0x896F, 0xE644, // + 0x8972, 0x8F50, // + 0x8974, 0xE645, // + 0x8977, 0xE646, // + 0x897E, 0xE647, // + 0x897F, 0x90BC, // + 0x8981, 0x9776, // + 0x8983, 0xE648, // + 0x8986, 0x95A2, // + 0x8987, 0x9465, // + 0x8988, 0xE649, // + 0x898A, 0xE64A, // + 0x898B, 0x8CA9, // + 0x898F, 0x8B4B, // + 0x8993, 0xE64B, // + 0x8996, 0x8E8B, // + 0x8997, 0x9460, // + 0x8998, 0xE64C, // + 0x899A, 0x8A6F, // + 0x89A1, 0xE64D, // + 0x89A6, 0xE64F, // + 0x89A7, 0x9797, // + 0x89A9, 0xE64E, // + 0x89AA, 0x9065, // + 0x89AC, 0xE650, // + 0x89AF, 0xE651, // + 0x89B2, 0xE652, // + 0x89B3, 0x8ACF, // + 0x89BA, 0xE653, // + 0x89BD, 0xE654, // + 0x89BF, 0xE655, // + 0x89C0, 0xE656, // + 0x89D2, 0x8A70, // + 0x89DA, 0xE657, // + 0x89DC, 0xE658, // + 0x89DD, 0xE659, // + 0x89E3, 0x89F0, // + 0x89E6, 0x9047, // + 0x89E7, 0xE65A, // + 0x89F8, 0xE65C, // + 0x8A00, 0x8CBE, // + 0x8A02, 0x92F9, // + 0x8A03, 0xE65D, // + 0x8A08, 0x8C76, // + 0x8A0A, 0x9075, // + 0x8A0C, 0xE660, // + 0x8A0E, 0x93A2, // + 0x8A10, 0xE65F, // + 0x8A13, 0x8C50, // + 0x8A16, 0xE65E, // + 0x8A17, 0x91F5, // + 0x8A18, 0x8B4C, // + 0x8A1B, 0xE661, // + 0x8A1D, 0xE662, // + 0x8A1F, 0x8FD7, // + 0x8A23, 0x8C8D, // + 0x8A25, 0xE663, // + 0x8A2A, 0x964B, // + 0x8A2D, 0x90DD, // + 0x8A31, 0x8B96, // + 0x8A33, 0x96F3, // + 0x8A34, 0x9169, // + 0x8A36, 0xE664, // + 0x8A3A, 0x9066, // + 0x8A3B, 0x9290, // + 0x8A3C, 0x8FD8, // + 0x8A41, 0xE665, // + 0x8A46, 0xE668, // + 0x8A48, 0xE669, // + 0x8A50, 0x8DBC, // + 0x8A51, 0x91C0, // + 0x8A52, 0xE667, // + 0x8A54, 0x8FD9, // + 0x8A55, 0x955D, // + 0x8A5B, 0xE666, // + 0x8A5E, 0x8E8C, // + 0x8A60, 0x8972, // + 0x8A62, 0xE66D, // + 0x8A63, 0x8C77, // + 0x8A66, 0x8E8E, // + 0x8A69, 0x8E8D, // + 0x8A6B, 0x986C, // + 0x8A6C, 0xE66C, // + 0x8A6D, 0xE66B, // + 0x8A6E, 0x9146, // + 0x8A70, 0x8B6C, // + 0x8A71, 0x9862, // + 0x8A72, 0x8A59, // + 0x8A73, 0x8FDA, // + 0x8A7C, 0xE66A, // + 0x8A82, 0xE66F, // + 0x8A84, 0xE670, // + 0x8A85, 0xE66E, // + 0x8A87, 0x8CD6, // + 0x8A89, 0x975F, // + 0x8A8C, 0x8E8F, // + 0x8A8D, 0x9446, // + 0x8A91, 0xE673, // + 0x8A93, 0x90BE, // + 0x8A95, 0x9261, // + 0x8A98, 0x9755, // + 0x8A9A, 0xE676, // + 0x8A9E, 0x8CEA, // + 0x8AA0, 0x90BD, // + 0x8AA1, 0xE672, // + 0x8AA3, 0xE677, // + 0x8AA4, 0x8CEB, // + 0x8AA5, 0xE674, // + 0x8AA6, 0xE675, // + 0x8AA8, 0xE671, // + 0x8AAC, 0x90E0, // + 0x8AAD, 0x93C7, // + 0x8AB0, 0x924E, // + 0x8AB2, 0x89DB, // + 0x8AB9, 0x94EE, // + 0x8ABC, 0x8B62, // + 0x8ABF, 0x92B2, // + 0x8AC2, 0xE67A, // + 0x8AC4, 0xE678, // + 0x8AC7, 0x926B, // + 0x8ACB, 0x90BF, // + 0x8ACC, 0x8AD0, // + 0x8ACD, 0xE679, // + 0x8ACF, 0x907A, // + 0x8AD2, 0x97C8, // + 0x8AD6, 0x985F, // + 0x8ADA, 0xE67B, // + 0x8ADB, 0xE687, // + 0x8ADC, 0x92B3, // + 0x8ADE, 0xE686, // + 0x8AE0, 0xE683, // + 0x8AE1, 0xE68B, // + 0x8AE2, 0xE684, // + 0x8AE4, 0xE680, // + 0x8AE6, 0x92FA, // + 0x8AE7, 0xE67E, // + 0x8AEB, 0xE67C, // + 0x8AED, 0x9740, // + 0x8AEE, 0x8E90, // + 0x8AF1, 0xE681, // + 0x8AF3, 0xE67D, // + 0x8AF7, 0xE685, // + 0x8AF8, 0x8F94, // + 0x8AFA, 0x8CBF, // + 0x8AFE, 0x91F8, // + 0x8B00, 0x9664, // + 0x8B01, 0x8979, // + 0x8B02, 0x88E0, // + 0x8B04, 0x93A3, // + 0x8B07, 0xE689, // + 0x8B0C, 0xE688, // + 0x8B0E, 0x93E4, // + 0x8B10, 0xE68D, // + 0x8B14, 0xE682, // + 0x8B16, 0xE68C, // + 0x8B17, 0xE68E, // + 0x8B19, 0x8CAA, // + 0x8B1A, 0xE68A, // + 0x8B1B, 0x8D75, // + 0x8B1D, 0x8ED3, // + 0x8B20, 0xE68F, // + 0x8B21, 0x9777, // + 0x8B26, 0xE692, // + 0x8B28, 0xE695, // + 0x8B2B, 0xE693, // + 0x8B2C, 0x9554, // + 0x8B33, 0xE690, // + 0x8B39, 0x8BDE, // + 0x8B3E, 0xE694, // + 0x8B41, 0xE696, // + 0x8B49, 0xE69A, // + 0x8B4C, 0xE697, // + 0x8B4E, 0xE699, // + 0x8B4F, 0xE698, // + 0x8B56, 0xE69B, // + 0x8B58, 0x8EAF, // + 0x8B5A, 0xE69D, // + 0x8B5B, 0xE69C, // + 0x8B5C, 0x9588, // + 0x8B5F, 0xE69F, // + 0x8B66, 0x8C78, // + 0x8B6B, 0xE69E, // + 0x8B6C, 0xE6A0, // + 0x8B6F, 0xE6A1, // + 0x8B70, 0x8B63, // + 0x8B71, 0xE3BF, // + 0x8B72, 0x8FF7, // + 0x8B74, 0xE6A2, // + 0x8B77, 0x8CEC, // + 0x8B7D, 0xE6A3, // + 0x8B80, 0xE6A4, // + 0x8B83, 0x8E5D, // + 0x8B8A, 0x9DCC, // + 0x8B8C, 0xE6A5, // + 0x8B8E, 0xE6A6, // + 0x8B90, 0x8F51, // + 0x8B92, 0xE6A7, // + 0x8B93, 0xE6A8, // + 0x8B96, 0xE6A9, // + 0x8B99, 0xE6AA, // + 0x8B9A, 0xE6AB, // + 0x8C37, 0x924A, // + 0x8C3A, 0xE6AC, // + 0x8C3F, 0xE6AE, // + 0x8C41, 0xE6AD, // + 0x8C46, 0x93A4, // + 0x8C48, 0xE6AF, // + 0x8C4A, 0x964C, // + 0x8C4C, 0xE6B0, // + 0x8C4E, 0xE6B1, // + 0x8C50, 0xE6B2, // + 0x8C55, 0xE6B3, // + 0x8C5A, 0x93D8, // + 0x8C61, 0x8FDB, // + 0x8C62, 0xE6B4, // + 0x8C6A, 0x8D8B, // + 0x8C6B, 0x98AC, // + 0x8C6C, 0xE6B5, // + 0x8C78, 0xE6B6, // + 0x8C79, 0x955E, // + 0x8C7A, 0xE6B7, // + 0x8C7C, 0xE6BF, // + 0x8C82, 0xE6B8, // + 0x8C85, 0xE6BA, // + 0x8C89, 0xE6B9, // + 0x8C8A, 0xE6BB, // + 0x8C8C, 0x9665, // + 0x8C8D, 0xE6BC, // + 0x8C8E, 0xE6BD, // + 0x8C94, 0xE6BE, // + 0x8C98, 0xE6C0, // + 0x8C9D, 0x8A4C, // + 0x8C9E, 0x92E5, // + 0x8CA0, 0x9589, // + 0x8CA1, 0x8DE0, // + 0x8CA2, 0x8D76, // + 0x8CA7, 0x956E, // + 0x8CA8, 0x89DD, // + 0x8CA9, 0x94CC, // + 0x8CAA, 0xE6C3, // + 0x8CAB, 0x8AD1, // + 0x8CAC, 0x90D3, // + 0x8CAD, 0xE6C2, // + 0x8CAE, 0xE6C7, // + 0x8CAF, 0x9299, // + 0x8CB0, 0x96E1, // + 0x8CB2, 0xE6C5, // + 0x8CB3, 0xE6C6, // + 0x8CB4, 0x8B4D, // + 0x8CB6, 0xE6C8, // + 0x8CB7, 0x9483, // + 0x8CB8, 0x91DD, // + 0x8CBB, 0x94EF, // + 0x8CBC, 0x935C, // + 0x8CBD, 0xE6C4, // + 0x8CBF, 0x9666, // + 0x8CC0, 0x89EA, // + 0x8CC1, 0xE6CA, // + 0x8CC2, 0x9847, // + 0x8CC3, 0x92C0, // + 0x8CC4, 0x9864, // + 0x8CC7, 0x8E91, // + 0x8CC8, 0xE6C9, // + 0x8CCA, 0x91AF, // + 0x8CCD, 0xE6DA, // + 0x8CCE, 0x9147, // + 0x8CD1, 0x93F6, // + 0x8CD3, 0x956F, // + 0x8CDA, 0xE6CD, // + 0x8CDB, 0x8E5E, // + 0x8CDC, 0x8E92, // + 0x8CDE, 0x8FDC, // + 0x8CE0, 0x9485, // + 0x8CE2, 0x8CAB, // + 0x8CE3, 0xE6CC, // + 0x8CE4, 0xE6CB, // + 0x8CE6, 0x958A, // + 0x8CEA, 0x8EBF, // + 0x8CED, 0x9371, // + 0x8CFA, 0xE6CF, // + 0x8CFB, 0xE6D0, // + 0x8CFC, 0x8D77, // + 0x8CFD, 0xE6CE, // + 0x8D04, 0xE6D1, // + 0x8D05, 0xE6D2, // + 0x8D07, 0xE6D4, // + 0x8D08, 0x91A1, // + 0x8D0A, 0xE6D3, // + 0x8D0B, 0x8AE4, // + 0x8D0D, 0xE6D6, // + 0x8D0F, 0xE6D5, // + 0x8D10, 0xE6D7, // + 0x8D13, 0xE6D9, // + 0x8D14, 0xE6DB, // + 0x8D16, 0xE6DC, // + 0x8D64, 0x90D4, // + 0x8D66, 0x8ECD, // + 0x8D67, 0xE6DD, // + 0x8D6B, 0x8A71, // + 0x8D6D, 0xE6DE, // + 0x8D70, 0x9196, // + 0x8D71, 0xE6DF, // + 0x8D73, 0xE6E0, // + 0x8D74, 0x958B, // + 0x8D77, 0x8B4E, // + 0x8D81, 0xE6E1, // + 0x8D85, 0x92B4, // + 0x8D8A, 0x897A, // + 0x8D99, 0xE6E2, // + 0x8DA3, 0x8EEF, // + 0x8DA8, 0x9096, // + 0x8DB3, 0x91AB, // + 0x8DBA, 0xE6E5, // + 0x8DBE, 0xE6E4, // + 0x8DC2, 0xE6E3, // + 0x8DCB, 0xE6EB, // + 0x8DCC, 0xE6E9, // + 0x8DCF, 0xE6E6, // + 0x8DD6, 0xE6E8, // + 0x8DDA, 0xE6E7, // + 0x8DDB, 0xE6EA, // + 0x8DDD, 0x8B97, // + 0x8DDF, 0xE6EE, // + 0x8DE1, 0x90D5, // + 0x8DE3, 0xE6EF, // + 0x8DE8, 0x8CD7, // + 0x8DEA, 0xE6EC, // + 0x8DEB, 0xE6ED, // + 0x8DEF, 0x9848, // + 0x8DF3, 0x92B5, // + 0x8DF5, 0x9148, // + 0x8DFC, 0xE6F0, // + 0x8DFF, 0xE6F3, // + 0x8E08, 0xE6F1, // + 0x8E09, 0xE6F2, // + 0x8E0A, 0x9778, // + 0x8E0F, 0x93A5, // + 0x8E10, 0xE6F6, // + 0x8E1D, 0xE6F4, // + 0x8E1E, 0xE6F5, // + 0x8E1F, 0xE6F7, // + 0x8E2A, 0xE748, // + 0x8E30, 0xE6FA, // + 0x8E34, 0xE6FB, // + 0x8E35, 0xE6F9, // + 0x8E42, 0xE6F8, // + 0x8E44, 0x92FB, // + 0x8E47, 0xE740, // + 0x8E48, 0xE744, // + 0x8E49, 0xE741, // + 0x8E4A, 0xE6FC, // + 0x8E4C, 0xE742, // + 0x8E50, 0xE743, // + 0x8E55, 0xE74A, // + 0x8E59, 0xE745, // + 0x8E5F, 0x90D6, // + 0x8E60, 0xE747, // + 0x8E63, 0xE749, // + 0x8E64, 0xE746, // + 0x8E72, 0xE74C, // + 0x8E74, 0x8F52, // + 0x8E76, 0xE74B, // + 0x8E7C, 0xE74D, // + 0x8E81, 0xE74E, // + 0x8E84, 0xE751, // + 0x8E85, 0xE750, // + 0x8E87, 0xE74F, // + 0x8E8A, 0xE753, // + 0x8E8B, 0xE752, // + 0x8E8D, 0x96F4, // + 0x8E91, 0xE755, // + 0x8E93, 0xE754, // + 0x8E94, 0xE756, // + 0x8E99, 0xE757, // + 0x8EA1, 0xE759, // + 0x8EAA, 0xE758, // + 0x8EAB, 0x9067, // + 0x8EAC, 0xE75A, // + 0x8EAF, 0x8BEB, // + 0x8EB1, 0xE75D, // + 0x8EBE, 0xE75E, // + 0x8EC5, 0xE75F, // + 0x8EC6, 0xE75C, // + 0x8EC8, 0xE760, // + 0x8ECA, 0x8ED4, // + 0x8ECB, 0xE761, // + 0x8ECC, 0x8B4F, // + 0x8ECD, 0x8C52, // + 0x8ED2, 0x8CAC, // + 0x8EDB, 0xE762, // + 0x8EDF, 0x93EE, // + 0x8EE2, 0x935D, // + 0x8EE3, 0xE763, // + 0x8EEB, 0xE766, // + 0x8EF8, 0x8EB2, // + 0x8EFB, 0xE765, // + 0x8EFC, 0xE764, // + 0x8EFD, 0x8C79, // + 0x8EFE, 0xE767, // + 0x8F03, 0x8A72, // + 0x8F05, 0xE769, // + 0x8F09, 0x8DDA, // + 0x8F0A, 0xE768, // + 0x8F0C, 0xE771, // + 0x8F12, 0xE76B, // + 0x8F13, 0xE76D, // + 0x8F14, 0x95E3, // + 0x8F15, 0xE76A, // + 0x8F19, 0xE76C, // + 0x8F1B, 0xE770, // + 0x8F1C, 0xE76E, // + 0x8F1D, 0x8B50, // + 0x8F1F, 0xE76F, // + 0x8F26, 0xE772, // + 0x8F29, 0x9479, // + 0x8F2A, 0x97D6, // + 0x8F2F, 0x8F53, // + 0x8F33, 0xE773, // + 0x8F38, 0x9741, // + 0x8F39, 0xE775, // + 0x8F3B, 0xE774, // + 0x8F3E, 0xE778, // + 0x8F3F, 0x9760, // + 0x8F42, 0xE777, // + 0x8F44, 0x8A8D, // + 0x8F45, 0xE776, // + 0x8F46, 0xE77B, // + 0x8F49, 0xE77A, // + 0x8F4C, 0xE779, // + 0x8F4D, 0x9351, // + 0x8F4E, 0xE77C, // + 0x8F57, 0xE77D, // + 0x8F5C, 0xE77E, // + 0x8F5F, 0x8D8C, // + 0x8F61, 0x8C44, // + 0x8F62, 0xE780, // + 0x8F63, 0xE781, // + 0x8F64, 0xE782, // + 0x8F9B, 0x9068, // + 0x8F9C, 0xE783, // + 0x8F9E, 0x8EAB, // + 0x8F9F, 0xE784, // + 0x8FA3, 0xE785, // + 0x8FA7, 0x999F, // + 0x8FA8, 0x999E, // + 0x8FAD, 0xE786, // + 0x8FAE, 0xE390, // + 0x8FAF, 0xE787, // + 0x8FB0, 0x9243, // + 0x8FB1, 0x904A, // + 0x8FB2, 0x945F, // + 0x8FB7, 0xE788, // + 0x8FBA, 0x95D3, // + 0x8FBB, 0x92D2, // + 0x8FBC, 0x8D9E, // + 0x8FBF, 0x9248, // + 0x8FC2, 0x8949, // + 0x8FC4, 0x9698, // + 0x8FC5, 0x9076, // + 0x8FCE, 0x8C7D, // + 0x8FD1, 0x8BDF, // + 0x8FD4, 0x95D4, // + 0x8FDA, 0xE789, // + 0x8FE2, 0xE78B, // + 0x8FE5, 0xE78A, // + 0x8FE6, 0x89DE, // + 0x8FE9, 0x93F4, // + 0x8FEA, 0xE78C, // + 0x8FEB, 0x9497, // + 0x8FED, 0x9352, // + 0x8FEF, 0xE78D, // + 0x8FF0, 0x8F71, // + 0x8FF4, 0xE78F, // + 0x8FF7, 0x96C0, // + 0x8FF8, 0xE79E, // + 0x8FF9, 0xE791, // + 0x8FFA, 0xE792, // + 0x8FFD, 0x92C7, // + 0x9000, 0x91DE, // + 0x9001, 0x9197, // + 0x9003, 0x93A6, // + 0x9005, 0xE790, // + 0x9006, 0x8B74, // + 0x900B, 0xE799, // + 0x900D, 0xE796, // + 0x900E, 0xE7A3, // + 0x900F, 0x93A7, // + 0x9010, 0x9280, // + 0x9011, 0xE793, // + 0x9013, 0x92FC, // + 0x9014, 0x9372, // + 0x9015, 0xE794, // + 0x9016, 0xE798, // + 0x9017, 0x9080, // + 0x9019, 0x9487, // + 0x901A, 0x92CA, // + 0x901D, 0x90C0, // + 0x901E, 0xE797, // + 0x901F, 0x91AC, // + 0x9020, 0x91A2, // + 0x9021, 0xE795, // + 0x9022, 0x88A7, // + 0x9023, 0x9841, // + 0x9027, 0xE79A, // + 0x902E, 0x91DF, // + 0x9031, 0x8F54, // + 0x9032, 0x9069, // + 0x9035, 0xE79C, // + 0x9036, 0xE79B, // + 0x9038, 0x88ED, // + 0x9039, 0xE79D, // + 0x903C, 0x954E, // + 0x903E, 0xE7A5, // + 0x9041, 0x93D9, // + 0x9042, 0x908B, // + 0x9045, 0x9278, // + 0x9047, 0x8BF6, // + 0x9049, 0xE7A4, // + 0x904A, 0x9756, // + 0x904B, 0x895E, // + 0x904D, 0x95D5, // + 0x904E, 0x89DF, // + 0x904F, 0xE79F, // + 0x9050, 0xE7A0, // + 0x9051, 0xE7A1, // + 0x9052, 0xE7A2, // + 0x9053, 0x93B9, // + 0x9054, 0x9242, // + 0x9055, 0x88E1, // + 0x9056, 0xE7A6, // + 0x9058, 0xE7A7, // + 0x9059, 0xEAA1, // + 0x905C, 0x91BB, // + 0x905E, 0xE7A8, // + 0x9060, 0x8993, // + 0x9061, 0x916B, // + 0x9063, 0x8CAD, // + 0x9065, 0x9779, // + 0x9068, 0xE7A9, // + 0x9069, 0x934B, // + 0x906D, 0x9198, // + 0x906E, 0x8ED5, // + 0x906F, 0xE7AA, // + 0x9072, 0xE7AD, // + 0x9075, 0x8F85, // + 0x9076, 0xE7AB, // + 0x9077, 0x914A, // + 0x9078, 0x9149, // + 0x907A, 0x88E2, // + 0x907C, 0x97C9, // + 0x907D, 0xE7AF, // + 0x907F, 0x94F0, // + 0x9080, 0xE7B1, // + 0x9081, 0xE7B0, // + 0x9082, 0xE7AE, // + 0x9083, 0xE284, // + 0x9084, 0x8AD2, // + 0x9087, 0xE78E, // + 0x9089, 0xE7B3, // + 0x908A, 0xE7B2, // + 0x908F, 0xE7B4, // + 0x9091, 0x9757, // + 0x90A3, 0x93DF, // + 0x90A6, 0x964D, // + 0x90A8, 0xE7B5, // + 0x90AA, 0x8ED7, // + 0x90AF, 0xE7B6, // + 0x90B1, 0xE7B7, // + 0x90B5, 0xE7B8, // + 0x90B8, 0x9340, // + 0x90C1, 0x88E8, // + 0x90CA, 0x8D78, // + 0x90CE, 0x9859, // + 0x90DB, 0xE7BC, // + 0x90E1, 0x8C53, // + 0x90E2, 0xE7B9, // + 0x90E4, 0xE7BA, // + 0x90E8, 0x9594, // + 0x90ED, 0x8A73, // + 0x90F5, 0x9758, // + 0x90F7, 0x8BBD, // + 0x90FD, 0x9373, // + 0x9102, 0xE7BD, // + 0x9112, 0xE7BE, // + 0x9119, 0xE7BF, // + 0x912D, 0x9341, // + 0x9130, 0xE7C1, // + 0x9132, 0xE7C0, // + 0x9149, 0x93D1, // + 0x914A, 0xE7C2, // + 0x914B, 0x8F55, // + 0x914C, 0x8EDE, // + 0x914D, 0x947A, // + 0x914E, 0x9291, // + 0x9152, 0x8EF0, // + 0x9154, 0x908C, // + 0x9156, 0xE7C3, // + 0x9158, 0xE7C4, // + 0x9162, 0x907C, // + 0x9163, 0xE7C5, // + 0x9165, 0xE7C6, // + 0x9169, 0xE7C7, // + 0x916A, 0x978F, // + 0x916C, 0x8F56, // + 0x9172, 0xE7C9, // + 0x9173, 0xE7C8, // + 0x9175, 0x8D79, // + 0x9177, 0x8D93, // + 0x9178, 0x8E5F, // + 0x9182, 0xE7CC, // + 0x9187, 0x8F86, // + 0x9189, 0xE7CB, // + 0x918B, 0xE7CA, // + 0x918D, 0x91E7, // + 0x9190, 0x8CED, // + 0x9192, 0x90C1, // + 0x9197, 0x94AE, // + 0x919C, 0x8F58, // + 0x91A2, 0xE7CD, // + 0x91A4, 0x8FDD, // + 0x91AA, 0xE7D0, // + 0x91AB, 0xE7CE, // + 0x91AF, 0xE7CF, // + 0x91B4, 0xE7D2, // + 0x91B5, 0xE7D1, // + 0x91B8, 0x8FF8, // + 0x91BA, 0xE7D3, // + 0x91C0, 0xE7D4, // + 0x91C1, 0xE7D5, // + 0x91C6, 0x94CE, // + 0x91C7, 0x8DD1, // + 0x91C8, 0x8EDF, // + 0x91C9, 0xE7D6, // + 0x91CB, 0xE7D7, // + 0x91CC, 0x97A2, // + 0x91CD, 0x8F64, // + 0x91CE, 0x96EC, // + 0x91CF, 0x97CA, // + 0x91D0, 0xE7D8, // + 0x91D1, 0x8BE0, // + 0x91D6, 0xE7D9, // + 0x91D8, 0x9342, // + 0x91DB, 0xE7DC, // + 0x91DC, 0x8A98, // + 0x91DD, 0x906A, // + 0x91DF, 0xE7DA, // + 0x91E1, 0xE7DB, // + 0x91E3, 0x92DE, // + 0x91E6, 0x9674, // + 0x91E7, 0x8BFA, // + 0x91F5, 0xE7DE, // + 0x91F6, 0xE7DF, // + 0x91FC, 0xE7DD, // + 0x91FF, 0xE7E1, // + 0x920D, 0x93DD, // + 0x920E, 0x8A62, // + 0x9211, 0xE7E5, // + 0x9214, 0xE7E2, // + 0x9215, 0xE7E4, // + 0x921E, 0xE7E0, // + 0x9229, 0xE86E, // + 0x922C, 0xE7E3, // + 0x9234, 0x97E9, // + 0x9237, 0x8CD8, // + 0x923F, 0xE7ED, // + 0x9244, 0x9353, // + 0x9245, 0xE7E8, // + 0x9248, 0xE7EB, // + 0x9249, 0xE7E9, // + 0x924B, 0xE7EE, // + 0x9250, 0xE7EF, // + 0x9257, 0xE7E7, // + 0x925A, 0xE7F4, // + 0x925B, 0x8994, // + 0x925E, 0xE7E6, // + 0x9262, 0x94AB, // + 0x9264, 0xE7EA, // + 0x9266, 0x8FDE, // + 0x9271, 0x8D7A, // + 0x927E, 0x9667, // + 0x9280, 0x8BE2, // + 0x9283, 0x8F65, // + 0x9285, 0x93BA, // + 0x9291, 0x914C, // + 0x9293, 0xE7F2, // + 0x9295, 0xE7EC, // + 0x9296, 0xE7F1, // + 0x9298, 0x96C1, // + 0x929A, 0x92B6, // + 0x929B, 0xE7F3, // + 0x929C, 0xE7F0, // + 0x92AD, 0x914B, // + 0x92B7, 0xE7F7, // + 0x92B9, 0xE7F6, // + 0x92CF, 0xE7F5, // + 0x92D2, 0x964E, // + 0x92E4, 0x8F9B, // + 0x92E9, 0xE7F8, // + 0x92EA, 0x95DD, // + 0x92ED, 0x8973, // + 0x92F2, 0x9565, // + 0x92F3, 0x9292, // + 0x92F8, 0x8B98, // + 0x92FA, 0xE7FA, // + 0x92FC, 0x8D7C, // + 0x9306, 0x8E4B, // + 0x930F, 0xE7F9, // + 0x9310, 0x908D, // + 0x9318, 0x908E, // + 0x9319, 0xE840, // + 0x931A, 0xE842, // + 0x9320, 0x8FF9, // + 0x9322, 0xE841, // + 0x9323, 0xE843, // + 0x9326, 0x8BD1, // + 0x9328, 0x9564, // + 0x932B, 0x8EE0, // + 0x932C, 0x9842, // + 0x932E, 0xE7FC, // + 0x932F, 0x8DF6, // + 0x9332, 0x985E, // + 0x9335, 0xE845, // + 0x933A, 0xE844, // + 0x933B, 0xE846, // + 0x9344, 0xE7FB, // + 0x934B, 0x93E7, // + 0x934D, 0x9374, // + 0x9354, 0x92D5, // + 0x9356, 0xE84B, // + 0x935B, 0x9262, // + 0x935C, 0xE847, // + 0x9360, 0xE848, // + 0x936C, 0x8C4C, // + 0x936E, 0xE84A, // + 0x9375, 0x8CAE, // + 0x937C, 0xE849, // + 0x937E, 0x8FDF, // + 0x938C, 0x8A99, // + 0x9394, 0xE84F, // + 0x9396, 0x8DBD, // + 0x9397, 0x9199, // + 0x939A, 0x92C8, // + 0x93A7, 0x8A5A, // + 0x93AC, 0xE84D, // + 0x93AD, 0xE84E, // + 0x93AE, 0x92C1, // + 0x93B0, 0xE84C, // + 0x93B9, 0xE850, // + 0x93C3, 0xE856, // + 0x93C8, 0xE859, // + 0x93D0, 0xE858, // + 0x93D1, 0x934C, // + 0x93D6, 0xE851, // + 0x93D7, 0xE852, // + 0x93D8, 0xE855, // + 0x93DD, 0xE857, // + 0x93E1, 0x8BBE, // + 0x93E4, 0xE85A, // + 0x93E5, 0xE854, // + 0x93E8, 0xE853, // + 0x9403, 0xE85E, // + 0x9407, 0xE85F, // + 0x9410, 0xE860, // + 0x9413, 0xE85D, // + 0x9414, 0xE85C, // + 0x9418, 0x8FE0, // + 0x9419, 0x93A8, // + 0x9421, 0xE864, // + 0x942B, 0xE862, // + 0x9435, 0xE863, // + 0x9436, 0xE861, // + 0x9438, 0x91F6, // + 0x943A, 0xE865, // + 0x9441, 0xE866, // + 0x9444, 0xE868, // + 0x9451, 0x8AD3, // + 0x9452, 0xE867, // + 0x9453, 0x96F8, // + 0x945A, 0xE873, // + 0x945B, 0xE869, // + 0x945E, 0xE86C, // + 0x9460, 0xE86A, // + 0x9462, 0xE86B, // + 0x946A, 0xE86D, // + 0x9470, 0xE86F, // + 0x9475, 0xE870, // + 0x9477, 0xE871, // + 0x947C, 0xE874, // + 0x947D, 0xE872, // + 0x947E, 0xE875, // + 0x947F, 0xE877, // + 0x9481, 0xE876, // + 0x9577, 0x92B7, // + 0x9580, 0x96E5, // + 0x9582, 0xE878, // + 0x9583, 0x914D, // + 0x9587, 0xE879, // + 0x9589, 0x95C2, // + 0x958A, 0xE87A, // + 0x958B, 0x8A4A, // + 0x9591, 0x8AD5, // + 0x9593, 0x8AD4, // + 0x9594, 0xE87B, // + 0x9596, 0xE87C, // + 0x9598, 0xE87D, // + 0x9599, 0xE87E, // + 0x95A0, 0xE880, // + 0x95A2, 0x8AD6, // + 0x95A3, 0x8A74, // + 0x95A4, 0x8D7D, // + 0x95A5, 0x94B4, // + 0x95A7, 0xE882, // + 0x95A8, 0xE881, // + 0x95AD, 0xE883, // + 0x95B2, 0x897B, // + 0x95B9, 0xE886, // + 0x95BB, 0xE885, // + 0x95BC, 0xE884, // + 0x95BE, 0xE887, // + 0x95C3, 0xE88A, // + 0x95C7, 0x88C5, // + 0x95CA, 0xE888, // + 0x95CC, 0xE88C, // + 0x95CD, 0xE88B, // + 0x95D4, 0xE88E, // + 0x95D5, 0xE88D, // + 0x95D6, 0xE88F, // + 0x95D8, 0x93AC, // + 0x95DC, 0xE890, // + 0x95E1, 0xE891, // + 0x95E2, 0xE893, // + 0x95E5, 0xE892, // + 0x961C, 0x958C, // + 0x9621, 0xE894, // + 0x9628, 0xE895, // + 0x962A, 0x8DE3, // + 0x962E, 0xE896, // + 0x962F, 0xE897, // + 0x9632, 0x9668, // + 0x963B, 0x916A, // + 0x963F, 0x88A2, // + 0x9640, 0x91C9, // + 0x9642, 0xE898, // + 0x9644, 0x958D, // + 0x964B, 0xE89B, // + 0x964C, 0xE899, // + 0x964D, 0x8D7E, // + 0x964F, 0xE89A, // + 0x9650, 0x8CC0, // + 0x965B, 0x95C3, // + 0x965C, 0xE89D, // + 0x965D, 0xE89F, // + 0x965E, 0xE89E, // + 0x965F, 0xE8A0, // + 0x9662, 0x8940, // + 0x9663, 0x9077, // + 0x9664, 0x8F9C, // + 0x9665, 0x8AD7, // + 0x9666, 0xE8A1, // + 0x966A, 0x9486, // + 0x966C, 0xE8A3, // + 0x9670, 0x8941, // + 0x9672, 0xE8A2, // + 0x9673, 0x92C2, // + 0x9675, 0x97CB, // + 0x9676, 0x93A9, // + 0x9677, 0xE89C, // + 0x9678, 0x97A4, // + 0x967A, 0x8CAF, // + 0x967D, 0x977A, // + 0x9685, 0x8BF7, // + 0x9686, 0x97B2, // + 0x9688, 0x8C47, // + 0x968A, 0x91E0, // + 0x968B, 0xE440, // + 0x968D, 0xE8A4, // + 0x968E, 0x8A4B, // + 0x968F, 0x908F, // + 0x9694, 0x8A75, // + 0x9695, 0xE8A6, // + 0x9697, 0xE8A7, // + 0x9698, 0xE8A5, // + 0x9699, 0x8C84, // + 0x969B, 0x8DDB, // + 0x969C, 0x8FE1, // + 0x96A0, 0x8942, // + 0x96A3, 0x97D7, // + 0x96A7, 0xE8A9, // + 0x96A8, 0xE7AC, // + 0x96AA, 0xE8A8, // + 0x96B0, 0xE8AC, // + 0x96B1, 0xE8AA, // + 0x96B2, 0xE8AB, // + 0x96B4, 0xE8AD, // + 0x96B6, 0xE8AE, // + 0x96B7, 0x97EA, // + 0x96B8, 0xE8AF, // + 0x96B9, 0xE8B0, // + 0x96BB, 0x90C7, // + 0x96BC, 0x94B9, // + 0x96C0, 0x909D, // + 0x96C1, 0x8AE5, // + 0x96C4, 0x9759, // + 0x96C5, 0x89EB, // + 0x96C6, 0x8F57, // + 0x96C7, 0x8CD9, // + 0x96C9, 0xE8B3, // + 0x96CB, 0xE8B2, // + 0x96CC, 0x8E93, // + 0x96CD, 0xE8B4, // + 0x96CE, 0xE8B1, // + 0x96D1, 0x8E47, // + 0x96D5, 0xE8B8, // + 0x96D6, 0xE5AB, // + 0x96D9, 0x99D4, // + 0x96DB, 0x9097, // + 0x96DC, 0xE8B6, // + 0x96E2, 0x97A3, // + 0x96E3, 0x93EF, // + 0x96E8, 0x894A, // + 0x96EA, 0x90E1, // + 0x96EB, 0x8EB4, // + 0x96F0, 0x95B5, // + 0x96F2, 0x895F, // + 0x96F6, 0x97EB, // + 0x96F7, 0x978B, // + 0x96F9, 0xE8B9, // + 0x96FB, 0x9364, // + 0x9700, 0x8EF9, // + 0x9704, 0xE8BA, // + 0x9706, 0xE8BB, // + 0x9707, 0x906B, // + 0x9708, 0xE8BC, // + 0x970A, 0x97EC, // + 0x970D, 0xE8B7, // + 0x970E, 0xE8BE, // + 0x970F, 0xE8C0, // + 0x9711, 0xE8BF, // + 0x9713, 0xE8BD, // + 0x9716, 0xE8C1, // + 0x9719, 0xE8C2, // + 0x971C, 0x919A, // + 0x971E, 0x89E0, // + 0x9724, 0xE8C3, // + 0x9727, 0x96B6, // + 0x972A, 0xE8C4, // + 0x9730, 0xE8C5, // + 0x9732, 0x9849, // + 0x9738, 0x9E50, // + 0x9739, 0xE8C6, // + 0x973D, 0xE8C7, // + 0x973E, 0xE8C8, // + 0x9742, 0xE8CC, // + 0x9744, 0xE8C9, // + 0x9746, 0xE8CA, // + 0x9748, 0xE8CB, // + 0x9749, 0xE8CD, // + 0x9752, 0x90C2, // + 0x9756, 0x96F5, // + 0x9759, 0x90C3, // + 0x975C, 0xE8CE, // + 0x975E, 0x94F1, // + 0x9760, 0xE8CF, // + 0x9761, 0xEA72, // + 0x9762, 0x96CA, // + 0x9764, 0xE8D0, // + 0x9766, 0xE8D1, // + 0x9768, 0xE8D2, // + 0x9769, 0x8A76, // + 0x976B, 0xE8D4, // + 0x976D, 0x9078, // + 0x9771, 0xE8D5, // + 0x9774, 0x8C43, // + 0x9779, 0xE8D6, // + 0x977A, 0xE8DA, // + 0x977C, 0xE8D8, // + 0x9781, 0xE8D9, // + 0x9784, 0x8A93, // + 0x9785, 0xE8D7, // + 0x9786, 0xE8DB, // + 0x978B, 0xE8DC, // + 0x978D, 0x88C6, // + 0x978F, 0xE8DD, // + 0x9790, 0xE8DE, // + 0x9798, 0x8FE2, // + 0x979C, 0xE8DF, // + 0x97A0, 0x8B66, // + 0x97A3, 0xE8E2, // + 0x97A6, 0xE8E1, // + 0x97A8, 0xE8E0, // + 0x97AB, 0xE691, // + 0x97AD, 0x95DA, // + 0x97B3, 0xE8E3, // + 0x97B4, 0xE8E4, // + 0x97C3, 0xE8E5, // + 0x97C6, 0xE8E6, // + 0x97C8, 0xE8E7, // + 0x97CB, 0xE8E8, // + 0x97D3, 0x8AD8, // + 0x97DC, 0xE8E9, // + 0x97ED, 0xE8EA, // + 0x97EE, 0x9442, // + 0x97F2, 0xE8EC, // + 0x97F3, 0x89B9, // + 0x97F5, 0xE8EF, // + 0x97F6, 0xE8EE, // + 0x97FB, 0x8943, // + 0x97FF, 0x8BBF, // + 0x9801, 0x95C5, // + 0x9802, 0x92B8, // + 0x9803, 0x8DA0, // + 0x9805, 0x8D80, // + 0x9806, 0x8F87, // + 0x9808, 0x907B, // + 0x980C, 0xE8F1, // + 0x980F, 0xE8F0, // + 0x9810, 0x9761, // + 0x9811, 0x8AE6, // + 0x9812, 0x94D0, // + 0x9813, 0x93DA, // + 0x9817, 0x909C, // + 0x9818, 0x97CC, // + 0x981A, 0x8C7A, // + 0x9821, 0xE8F4, // + 0x9824, 0xE8F3, // + 0x982C, 0x966A, // + 0x982D, 0x93AA, // + 0x9834, 0x896F, // + 0x9837, 0xE8F5, // + 0x9838, 0xE8F2, // + 0x983B, 0x9570, // + 0x983C, 0x978A, // + 0x983D, 0xE8F6, // + 0x9846, 0xE8F7, // + 0x984B, 0xE8F9, // + 0x984C, 0x91E8, // + 0x984D, 0x8A7A, // + 0x984E, 0x8A7B, // + 0x984F, 0xE8F8, // + 0x9854, 0x8AE7, // + 0x9855, 0x8CB0, // + 0x9858, 0x8AE8, // + 0x985B, 0x935E, // + 0x985E, 0x97DE, // + 0x9867, 0x8CDA, // + 0x986B, 0xE8FA, // + 0x986F, 0xE8FB, // + 0x9870, 0xE8FC, // + 0x9871, 0xE940, // + 0x9873, 0xE942, // + 0x9874, 0xE941, // + 0x98A8, 0x9597, // + 0x98AA, 0xE943, // + 0x98AF, 0xE944, // + 0x98B1, 0xE945, // + 0x98B6, 0xE946, // + 0x98C3, 0xE948, // + 0x98C4, 0xE947, // + 0x98C6, 0xE949, // + 0x98DB, 0x94F2, // + 0x98DC, 0xE3CA, // + 0x98DF, 0x9048, // + 0x98E2, 0x8B51, // + 0x98E9, 0xE94A, // + 0x98EB, 0xE94B, // + 0x98ED, 0x99AA, // + 0x98EE, 0x9F5A, // + 0x98EF, 0x94D1, // + 0x98F2, 0x88F9, // + 0x98F4, 0x88B9, // + 0x98FC, 0x8E94, // + 0x98FD, 0x964F, // + 0x98FE, 0x8FFC, // + 0x9903, 0xE94C, // + 0x9905, 0x96DD, // + 0x9909, 0xE94D, // + 0x990A, 0x977B, // + 0x990C, 0x8961, // + 0x9910, 0x8E60, // + 0x9912, 0xE94E, // + 0x9913, 0x89EC, // + 0x9914, 0xE94F, // + 0x9918, 0xE950, // + 0x991D, 0xE952, // + 0x991E, 0xE953, // + 0x9920, 0xE955, // + 0x9921, 0xE951, // + 0x9924, 0xE954, // + 0x9928, 0x8AD9, // + 0x992C, 0xE956, // + 0x992E, 0xE957, // + 0x993D, 0xE958, // + 0x993E, 0xE959, // + 0x9942, 0xE95A, // + 0x9945, 0xE95C, // + 0x994B, 0xE95E, // + 0x994C, 0xE961, // + 0x9950, 0xE95D, // + 0x9951, 0xE95F, // + 0x9952, 0xE960, // + 0x9955, 0xE962, // + 0x9957, 0x8BC0, // + 0x9996, 0x8EF1, // + 0x9997, 0xE963, // + 0x9998, 0xE964, // + 0x9999, 0x8D81, // + 0x99A5, 0xE965, // + 0x99A8, 0x8A5D, // + 0x99AC, 0x946E, // + 0x99AD, 0xE966, // + 0x99AE, 0xE967, // + 0x99B3, 0x9279, // + 0x99B4, 0x93E9, // + 0x99BC, 0xE968, // + 0x99C1, 0x949D, // + 0x99C4, 0x91CA, // + 0x99C5, 0x8977, // + 0x99C6, 0x8BEC, // + 0x99C8, 0x8BED, // + 0x99D0, 0x9293, // + 0x99D1, 0xE96D, // + 0x99D2, 0x8BEE, // + 0x99D5, 0x89ED, // + 0x99D8, 0xE96C, // + 0x99DB, 0xE96A, // + 0x99DD, 0xE96B, // + 0x99DF, 0xE969, // + 0x99E2, 0xE977, // + 0x99ED, 0xE96E, // + 0x99EE, 0xE96F, // + 0x99F1, 0xE970, // + 0x99F2, 0xE971, // + 0x99F8, 0xE973, // + 0x99FB, 0xE972, // + 0x99FF, 0x8F78, // + 0x9A01, 0xE974, // + 0x9A05, 0xE976, // + 0x9A0E, 0x8B52, // + 0x9A0F, 0xE975, // + 0x9A12, 0x919B, // + 0x9A13, 0x8CB1, // + 0x9A19, 0xE978, // + 0x9A28, 0x91CB, // + 0x9A2B, 0xE979, // + 0x9A30, 0x93AB, // + 0x9A37, 0xE97A, // + 0x9A3E, 0xE980, // + 0x9A40, 0xE97D, // + 0x9A42, 0xE97C, // + 0x9A43, 0xE97E, // + 0x9A45, 0xE97B, // + 0x9A4D, 0xE982, // + 0x9A55, 0xE981, // + 0x9A57, 0xE984, // + 0x9A5A, 0x8BC1, // + 0x9A5B, 0xE983, // + 0x9A5F, 0xE985, // + 0x9A62, 0xE986, // + 0x9A64, 0xE988, // + 0x9A65, 0xE987, // + 0x9A69, 0xE989, // + 0x9A6A, 0xE98B, // + 0x9A6B, 0xE98A, // + 0x9AA8, 0x8D9C, // + 0x9AAD, 0xE98C, // + 0x9AB0, 0xE98D, // + 0x9ABC, 0xE98E, // + 0x9AC0, 0xE98F, // + 0x9AC4, 0x9091, // + 0x9ACF, 0xE990, // + 0x9AD1, 0xE991, // + 0x9AD3, 0xE992, // + 0x9AD4, 0xE993, // + 0x9AD8, 0x8D82, // + 0x9ADE, 0xE994, // + 0x9ADF, 0xE995, // + 0x9AE2, 0xE996, // + 0x9AE3, 0xE997, // + 0x9AE6, 0xE998, // + 0x9AEA, 0x94AF, // + 0x9AEB, 0xE99A, // + 0x9AED, 0x9545, // + 0x9AEE, 0xE99B, // + 0x9AEF, 0xE999, // + 0x9AF1, 0xE99D, // + 0x9AF4, 0xE99C, // + 0x9AF7, 0xE99E, // + 0x9AFB, 0xE99F, // + 0x9B06, 0xE9A0, // + 0x9B18, 0xE9A1, // + 0x9B1A, 0xE9A2, // + 0x9B1F, 0xE9A3, // + 0x9B22, 0xE9A4, // + 0x9B23, 0xE9A5, // + 0x9B25, 0xE9A6, // + 0x9B27, 0xE9A7, // + 0x9B28, 0xE9A8, // + 0x9B29, 0xE9A9, // + 0x9B2A, 0xE9AA, // + 0x9B2E, 0xE9AB, // + 0x9B2F, 0xE9AC, // + 0x9B31, 0x9F54, // + 0x9B32, 0xE9AD, // + 0x9B3B, 0xE2F6, // + 0x9B3C, 0x8B53, // + 0x9B41, 0x8A40, // + 0x9B42, 0x8DB0, // + 0x9B43, 0xE9AF, // + 0x9B44, 0xE9AE, // + 0x9B45, 0x96A3, // + 0x9B4D, 0xE9B1, // + 0x9B4E, 0xE9B2, // + 0x9B4F, 0xE9B0, // + 0x9B51, 0xE9B3, // + 0x9B54, 0x9682, // + 0x9B58, 0xE9B4, // + 0x9B5A, 0x8B9B, // + 0x9B6F, 0x9844, // + 0x9B74, 0xE9B5, // + 0x9B83, 0xE9B7, // + 0x9B8E, 0x88BC, // + 0x9B91, 0xE9B8, // + 0x9B92, 0x95A9, // + 0x9B93, 0xE9B6, // + 0x9B96, 0xE9B9, // + 0x9B97, 0xE9BA, // + 0x9B9F, 0xE9BB, // + 0x9BA0, 0xE9BC, // + 0x9BA8, 0xE9BD, // + 0x9BAA, 0x968E, // + 0x9BAB, 0x8E4C, // + 0x9BAD, 0x8DF8, // + 0x9BAE, 0x914E, // + 0x9BB4, 0xE9BE, // + 0x9BB9, 0xE9C1, // + 0x9BC0, 0xE9BF, // + 0x9BC6, 0xE9C2, // + 0x9BC9, 0x8CEF, // + 0x9BCA, 0xE9C0, // + 0x9BCF, 0xE9C3, // + 0x9BD1, 0xE9C4, // + 0x9BD2, 0xE9C5, // + 0x9BD4, 0xE9C9, // + 0x9BD6, 0x8E49, // + 0x9BDB, 0x91E2, // + 0x9BE1, 0xE9CA, // + 0x9BE2, 0xE9C7, // + 0x9BE3, 0xE9C6, // + 0x9BE4, 0xE9C8, // + 0x9BE8, 0x8C7E, // + 0x9BF0, 0xE9CE, // + 0x9BF1, 0xE9CD, // + 0x9BF2, 0xE9CC, // + 0x9BF5, 0x88B1, // + 0x9C04, 0xE9D8, // + 0x9C06, 0xE9D4, // + 0x9C08, 0xE9D5, // + 0x9C09, 0xE9D1, // + 0x9C0A, 0xE9D7, // + 0x9C0C, 0xE9D3, // + 0x9C0D, 0x8A82, // + 0x9C10, 0x986B, // + 0x9C12, 0xE9D6, // + 0x9C13, 0xE9D2, // + 0x9C14, 0xE9D0, // + 0x9C15, 0xE9CF, // + 0x9C1B, 0xE9DA, // + 0x9C21, 0xE9DD, // + 0x9C24, 0xE9DC, // + 0x9C25, 0xE9DB, // + 0x9C2D, 0x9568, // + 0x9C2E, 0xE9D9, // + 0x9C2F, 0x88F1, // + 0x9C30, 0xE9DE, // + 0x9C32, 0xE9E0, // + 0x9C39, 0x8A8F, // + 0x9C3A, 0xE9CB, // + 0x9C3B, 0x8956, // + 0x9C3E, 0xE9E2, // + 0x9C46, 0xE9E1, // + 0x9C47, 0xE9DF, // + 0x9C48, 0x924C, // + 0x9C52, 0x9690, // + 0x9C57, 0x97D8, // + 0x9C5A, 0xE9E3, // + 0x9C60, 0xE9E4, // + 0x9C67, 0xE9E5, // + 0x9C76, 0xE9E6, // + 0x9C78, 0xE9E7, // + 0x9CE5, 0x92B9, // + 0x9CE7, 0xE9E8, // + 0x9CE9, 0x94B5, // + 0x9CEB, 0xE9ED, // + 0x9CEC, 0xE9E9, // + 0x9CF0, 0xE9EA, // + 0x9CF3, 0x9650, // + 0x9CF4, 0x96C2, // + 0x9CF6, 0x93CE, // + 0x9D03, 0xE9EE, // + 0x9D06, 0xE9EF, // + 0x9D07, 0x93BC, // + 0x9D08, 0xE9EC, // + 0x9D09, 0xE9EB, // + 0x9D0E, 0x89A8, // + 0x9D12, 0xE9F7, // + 0x9D15, 0xE9F6, // + 0x9D1B, 0x8995, // + 0x9D1F, 0xE9F4, // + 0x9D23, 0xE9F3, // + 0x9D26, 0xE9F1, // + 0x9D28, 0x8A9B, // + 0x9D2A, 0xE9F0, // + 0x9D2B, 0x8EB0, // + 0x9D2C, 0x89A7, // + 0x9D3B, 0x8D83, // + 0x9D3E, 0xE9FA, // + 0x9D3F, 0xE9F9, // + 0x9D41, 0xE9F8, // + 0x9D44, 0xE9F5, // + 0x9D46, 0xE9FB, // + 0x9D48, 0xE9FC, // + 0x9D50, 0xEA44, // + 0x9D51, 0xEA43, // + 0x9D59, 0xEA45, // + 0x9D5C, 0x894C, // + 0x9D5D, 0xEA40, // + 0x9D5E, 0xEA41, // + 0x9D60, 0x8D94, // + 0x9D61, 0x96B7, // + 0x9D64, 0xEA42, // + 0x9D6C, 0x9651, // + 0x9D6F, 0xEA4A, // + 0x9D72, 0xEA46, // + 0x9D7A, 0xEA4B, // + 0x9D87, 0xEA48, // + 0x9D89, 0xEA47, // + 0x9D8F, 0x8C7B, // + 0x9D9A, 0xEA4C, // + 0x9DA4, 0xEA4D, // + 0x9DA9, 0xEA4E, // + 0x9DAB, 0xEA49, // + 0x9DAF, 0xE9F2, // + 0x9DB2, 0xEA4F, // + 0x9DB4, 0x92DF, // + 0x9DB8, 0xEA53, // + 0x9DBA, 0xEA54, // + 0x9DBB, 0xEA52, // + 0x9DC1, 0xEA51, // + 0x9DC2, 0xEA57, // + 0x9DC4, 0xEA50, // + 0x9DC6, 0xEA55, // + 0x9DCF, 0xEA56, // + 0x9DD3, 0xEA59, // + 0x9DD9, 0xEA58, // + 0x9DED, 0xEA5C, // + 0x9DEF, 0xEA5D, // + 0x9DF2, 0x9868, // + 0x9DF8, 0xEA5A, // + 0x9DF9, 0x91E9, // + 0x9DFA, 0x8DEB, // + 0x9DFD, 0xEA5E, // + 0x9E1A, 0xEA5F, // + 0x9E1B, 0xEA60, // + 0x9E1E, 0xEA61, // + 0x9E75, 0xEA62, // + 0x9E78, 0x8CB2, // + 0x9E79, 0xEA63, // + 0x9E7D, 0xEA64, // + 0x9E7F, 0x8EAD, // + 0x9E81, 0xEA65, // + 0x9E88, 0xEA66, // + 0x9E8B, 0xEA67, // + 0x9E8C, 0xEA68, // + 0x9E91, 0xEA6B, // + 0x9E92, 0xEA69, // + 0x9E95, 0xEA6A, // + 0x9E97, 0x97ED, // + 0x9E9D, 0xEA6C, // + 0x9E9F, 0x97D9, // + 0x9EA5, 0xEA6D, // + 0x9EA6, 0x949E, // + 0x9EA9, 0xEA6E, // + 0x9EAA, 0xEA70, // + 0x9EAD, 0xEA71, // + 0x9EB8, 0xEA6F, // + 0x9EB9, 0x8D8D, // + 0x9EBA, 0x96CB, // + 0x9EBB, 0x9683, // + 0x9EBC, 0x9BF5, // + 0x9EBE, 0x9F80, // + 0x9EBF, 0x969B, // + 0x9EC4, 0x89A9, // + 0x9ECC, 0xEA73, // + 0x9ECD, 0x8B6F, // + 0x9ECE, 0xEA74, // + 0x9ECF, 0xEA75, // + 0x9ED0, 0xEA76, // + 0x9ED2, 0x8D95, // + 0x9ED4, 0xEA77, // + 0x9ED8, 0xE0D2, // + 0x9ED9, 0x96D9, // + 0x9EDB, 0x91E1, // + 0x9EDC, 0xEA78, // + 0x9EDD, 0xEA7A, // + 0x9EDE, 0xEA79, // + 0x9EE0, 0xEA7B, // + 0x9EE5, 0xEA7C, // + 0x9EE8, 0xEA7D, // + 0x9EEF, 0xEA7E, // + 0x9EF4, 0xEA80, // + 0x9EF6, 0xEA81, // + 0x9EF7, 0xEA82, // + 0x9EF9, 0xEA83, // + 0x9EFB, 0xEA84, // + 0x9EFC, 0xEA85, // + 0x9EFD, 0xEA86, // + 0x9F07, 0xEA87, // + 0x9F08, 0xEA88, // + 0x9F0E, 0x9343, // + 0x9F13, 0x8CDB, // + 0x9F15, 0xEA8A, // + 0x9F20, 0x916C, // + 0x9F21, 0xEA8B, // + 0x9F2C, 0xEA8C, // + 0x9F3B, 0x9540, // + 0x9F3E, 0xEA8D, // + 0x9F4A, 0xEA8E, // + 0x9F4B, 0xE256, // + 0x9F4E, 0xE6D8, // + 0x9F4F, 0xE8EB, // + 0x9F52, 0xEA8F, // + 0x9F54, 0xEA90, // + 0x9F5F, 0xEA92, // + 0x9F60, 0xEA93, // + 0x9F61, 0xEA94, // + 0x9F62, 0x97EE, // + 0x9F63, 0xEA91, // + 0x9F66, 0xEA95, // + 0x9F67, 0xEA96, // + 0x9F6A, 0xEA98, // + 0x9F6C, 0xEA97, // + 0x9F72, 0xEA9A, // + 0x9F76, 0xEA9B, // + 0x9F77, 0xEA99, // + 0x9F8D, 0x97B4, // + 0x9F95, 0xEA9C, // + 0x9F9C, 0xEA9D, // + 0x9F9D, 0xE273, // + 0x9FA0, 0xEA9E, // + 0xFF01, 0x8149, // FULLWIDTH EXCLAMATION MARK + 0xFF03, 0x8194, // FULLWIDTH NUMBER SIGN + 0xFF04, 0x8190, // FULLWIDTH DOLLAR SIGN + 0xFF05, 0x8193, // FULLWIDTH PERCENT SIGN + 0xFF06, 0x8195, // FULLWIDTH AMPERSAND + 0xFF07, 0x81AD, // FULLWIDTH APOSTROPHE + 0xFF08, 0x8169, // FULLWIDTH LEFT PARENTHESIS + 0xFF09, 0x816A, // FULLWIDTH RIGHT PARENTHESIS + 0xFF0A, 0x8196, // FULLWIDTH ASTERISK + 0xFF0B, 0x817B, // FULLWIDTH PLUS SIGN + 0xFF0C, 0x8143, // FULLWIDTH COMMA + 0xFF0E, 0x8144, // FULLWIDTH FULL STOP + 0xFF0F, 0x815E, // FULLWIDTH SOLIDUS + 0xFF10, 0x824F, // FULLWIDTH DIGIT ZERO + 0xFF11, 0x8250, // FULLWIDTH DIGIT ONE + 0xFF12, 0x8251, // FULLWIDTH DIGIT TWO + 0xFF13, 0x8252, // FULLWIDTH DIGIT THREE + 0xFF14, 0x8253, // FULLWIDTH DIGIT FOUR + 0xFF15, 0x8254, // FULLWIDTH DIGIT FIVE + 0xFF16, 0x8255, // FULLWIDTH DIGIT SIX + 0xFF17, 0x8256, // FULLWIDTH DIGIT SEVEN + 0xFF18, 0x8257, // FULLWIDTH DIGIT EIGHT + 0xFF19, 0x8258, // FULLWIDTH DIGIT NINE + 0xFF1A, 0x8146, // FULLWIDTH COLON + 0xFF1B, 0x8147, // FULLWIDTH SEMICOLON + 0xFF1C, 0x8183, // FULLWIDTH LESS-THAN SIGN + 0xFF1D, 0x8181, // FULLWIDTH EQUALS SIGN + 0xFF1E, 0x8184, // FULLWIDTH GREATER-THAN SIGN + 0xFF1F, 0x8148, // FULLWIDTH QUESTION MARK + 0xFF20, 0x8197, // FULLWIDTH COMMERCIAL AT + 0xFF21, 0x8260, // FULLWIDTH LATIN CAPITAL LETTER A + 0xFF22, 0x8261, // FULLWIDTH LATIN CAPITAL LETTER B + 0xFF23, 0x8262, // FULLWIDTH LATIN CAPITAL LETTER C + 0xFF24, 0x8263, // FULLWIDTH LATIN CAPITAL LETTER D + 0xFF25, 0x8264, // FULLWIDTH LATIN CAPITAL LETTER E + 0xFF26, 0x8265, // FULLWIDTH LATIN CAPITAL LETTER F + 0xFF27, 0x8266, // FULLWIDTH LATIN CAPITAL LETTER G + 0xFF28, 0x8267, // FULLWIDTH LATIN CAPITAL LETTER H + 0xFF29, 0x8268, // FULLWIDTH LATIN CAPITAL LETTER I + 0xFF2A, 0x8269, // FULLWIDTH LATIN CAPITAL LETTER J + 0xFF2B, 0x826A, // FULLWIDTH LATIN CAPITAL LETTER K + 0xFF2C, 0x826B, // FULLWIDTH LATIN CAPITAL LETTER L + 0xFF2D, 0x826C, // FULLWIDTH LATIN CAPITAL LETTER M + 0xFF2E, 0x826D, // FULLWIDTH LATIN CAPITAL LETTER N + 0xFF2F, 0x826E, // FULLWIDTH LATIN CAPITAL LETTER O + 0xFF30, 0x826F, // FULLWIDTH LATIN CAPITAL LETTER P + 0xFF31, 0x8270, // FULLWIDTH LATIN CAPITAL LETTER Q + 0xFF32, 0x8271, // FULLWIDTH LATIN CAPITAL LETTER R + 0xFF33, 0x8272, // FULLWIDTH LATIN CAPITAL LETTER S + 0xFF34, 0x8273, // FULLWIDTH LATIN CAPITAL LETTER T + 0xFF35, 0x8274, // FULLWIDTH LATIN CAPITAL LETTER U + 0xFF36, 0x8275, // FULLWIDTH LATIN CAPITAL LETTER V + 0xFF37, 0x8276, // FULLWIDTH LATIN CAPITAL LETTER W + 0xFF38, 0x8277, // FULLWIDTH LATIN CAPITAL LETTER X + 0xFF39, 0x8278, // FULLWIDTH LATIN CAPITAL LETTER Y + 0xFF3A, 0x8279, // FULLWIDTH LATIN CAPITAL LETTER Z + 0xFF3B, 0x816D, // FULLWIDTH LEFT SQUARE BRACKET + 0xFF3D, 0x816E, // FULLWIDTH RIGHT SQUARE BRACKET + 0xFF3E, 0x814F, // FULLWIDTH CIRCUMFLEX ACCENT + 0xFF3F, 0x8151, // FULLWIDTH LOW LINE + 0xFF40, 0x814D, // FULLWIDTH GRAVE ACCENT + 0xFF41, 0x8281, // FULLWIDTH LATIN SMALL LETTER A + 0xFF42, 0x8282, // FULLWIDTH LATIN SMALL LETTER B + 0xFF43, 0x8283, // FULLWIDTH LATIN SMALL LETTER C + 0xFF44, 0x8284, // FULLWIDTH LATIN SMALL LETTER D + 0xFF45, 0x8285, // FULLWIDTH LATIN SMALL LETTER E + 0xFF46, 0x8286, // FULLWIDTH LATIN SMALL LETTER F + 0xFF47, 0x8287, // FULLWIDTH LATIN SMALL LETTER G + 0xFF48, 0x8288, // FULLWIDTH LATIN SMALL LETTER H + 0xFF49, 0x8289, // FULLWIDTH LATIN SMALL LETTER I + 0xFF4A, 0x828A, // FULLWIDTH LATIN SMALL LETTER J + 0xFF4B, 0x828B, // FULLWIDTH LATIN SMALL LETTER K + 0xFF4C, 0x828C, // FULLWIDTH LATIN SMALL LETTER L + 0xFF4D, 0x828D, // FULLWIDTH LATIN SMALL LETTER M + 0xFF4E, 0x828E, // FULLWIDTH LATIN SMALL LETTER N + 0xFF4F, 0x828F, // FULLWIDTH LATIN SMALL LETTER O + 0xFF50, 0x8290, // FULLWIDTH LATIN SMALL LETTER P + 0xFF51, 0x8291, // FULLWIDTH LATIN SMALL LETTER Q + 0xFF52, 0x8292, // FULLWIDTH LATIN SMALL LETTER R + 0xFF53, 0x8293, // FULLWIDTH LATIN SMALL LETTER S + 0xFF54, 0x8294, // FULLWIDTH LATIN SMALL LETTER T + 0xFF55, 0x8295, // FULLWIDTH LATIN SMALL LETTER U + 0xFF56, 0x8296, // FULLWIDTH LATIN SMALL LETTER V + 0xFF57, 0x8297, // FULLWIDTH LATIN SMALL LETTER W + 0xFF58, 0x8298, // FULLWIDTH LATIN SMALL LETTER X + 0xFF59, 0x8299, // FULLWIDTH LATIN SMALL LETTER Y + 0xFF5A, 0x829A, // FULLWIDTH LATIN SMALL LETTER Z + 0xFF5B, 0x816F, // FULLWIDTH LEFT CURLY BRACKET + 0xFF5C, 0x8162, // FULLWIDTH VERTICAL LINE + 0xFF5D, 0x8170, // FULLWIDTH RIGHT CURLY BRACKET + 0xFFE3, 0x8150, // FULLWIDTH MACRON + 0xFFE5, 0x818F // FULLWIDTH YEN SIGN +}; \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/stdint_msvc.h b/3rdparty/zint-2.6.1/backend/stdint_msvc.h new file mode 100644 index 0000000..f306a4c --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/stdint_msvc.h @@ -0,0 +1,52 @@ +/* stdint_msvc.h - definitions for libzint + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#ifndef STDINT_MSVC_H +#define STDINT_MSVC_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef _MSC_VER + +typedef BYTE uint8_t; +typedef WORD uint16_t; +typedef DWORD uint32_t; +typedef INT32 int32_t; + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STDINT_MSVC_H */ diff --git a/3rdparty/zint-2.6.1/backend/svg.c b/3rdparty/zint-2.6.1/backend/svg.c new file mode 100644 index 0000000..04a1ab6 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/svg.c @@ -0,0 +1,679 @@ +/* svg.c - Scalable Vector Graphics */ + +/* + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#endif + +#include "common.h" + +#define SSET "0123456789ABCDEF" + +int svg_plot(struct zint_symbol *symbol) { + int i, block_width, latch, r, this_row; + float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0; + FILE *fsvg; + int error_number = 0; + int textoffset, xoffset, yoffset, textdone, main_width; + char textpart[10], addon[6]; + int large_bar_count, comp_offset; + float addon_text_posn; + float scaler = symbol->scale; + float default_text_posn; + const char *locale = NULL; +#ifndef _MSC_VER + unsigned char local_text[ustrlen(symbol->text) + 1]; +#else + unsigned char* local_text = (unsigned char*) _alloca(ustrlen(symbol->text) + 1); +#endif + + row_height = 0; + textdone = 0; + main_width = symbol->width; + strcpy(addon, ""); + comp_offset = 0; + addon_text_posn = 0.0; + + if (symbol->show_hrt != 0) { + /* Copy text from symbol */ + ustrcpy(local_text, symbol->text); + } else { + /* No text needed */ + switch (symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CC: + case BARCODE_ISBNX: + case BARCODE_UPCA: + case BARCODE_UPCE: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + /* For these symbols use dummy text to ensure formatting is done + * properly even if no text is required */ + for (i = 0; i < ustrlen(symbol->text); i++) { + if (symbol->text[i] == '+') { + local_text[i] = '+'; + } else { + local_text[i] = ' '; + } + local_text[ustrlen(symbol->text)] = '\0'; + } + break; + default: + /* For everything else, just remove the text */ + local_text[0] = '\0'; + break; + } + } + + if (symbol->output_options & BARCODE_STDOUT) { + fsvg = stdout; + } else { + fsvg = fopen(symbol->outfile, "w"); + } + if (fsvg == NULL) { + strcpy(symbol->errtxt, "660: Could not open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + + /* sort out colour options */ + to_upper((unsigned char*) symbol->fgcolour); + to_upper((unsigned char*) symbol->bgcolour); + + if (strlen(symbol->fgcolour) != 6) { + strcpy(symbol->errtxt, "661: Malformed foreground colour target"); + fclose(fsvg); + return ZINT_ERROR_INVALID_OPTION; + } + if (strlen(symbol->bgcolour) != 6) { + strcpy(symbol->errtxt, "662: Malformed background colour target"); + fclose(fsvg); + return ZINT_ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "663: Malformed foreground colour target"); + fclose(fsvg); + return ZINT_ERROR_INVALID_OPTION; + } + error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour)); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "664: Malformed background colour target"); + fclose(fsvg); + return ZINT_ERROR_INVALID_OPTION; + } + locale = setlocale(LC_ALL, "C"); + + if (symbol->height == 0) { + symbol->height = 50; + } + + large_bar_count = 0; + preset_height = 0.0; + for (i = 0; i < symbol->rows; i++) { + preset_height += symbol->row_height[i]; + if (symbol->row_height[i] == 0) { + large_bar_count++; + } + } + large_bar_height = (symbol->height - preset_height) / large_bar_count; + + if (large_bar_count == 0) { + symbol->height = preset_height; + } + + while (!(module_is_set(symbol, symbol->rows - 1, comp_offset))) { + comp_offset++; + } + + /* Certain symbols need whitespace otherwise characters get chopped off the sides */ + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) + || (symbol->symbology == BARCODE_ISBNX)) { + switch (ustrlen(local_text)) { + case 13: /* EAN 13 */ + case 16: + case 19: + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 96 + comp_offset; + } + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + if (symbol->whitespace_width == 0) { + symbol->whitespace_width = 10; + main_width = 51 + comp_offset; + } + } + + latch = 0; + r = 0; + /* Isolate add-on text */ + if (is_extendable(symbol->symbology)) { + for (i = 0; i < ustrlen(local_text); i++) { + if (latch == 1) { + addon[r] = local_text[i]; + r++; + } + if (local_text[i] == '+') { + latch = 1; + } + } + } + addon[r] = '\0'; + + /* Don't include control characters in output text */ + for(i = 0; i < ustrlen(local_text); i++) { + if (local_text[i] < ' ') { + local_text[i] = ' '; + } + } + + if (ustrlen(local_text) != 0) { + textoffset = 9; + } else { + textoffset = 0; + } + xoffset = symbol->border_width + symbol->whitespace_width; + yoffset = symbol->border_width; + + /* Start writing the header */ + fprintf(fsvg, "\n"); + fprintf(fsvg, "\n"); + if (symbol->symbology != BARCODE_MAXICODE) { + fprintf(fsvg, "width + xoffset + xoffset) * scaler), (int) ceil((symbol->height + textoffset + yoffset + yoffset) * scaler)); + } else { + fprintf(fsvg, "\n"); + if ((ustrlen(local_text) != 0) && (symbol->show_hrt != 0)) { + fprintf(fsvg, " %s\n", local_text); + } else { + fprintf(fsvg, " Zint Generated Symbol\n"); + } + fprintf(fsvg, " \n"); + fprintf(fsvg, "\n \n", symbol->fgcolour); + + if (symbol->symbology != BARCODE_MAXICODE) { + fprintf(fsvg, " \n", (int) ceil((symbol->width + xoffset + xoffset) * scaler), (int) ceil((symbol->height + textoffset + yoffset + yoffset) * scaler), symbol->bgcolour); + } else { + fprintf(fsvg, " \n", (int) ceil((74.0F + xoffset + xoffset) * scaler), (int) ceil((72.0F + yoffset + yoffset) * scaler), symbol->bgcolour); + } + + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + default_text_posn = (symbol->height + textoffset + symbol->border_width + symbol->border_width) * scaler; + } else { + default_text_posn = (symbol->height + textoffset + symbol->border_width) * scaler; + } + + if (symbol->symbology == BARCODE_MAXICODE) { + /* Maxicode uses hexagons */ + float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my; + + + textoffset = 0.0; + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + fprintf(fsvg, " \n", 0.0, 0.0, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", 0.0, (72.0 + symbol->border_width) * scaler, (74.0 + xoffset + xoffset) * scaler, symbol->border_width * scaler); + } + if (symbol->output_options & BARCODE_BOX) { + /* side bars */ + fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); + fprintf(fsvg, " \n", (74.0 + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (72.0 + (2 * symbol->border_width)) * scaler); + } + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 10.85 * scaler, symbol->fgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 8.97 * scaler, symbol->bgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 7.10 * scaler, symbol->fgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 5.22 * scaler, symbol->bgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 3.31 * scaler, symbol->fgcolour); + fprintf(fsvg, " \n", (35.76 + xoffset) * scaler, (35.60 + yoffset) * scaler, 1.43 * scaler, symbol->bgcolour); + for (r = 0; r < symbol->rows; r++) { + for (i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, r, i)) { + /* Dump a hexagon */ + my = r * 2.135 + 1.43; + ay = my + 1.0 + yoffset; + by = my + 0.5 + yoffset; + cy = my - 0.5 + yoffset; + dy = my - 1.0 + yoffset; + ey = my - 0.5 + yoffset; + fy = my + 0.5 + yoffset; + if (r & 1) { + mx = (2.46 * i) + 1.23 + 1.23; + } else { + mx = (2.46 * i) + 1.23; + } + ax = mx + xoffset; + bx = mx + 0.86 + xoffset; + cx = mx + 0.86 + xoffset; + dx = mx + xoffset; + ex = mx - 0.86 + xoffset; + fx = mx - 0.86 + xoffset; + fprintf(fsvg, " \n", ax * scaler, ay * scaler, bx * scaler, by * scaler, cx * scaler, cy * scaler, dx * scaler, dy * scaler, ex * scaler, ey * scaler, fx * scaler, fy * scaler); + } + } + } + } + + if (symbol->symbology != BARCODE_MAXICODE) { + /* everything else uses rectangles (or squares) */ + /* Works from the bottom of the symbol up */ + int addon_latch = 0; + + for (r = 0; r < symbol->rows; r++) { + this_row = r; + if (symbol->row_height[this_row] == 0) { + row_height = large_bar_height; + } else { + row_height = symbol->row_height[this_row]; + } + row_posn = 0; + for (i = 0; i < r; i++) { + if (symbol->row_height[i] == 0) { + row_posn += large_bar_height; + } else { + row_posn += symbol->row_height[i]; + } + } + row_posn += yoffset; + + if (symbol->output_options & BARCODE_DOTTY_MODE) { + /* Use dot mode */ + for (i = 0; i < symbol->width; i++) { + if (module_is_set(symbol, this_row, i)) { + fprintf(fsvg, " \n", ((i + xoffset) * scaler) + (scaler / 2.0), (row_posn * scaler) + (scaler / 2.0), (symbol->dot_size / 2.0) * scaler, symbol->fgcolour); + } + } + } else { + /* Normal mode, with rectangles */ + i = 0; + if (module_is_set(symbol, this_row, 0)) { + latch = 1; + } else { + latch = 0; + } + + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i)); + if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_width)) { + addon_text_posn = (row_posn + 8.0) * scaler; + addon_latch = 1; + } + if (latch == 1) { + /* a bar */ + if (addon_latch == 0) { + fprintf(fsvg, " \n", (i + xoffset) * scaler, row_posn * scaler, block_width * scaler, row_height * scaler); + } else { + fprintf(fsvg, " \n", (i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler); + } + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + + } while (i < symbol->width); + } + } + } + /* That's done the actual data area, everything else is human-friendly */ + + xoffset += comp_offset; + row_posn = (row_posn + large_bar_height) * scaler; + + if ((((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) || + (symbol->symbology == BARCODE_ISBNX)) { + /* guard bar extensions and text formatting for EAN8 and EAN13 */ + switch (ustrlen(local_text)) { + case 8: /* EAN-8 */ + case 11: + case 14: + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (32 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (34 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (64 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (66 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + for (i = 0; i < 4; i++) { + textpart[i] = local_text[i]; + } + textpart[4] = '\0'; + textpos = 17; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for (i = 0; i < 4; i++) { + textpart[i] = local_text[i + 4]; + } + textpart[4] = '\0'; + textpos = 50; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 86; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 100; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + + break; + case 13: /* EAN 13 */ + case 16: + case 19: + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (92 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (94 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + textpos = -7; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[6] = '\0'; + textpos = 24; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 7]; + } + textpart[6] = '\0'; + textpos = 71; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 114; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 128; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + break; + + } + } + + if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) { + /* guard bar extensions and text formatting for UPCA */ + latch = 1; + + i = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if (latch == 1) { + /* a bar */ + fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 11 + comp_offset); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + latch = 1; + i = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i)); + if (latch == 1) { + /* a bar */ + fprintf(fsvg, " \n", (i + xoffset - comp_offset) * scaler, row_posn, block_width * scaler, 5.0 * scaler); + latch = 0; + } else { + /* a space */ + latch = 1; + } + i += block_width; + } while (i < 96 + comp_offset); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + textpos = -5; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for (i = 0; i < 5; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[5] = '\0'; + textpos = 27; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for (i = 0; i < 5; i++) { + textpart[i] = local_text[i + 6]; + } + textpart[6] = '\0'; + textpos = 68; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textpart[0] = local_text[11]; + textpart[1] = '\0'; + textpos = 100; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 116; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 130; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + + } + + if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) { + /* guard bar extensions and text formatting for UPCE */ + fprintf(fsvg, " \n", (0 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (2 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (46 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (48 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + fprintf(fsvg, " \n", (50 + xoffset) * scaler, row_posn, scaler, 5.0 * scaler); + textpart[0] = local_text[0]; + textpart[1] = '\0'; + textpos = -5; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + for (i = 0; i < 6; i++) { + textpart[i] = local_text[i + 1]; + } + textpart[6] = '\0'; + textpos = 24; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textpart[0] = local_text[7]; + textpart[1] = '\0'; + textpos = 55; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", textpart); + fprintf(fsvg, " \n"); + textdone = 1; + switch (strlen(addon)) { + case 2: + textpos = xoffset + 70; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + case 5: + textpos = xoffset + 84; + fprintf(fsvg, " \n", 11.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", addon); + fprintf(fsvg, " \n"); + break; + } + + } + + xoffset -= comp_offset; + + switch (symbol->symbology) { + case BARCODE_MAXICODE: + /* Do nothing! (It's already been done) */ + break; + default: + if (symbol->output_options & BARCODE_BIND) { + if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) { + /* row binding */ + if (symbol->symbology != BARCODE_CODABLOCKF) { + for (r = 1; r < symbol->rows; r++) { + fprintf(fsvg, " \n", xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler); + } + } else { + for (r = 1; r < symbol->rows; r++) { + fprintf(fsvg, " \n", (xoffset + 11) * scaler, ((r * row_height) + yoffset - 1) * scaler, (symbol->width - 25) * scaler, 2.0 * scaler); + } + } + } + } + if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) { + if (symbol->symbology != BARCODE_CODABLOCKF) { + fprintf(fsvg, " \n", 0.0, 0.0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", 0.0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler); + } else { + fprintf(fsvg, " \n", xoffset * scaler, 0.0, symbol->width * scaler, symbol->border_width * scaler); + fprintf(fsvg, " \n", xoffset * scaler, (symbol->height + symbol->border_width) * scaler, symbol->width * scaler, symbol->border_width * scaler); + } + } + if (symbol->output_options & BARCODE_BOX) { + /* side bars */ + fprintf(fsvg, " \n", 0.0, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + fprintf(fsvg, " \n", (symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0.0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler); + } + break; + } + + /* Put the human readable text at the bottom */ + if ((textdone == 0) && ustrlen(local_text)) { + textpos = symbol->width / 2.0; + fprintf(fsvg, " \n", 8.0 * scaler, symbol->fgcolour); + fprintf(fsvg, " %s\n", local_text); + fprintf(fsvg, " \n"); + } + fprintf(fsvg, " \n"); + fprintf(fsvg, "\n"); + + if (symbol->output_options & BARCODE_STDOUT) { + fflush(fsvg); + } else { + fclose(fsvg); + } + + if (locale) + setlocale(LC_ALL, locale); + + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/telepen.c b/3rdparty/zint-2.6.1/backend/telepen.c new file mode 100644 index 0000000..f82c4d4 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/telepen.c @@ -0,0 +1,167 @@ +/* telepen.c - Handles Telepen and Telepen numeric */ + +/* + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define SODIUM "0123456789X" + +#include +#include +#include +#include "common.h" + +static char *TeleTable[] = { + "1111111111111111", "1131313111", "33313111", "1111313131", "3111313111", "11333131", "13133131", "111111313111", + "31333111", "1131113131", "33113131", "1111333111", "3111113131", "1113133111", "1311133111", "111111113131", + "3131113111", "11313331", "333331", "111131113111", "31113331", "1133113111", "1313113111", "1111113331", + "31131331", "113111113111", "3311113111", "1111131331", "311111113111", "1113111331", "1311111331", "11111111113111", + "31313311", "1131311131", "33311131", "1111313311", "3111311131", "11333311", "13133311", "111111311131", + "31331131", "1131113311", "33113311", "1111331131", "3111113311", "1113131131", "1311131131", "111111113311", + "3131111131", "1131131311", "33131311", "111131111131", "3111131311", "1133111131", "1313111131", "111111131311", + "3113111311", "113111111131", "3311111131", "111113111311", "311111111131", "111311111311", "131111111311", "11111111111131", + "3131311111", "11313133", "333133", "111131311111", "31113133", "1133311111", "1313311111", "1111113133", + "313333", "113111311111", "3311311111", "11113333", "311111311111", "11131333", "13111333", "11111111311111", + "31311133", "1131331111", "33331111", " 1111311133", "3111331111", "11331133", "13131133", "111111331111", + "3113131111", "1131111133", "33111133", "111113131111", "3111111133", "111311131111", "131111131111", "111111111133", + "31311313", "113131111111", "3331111111", "1111311313", "311131111111", "11331313", "13131313", "11111131111111", + "3133111111", "1131111313", "33111313", "111133111111", "3111111313", "111313111111", "131113111111", "111111111313", + "313111111111", "1131131113", "33131113", "11113111111111", "3111131113", "113311111111", "131311111111", "111111131113", + "3113111113", "11311111111111", "331111111111", "111113111113", "31111111111111", "111311111113", "131111111113" +}; + +int telepen(struct zint_symbol *symbol, unsigned char source[], const size_t src_len) { + unsigned int i, count, check_digit; + int error_number; + char dest[512]; /*14 + 30 * 14 + 14 + 14 + 1 ~ 512 */ + + error_number = 0; + + count = 0; + + if (src_len > 30) { + strcpy(symbol->errtxt, "390: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + /* Start character */ + strcpy(dest, TeleTable['_']); + + for (i = 0; i < src_len; i++) { + if (source[i] > 126) { + /* Cannot encode extended ASCII */ + strcpy(symbol->errtxt, "391: Invalid characters in input data"); + return ZINT_ERROR_INVALID_DATA; + } + strcat(dest, TeleTable[source[i]]); + count += source[i]; + } + + check_digit = 127 - (count % 127); + if (check_digit == 127) { + check_digit = 0; + } + strcat(dest, TeleTable[check_digit]); + + /* Stop character */ + strcat(dest, TeleTable['z']); + + expand(symbol, dest); + for (i = 0; i < src_len; i++) { + if (source[i] == '\0') { + symbol->text[i] = ' '; + } else { + symbol->text[i] = source[i]; + } + } + symbol->text[src_len] = '\0'; + return error_number; +} + +int telepen_num(struct zint_symbol *symbol, unsigned char source[], const size_t src_len) { + unsigned int count, check_digit, glyph; + int error_number; + size_t i,temp_length = src_len; + char dest[1024]; /* 14 + 60 * 14 + 14 + 14 + 1 ~ 1024 */ + unsigned char temp[64]; + + count = 0; + + if (temp_length > 60) { + strcpy(symbol->errtxt, "392: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + ustrcpy(temp, source); + to_upper(temp); + error_number = is_sane(SODIUM, temp, temp_length); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "393: Invalid characters in data"); + return error_number; + } + + /* Add a leading zero if required */ + if (temp_length & 1) { + memmove(temp + 1, temp, temp_length); + temp[0] = '0'; + + temp[++temp_length] = '\0'; + } + + /* Start character */ + strcpy(dest, TeleTable['_']); + + for (i = 0; i < temp_length; i += 2) { + if (temp[i] == 'X') { + strcpy(symbol->errtxt, "394: Invalid position of X in Telepen data"); + return ZINT_ERROR_INVALID_DATA; + } + + if (temp[i + 1] == 'X') { + glyph = ctoi(temp[i]) + 17; + count += glyph; + } else { + glyph = (10 * ctoi(temp[i])) + ctoi(temp[i + 1]); + glyph += 27; + count += glyph; + } + strcat(dest, TeleTable[glyph]); + } + + check_digit = 127 - (count % 127); + if (check_digit == 127) { + check_digit = 0; + } + strcat(dest, TeleTable[check_digit]); + + /* Stop character */ + strcat(dest, TeleTable['z']); + + expand(symbol, dest); + ustrcpy(symbol->text, temp); + return error_number; +} diff --git a/3rdparty/zint-2.6.1/backend/tif.c b/3rdparty/zint-2.6.1/backend/tif.c new file mode 100644 index 0000000..7b9b360 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/tif.c @@ -0,0 +1,289 @@ +/* tif.c - Aldus Tagged Image File Format support */ + +/* + libzint - the open source barcode library + Copyright (C) 2016-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "common.h" +#include "tif.h" +#ifdef _MSC_VER +#include +#include +#include +#endif + +int tbump_up(int input) { + /* Strings length must be a multiple of 4 bytes */ + if ((input % 2) == 1) { + input++; + } + return input; +} + +int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { + int fgred, fggrn, fgblu, bgred, bggrn, bgblu; + int i; + int rows_per_strip, strip_count; + int free_memory; + int row, column; + FILE *tif_file; +#ifdef _MSC_VER + uint32_t* strip_offset; + uint32_t* strip_bytes; +#endif + + tiff_header_t header; + tiff_ifd_t ifd; + uint16_t temp; + uint32_t temp32; + + fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + + rows_per_strip = 8192 / (symbol->bitmap_width * 3); + if (rows_per_strip == 0) { + rows_per_strip = 1; + } + + strip_count = symbol->bitmap_height / rows_per_strip; + if ((symbol->bitmap_height % rows_per_strip) != 0) { + strip_count++; + } + +#ifndef _MSC_VER + uint32_t strip_offset[strip_count]; + uint32_t strip_bytes[strip_count]; +#else + strip_offset = (uint32_t*) _alloca(strip_count * sizeof(uint32_t)); + strip_bytes = (uint32_t*) _alloca(strip_count * sizeof(uint32_t)); +#endif + free_memory = 8; + + for(i = 0; i < strip_count; i++) { + strip_offset[i] = free_memory; + if (i != (strip_count - 1)) { + strip_bytes[i] = rows_per_strip * symbol->bitmap_width * 3; + } else { + if ((symbol->bitmap_height % rows_per_strip) != 0) { + strip_bytes[i] = (symbol->bitmap_height % rows_per_strip) * symbol->bitmap_width * 3; + } else { + strip_bytes[i] = rows_per_strip * symbol->bitmap_width * 3; + } + } + free_memory += strip_bytes[i]; + if ((free_memory % 2) == 1) { + free_memory++; + } + } + + if (free_memory > 0xffff0000) { +#ifdef _MSC_VER + free(strip_offset); + free(strip_bytes); +#endif + strcpy(symbol->errtxt, "670: Output file size too big"); + return ZINT_ERROR_MEMORY; + } + + /* Open output file in binary mode */ + if (symbol->output_options & BARCODE_STDOUT) { +#ifdef _MSC_VER + if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { + strcpy(symbol->errtxt, "671: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } +#endif + tif_file = stdout; + } else { + if (!(tif_file = fopen(symbol->outfile, "wb"))) { + strcpy(symbol->errtxt, "672: Can't open output file"); + return ZINT_ERROR_FILE_ACCESS; + } + } + + /* Header */ + header.byte_order = 0x4949; + header.identity = 42; + header.offset = free_memory; + + fwrite(&header, sizeof(tiff_header_t), 1, tif_file); + free_memory += sizeof(tiff_ifd_t); + + /* Pixel data */ + for (row = 0; row < symbol->bitmap_height; row++) { + for (column = 0; column < symbol->bitmap_width; column++) { + if (pixelbuf[(row * symbol->bitmap_width) + column] == '1') { + putc(fgred, tif_file); + putc(fggrn, tif_file); + putc(fgblu, tif_file); + } else { + putc(bgred, tif_file); + putc(bggrn, tif_file); + putc(bgblu, tif_file); + } + } + if (((row + 1) % rows_per_strip) == 0) { + /* End of a strip */ + if ((strip_bytes[0] % 2) == 1) { + /* Add end-of strip pad */ + putc(0, tif_file); + } + } + } + + /* Image File Directory */ + ifd.entries = 14; + ifd.offset = 0; + + ifd.new_subset.tag = 0xfe; + ifd.new_subset.type = 4; + ifd.new_subset.count = 1; + ifd.new_subset.offset = 0; + + ifd.image_width.tag = 0x0100; + ifd.image_width.type = 3; // SHORT + ifd.image_width.count = 1; + ifd.image_width.offset = symbol->bitmap_width; + + ifd.image_length.tag = 0x0101; + ifd.image_length.type = 3; // SHORT + ifd.image_length.count = 1; + ifd.image_length.offset = symbol->bitmap_height; + + ifd.bits_per_sample.tag = 0x0102; + ifd.bits_per_sample.type = 3; // SHORT + ifd.bits_per_sample.count = 3; + ifd.bits_per_sample.offset = free_memory; + free_memory += 6; + + ifd.compression.tag = 0x0103; + ifd.compression.type = 3; + ifd.compression.count = 1; + ifd.compression.offset = 1; // Uncompressed + + ifd.photometric.tag = 0x0106; + ifd.photometric.type = 3; // SHORT + ifd.photometric.count = 1; + ifd.photometric.offset = 2; // RGB Model + + ifd.strip_offsets.tag = 0x0111; + ifd.strip_offsets.type = 4; // LONG + ifd.strip_offsets.count = strip_count; + ifd.strip_offsets.offset = free_memory; + free_memory += strip_count * 4; + + ifd.samples_per_pixel.tag = 0x0115; + ifd.samples_per_pixel.type = 3; + ifd.samples_per_pixel.count = 1; + ifd.samples_per_pixel.offset = 3; + + ifd.rows_per_strip.tag = 0x0116; + ifd.rows_per_strip.type = 4; + ifd.rows_per_strip.count = 1; + ifd.rows_per_strip.offset = rows_per_strip; + + ifd.strip_byte_counts.tag = 0x0117; + ifd.strip_byte_counts.type = 4; + ifd.strip_byte_counts.count = strip_count; + ifd.strip_byte_counts.offset = free_memory; + free_memory += strip_count * 4; + + ifd.x_resolution.tag = 0x011a; + ifd.x_resolution.type = 5; + ifd.x_resolution.count = 1; + ifd.x_resolution.offset = free_memory; + free_memory += 8; + + ifd.y_resolution.tag = 0x011b; + ifd.y_resolution.type = 5; + ifd.y_resolution.count = 1; + ifd.y_resolution.offset = free_memory; + free_memory += 8; + + ifd.planar_config.tag = 0x11c; + ifd.planar_config.type = 3; + ifd.planar_config.count = 1; + ifd.planar_config.offset = 1; + + ifd.resolution_unit.tag = 0x0128; + ifd.resolution_unit.type = 3; + ifd.resolution_unit.count = 1; + ifd.resolution_unit.offset = 2; // Inches + + fwrite(&ifd, sizeof(tiff_ifd_t), 1, tif_file); + + /* Bits per sample */ + temp = 8; + fwrite(&temp, 2, 1, tif_file); // Red Bytes + fwrite(&temp, 2, 1, tif_file); // Green Bytes + fwrite(&temp, 2, 1, tif_file); // Blue Bytes + + /* Strip offsets */ + for(i = 0; i < strip_count; i++) { + fwrite(&strip_offset[i], 4, 1, tif_file); + } + + /* Strip byte lengths */ + for(i = 0; i < strip_count; i++) { + fwrite(&strip_bytes[i], 4, 1, tif_file); + } + + /* X Resolution */ + temp32 = 72; + fwrite(&temp32, 4, 1, tif_file); + temp32 = 1; + fwrite(&temp32, 4, 1, tif_file); + + /* Y Resolution */ + temp32 = 72; + fwrite(&temp32, 4, 1, tif_file); + temp32 = 1; + fwrite(&temp32, 4, 1, tif_file); + + if (symbol->output_options & BARCODE_STDOUT) { + fflush(tif_file); + } else { + fclose(tif_file); + } + +#ifdef _MSC_VER + free(strip_offset); + free(strip_bytes); +#endif + + return 0; +} \ No newline at end of file diff --git a/3rdparty/zint-2.6.1/backend/tif.h b/3rdparty/zint-2.6.1/backend/tif.h new file mode 100644 index 0000000..76f1960 --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/tif.h @@ -0,0 +1,87 @@ +/* tif.h - Aldus Tagged Image File Format */ + +/* + libzint - the open source barcode library + Copyright (C) 2016-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ +#ifndef TIF_H +#define TIF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +#include +#include "stdint_msvc.h" +#else +#include +#endif + +#pragma pack(1) + + typedef struct tiff_header { + uint16_t byte_order; + uint16_t identity; + uint32_t offset; + } tiff_header_t; + + typedef struct tiff_tag { + uint16_t tag; + uint16_t type; + uint32_t count; + uint32_t offset; + } tiff_tag_t; + + typedef struct tiff_ifd { + uint16_t entries; + tiff_tag_t new_subset; + tiff_tag_t image_width; + tiff_tag_t image_length; + tiff_tag_t bits_per_sample; + tiff_tag_t compression; + tiff_tag_t photometric; + tiff_tag_t strip_offsets; + tiff_tag_t samples_per_pixel; + tiff_tag_t rows_per_strip; + tiff_tag_t strip_byte_counts; + tiff_tag_t x_resolution; + tiff_tag_t y_resolution; + tiff_tag_t planar_config; + tiff_tag_t resolution_unit; + uint32_t offset; + } tiff_ifd_t; + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* TIF_H */ + diff --git a/3rdparty/zint-2.6.1/backend/upcean.c b/3rdparty/zint-2.6.1/backend/upcean.c new file mode 100644 index 0000000..d11343c --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/upcean.c @@ -0,0 +1,936 @@ +/* upcean.c - Handles UPC, EAN and ISBN + + libzint - the open source barcode library + Copyright (C) 2008-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#define SODIUM "0123456789+" +#define EAN2 102 +#define EAN5 105 + +#include +#include +#include +#include "common.h" + +/* UPC and EAN tables checked against EN 797:1996 */ + +static const char *UPCParity0[10] = { + /* Number set for UPC-E symbol (EN Table 4) */ + "BBBAAA", "BBABAA", "BBAABA", "BBAAAB", "BABBAA", "BAABBA", "BAAABB", + "BABABA", "BABAAB", "BAABAB" +}; + +static const char *UPCParity1[10] = { + /* Not covered by BS EN 797:1995 */ + "AAABBB", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA", + "ABABAB", "ABABBA", "ABBABA" +}; + +static const char *EAN2Parity[4] = { + /* Number sets for 2-digit add-on (EN Table 6) */ + "AA", "AB", "BA", "BB" +}; + +static const char *EAN5Parity[10] = { + /* Number set for 5-digit add-on (EN Table 7) */ + "BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA", + "ABAAB", "AABAB" +}; + +static const char *EAN13Parity[10] = { + /* Left hand of the EAN-13 symbol (EN Table 3) */ + "AAAAA", "ABABB", "ABBAB", "ABBBA", "BAABB", "BBAAB", "BBBAA", "BABAB", + "BABBA", "BBABA" +}; + +static const char *EANsetA[10] = { + /* Representation set A and C (EN Table 1) */ + "3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213", "3112" +}; + +static const char *EANsetB[10] = { + /* Representation set B (EN Table 1) */ + "1123", "1222", "2212", "1141", "2311", "1321", "4111", "2131", "3121", "2113" +}; + +/* Calculate the correct check digit for a UPC barcode */ +char upc_check(char source[]) { + unsigned int i, count, check_digit; + + count = 0; + + for (i = 0; i < strlen(source); i++) { + count += ctoi(source[i]); + + if (!(i & 1)) { + count += 2 * (ctoi(source[i])); + } + } + + check_digit = 10 - (count % 10); + if (check_digit == 10) { + check_digit = 0; + } + return itoc(check_digit); +} + +/* UPC A is usually used for 12 digit numbers, but this function takes a source of any length */ +void upca_draw(char source[], char dest[]) { + unsigned int i, half_way; + + half_way = strlen(source) / 2; + + /* start character */ + strcat(dest, "111"); + + for (i = 0; i <= strlen(source); i++) { + if (i == half_way) { + /* middle character - separates manufacturer no. from product no. */ + /* also inverts right hand characters */ + strcat(dest, "11111"); + } + + lookup(NEON, EANsetA, source[i], dest); + } + + /* stop character */ + strcat(dest, "111"); +} + +/* Make a UPC A barcode when we haven't been given the check digit */ +int upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) { + int length; + char gtin[15]; + + strcpy(gtin, (char*) source); + length = strlen(gtin); + + if (length == 11) { + gtin[length] = upc_check(gtin); + gtin[length + 1] = '\0'; + } else { + gtin[length - 1] = '\0'; + if (source[length - 1] != upc_check(gtin)) { + strcpy(symbol->errtxt, "270: Invalid check digit"); + return ZINT_ERROR_INVALID_DATA; + } + gtin[length - 1] = upc_check(gtin); + } + upca_draw(gtin, dest); + ustrcpy(symbol->text, (unsigned char*) gtin); + return 0; +} + +/* UPC E is a zero-compressed version of UPC A */ +int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) { + unsigned int i, num_system; + char emode, equivalent[12], check_digit, parity[8], temp[8]; + char hrt[9]; + + /* Two number systems can be used - system 0 and system 1 */ + if (symbol->symbology != BARCODE_UPCE_CHK) { + /* No check digit in input data */ + if (ustrlen(source) == 7) { + switch (source[0]) { + case '0': num_system = 0; + break; + case '1': num_system = 1; + break; + default: num_system = 0; + source[0] = '0'; + break; + } + strcpy(temp, (char*) source); + strcpy(hrt, (char*) source); + for (i = 1; i <= 7; i++) { + source[i - 1] = temp[i]; + } + } else { + num_system = 0; + hrt[0] = '0'; + hrt[1] = '\0'; + strcat(hrt, (char*) source); + } + } else { + /* Check digit is included in input data */ + if (ustrlen(source) == 8) { + switch (source[0]) { + case '0': num_system = 0; + break; + case '1': num_system = 1; + break; + default: num_system = 0; + source[0] = '0'; + break; + } + strcpy(temp, (char*) source); + strcpy(hrt, (char*) source); + for (i = 1; i <= 7; i++) { + source[i - 1] = temp[i]; + } + } else { + num_system = 0; + hrt[0] = '0'; + hrt[1] = '\0'; + strcat(hrt, (char*) source); + } + } + + /* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */ + emode = source[5]; + for (i = 0; i < 11; i++) { + equivalent[i] = '0'; + } + if (num_system == 1) { + equivalent[0] = temp[0]; + } + equivalent[1] = source[0]; + equivalent[2] = source[1]; + equivalent[11] = '\0'; + + switch (emode) { + case '0': + case '1': + case '2': + equivalent[3] = emode; + equivalent[8] = source[2]; + equivalent[9] = source[3]; + equivalent[10] = source[4]; + break; + case '3': + equivalent[3] = source[2]; + equivalent[9] = source[3]; + equivalent[10] = source[4]; + if (((source[2] == '0') || (source[2] == '1')) || (source[2] == '2')) { + /* Note 1 - "X3 shall not be equal to 0, 1 or 2" */ + strcpy(symbol->errtxt, "271: Invalid UPC-E data"); + return ZINT_ERROR_INVALID_DATA; + } + break; + case '4': + equivalent[3] = source[2]; + equivalent[4] = source[3]; + equivalent[10] = source[4]; + if (source[3] == '0') { + /* Note 2 - "X4 shall not be equal to 0" */ + strcpy(symbol->errtxt, "272: Invalid UPC-E data"); + return ZINT_ERROR_INVALID_DATA; + } + break; + case '5': + case '6': + case '7': + case '8': + case '9': + equivalent[3] = source[2]; + equivalent[4] = source[3]; + equivalent[5] = source[4]; + equivalent[10] = emode; + if (source[4] == '0') { + /* Note 3 - "X5 shall not be equal to 0" */ + strcpy(symbol->errtxt, "273: Invalid UPC-E data"); + return ZINT_ERROR_INVALID_DATA; + } + break; + } + + /* Get the check digit from the expanded UPCA code */ + + check_digit = upc_check(equivalent); + + /* Use the number system and check digit information to choose a parity scheme */ + if (num_system == 1) { + strcpy(parity, UPCParity1[ctoi(check_digit)]); + } else { + strcpy(parity, UPCParity0[ctoi(check_digit)]); + } + + /* Take all this information and make the barcode pattern */ + + /* start character */ + strcat(dest, "111"); + + for (i = 0; i <= ustrlen(source); i++) { + switch (parity[i]) { + case 'A': lookup(NEON, EANsetA, source[i], dest); + break; + case 'B': lookup(NEON, EANsetB, source[i], dest); + break; + } + } + + /* stop character */ + strcat(dest, "111111"); + + if (symbol->symbology != BARCODE_UPCE_CHK) { + hrt[7] = check_digit; + hrt[8] = '\0'; + } else { + if (hrt[7] != check_digit) { + strcpy(symbol->errtxt, "274: Invalid check digit"); + return ZINT_ERROR_INVALID_DATA; + } + } + ustrcpy(symbol->text, (unsigned char*) hrt); + return 0; +} + +/* EAN-2 and EAN-5 add-on codes */ +void add_on(unsigned char source[], char dest[], int mode) { + char parity[6]; + unsigned int i, code_type; + + /* If an add-on then append with space */ + if (mode != 0) { + strcat(dest, "9"); + } + + /* Start character */ + strcat(dest, "112"); + + /* Determine EAN2 or EAN5 add-on */ + if (ustrlen(source) == 2) { + code_type = EAN2; + } else { + code_type = EAN5; + } + + /* Calculate parity for EAN2 */ + if (code_type == EAN2) { + int code_value, parity_bit; + + code_value = (10 * ctoi(source[0])) + ctoi(source[1]); + parity_bit = code_value % 4; + strcpy(parity, EAN2Parity[parity_bit]); + } + + if (code_type == EAN5) { + int values[6], parity_sum, parity_bit; + + for (i = 0; i < 6; i++) { + values[i] = ctoi(source[i]); + } + + parity_sum = (3 * (values[0] + values[2] + values[4])); + parity_sum += (9 * (values[1] + values[3])); + + parity_bit = parity_sum % 10; + strcpy(parity, EAN5Parity[parity_bit]); + } + + for (i = 0; i < ustrlen(source); i++) { + switch (parity[i]) { + case 'A': lookup(NEON, EANsetA, source[i], dest); + break; + case 'B': lookup(NEON, EANsetB, source[i], dest); + break; + } + + /* Glyph separator */ + if (i != (ustrlen(source) - 1)) { + strcat(dest, "11"); + } + } +} + +/* ************************ EAN-13 ****************** */ + +/* Calculate the correct check digit for a EAN-13 barcode */ +char ean_check(char source[]) { + int i; + unsigned int h, count, check_digit; + + count = 0; + + h = strlen(source); + for (i = h - 1; i >= 0; i--) { + count += ctoi(source[i]); + + if (i & 1) { + count += 2 * ctoi(source[i]); + } + } + check_digit = 10 - (count % 10); + if (check_digit == 10) { + check_digit = 0; + } + return itoc(check_digit); +} + +int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[]) { + unsigned int length, i, half_way; + char parity[6]; + char gtin[15]; + + strcpy(parity, ""); + strcpy(gtin, (char*) source); + + /* Add the appropriate check digit */ + length = strlen(gtin); + + if (length == 12) { + gtin[length] = ean_check(gtin); + gtin[length + 1] = '\0'; + } else { + gtin[length - 1] = '\0'; + if (source[length - 1] != ean_check(gtin)) { + strcpy(symbol->errtxt, "275: Invalid check digit"); + return ZINT_ERROR_INVALID_DATA; + } + gtin[length - 1] = ean_check(gtin); + } + + /* Get parity for first half of the symbol */ + lookup(SODIUM, EAN13Parity, gtin[0], parity); + + /* Now get on with the cipher */ + half_way = 7; + + /* start character */ + strcat(dest, "111"); + length = strlen(gtin); + for (i = 1; i <= length; i++) { + if (i == half_way) { + /* middle character - separates manufacturer no. from product no. */ + /* also inverses right hand characters */ + strcat(dest, "11111"); + } + + if (((i > 1) && (i < 7)) && (parity[i - 2] == 'B')) { + lookup(NEON, EANsetB, gtin[i], dest); + } else { + lookup(NEON, EANsetA, gtin[i], dest); + } + } + + /* stop character */ + strcat(dest, "111"); + + ustrcpy(symbol->text, (unsigned char*) gtin); + return 0; +} + +/* Make an EAN-8 barcode when we haven't been given the check digit */ +int ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) { + /* EAN-8 is basically the same as UPC-A but with fewer digits */ + int length; + char gtin[10]; + + strcpy(gtin, (char*) source); + length = strlen(gtin); + + if (length == 7) { + gtin[length] = upc_check(gtin); + gtin[length + 1] = '\0'; + } else { + gtin[length - 1] = '\0'; + if (source[length - 1] != upc_check(gtin)) { + strcpy(symbol->errtxt, "276: Invalid check digit"); + return ZINT_ERROR_INVALID_DATA; + } + gtin[length - 1] = upc_check(gtin); + } + upca_draw(gtin, dest); + ustrcpy(symbol->text, (unsigned char*) gtin); + + return 0; +} + +/* For ISBN(13) only */ +char isbn13_check(unsigned char source[]) { + unsigned int i, weight, sum, check, h; + + sum = 0; + weight = 1; + h = ustrlen(source) - 1; + + for (i = 0; i < h; i++) { + sum += ctoi(source[i]) * weight; + if (weight == 1) weight = 3; + else weight = 1; + } + + check = sum % 10; + check = 10 - check; + if (check == 10) check = 0; + return itoc(check); +} + +/* For ISBN(10) and SBN only */ +char isbn_check(unsigned char source[]) { + unsigned int i, weight, sum, check, h; + char check_char; + + sum = 0; + weight = 1; + h = ustrlen(source) - 1; + + for (i = 0; i < h; i++) { + sum += ctoi(source[i]) * weight; + weight++; + } + + check = sum % 11; + check_char = itoc(check); + if (check == 10) { + check_char = 'X'; + } + return check_char; +} + +/* Make an EAN-13 barcode from an SBN or ISBN */ +static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t src_len, char dest[]) { + int i, error_number; + char check_digit; + + to_upper(source); + error_number = is_sane("0123456789X", source, src_len); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "277: Invalid characters in input"); + return error_number; + } + + /* Input must be 9, 10 or 13 characters */ + if (((src_len < 9) || (src_len > 13)) || ((src_len > 10) && (src_len < 13))) { + strcpy(symbol->errtxt, "278: Input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + + if (src_len == 13) /* Using 13 character ISBN */ { + if (!(((source[0] == '9') && (source[1] == '7')) && + ((source[2] == '8') || (source[2] == '9')))) { + strcpy(symbol->errtxt, "279: Invalid ISBN"); + return ZINT_ERROR_INVALID_DATA; + } + + check_digit = isbn13_check(source); + if (source[src_len - 1] != check_digit) { + strcpy(symbol->errtxt, "280: Incorrect ISBN check"); + return ZINT_ERROR_INVALID_CHECK; + } + source[12] = '\0'; + + ean13(symbol, source, dest); + } + + if (src_len == 10) /* Using 10 digit ISBN */ { + check_digit = isbn_check(source); + if (check_digit != source[src_len - 1]) { + strcpy(symbol->errtxt, "281: Incorrect ISBN check"); + return ZINT_ERROR_INVALID_CHECK; + } + for (i = 13; i > 0; i--) { + source[i] = source[i - 3]; + } + source[0] = '9'; + source[1] = '7'; + source[2] = '8'; + source[12] = '\0'; + + ean13(symbol, source, dest); + } + + if (src_len == 9) /* Using 9 digit SBN */ { + /* Add leading zero */ + for (i = 10; i > 0; i--) { + source[i] = source[i - 1]; + } + source[0] = '0'; + + /* Verify check digit */ + check_digit = isbn_check(source); + if (check_digit != source[ustrlen(source) - 1]) { + strcpy(symbol->errtxt, "282: Incorrect SBN check"); + return ZINT_ERROR_INVALID_CHECK; + } + + /* Convert to EAN-13 number */ + for (i = 13; i > 0; i--) { + source[i] = source[i - 3]; + } + source[0] = '9'; + source[1] = '7'; + source[2] = '8'; + source[12] = '\0'; + + ean13(symbol, source, dest); + } + + return 0; +} + +/* Add leading zeroes to EAN and UPC strings */ +void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) { + unsigned char first_part[20], second_part[20], zfirst_part[20], zsecond_part[20]; + int with_addon = 0; + int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; + + h = ustrlen(source); + for (i = 0; i < h; i++) { + if (source[i] == '+') { + with_addon = 1; + } else { + if (with_addon == 0) { + first_len++; + } else { + second_len++; + } + } + } + + ustrcpy(first_part, (unsigned char *) ""); + ustrcpy(second_part, (unsigned char *) ""); + ustrcpy(zfirst_part, (unsigned char *) ""); + ustrcpy(zsecond_part, (unsigned char *) ""); + + /* Split input into two strings */ + for (i = 0; i < first_len; i++) { + first_part[i] = source[i]; + first_part[i + 1] = '\0'; + } + + for (i = 0; i < second_len; i++) { + second_part[i] = source[i + first_len + 1]; + second_part[i + 1] = '\0'; + } + + /* Calculate target lengths */ + if (second_len <= 5) { + zsecond_len = 5; + } + if (second_len <= 2) { + zsecond_len = 2; + } + if (second_len == 0) { + zsecond_len = 0; + } + switch (symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CC: + if (first_len <= 12) { + zfirst_len = 12; + } + if (first_len <= 7) { + zfirst_len = 7; + } + if (second_len == 0) { + if (first_len <= 5) { + zfirst_len = 5; + } + if (first_len <= 2) { + zfirst_len = 2; + } + } + break; + case BARCODE_EANX_CHK: + if (first_len <= 13) { + zfirst_len = 13; + } + if (first_len <= 8) { + zfirst_len = 8; + } + if (second_len == 0) { + if (first_len <= 5) { + zfirst_len = 5; + } + if (first_len <= 2) { + zfirst_len = 2; + } + } + break; + case BARCODE_UPCA: + case BARCODE_UPCA_CC: + zfirst_len = 11; + break; + case BARCODE_UPCA_CHK: + zfirst_len = 12; + break; + case BARCODE_UPCE: + case BARCODE_UPCE_CC: + if (first_len == 7) { + zfirst_len = 7; + } + if (first_len <= 6) { + zfirst_len = 6; + } + break; + case BARCODE_UPCE_CHK: + if (first_len == 8) { + zfirst_len = 8; + } + if (first_len <= 7) { + zfirst_len = 7; + } + break; + case BARCODE_ISBNX: + if (first_len <= 9) { + zfirst_len = 9; + } + break; + } + + + /* Add leading zeroes */ + for (i = 0; i < (zfirst_len - first_len); i++) { + strcat((char*) zfirst_part, "0"); + } + strcat((char*) zfirst_part, (char*) first_part); + for (i = 0; i < (zsecond_len - second_len); i++) { + strcat((char*) zsecond_part, "0"); + } + strcat((char*) zsecond_part, (char*) second_part); + + /* Copy adjusted data back to local_source */ + strcat((char*) local_source, (char*) zfirst_part); + if (zsecond_len != 0) { + strcat((char*) local_source, "+"); + strcat((char*) local_source, (char*) zsecond_part); + } +} + +/* splits string to parts before and after '+' parts */ +int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { + unsigned char first_part[20] = {0}, second_part[20] = {0}, dest[1000] = {0}; + unsigned char local_source[20] = {0}; + unsigned int latch, reader, writer, with_addon; + int error_number, i; + + + with_addon = FALSE; + latch = FALSE; + writer = 0; + + if (src_len > 19) { + strcpy(symbol->errtxt, "283: Input too long"); + return ZINT_ERROR_TOO_LONG; + } + if (symbol->symbology != BARCODE_ISBNX) { + /* ISBN has it's own checking routine */ + error_number = is_sane("0123456789+", source, src_len); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "284: Invalid characters in data"); + return error_number; + } + } else { + error_number = is_sane("0123456789Xx", source, src_len); + if (error_number == ZINT_ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "285: Invalid characters in input"); + return error_number; + } + } + + /* Add leading zeroes */ + ustrcpy(local_source, (unsigned char *) ""); + if (symbol->symbology == BARCODE_ISBNX) { + to_upper(local_source); + } + + ean_leading_zeroes(symbol, source, local_source); + + for (reader = 0; reader < ustrlen(local_source); reader++) { + if (local_source[reader] == '+') { + with_addon = TRUE; + } + } + + reader = 0; + if (with_addon) { + do { + if (local_source[reader] == '+') { + first_part[writer] = '\0'; + latch = TRUE; + reader++; + writer = 0; + } + + if (latch) { + second_part[writer] = local_source[reader]; + reader++; + writer++; + } else { + first_part[writer] = local_source[reader]; + reader++; + writer++; + } + } while (reader <= ustrlen(local_source)); + } else { + strcpy((char*) first_part, (char*) local_source); + } + + switch (symbol->symbology) { + case BARCODE_EANX: + case BARCODE_EANX_CHK: + switch (ustrlen(first_part)) { + case 2: add_on(first_part, (char*) dest, 0); + ustrcpy(symbol->text, first_part); + break; + case 5: add_on(first_part, (char*) dest, 0); + ustrcpy(symbol->text, first_part); + break; + case 7: + case 8: error_number = ean8(symbol, first_part, (char*) dest); + break; + case 12: + case 13: error_number = ean13(symbol, first_part, (char*) dest); + break; + default: strcpy(symbol->errtxt, "286: Invalid length input"); + return ZINT_ERROR_TOO_LONG; + } + break; + case BARCODE_EANX_CC: + switch (ustrlen(first_part)) { /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */ + case 7: set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 67); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 68); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 1, 67); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + error_number = ean8(symbol, first_part, (char*) dest); + break; + case 12:set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 95); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 96); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 2, 95); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + error_number = ean13(symbol, first_part, (char*) dest); + break; + default: strcpy(symbol->errtxt, "287: Invalid length EAN input"); + return ZINT_ERROR_TOO_LONG; + } + break; + case BARCODE_UPCA: + case BARCODE_UPCA_CHK: + if ((ustrlen(first_part) == 11) || (ustrlen(first_part) == 12)) { + error_number = upca(symbol, first_part, (char*) dest); + } else { + strcpy(symbol->errtxt, "288: Input wrong length (C6I)"); + return ZINT_ERROR_TOO_LONG; + } + break; + case BARCODE_UPCA_CC: + if (ustrlen(first_part) == 11) { + set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 95); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 96); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 2, 95); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + error_number = upca(symbol, first_part, (char*) dest); + } else { + strcpy(symbol->errtxt, "289: UPCA input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + break; + case BARCODE_UPCE: + case BARCODE_UPCE_CHK: + if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 8)) { + error_number = upce(symbol, first_part, (char*) dest); + } else { + strcpy(symbol->errtxt, "290: Input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + break; + case BARCODE_UPCE_CC: + if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= 7)) { + set_module(symbol, symbol->rows, 1); + set_module(symbol, symbol->rows, 51); + set_module(symbol, symbol->rows + 1, 0); + set_module(symbol, symbol->rows + 1, 52); + set_module(symbol, symbol->rows + 2, 1); + set_module(symbol, symbol->rows + 2, 51); + symbol->row_height[symbol->rows] = 2; + symbol->row_height[symbol->rows + 1] = 2; + symbol->row_height[symbol->rows + 2] = 2; + symbol->rows += 3; + error_number = upce(symbol, first_part, (char*) dest); + } else { + strcpy(symbol->errtxt, "291: UPCE input wrong length"); + return ZINT_ERROR_TOO_LONG; + } + break; + case BARCODE_ISBNX: + error_number = isbn(symbol, first_part, ustrlen(first_part), (char*) dest); + break; + } + + if (error_number > 4) { + return error_number; + } + + switch (ustrlen(second_part)) { + case 0: break; + case 2: + add_on(second_part, (char*) dest, 1); + strcat((char*) symbol->text, "+"); + strcat((char*) symbol->text, (char*) second_part); + break; + case 5: + add_on(second_part, (char*) dest, 1); + strcat((char*) symbol->text, "+"); + strcat((char*) symbol->text, (char*) second_part); + break; + default: + strcpy(symbol->errtxt, "292: Invalid length input"); + return ZINT_ERROR_TOO_LONG; + } + + expand(symbol, (char*) dest); + + switch (symbol->symbology) { + case BARCODE_EANX_CC: + case BARCODE_UPCA_CC: + case BARCODE_UPCE_CC: + /* shift the symbol to the right one space to allow for separator bars */ + for (i = (symbol->width + 1); i >= 1; i--) { + if (module_is_set(symbol, symbol->rows - 1, i - 1)) { + set_module(symbol, symbol->rows - 1, i); + } else { + unset_module(symbol, symbol->rows - 1, i); + } + } + unset_module(symbol, symbol->rows - 1, 0); + symbol->width += 2; + break; + } + + return 0; +} diff --git a/3rdparty/zint-2.6.1/backend/zint.h b/3rdparty/zint-2.6.1/backend/zint.h new file mode 100644 index 0000000..988db7d --- /dev/null +++ b/3rdparty/zint-2.6.1/backend/zint.h @@ -0,0 +1,283 @@ +/* zint.h - definitions for libzint + + libzint - the open source barcode library + Copyright (C) 2009-2017 Robin Stuart + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + */ + +#ifndef ZINT_H +#define ZINT_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + struct zint_render_line { + float x, y, length, width; + struct zint_render_line *next; /* Pointer to next line */ + }; + + struct zint_render_string { + float x, y, fsize; + float width; /* Suggested string width, may be 0 if none recommended */ + int length; + unsigned char *text; + struct zint_render_string *next; /* Pointer to next character */ + }; + + struct zint_render_ring { + float x, y, radius, line_width; + struct zint_render_ring *next; /* Pointer to next ring */ + }; + + struct zint_render_hexagon { + float x, y; + struct zint_render_hexagon *next; /* Pointer to next hexagon */ + }; + + struct zint_render { + float width, height; + struct zint_render_line *lines; /* Pointer to first line */ + struct zint_render_string *strings; /* Pointer to first string */ + struct zint_render_ring *rings; /* Pointer to first ring */ + struct zint_render_hexagon *hexagons; /* Pointer to first hexagon */ + }; + + struct zint_symbol { + int symbology; + int height; + int whitespace_width; + int border_width; + int output_options; + char fgcolour[10]; + char bgcolour[10]; + char outfile[256]; + float scale; + int option_1; + int option_2; + int option_3; + int show_hrt; + int input_mode; + int eci; + unsigned char text[128]; + int rows; + int width; + char primary[128]; + unsigned char encoded_data[200][143]; + int row_height[200]; /* Largest symbol is 189 x 189 Han Xin */ + char errtxt[100]; + char *bitmap; + int bitmap_width; + int bitmap_height; + unsigned int bitmap_byte_length; + float dot_size; + struct zint_render *rendered; + int debug; + }; + +#define ZINT_VERSION_MAJOR 2 +#define ZINT_VERSION_MINOR 6 +#define ZINT_VERSION_RELEASE 1 + + /* Tbarcode 7 codes */ +#define BARCODE_CODE11 1 +#define BARCODE_C25MATRIX 2 +#define BARCODE_C25INTER 3 +#define BARCODE_C25IATA 4 +#define BARCODE_C25LOGIC 6 +#define BARCODE_C25IND 7 +#define BARCODE_CODE39 8 +#define BARCODE_EXCODE39 9 +#define BARCODE_EANX 13 +#define BARCODE_EANX_CHK 14 +#define BARCODE_EAN128 16 +#define BARCODE_CODABAR 18 +#define BARCODE_CODE128 20 +#define BARCODE_DPLEIT 21 +#define BARCODE_DPIDENT 22 +#define BARCODE_CODE16K 23 +#define BARCODE_CODE49 24 +#define BARCODE_CODE93 25 +#define BARCODE_FLAT 28 +#define BARCODE_RSS14 29 +#define BARCODE_RSS_LTD 30 +#define BARCODE_RSS_EXP 31 +#define BARCODE_TELEPEN 32 +#define BARCODE_UPCA 34 +#define BARCODE_UPCA_CHK 35 +#define BARCODE_UPCE 37 +#define BARCODE_UPCE_CHK 38 +#define BARCODE_POSTNET 40 +#define BARCODE_MSI_PLESSEY 47 +#define BARCODE_FIM 49 +#define BARCODE_LOGMARS 50 +#define BARCODE_PHARMA 51 +#define BARCODE_PZN 52 +#define BARCODE_PHARMA_TWO 53 +#define BARCODE_PDF417 55 +#define BARCODE_PDF417TRUNC 56 +#define BARCODE_MAXICODE 57 +#define BARCODE_QRCODE 58 +#define BARCODE_CODE128B 60 +#define BARCODE_AUSPOST 63 +#define BARCODE_AUSREPLY 66 +#define BARCODE_AUSROUTE 67 +#define BARCODE_AUSREDIRECT 68 +#define BARCODE_ISBNX 69 +#define BARCODE_RM4SCC 70 +#define BARCODE_DATAMATRIX 71 +#define BARCODE_EAN14 72 +#define BARCODE_CODABLOCKF 74 +#define BARCODE_NVE18 75 +#define BARCODE_JAPANPOST 76 +#define BARCODE_KOREAPOST 77 +#define BARCODE_RSS14STACK 79 +#define BARCODE_RSS14STACK_OMNI 80 +#define BARCODE_RSS_EXPSTACK 81 +#define BARCODE_PLANET 82 +#define BARCODE_MICROPDF417 84 +#define BARCODE_ONECODE 85 +#define BARCODE_PLESSEY 86 + + /* Tbarcode 8 codes */ +#define BARCODE_TELEPEN_NUM 87 +#define BARCODE_ITF14 89 +#define BARCODE_KIX 90 +#define BARCODE_AZTEC 92 +#define BARCODE_DAFT 93 +#define BARCODE_MICROQR 97 + + /* Tbarcode 9 codes */ +#define BARCODE_HIBC_128 98 +#define BARCODE_HIBC_39 99 +#define BARCODE_HIBC_DM 102 +#define BARCODE_HIBC_QR 104 +#define BARCODE_HIBC_PDF 106 +#define BARCODE_HIBC_MICPDF 108 +#define BARCODE_HIBC_BLOCKF 110 +#define BARCODE_HIBC_AZTEC 112 + + /* Tbarcode 10 codes */ +#define BARCODE_DOTCODE 115 +#define BARCODE_HANXIN 116 + + /* Zint specific */ +#define BARCODE_AZRUNE 128 +#define BARCODE_CODE32 129 +#define BARCODE_EANX_CC 130 +#define BARCODE_EAN128_CC 131 +#define BARCODE_RSS14_CC 132 +#define BARCODE_RSS_LTD_CC 133 +#define BARCODE_RSS_EXP_CC 134 +#define BARCODE_UPCA_CC 135 +#define BARCODE_UPCE_CC 136 +#define BARCODE_RSS14STACK_CC 137 +#define BARCODE_RSS14_OMNI_CC 138 +#define BARCODE_RSS_EXPSTACK_CC 139 +#define BARCODE_CHANNEL 140 +#define BARCODE_CODEONE 141 +#define BARCODE_GRIDMATRIX 142 +#define BARCODE_UPNQR 143 + +// Output options +#define BARCODE_NO_ASCII 1 +#define BARCODE_BIND 2 +#define BARCODE_BOX 4 +#define BARCODE_STDOUT 8 +#define READER_INIT 16 +#define SMALL_TEXT 32 +#define BOLD_TEXT 64 +#define CMYK_COLOUR 128 +#define BARCODE_DOTTY_MODE 256 + +// Input data types +#define DATA_MODE 0 +#define UNICODE_MODE 1 +#define GS1_MODE 2 +#define KANJI_MODE 3 +#define SJIS_MODE 4 + +// Data Matrix specific options +#define DM_SQUARE 100 +#define DM_DMRE 101 + +// Warning and error conditions +#define ZINT_WARN_INVALID_OPTION 2 +#define ZINT_WARN_USES_ECI 3 +#define ZINT_ERROR_TOO_LONG 5 +#define ZINT_ERROR_INVALID_DATA 6 +#define ZINT_ERROR_INVALID_CHECK 7 +#define ZINT_ERROR_INVALID_OPTION 8 +#define ZINT_ERROR_ENCODING_PROBLEM 9 +#define ZINT_ERROR_FILE_ACCESS 10 +#define ZINT_ERROR_MEMORY 11 + +// Raster file types +#define OUT_BUFFER 0 +#define OUT_PNG_FILE 100 +#define OUT_BMP_FILE 120 +#define OUT_GIF_FILE 140 +#define OUT_PCX_FILE 160 +#define OUT_JPG_FILE 180 +#define OUT_TIF_FILE 200 + +#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER) +#if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL) +#define ZINT_EXTERN __declspec(dllexport) +#elif defined(ZINT_DLL) +#define ZINT_EXTERN __declspec(dllimport) +#else +#define ZINT_EXTERN extern +#endif +#else +#define ZINT_EXTERN extern +#endif + + ZINT_EXTERN struct zint_symbol *ZBarcode_Create(void); + ZINT_EXTERN void ZBarcode_Clear(struct zint_symbol *symbol); + ZINT_EXTERN void ZBarcode_Delete(struct zint_symbol *symbol); + + ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *input, int length); + ZINT_EXTERN int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename); + ZINT_EXTERN int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle); + ZINT_EXTERN int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); + ZINT_EXTERN int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle); + + ZINT_EXTERN int ZBarcode_Render(struct zint_symbol *symbol, const float width, const float height); + + ZINT_EXTERN int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle); + ZINT_EXTERN int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle); + ZINT_EXTERN int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle); + + ZINT_EXTERN int ZBarcode_ValidID(int symbol_id); + ZINT_EXTERN int ZBarcode_Version(); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ZINT_H */ diff --git a/3rdparty/zint-2.6.1/backend_qt/CMakeLists.txt b/3rdparty/zint-2.6.1/backend_qt/CMakeLists.txt new file mode 100644 index 0000000..9a34e3b --- /dev/null +++ b/3rdparty/zint-2.6.1/backend_qt/CMakeLists.txt @@ -0,0 +1,21 @@ +# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > + +project(QZint) + +include_directories(BEFORE "${CMAKE_SOURCE_DIR}/backend" ) + +set(QZint_SRCS qzint.cpp) + +add_library(QZint SHARED ${QZint_SRCS}) + +set_target_properties(QZint PROPERTIES SOVERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}" + VERSION ${ZINT_VERSION}) + +add_dependencies(QZint zint) + +link_directories( "${CMAKE_BINARY_DIR}/backend" ) + +target_link_libraries(QZint zint Qt5::Widgets Qt5::Gui ) + +install(TARGETS QZint ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(FILES qzint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) diff --git a/3rdparty/zint-2.6.1/backend_qt/backend_qt.pro b/3rdparty/zint-2.6.1/backend_qt/backend_qt.pro new file mode 100644 index 0000000..63eadfd --- /dev/null +++ b/3rdparty/zint-2.6.1/backend_qt/backend_qt.pro @@ -0,0 +1,119 @@ +DEFINES += NO_PNG +TEMPLATE = lib + +contains(CONFIG, static_build){ + message(Static Build) + CONFIG += staticlib + DEFINES += HAVE_STATIC_BUILD +} + +!contains(CONFIG, staticlib){ + CONFIG += dll + DEFINES += QZINT_LIBRARY +} + +include(../../../common.pri) + +macx{ + CONFIG -= dll + CONFIG += lib_bundle +} + +unix{ + CONFIG += plugin +} + +INCLUDEPATH += $$PWD/../backend +DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$VERSION\\\" +CONFIG(release, debug|release){ + TARGET = QtZint +} else { + TARGET = QtZintd +} + +!contains(DEFINES, NO_PNG) { + SOURCES += $$PWD/../backend/png.c + LIBS += -lpng +} + + +win32-msvc* { + DEFINES += _CRT_SECURE_NO_WARNINGS + #QMAKE_CFLAGS += /TP /wd4018 /wd4244 /wd4305 + #QMAKE_CXXFLAGS += /TP /wd4018 /wd4244 /wd4305 +} + + +INCLUDEPATH += zint zint/backend zint/backend_qt + +HEADERS += $$PWD/../backend/aztec.h \ + $$PWD/../backend/bmp.h \ + $$PWD/../backend/code49.h \ + $$PWD/../backend/common.h \ + $$PWD/../backend/composite.h \ + $$PWD/../backend/dmatrix.h \ + $$PWD/../backend/eci.h \ + $$PWD/../backend/font.h \ + $$PWD/../backend/gridmtx.h \ + $$PWD/../backend/gs1.h \ + $$PWD/../backend/hanxin.h \ + $$PWD/../backend/large.h \ + $$PWD/../backend/maxicode.h \ + $$PWD/../backend/pcx.h \ + $$PWD/../backend/pdf417.h \ + $$PWD/../backend/reedsol.h \ + $$PWD/../backend/rss.h \ + $$PWD/../backend/sjis.h \ + $$PWD/../backend/stdint_msvc.h \ + $$PWD/../backend/zint.h \ + $$PWD/qzint.h + +SOURCES += $$PWD/../backend/2of5.c \ + $$PWD/../backend/auspost.c \ + $$PWD/../backend/aztec.c \ + $$PWD/../backend/bmp.c \ + $$PWD/../backend/codablock.c \ + $$PWD/../backend/code.c \ + $$PWD/../backend/code1.c \ + $$PWD/../backend/code128.c \ + $$PWD/../backend/code16k.c \ + $$PWD/../backend/code49.c \ + $$PWD/../backend/common.c \ + $$PWD/../backend/composite.c \ + $$PWD/../backend/dllversion.c \ + $$PWD/../backend/dmatrix.c \ + $$PWD/../backend/dotcode.c \ + $$PWD/../backend/eci.c \ + $$PWD/../backend/emf.c \ + $$PWD/../backend/gif.c \ + $$PWD/../backend/gridmtx.c \ + $$PWD/../backend/gs1.c \ + $$PWD/../backend/hanxin.c \ + $$PWD/../backend/imail.c \ + $$PWD/../backend/large.c \ + $$PWD/../backend/library.c \ + $$PWD/../backend/maxicode.c \ + $$PWD/../backend/medical.c \ + $$PWD/../backend/pcx.c \ + $$PWD/../backend/pdf417.c \ + $$PWD/../backend/plessey.c \ + $$PWD/../backend/png.c \ + $$PWD/../backend/postal.c \ + $$PWD/../backend/ps.c \ + $$PWD/../backend/qr.c \ + $$PWD/../backend/raster.c \ + $$PWD/../backend/reedsol.c \ + $$PWD/../backend/render.c \ + $$PWD/../backend/rss.c \ + $$PWD/../backend/svg.c \ + $$PWD/../backend/telepen.c \ + $$PWD/../backend/tif.c \ + $$PWD/../backend/upcean.c \ + $$PWD/qzint.cpp + +DESTDIR = $${DEST_LIBS} +#DLLDESTDIR = $${DESTDIR} +unix { + target.path = $${DESTDIR} + INSTALLS = target +} diff --git a/3rdparty/zint-2.6.1/backend_qt/backend_vc8.pro b/3rdparty/zint-2.6.1/backend_qt/backend_vc8.pro new file mode 100644 index 0000000..7a7a12a --- /dev/null +++ b/3rdparty/zint-2.6.1/backend_qt/backend_vc8.pro @@ -0,0 +1,71 @@ +win32 { + TEMPLATE = vclib + CONFIG += staticlib debug-and-release +} + +TARGET = QtZint2 +VERSION = 2.3.0 + +QMAKE_CFLAGS += /TP /wd4018 /wd4244 /wd4305 +QMAKE_CXXFLAGS += /TP /wd4018 /wd4244 /wd4305 + +INCLUDEPATH += ../backend d:\\opt\\include + +DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$VERSION\\\" include="" + +!contains(DEFINES, NO_PNG) { + SOURCES += ../backend/png.c +} + +HEADERS += ../backend/aztec.h \ + ../backend/code1.h \ + ../backend/code49.h \ + ../backend/common.h \ + ../backend/composite.h \ + ../backend/dmatrix.h \ + ../backend/font.h \ + ../backend/gb2312.h \ + ../backend/gridmtx.h \ + ../backend/gs1.h \ + ../backend/large.h \ + ../backend/maxicode.h \ + ../backend/maxihex.h \ + ../backend/ms_stdint.h \ + ../backend/pdf417.h \ + ../backend/qr.h \ + ../backend/reedsol.h \ + ../backend/rss.h \ + ../backend/sjis.h \ + ../backend/zint.h \ + qzint.h + +SOURCES += ../backend/2of5.c \ + ../backend/auspost.c \ + ../backend/aztec.c \ + ../backend/code.c \ + ../backend/code1.c \ + ../backend/code128.c \ + ../backend/code16k.c \ + ../backend/code49.c \ + ../backend/common.c \ + ../backend/composite.c \ + ../backend/dmatrix.c \ + ../backend/gridmtx.c \ + ../backend/gs1.c \ + ../backend/imail.c \ + ../backend/large.c \ + ../backend/library.c \ + ../backend/maxicode.c \ + ../backend/medical.c \ + ../backend/pdf417.c \ + ../backend/plessey.c \ + ../backend/postal.c \ + ../backend/ps.c \ + ../backend/qr.c \ + ../backend/reedsol.c \ + ../backend/render.c \ + ../backend/rss.c \ + ../backend/svg.c \ + ../backend/telepen.c \ + ../backend/upcean.c \ + qzint.cpp diff --git a/3rdparty/zint-2.6.1/backend_qt/qzint.cpp b/3rdparty/zint-2.6.1/backend_qt/qzint.cpp new file mode 100644 index 0000000..cec92ce --- /dev/null +++ b/3rdparty/zint-2.6.1/backend_qt/qzint.cpp @@ -0,0 +1,692 @@ +/*************************************************************************** + * Copyright (C) 2008 by BogDan Vatra * + * bogdan@licentia.eu * + * Copyright (C) 2010-2017 Robin Stuart * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "qzint.h" +#include + +namespace Zint { + + static const qreal maxi_diagonal = 11; + static const qreal maxi_width = 1.73205807568877 * maxi_diagonal / 2; + static const char* fontstyle = "Arial"; + static const int fontPixelSizeSmall = 6; + static const int fontPixelSizeLarge = 8; + + QZint::QZint() { + m_symbol = BARCODE_CODE128; + m_height = 50; + m_border = NO_BORDER; + m_borderWidth = 0; + m_securityLevel = -1; + m_pdf417CodeWords = 928; + m_fgColor = Qt::black; + m_bgColor = Qt::white; + m_zintSymbol = 0; + m_error = 0; + m_input_mode = UNICODE_MODE; + m_scale = 1.0; + m_option_3 = 0; + m_hidetext = 0; + m_dot_size = 4.0 / 5.0; + target_size_horiz = 0; + target_size_vert = 0; + m_width = 0; + m_whitespace = 0; + } + + QZint::~QZint() { + if (m_zintSymbol) + ZBarcode_Delete(m_zintSymbol); + } + + void QZint::encode() { + if (m_zintSymbol) + ZBarcode_Delete(m_zintSymbol); + + m_lastError.clear(); + m_zintSymbol = ZBarcode_Create(); + m_zintSymbol->output_options = m_border; + m_zintSymbol->symbology = m_symbol; + m_zintSymbol->height = m_height; + m_zintSymbol->whitespace_width = m_whitespace; + m_zintSymbol->border_width = m_borderWidth; + m_zintSymbol->option_1 = m_securityLevel; + m_zintSymbol->input_mode = m_input_mode; + m_zintSymbol->option_2 = m_width; + m_zintSymbol->dot_size = m_dot_size; + if (m_hidetext) { + m_zintSymbol->show_hrt = 0; + } else { + m_zintSymbol->show_hrt = 1; + } + if (m_symbol == BARCODE_PDF417) { + m_zintSymbol->option_3 = m_pdf417CodeWords; + } else { + m_zintSymbol->option_3 = m_option_3; + } + QByteArray bstr = m_text.toUtf8(); + QByteArray pstr = m_primaryMessage.left(99).toLatin1(); + strcpy(m_zintSymbol->primary, pstr.data()); + int error = ZBarcode_Encode(m_zintSymbol, (unsigned char*) bstr.data(), bstr.length()); + if (error > ZINT_WARN_INVALID_OPTION) + m_lastError = m_zintSymbol->errtxt; + + if (m_zintSymbol->symbology == BARCODE_MAXICODE) + m_zintSymbol->height = 33; + + switch (m_zintSymbol->output_options) { + case 0: m_border = NO_BORDER; + break; + case 2: m_border = BIND; + break; + case 4: m_border = BOX; + break; + } + m_borderWidth = m_zintSymbol->border_width; + m_whitespace = m_zintSymbol->whitespace_width; + } + + int QZint::symbol() { + return m_symbol; + } + + void QZint::setSymbol(int symbol) { + m_symbol = symbol; + } + + void QZint::setInputMode(int input_mode) { + m_input_mode = input_mode; + } + + QString QZint::text() { + return m_text; + } + + void QZint::setText(const QString & text) { + m_text = text; + } + + void QZint::setTargetSize(int width, int height) { + target_size_horiz = width; + target_size_vert = height; + } + + QString QZint::primaryMessage() { + return m_primaryMessage; + } + + void QZint::setPrimaryMessage(const QString & primaryMessage) { + m_primaryMessage = primaryMessage; + } + + int QZint::height() { + encode(); + return (m_zintSymbol->height + (m_border != NO_BORDER) ? m_borderWidth * 2 : 0)*(m_zintSymbol->symbology == BARCODE_MAXICODE ? (maxi_width + 1) : 1); + } + + void QZint::setHeight(int height) { + m_height = height; + } + + void QZint::setWidth(int width) { + m_width = width; + } + + void QZint::setOption3(int option) { + m_option_3 = option; + } + + int QZint::width() { + encode(); + return (m_zintSymbol->width + (m_border == BOX) ? m_borderWidth * 2 : 0)*(m_zintSymbol->symbology == BARCODE_MAXICODE ? (maxi_width + 1) : 1); + } + + float QZint::scale() { + return m_scale; + } + + void QZint::setScale(float scale) { + m_scale = scale; + } + + void QZint::setDotSize(float dot_size) { + m_dot_size = dot_size; + } + + QColor QZint::fgColor() { + return m_fgColor; + } + + void QZint::setFgColor(const QColor & fgColor) { + m_fgColor = fgColor; + } + + QColor QZint::bgColor() { + return m_bgColor; + } + + void QZint::setBgColor(const QColor & bgColor) { + m_bgColor = bgColor; + } + + QZint::BorderType QZint::borderType() { + return m_border; + } + + void QZint::setBorderType(BorderType border) { + m_border = border; + } + + int QZint::borderWidth() { + return m_borderWidth; + } + + void QZint::setBorderWidth(int boderWidth) { + if (boderWidth < 0 || boderWidth > 16) + boderWidth = 0; + m_borderWidth = boderWidth; + } + + void QZint::setWhitespace(int whitespace) { + m_whitespace = whitespace; + } + + int QZint::pdf417CodeWords() { + return m_pdf417CodeWords; + } + + void QZint::setPdf417CodeWords(int pdf417CodeWords) { + m_pdf417CodeWords = pdf417CodeWords; + } + + int QZint::securityLevel() { + return m_securityLevel; + } + + void QZint::setSecurityLevel(int securityLevel) { + m_securityLevel = securityLevel; + } + + QString QZint::error_message() { + return m_lastError; + } + + int QZint::mode() { + return m_securityLevel; + } + + void QZint::setMode(int securityLevel) { + m_securityLevel = securityLevel; + } + + void QZint::setHideText(bool hide) { + m_hidetext = hide; + } + + bool QZint::save_to_file(QString filename) { + if (m_zintSymbol) + ZBarcode_Delete(m_zintSymbol); + + QString fg_colour_hash = m_fgColor.name(); + QString bg_colour_hash = m_bgColor.name(); + + m_lastError.clear(); + m_zintSymbol = ZBarcode_Create(); + m_zintSymbol->output_options = m_border; + m_zintSymbol->symbology = m_symbol; + m_zintSymbol->height = m_height; + m_zintSymbol->whitespace_width = m_whitespace; + m_zintSymbol->border_width = m_borderWidth; + m_zintSymbol->option_1 = m_securityLevel; + m_zintSymbol->input_mode = m_input_mode; + m_zintSymbol->option_2 = m_width; + m_zintSymbol->dot_size = m_dot_size; + if (m_hidetext) { + m_zintSymbol->show_hrt = 0; + } else { + m_zintSymbol->show_hrt = 1; + } + if (m_symbol == BARCODE_PDF417) { + m_zintSymbol->option_3 = m_pdf417CodeWords; + } else { + m_zintSymbol->option_3 = m_option_3; + } + m_zintSymbol->scale = m_scale; + QByteArray bstr = m_text.toUtf8(); + QByteArray pstr = m_primaryMessage.left(99).toLatin1(); + QByteArray fstr = filename.left(255).toLatin1(); + strcpy(m_zintSymbol->primary, pstr.data()); + strcpy(m_zintSymbol->outfile, fstr.data()); + QByteArray fgcol = fg_colour_hash.right(6).toLatin1(); + QByteArray bgcol = bg_colour_hash.right(6).toLatin1(); + strcpy(m_zintSymbol->fgcolour, fgcol.data()); + strcpy(m_zintSymbol->bgcolour, bgcol.data()); + int error = ZBarcode_Encode_and_Print(m_zintSymbol, (unsigned char*) bstr.data(), bstr.length(), 0); + if (error > ZINT_WARN_INVALID_OPTION) { + m_lastError = m_zintSymbol->errtxt; + } + if (error == 0) { + return true; + } else { + return false; + } + } + + int QZint::module_set(int y_coord, int x_coord) { + int x_char, x_sub, result; + + x_char = x_coord / 7; + x_sub = x_coord % 7; + result = 0; + + if (m_zintSymbol->encoded_data[y_coord][x_char] & (0x01 << x_sub)) { + result = 1; + } + + return result; + } + + void QZint::render(QPainter & painter, const QRectF & paintRect) { + bool textdone; + int comp_offset = 0; + int xoffset = m_whitespace; + int j, main_width = 0, addon_text_height = 0; + int yoffset = 0; + + encode(); + + QString caption = QString::fromUtf8((const char *) m_zintSymbol->text, -1); + QFont fontSmall(fontstyle); + fontSmall.setPixelSize(fontPixelSizeSmall); + QFont fontLarge(fontstyle); + fontLarge.setPixelSize(fontPixelSizeLarge); + + if (m_lastError.length()) { + fontLarge.setPointSize(14); + painter.setFont(fontLarge); + painter.drawText(paintRect, Qt::AlignCenter, m_lastError); + return; + } + + painter.save(); + painter.setClipRect(paintRect, Qt::IntersectClip); + + qreal xtr = paintRect.x(); + qreal ytr = paintRect.y(); + + int zrow_height = m_zintSymbol->height; + int zrows = 0; + for (int i = 0; i < m_zintSymbol->rows; i++) { + zrow_height -= m_zintSymbol->row_height[i]; + if (!m_zintSymbol->row_height[i]) + zrows++; + } + if (zrows) { + zrow_height /= zrows; + for (int i = 0; i < m_zintSymbol->rows; i++) + if (!m_zintSymbol->row_height[i]) + m_zintSymbol->row_height[i] = zrow_height; + } else + m_zintSymbol->height -= zrow_height; + + + qreal gwidth = m_zintSymbol->width; + qreal gheight = m_zintSymbol->height; + if (m_zintSymbol->symbology == BARCODE_MAXICODE) { + gwidth = (33.0 * maxi_width); + gheight = (32.0 * maxi_width); + } + + if (m_zintSymbol->output_options & BARCODE_DOTTY_MODE) { + gwidth += 2.0; + gheight += 2.0; + } + + qreal xsf = 1; + qreal ysf = 1; + qreal textoffset = 0; + + gwidth += ((m_border == BOX) ? m_borderWidth * 2 : 0); + gheight += ((m_border != NO_BORDER) ? m_borderWidth * 2 : 0); + if (QString((const char*) m_zintSymbol->text).isEmpty() == false) { + textoffset = 9; + gheight += textoffset; + } else { + textoffset = 0; + } + gwidth += m_zintSymbol->whitespace_width * 2; + + if (paintRect.width() / gwidth < paintRect.height() / gheight) { + ysf = xsf = (qreal) paintRect.width() / gwidth; + ytr += (qreal) (paintRect.height() - gheight * ysf) / 2; + } else { + ysf = xsf = (qreal) paintRect.height() / gheight; + xtr += (qreal) (paintRect.width() - gwidth * xsf) / 2; + } + + painter.setBackground(QBrush(m_bgColor)); + painter.fillRect(paintRect, QBrush(m_bgColor)); + painter.translate(xtr, ytr); + painter.scale(xsf, ysf); + + QPen p; + + p.setColor(m_fgColor); + p.setWidth(m_borderWidth); + painter.setPen(p); + + if (m_zintSymbol->symbology != BARCODE_MAXICODE) { + /* Draw boundary bars or boxes around the symbol */ + switch (m_border) { + case BOX: + painter.fillRect(0, m_borderWidth, m_borderWidth, m_zintSymbol->height, QBrush(m_fgColor)); + painter.fillRect(m_zintSymbol->width + m_zintSymbol->whitespace_width + m_zintSymbol->whitespace_width + m_borderWidth, m_borderWidth, m_borderWidth, m_zintSymbol->height, QBrush(m_fgColor)); + painter.fillRect(0, 0, m_zintSymbol->width + m_zintSymbol->whitespace_width + m_zintSymbol->whitespace_width + m_borderWidth + m_borderWidth, m_borderWidth, QBrush(m_fgColor)); + painter.fillRect(0, m_zintSymbol->height + m_borderWidth, m_zintSymbol->width + m_zintSymbol->whitespace_width + m_zintSymbol->whitespace_width + m_borderWidth + m_borderWidth, m_borderWidth, QBrush(m_fgColor)); + painter.translate(m_borderWidth + m_zintSymbol->whitespace_width, m_borderWidth); + yoffset = m_borderWidth; + break; + case BIND: + if (m_zintSymbol->symbology != BARCODE_CODABLOCKF) { + painter.fillRect(0, 0, m_zintSymbol->width + m_zintSymbol->whitespace_width + m_zintSymbol->whitespace_width, m_borderWidth, QBrush(m_fgColor)); + painter.fillRect(0, m_zintSymbol->height, m_zintSymbol->width + m_zintSymbol->whitespace_width + m_zintSymbol->whitespace_width, m_borderWidth, QBrush(m_fgColor)); + } else { + painter.fillRect(m_zintSymbol->whitespace_width, 0, m_zintSymbol->width, m_borderWidth, QBrush(m_fgColor)); + painter.fillRect(m_zintSymbol->whitespace_width, m_zintSymbol->height, m_zintSymbol->width, m_borderWidth, QBrush(m_fgColor)); + } + painter.translate(m_zintSymbol->whitespace_width, m_borderWidth); + yoffset = m_borderWidth; + break; + + default: + painter.translate(m_zintSymbol->whitespace_width, 0); + break; + } + } + + while (!(module_set(m_zintSymbol->rows - 1, comp_offset))) { + comp_offset++; + } + xoffset = comp_offset; + + /* Set up some values for displaying EAN and UPC symbols correctly */ + main_width = m_zintSymbol->width; + if ((((m_zintSymbol->symbology == BARCODE_EANX) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) + || (m_zintSymbol->symbology == BARCODE_ISBNX)) { + switch (caption.size()) { + case 13: /* EAN 13 */ + case 16: + case 19: + if (m_zintSymbol->whitespace_width == 0) { + m_zintSymbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + break; + default: + main_width = 68 + comp_offset; + break; + } + } + + if (((m_zintSymbol->symbology == BARCODE_UPCA) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) { + if (m_zintSymbol->whitespace_width == 0) { + m_zintSymbol->whitespace_width = 10; + } + main_width = 96 + comp_offset; + } + + if (((m_zintSymbol->symbology == BARCODE_UPCE) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) { + if (m_zintSymbol->whitespace_width == 0) { + m_zintSymbol->whitespace_width = 10; + } + main_width = 51 + comp_offset; + } + + p.setWidth(1); + painter.setPen(p); + + if (m_zintSymbol->symbology == BARCODE_MAXICODE) { + /* Draw Maxicode with hexagons */ + painter.save(); + painter.setRenderHint(QPainter::Antialiasing); + for (int r = 0; r < m_zintSymbol->rows; r++) { + for (int c = 0; c < m_zintSymbol->width; c++) { + if (module_set(r, c)) { + qreal col = (qreal) c * (maxi_width + 1)+(r % 2)*((maxi_width + 1) / 2); + qreal row = (qreal) r * (maxi_width + 1)*0.868; + QPainterPath pt; + pt.moveTo(col + maxi_width / 2, row); + pt.lineTo(col + maxi_width, row + maxi_diagonal / 4); + pt.lineTo(col + maxi_width, row + (maxi_diagonal - maxi_diagonal / 4)); + pt.lineTo(col + maxi_width / 2, row + maxi_diagonal); + pt.lineTo(col, row + (maxi_diagonal - maxi_diagonal / 4)); + pt.lineTo(col, row + maxi_diagonal / 4); + pt.lineTo(col + maxi_width / 2, row); + painter.fillPath(pt, QBrush(m_fgColor)); + } + } + } + p.setWidth(maxi_width); + painter.setPen(p); + const qreal w = maxi_width + 1; + painter.drawEllipse(QPointF(14.5 * w, 16.5 * w * 0.868), w, w); + painter.drawEllipse(QPointF(14.5 * w, 16.5 * w * 0.868), w + w * 1.5, w + w * 1.5); + painter.drawEllipse(QPointF(14.5 * w, 16.5 * w * 0.868), w + w * 3, w + w * 3); + painter.restore(); + } else if (m_zintSymbol->output_options & BARCODE_DOTTY_MODE) { + /* Draw with dots (circles) */ + + p.setColor(m_fgColor); + p.setWidth(0); + painter.setPen(p); + painter.setBrush(QBrush(m_fgColor)); + painter.setRenderHint(QPainter::Antialiasing); + for (int r = 0; r < m_zintSymbol->rows; r++) { + for (int c = 0; c < m_zintSymbol->width; c++) { + if (module_set(r, c)) { + + painter.drawEllipse(QPointF((c + 1.0), (r + 1.0)), m_dot_size / 2.0, m_dot_size / 2.0); + } + } + } + } else { + /* Draw all other symbols with rectangles */ + int y = 0; + for (int row = 0; row < m_zintSymbol->rows; row++) { + for (int i = 0; i < m_zintSymbol->width; i++) { + if (module_set(row, i)) { + int ed = module_set(row, i); + int linewidth = 0; + for (int j = i; j < m_zintSymbol->width; j++, linewidth++) + if (ed != module_set(row, j)) + break; + QColor color; + color = m_fgColor; + + if (!((i > main_width) && (row == m_zintSymbol->rows - 1))) { + painter.fillRect(i, y, linewidth, m_zintSymbol->row_height[row], QBrush(color)); + } else { + painter.fillRect(i, y + 8, linewidth, m_zintSymbol->row_height[row] - 3, QBrush(color)); + addon_text_height = y; + } + } + } + /* Add row binding */ + if (((m_zintSymbol->symbology == BARCODE_CODE16K) + || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) { + painter.fillRect(0, y - 1, m_zintSymbol->width, 2, QBrush(m_fgColor)); + } + if ((m_zintSymbol->symbology == BARCODE_CODABLOCKF) && (row != 0)) { + painter.fillRect(11, y - 1, m_zintSymbol->width - 25, 2, QBrush(m_fgColor)); + } + y += m_zintSymbol->row_height[row]; + } + } + + textdone = false; + + if (m_hidetext == false) { + painter.setFont(fontSmall); + if (((m_zintSymbol->symbology == BARCODE_EANX) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) || + (m_zintSymbol->symbology == BARCODE_ISBNX)) { + /* Add bridge and format text for EAN */ + switch (caption.size()) { + case 8: + case 11: + case 14: + painter.fillRect(0 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(2 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(32 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(34 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(64 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(66 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.setFont(fontLarge); + painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 29, 9, Qt::AlignCenter, caption.mid(0, 4)); + painter.drawText(35 + xoffset, m_zintSymbol->height + yoffset, 29, 9, Qt::AlignCenter, caption.mid(4, 4)); + if (caption.size() == 11) { + /* EAN-2 */ painter.drawText(76 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(9, 2)); + }; + if (caption.size() == 14) { + /* EAN-5 */ painter.drawText(76 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(9, 5)); + }; + painter.setFont(fontSmall); + textdone = true; + break; + case 13: + case 16: + case 19: + painter.fillRect(0 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(2 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(46 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(48 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(92 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(94 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.setFont(fontLarge); + painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 9, Qt::AlignCenter, caption.mid(0, 1)); + painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9, Qt::AlignCenter, caption.mid(1, 6)); + painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 43, 9, Qt::AlignCenter, caption.mid(7, 6)); + if (caption.size() == 16) { + /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(14, 2)); + }; + if (caption.size() == 19) { + /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(14, 5)); + }; + painter.setFont(fontSmall); + textdone = true; + break; + } + if (textdone == false) { + painter.setFont(fontLarge); + painter.drawText(0, m_zintSymbol->height, m_zintSymbol->width, 9, Qt::AlignCenter, caption); + painter.setFont(fontSmall); + textdone = true; + } + } + + if ((m_zintSymbol->symbology == BARCODE_UPCA) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) { + /* Add bridge and format text for UPC-A */ + int block_width; + bool latch = true; + + j = 0 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j)); + if (latch == true) { + /* a bar */ + painter.fillRect(j + xoffset - comp_offset, m_zintSymbol->height, block_width, 5, QBrush(m_fgColor)); + latch = false; + } else { + /* a space */ + latch = true; + } + j += block_width; + } while (j < 11 + comp_offset); + painter.fillRect(46 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(48 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + latch = true; + j = 85 + comp_offset; + do { + block_width = 0; + do { + block_width++; + } while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j)); + if (latch == true) { + /* a bar */ + painter.fillRect(j + xoffset - comp_offset, m_zintSymbol->height, block_width, 5, QBrush(m_fgColor)); + latch = false; + } else { + /* a space */ + latch = true; + } + j += block_width; + } while (j < 96 + comp_offset); + painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(0, 1)); + painter.drawText(96 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(11, 1)); + painter.setFont(fontLarge); + painter.drawText(11 + xoffset, m_zintSymbol->height + yoffset, 35, 9, Qt::AlignCenter, caption.mid(1, 5)); + painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 35, 9, Qt::AlignCenter, caption.mid(6, 5)); + if (caption.size() == 15) { + /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(13, 2)); + }; + if (caption.size() == 18) { + /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(13, 5)); + }; + painter.setFont(fontSmall); + textdone = true; + } + + if ((m_zintSymbol->symbology == BARCODE_UPCE) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) { + /* Add bridge and format text for UPC-E */ + painter.fillRect(0 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(2 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(46 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(48 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.fillRect(50 + xoffset, m_zintSymbol->height, 1, 5, QBrush(m_fgColor)); + painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(0, 1)); + painter.drawText(51 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7, Qt::AlignCenter, caption.mid(7, 1)); + painter.setFont(fontLarge); + painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9, Qt::AlignCenter, caption.mid(1, 6)); + if (caption.size() == 11) { + /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 20, 9, Qt::AlignCenter, caption.mid(9, 2)); + }; + if (caption.size() == 14) { + /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 47, 9, Qt::AlignCenter, caption.mid(9, 5)); + }; + painter.setFont(fontSmall); + textdone = true; + } + } /* if (m_hidetext == false) */ + + if ((m_hidetext == false) && (textdone == false)) { + /* Add text to any other symbol */ + painter.drawText(0, m_zintSymbol->height + yoffset, m_zintSymbol->width, 7, Qt::AlignCenter, caption); + } + painter.restore(); + } + + const QString & QZint::lastError() { + return m_lastError; + } + + bool QZint::hasErrors() { + return m_lastError.length(); + } + +} diff --git a/3rdparty/zint-2.4.4/backend_qt4/qzint.h b/3rdparty/zint-2.6.1/backend_qt/qzint.h similarity index 92% rename from 3rdparty/zint-2.4.4/backend_qt4/qzint.h rename to 3rdparty/zint-2.6.1/backend_qt/qzint.h index cf11a04..70b5acc 100644 --- a/3rdparty/zint-2.4.4/backend_qt4/qzint.h +++ b/3rdparty/zint-2.6.1/backend_qt/qzint.h @@ -16,15 +16,14 @@ #ifndef BARCODERENDER_H #define BARCODERENDER_H - -#include "qzint_global.h" #include #include +#include "qzint_global.h" +#include "zint.h" namespace Zint { -#include "zint.h" class QZINTSHARED_EXPORT QZint { @@ -75,6 +74,8 @@ public: float scale(); void setScale(float scale); + + void setDotSize(float dot_size); int mode(); void setMode(int securityLevel); @@ -85,7 +86,7 @@ public: QString error_message(); - void render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode=IgnoreAspectRatio); + void render(QPainter & painter, const QRectF & paintRect); const QString & lastError(); bool hasErrors(); @@ -93,6 +94,8 @@ public: bool save_to_file(QString filename); void setHideText(bool hide); + + void setTargetSize(int width, int height); private: void encode(); @@ -118,9 +121,9 @@ private: float m_scale; int m_option_3; bool m_hidetext; + float m_dot_size; + int target_size_horiz; + int target_size_vert; }; } - -extern "C" QZINTSHARED_EXPORT Zint::QZint* createWidget(); - #endif diff --git a/3rdparty/zint-2.4.4/backend_qt4/qzint_global.h b/3rdparty/zint-2.6.1/backend_qt/qzint_global.h similarity index 76% rename from 3rdparty/zint-2.4.4/backend_qt4/qzint_global.h rename to 3rdparty/zint-2.6.1/backend_qt/qzint_global.h index ea46fe2..025b16e 100644 --- a/3rdparty/zint-2.4.4/backend_qt4/qzint_global.h +++ b/3rdparty/zint-2.6.1/backend_qt/qzint_global.h @@ -3,14 +3,10 @@ #include -#ifdef HAVE_STATIC_BUILD -# define QZINTSHARED_EXPORT /**/ -#else #if defined(QZINT_LIBRARY) # define QZINTSHARED_EXPORT Q_DECL_EXPORT #else # define QZINTSHARED_EXPORT Q_DECL_IMPORT #endif -#endif #endif // QZINT_GLOBAL_H diff --git a/3rdparty/zint-2.6.1/backend_qt/readme b/3rdparty/zint-2.6.1/backend_qt/readme new file mode 100644 index 0000000..2ec3a7d --- /dev/null +++ b/3rdparty/zint-2.6.1/backend_qt/readme @@ -0,0 +1,9 @@ +Edit zint-1.6.pro and edit the 'DEFINES' section + NO_PNG -> compile zint without png support + NO_QR -> compile zint without QR support + QR_SYSTEM -> if you have QT installed in your system, zint will be compiled with QT support + QR -> compile zint with QR support static (you must have qrencode in the current folder) + +Edit compile_n_config and set the paths. + +Exec compile_n_config diff --git a/common.pri b/common.pri index 556482b..e4c3616 100644 --- a/common.pri +++ b/common.pri @@ -13,21 +13,64 @@ message(TOP_BUILD_DIR: $$TOP_BUILD_DIR) !contains(CONFIG, no_build_translations){ CONFIG += build_translations } +#CONFIG *= easy_profiler !contains(CONFIG, no_zint){ - CONFIG += zint + CONFIG *= zint } -ZINT_PATH = $$PWD/3rdparty/zint-2.4.4 +INCLUDEPATH += $$PWD/3rdparty/easyprofiler/easy_profiler_core/include +DEPENDPATH += $$PWD/3rdparty/easyprofiler/easy_profiler_core/include + +contains(CONFIG, easy_profiler){ + message(EasyProfiler) + unix|win32: LIBS += -L$$PWD/3rdparty/easyprofiler/build/bin/ -leasy_profiler + greaterThan(QT_MAJOR_VERSION, 4){ + DEFINES += BUILD_WITH_EASY_PROFILER + } +} + +!contains(CONFIG, qtscriptengine){ +greaterThan(QT_MAJOR_VERSION, 4){ +greaterThan(QT_MINOR_VERSION, 5){ + CONFIG *= qjsengine +} +lessThan(QT_MINOR_VERSION, 6){ + CONFIG *= qtscriptengine +} +} +lessThan(QT_MAJOR_VERSION, 5){ + CONFIG *= qtscriptengine +} +} + +contains(CONFIG, qtscriptengine){ + CONFIG -= qjsengine + QT *= script + DEFINES *= USE_QTSCRIPTENGINE + message(qtscriptengine) +} + +!contains(CONFIG, no_formdesigner){ + CONFIG *= dialogdesigner +} + +!contains(CONFIG, no_embedded_designer){ + CONFIG *= embedded_designer + DEFINES += HAVE_REPORT_DESIGNER +} + +ZINT_PATH = $$PWD/3rdparty/zint-2.6.1 contains(CONFIG,zint){ - DEFINES += HAVE_ZINT + DEFINES *= HAVE_ZINT } greaterThan(QT_MAJOR_VERSION, 4) { - QT += uitools + QT *= uitools } + lessThan(QT_MAJOR_VERSION, 5){ - CONFIG += uitools + CONFIG *= uitools } CONFIG(release, debug|release){ @@ -83,30 +126,35 @@ OBJECTS_DIR = $${ARCH_DIR}/$${BUILD_TYPE}/obj RCC_DIR = $${ARCH_DIR}/$${BUILD_TYPE}/rcc LIMEREPORT_VERSION_MAJOR = 1 -LIMEREPORT_VERSION_MINOR = 4 -LIMEREPORT_VERSION_RELEASE = 136 +LIMEREPORT_VERSION_MINOR = 5 +LIMEREPORT_VERSION_RELEASE = 0 -LIMEREPORT_VERSION = '\\"$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}\\"' -DEFINES += LIMEREPORT_VERSION_STR=\"$${LIMEREPORT_VERSION}\" -DEFINES += LIMEREPORT_VERSION=$${LIMEREPORT_VERSION} +LIMEREPORT_VERSION = '$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}' +DEFINES *= LIMEREPORT_VERSION_STR=\\\"$${LIMEREPORT_VERSION}\\\" + +QT *= xml sql -QT += script xml sql REPORT_PATH = $$PWD/limereport TRANSLATIONS_PATH = $$PWD/translations greaterThan(QT_MAJOR_VERSION, 4) { - DEFINES+=HAVE_QT5 - QT+= printsupport widgets + DEFINES *= HAVE_QT5 + QT *= printsupport widgets contains(QT,uitools){ message(uitools) - DEFINES += HAVE_UI_LOADER + DEFINES *= HAVE_UI_LOADER + } + contains(CONFIG, qjsengine){ + message(qjsengine) + DEFINES *= USE_QJSENGINE + QT *= qml } } lessThan(QT_MAJOR_VERSION, 5){ - DEFINES+=HAVE_QT4 + DEFINES *= HAVE_QT4 CONFIG(uitools){ message(uitools) - DEFINES += HAVE_UI_LOADER + DEFINES *= HAVE_UI_LOADER } } diff --git a/console/console.pro b/console/console.pro new file mode 100644 index 0000000..cea280f --- /dev/null +++ b/console/console.pro @@ -0,0 +1,35 @@ +include(../common.pri) +QT += core +QT -= gui + +TARGET = limereport +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app +SOURCES += main.cpp + +DEFINES += QT_DEPRECATED_WARNINGS + +DESTDIR = $${DEST_BINS} + +INCLUDEPATH += $$PWD/../include +DEPENDPATH += $$PWD/../include + +LIBS += -L$${DEST_LIBS} + +CONFIG(debug, debug|release) { + LIBS += -llimereportd +} else { + LIBS += -llimereport +} +!contains(CONFIG, static_build){ + contains(CONFIG,zint){ + LIBS += -L$${DEST_LIBS} + CONFIG(debug, debug|release) { + LIBS += -lQtZintd + } else { + LIBS += -lQtZint + } + } +} diff --git a/console/main.cpp b/console/main.cpp new file mode 100644 index 0000000..764fc36 --- /dev/null +++ b/console/main.cpp @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 + #include + #include +#endif + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + QApplication::setApplicationVersion(LIMEREPORT_VERSION_STR); + QStringList vars; + +#if QT_VERSION > QT_VERSION_CHECK(5, 2, 0) + QCommandLineParser parser; + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption sourceOption(QStringList() << "s" << "source", + QCoreApplication::translate("main", "Limereport pattern file name"), + QCoreApplication::translate("main", "source")); + parser.addOption(sourceOption); + QCommandLineOption destinationOption(QStringList() << "d" << "destination", + QCoreApplication::translate("main", "Output file name"), + QCoreApplication::translate("main", "destination")); + parser.addOption(destinationOption); + QCommandLineOption variablesOption(QStringList() << "p" << "param", + QCoreApplication::translate("main", "Report parameter (can be more than one)"), + QCoreApplication::translate("main", "param_name=param_value")); + parser.addOption(variablesOption); + parser.process(a); + + LimeReport::ReportEngine report; + + if (parser.value(sourceOption).isEmpty()){ + std::cerr<<"Error! Report file is not specified !! \n"; + return 1; + } + + if (!report.loadFromFile(parser.value(sourceOption))){ + std::cerr<<"Error! Report file \""+parser.value(sourceOption).toStdString()+"\" not found \n"; + return 1; + } + + if (!parser.values(variablesOption).isEmpty()){ + foreach(QString var, parser.values(variablesOption)){ + QStringList varItem = var.split("="); + if (varItem.size() == 2) + report.dataManager()->setReportVariable(varItem.at(0),varItem.at(1)); + } + } + + if (parser.value(destinationOption).isEmpty()){ + report.printToPDF(QFileInfo(parser.value(sourceOption)).baseName()); + } else { + report.printToPDF(parser.value(destinationOption)); + } +#else + std::cerr<<"This demo intended for Qt 5.2 and higher\n"; +#endif +// QUuid uid = QUuid::createUuid(); +// QString uidStr = uid.toString()+".pdf"; +// report.printToPDF(uidStr); +// QFile in(uidStr); +// QFile out; +// out.open(stdout, QFile::WriteOnly); +// in.open(QIODevice::ReadOnly); +//#ifdef _WIN32 +// _setmode(fileno(stdout),O_BINARY); +//#endif +// QByteArray buffer = in.readAll(); +// fwrite(buffer,1,buffer.size(),stdout); +// in.close(); +// in.remove(); + + return 0; + //return a.exec(); +} diff --git a/demo_r1/demo_r1.pro b/demo_r1/demo_r1.pro index 8c09816..ddaa50d 100644 --- a/demo_r1/demo_r1.pro +++ b/demo_r1/demo_r1.pro @@ -1,7 +1,12 @@ include(../common.pri) QT += core gui -TARGET = LRDemo_r1 +CONFIG(release, debug|release) { + TARGET = LRDemo_r1 +} else { + TARGET = LRDemo_r1d +} + TEMPLATE = app SOURCES += main.cpp\ @@ -26,7 +31,6 @@ macx{ } unix:{ - DESTDIR = $$DEST_DIR # QMAKE_POST_LINK += mkdir -p $$quote($$REPORTS_DIR) | QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$quote($$EXTRA_DIR) $$quote($$REPORTS_DIR) $$escape_expand(\n\t) @@ -52,8 +56,14 @@ win32 { REPORTS_DIR ~= s,/,\\,g RC_FILE += mainicon.rc - - QMAKE_POST_LINK += $$QMAKE_COPY_DIR \"$$EXTRA_DIR\" \"$$REPORTS_DIR\\demo_reports\" $$escape_expand(\\n\\t) + + greaterThan(QT_MAJOR_VERSION, 4) { + QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$shell_quote($$EXTRA_DIR\\*) $$shell_quote($$REPORTS_DIR\\demo_reports) $$escape_expand(\\n\\t) + } + lessThan(QT_MAJOR_VERSION, 5){ + QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$quote($$EXTRA_DIR\\*) $$quote($$REPORTS_DIR\\demo_reports) $$escape_expand(\\n\\t) + } + #QMAKE_POST_LINK += $$QMAKE_COPY_DIR \"$$EXTRA_DIR\" \"$$REPORTS_DIR\\demo_reports\" $$escape_expand(\\n\\t) #QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$quote($$EXTRA_DIR\\*) $$quote($$REPORTS_DIR\\demo_reports) $$escape_expand(\\n\\t) } } @@ -64,7 +74,7 @@ CONFIG(debug, debug|release) { } else { LIBS += -llimereport } - +message($$LIBS) !contains(CONFIG, static_build){ contains(CONFIG,zint){ diff --git a/demo_r1/demo_reports/1.4/1_simple_list.lrxml b/demo_r1/demo_reports/1.4/1_simple_list.lrxml new file mode 100644 index 0000000..7eb6add --- /dev/null +++ b/demo_r1/demo_reports/1.4/1_simple_list.lrxml @@ -0,0 +1,656 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + DataBand1 + + + + TextItem2 + + + + + DataBand1 + + + + + + + $D{customers.Company} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem3 + + + + + DataBand1 + + + + + + + $D{customers.Addr1} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem4 + + + + + DataBand1 + + + + + + + $D{customers.Contact} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem5 + + + + + DataBand1 + + + + + + + $D{customers.Phone} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem6 + + + + + DataBand1 + + + + + + + $D{customers.FAX} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + customers + + + + + + + + + + + + DataHeaderBand1 + + + + TextItem7 + + + + + DataHeaderBand1 + + + + + + + Company + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem8 + + + + + DataHeaderBand1 + + + + + + + Address + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem9 + + + + + DataHeaderBand1 + + + + + + + Contact + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem10 + + + + + DataHeaderBand1 + + + + + + + Phone + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem11 + + + + + DataHeaderBand1 + + + + + + + Fax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + + + + + + + + ReportHeader1 + + + + TextItem1 + + + + + ReportHeader1 + + + + + + + Customers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + PageFooter11 + + + + ShapeItem11 + + + + + PageFooter11 + + + + + + + + + + + + + + + + + TextItem12 + + + + + PageFooter11 + + + + + + + Page $V{#PAGE} of $V{#PAGE_COUNT} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + db + QSQLITE + ./demo_reports/demo_db.db + + + + + + + + + + + customers + Select * from customer + db + + + + + + + + + + + + + + diff --git a/demo_r1/demo_reports/1.4/2_simple_group.lrxml b/demo_r1/demo_reports/1.4/2_simple_group.lrxml new file mode 100644 index 0000000..fc47597 --- /dev/null +++ b/demo_r1/demo_reports/1.4/2_simple_group.lrxml @@ -0,0 +1,801 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + DataBand1 + + + + TextItem2 + + + + + DataBand1 + + + + + + + $D{customers.Company} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem3 + + + + + DataBand1 + + + + + + + $D{customers.Addr1} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem4 + + + + + DataBand1 + + + + + + + $D{customers.Contact} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem5 + + + + + DataBand1 + + + + + + + $D{customers.Phone} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem6 + + + + + DataBand1 + + + + + + + $D{customers.FAX} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + customers + + + + + + + + + + + + DataHeaderBand1 + + + + TextItem7 + + + + + DataHeaderBand1 + + + + + + + Company + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem8 + + + + + DataHeaderBand1 + + + + + + + Address + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem9 + + + + + DataHeaderBand1 + + + + + + + Contact + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem10 + + + + + DataHeaderBand1 + + + + + + + Phone + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem11 + + + + + DataHeaderBand1 + + + + + + + Fax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + + + + + + + + ReportHeader1 + + + + TextItem1 + + + + + ReportHeader1 + + + + + + + Customers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + PageFooter11 + + + + ShapeItem11 + + + + + PageFooter11 + + + + + + + + + + + + + + + + + TextItem12 + + + + + PageFooter11 + + + + + + + Page $V{#PAGE} of $V{#PAGE_COUNT} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + + GroupBandHeader1 + + + + TextItem13 + + + + + GroupBandHeader1 + + + + + + + $S{$D{customers.Company}.substring(0,1).toUpperCase();} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + + + + + + + $S{$D{customers.Company}.substring(0,1).toUpperCase();} + + + GroupBandFooter13 + + + + TextItem14 + + + + + GroupBandFooter13 + + + + + + + Count: $S{COUNT("DataBand1")} + + + + + + + + + + + + + + + + + + + + + + + + + + + ShapeItem1 + + + + + GroupBandFooter13 + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + GroupBandHeader1 + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + db + QSQLITE + ./demo_reports/demo_db.db + + + + + + + + + + + customers + Select * from customer order by Company + db + + + + + + + + + + + + + + diff --git a/demo_r1/demo_reports/1.4/3_memos_and_pictures.lrxml b/demo_r1/demo_reports/1.4/3_memos_and_pictures.lrxml new file mode 100644 index 0000000..883feae --- /dev/null +++ b/demo_r1/demo_reports/1.4/3_memos_and_pictures.lrxml @@ -0,0 +1,286 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + ReportHeader1 + + + + TextItem1 + + + + + ReportHeader1 + + + + + + + Fishes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + DataBand1 + + + + TextItem2 + + + + + DataBand1 + + + + + + + Number: $D{bio.Species_No} +Name: $D{bio.Common_Name} +Spec name: $D{bio.Species_Name} +Length (cm): $D{bio.Length_cm} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem3 + + + + + DataBand1 + + + + + + + $D{bio.Notes} + + + + + + + + + + + + + + + + + + + + + + + + + + + ImageItem3 + + + + + DataBand1 + + + + + + + + + bio + Graphic + + + +
+ + + + ShapeItem3 + + + + + DataBand1 + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + bio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + db + QSQLITE + ./demo_reports/demo_db.db + + + + + + + + + + + bio + Select * from biolife + db + + + + + + + + + + + + + + diff --git a/demo_r1/demo_reports/1.4/4_nested_group.lrxml b/demo_r1/demo_reports/1.4/4_nested_group.lrxml new file mode 100644 index 0000000..0d7e59c --- /dev/null +++ b/demo_r1/demo_reports/1.4/4_nested_group.lrxml @@ -0,0 +1,1155 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + DataBand1 + + + + HorizontalLayout23 + + + + TextItem2 + + + + + HorizontalLayout23 + + + + + + + $D{sales.PartNo} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem3 + + + + + HorizontalLayout23 + + + + + + + $D{sales.Description} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem4 + + + + + HorizontalLayout23 + + + + + + + $S{numberFormat($D{sales.ListPrice})} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem5 + + + + + HorizontalLayout23 + + + + + + + $D{sales.Qty} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem6 + + + + + HorizontalLayout23 + + + + + + + $S{numberFormat($D{sales.Qty}*$D{sales.ListPrice})} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DataBand1 + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + sales + + + + + + + + + + + + GroupBandHeader1 + + + + HorizontalLayout14 + + + + TextItem12 + + + + + HorizontalLayout14 + + + + + + + $D{sales.Company} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem13 + + + + + HorizontalLayout14 + + + + + + + $D{sales.Phone} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem14 + + + + + HorizontalLayout14 + + + + + + + $D{sales.FAX} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GroupBandHeader1 + + + + + + + + + + HorizontalLayout15 + + + + TextItem9 + + + + + HorizontalLayout15 + + + + + + + Company + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem10 + + + + + HorizontalLayout15 + + + + + + + Phone + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem11 + + + + + HorizontalLayout15 + + + + + + + Fax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GroupBandHeader1 + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + CustNo + + + + + + + + + GroupBandHeader2 + + + + HorizontalLayout16 + + + + TextItem7 + + + + + HorizontalLayout16 + + + + + + + $D{sales.OrderNo} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem15 + + + + + HorizontalLayout16 + + + + + + + $D{sales.SaleDate} + + + + + + + + + + + + + + + + + + + dd.MM.yyyy + + + + + + + + + + GroupBandHeader2 + + + + + + + + + + HorizontalLayout22 + + + + TextItem18 + + + + + HorizontalLayout22 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem16 + + + + + HorizontalLayout22 + + + + + + + Part + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem17 + + + + + HorizontalLayout22 + + + + + + + Description + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem19 + + + + + HorizontalLayout22 + + + + + + + Price + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem20 + + + + + HorizontalLayout22 + + + + + + + Qty + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem21 + + + + + HorizontalLayout22 + + + + + + + Total + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem22 + + + + + HorizontalLayout22 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GroupBandHeader2 + + + + + + + + + + + + ReportPage1 + + + + + + + GroupBandHeader1 + + + + OrderNo + + + + + + + + + GroupBandFooter1 + + + + TextItem1 + + + + + GroupBandFooter1 + + + + + + + Total this order: $S{ numberFormat(SUM($S{$D{sales.Qty}*$D{sales.ListPrice}},"DataBand1"))} + + + + + + + + + + + + + + + + + + + + + + + + + + + ShapeItem8 + + + + + GroupBandFooter1 + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + GroupBandHeader2 + + + + + + GroupBandFooter2 + + + + TextItem8 + + + + + GroupBandFooter2 + + + + + + + Total this customer: $S{ numberFormat(SUM($S{$D{sales.Qty}*$D{sales.ListPrice}},"DataBand1"))} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + GroupBandHeader1 + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + db + QSQLITE + ./demo_reports/demo_db.db + + + + + + + + + + + sales + select * from customer a, orders b, items c, parts d +where a.custno = b.custno + and b.orderno = c.orderno + and c.partno = d.partno +order by a.company, b.orderno limit 20 + db + + + + + + + + + + + + + + diff --git a/demo_r1/demo_reports/1.4/5_dialogDemo.lrxml b/demo_r1/demo_reports/1.4/5_dialogDemo.lrxml new file mode 100644 index 0000000..eb5780a --- /dev/null +++ b/demo_r1/demo_reports/1.4/5_dialogDemo.lrxml @@ -0,0 +1,93 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + TextItem1 + + + + + ReportPage1 + + + + + + + $S{Dialog.lineEdit.text} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + + + + + + + + + Dialog + + + + Dialog.exec()==1 + + + + diff --git a/demo_r1/demo_reports/1.4/6_change_page_margins_by_script.lrxml b/demo_r1/demo_reports/1.4/6_change_page_margins_by_script.lrxml new file mode 100644 index 0000000..6a8ba1e --- /dev/null +++ b/demo_r1/demo_reports/1.4/6_change_page_margins_by_script.lrxml @@ -0,0 +1,291 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + ReportHeader1 + + + + TextItem1 + + + + + ReportHeader1 + + + + + + + Fishes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + DataBand1 + + + + TextItem2 + + + + + DataBand1 + + + + + + + Number: $D{bio.Species_No} +Name: $D{bio.Common_Name} +Spec name: $D{bio.Species_Name} +Length (cm): $D{bio.Length_cm} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem3 + + + + + DataBand1 + + + + + + + $D{bio.Notes} + + + + + + + + + + + + + + + + + + + + + + + + + + + ImageItem3 + + + + + DataBand1 + + + + + + + + + bio + Graphic + + + +
+ + + + ShapeItem3 + + + + + DataBand1 + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + bio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + db + QSQLITE + ./demo_reports/demo_db.db + + + + + + + + + + + bio + Select * from biolife + db + + + + + + + + + + ReportPage1.beforeRender.connect( ReportPage1BeforeRender ); + +function ReportPage1BeforeRender(){ + ReportPage1.leftMargin = getVariable("#PAGE")%2 == 0 ? 20 : 5; + ReportPage1.rightMargin = getVariable("#PAGE")%2 == 0 ? 5 : 20; +} + + +
+
diff --git a/demo_r1/demo_reports/1.4/7_change_subband_visibility_by_script.lrxml b/demo_r1/demo_reports/1.4/7_change_subband_visibility_by_script.lrxml new file mode 100644 index 0000000..0ebccf2 --- /dev/null +++ b/demo_r1/demo_reports/1.4/7_change_subband_visibility_by_script.lrxml @@ -0,0 +1,295 @@ + + + + + + + page1 + + + + + + + + ReportPage1 + + + + DataBand1 + + + + TextItem2 + + + + + DataBand1 + + + + + + + $S{ +if ( $D{master.CustomerID} == "ALFKI") THIS.fontColor=QColor("red");""}$D{master.CompanyName} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem1 + + + + + DataBand1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + master + + + + + + + + + + + + SubDetailBand1 + + + + TextItem5 + + + + + SubDetailBand1 + + + + + + + $D{master.CustomerID} + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem6 + + + + + SubDetailBand1 + + + + + + + $D{master.City} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + db + QSQLITE + ./demo_reports/northwind.db + + + + + + + + + + + master + Select * from customers limit 5 + db + + + + + + + + + + SubDetailBand1.afterData.connect(SB1AfterData); + +function SB1AfterData(){ + if (getField("master.CustomerID")=="ALFKI") { + SubDetailBand1.isVisible = false; + TextItem2.fontColor = QColor("red"); + TextItem1.content = "sub band is not visible" + } else { + TextItem5.fontColor = QColor("red"); + TextItem1.content = "sub band is visible" + } +} + + + + + diff --git a/demo_r1/demo_reports/1.4/demoDialog.ui b/demo_r1/demo_reports/1.4/demoDialog.ui new file mode 100644 index 0000000..8f387f9 --- /dev/null +++ b/demo_r1/demo_reports/1.4/demoDialog.ui @@ -0,0 +1,82 @@ + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + + + + Message + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/demo_r1/demo_reports/change_alignment.lrxml b/demo_r1/demo_reports/change_alignment.lrxml new file mode 100644 index 0000000..507954e --- /dev/null +++ b/demo_r1/demo_reports/change_alignment.lrxml @@ -0,0 +1,105 @@ + + + + + + + page1 + + + + + + + + Reportpage1 + + + + TextItem1 + + + + + Reportpage1 + + + + + + + $S{ +const Alignment = { + Left : 1, + Right: 2, + HCenter: 4, + Justify: 8, + Top: 32, + Bottom: 64, + VCenter: 128 +} + +THIS.alignment = (Alignment.Right | Alignment.Bottom); + "Test" +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + + + + + + + + + + + diff --git a/demo_r1/demo_reports/change_item_from_script.lrxml b/demo_r1/demo_reports/change_item_from_script.lrxml index 6d92ba8..301c326 100644 --- a/demo_r1/demo_reports/change_item_from_script.lrxml +++ b/demo_r1/demo_reports/change_item_from_script.lrxml @@ -1,27 +1,27 @@ - + - + page1 - + - + - + ReportPage1 - + - + DataBand1 - + - + TextItem2 - + @@ -51,7 +51,7 @@ if ($D{customers.CustomerID}=="ANTON"){ - + @@ -65,6 +65,13 @@ if ($D{customers.CustomerID}=="ANTON"){ + + + + + + + @@ -78,6 +85,7 @@ if ($D{customers.CustomerID}=="ANTON"){ + customers @@ -88,14 +96,16 @@ if ($D{customers.CustomerID}=="ANTON"){ + + - + ReportHeader1 - + - + TextItem1 - + @@ -107,10 +117,10 @@ if ($D{customers.CustomerID}=="ANTON"){ $S{ -var color = new QColor('#DEB887'); -var font = new QFont('Times New Roman',26,false,true); +var color = LimeReport.color('#DEB887'); +var font = LimeReport.font('Times New Roman',26,false,true); THIS.backgroundColor = color; -THIS.fontColor = QColor('red'); +THIS.fontColor = LimeReport.color('red'); THIS.font = font; 'Test'} @@ -118,7 +128,7 @@ THIS.font = font; - + @@ -132,10 +142,17 @@ THIS.font = font; + + + + + + + - + TextItem3 - + @@ -151,7 +168,7 @@ THIS.font = font; - + @@ -165,6 +182,13 @@ THIS.font = font; + + + + + + + @@ -178,8 +202,10 @@ THIS.font = font; + + @@ -197,13 +223,19 @@ THIS.font = font; + + + + + + - + datasources - + test QSQLITE @@ -212,10 +244,11 @@ THIS.font = font; + - + customers Select * from customers limit 5 @@ -225,18 +258,21 @@ THIS.font = font; - + TestName TestValue + + - + + diff --git a/demo_r1/demo_reports/change_lang_from_script.lrxml b/demo_r1/demo_reports/change_lang_from_script.lrxml new file mode 100644 index 0000000..d09801f --- /dev/null +++ b/demo_r1/demo_reports/change_lang_from_script.lrxml @@ -0,0 +1,129 @@ + + + + + + + page1 + + + + + + + + Reportpage1 + + + + TextItem1 + + + + + Reportpage1 + + + + + + + Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + + + + + + + + + Dialog + + + + function OnAccept(){ + engine.setReportTranslation(Dialog.comboBox.currentText); +} +Dialog.accepted.connect(OnAccept); + +var comboBox = LimeReport.createWrapper(Dialog.comboBox); +comboBox.addItems(engine.aviableReportTranslations()); + +Dialog.exec() == 1; + + + + + + + + + + + + + + + + + diff --git a/demo_r1/demo_reports/demoReport1_report_header_group_subdetail_TOC.lrxml b/demo_r1/demo_reports/demoReport1_report_header_group_subdetail_TOC.lrxml new file mode 100644 index 0000000..141b5b0 --- /dev/null +++ b/demo_r1/demo_reports/demoReport1_report_header_group_subdetail_TOC.lrxml @@ -0,0 +1,1300 @@ + + + + + + + page2 + + + + + + + + TOC + + + + DataBand1 + + + + TextItem1 + + + + + DataBand1 + + + + + + + $D{tableofcontents.Content} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem2 + + + + + DataBand1 + + + + + + + $S{ +getFieldByKeyField( + "tableofcontents", + "Page number", + "Content Key", + "$D{tableofcontents.Content Key}" +) +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TOC + + + + + + + + + + + tableofcontents + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + page1 + + + + + + + + ReportPage1 + + + + ReportHeader1 + + + + TextItem1 + + + + + ReportHeader1 + + + + + + + Lime +Report + + + + + + + + + + + + + + + + + + + + + + + + + + + + ImageItem1 + + + + + ReportHeader1 + + + + + + + 89504e470d0a1a0a0000000d494844520000006400000071080600000023f9067c000000097048597300000dd700000dd70142289b780000119c49444154789ced9d79701cd59dc73feff55cba46b7c18eed8d84c1b6c02c4636b58ea928d8c609b0bb64c3429104ca5420b001c292cd3ae50d7120091bbb300e570a0c2609391c0889b99c1828b0036c42488c8d8d1cf9968c25d91aeb1849a3397afa78fb47cf48e383b2248f3c9a91be5553d3d3afbbe7757ffbbddfeffd8ef704a780dfef07104208745d17a73a7e1c83871002c330304d13c00638e503deb871a36bf1e2c5771886e1374d5328a546ba9e630642086f2010f8d3b469d35ec7e1c2729deaa44020e002beee72b9ced6340da5d4782b49135c2e577e28145a0b6c077a80e82909e9eaea12b66d8b6834aaaf5cb9f2059fcf67bb5c2e4388715e868b4824622e58b060e6a5975eba2810084c00a602fb180421a2b7b7570098a669ad58b1621b70180802d688d63ab711abadadfdbc94b2ce344d17e00524c0295b4812524a05f402078056c0601032681c274001d1d9b367cf9152da899e46e13c4b31684212308128104e6c8f6378b04b4b4b63272b182a2149a894cf38860129e5c9f79fe17a8ce31418276494619c905186e1ca9013a094e2b8b1c9b806360c199b36428410ac59b3068fc7a3b5b5b5b9bababa4428143a9ea49c47d23ed5d8d8686fdebcd92461a31a2cd24608c0c2850b7d555555cb84105f554a598ccd56226ddb8eb6b4b43c595d5dfd108e5818f41021ad843cf0c003f1bababab57bf6ec79aba9a9a9c2300c4f3aaf9f0d104208cbb2ac8f3efa28004c04dac904215eaf97b56bd7aab56bd776242a509cb8fe586b25c9f1591c88e0989804839427692344d7f56465e240178ef5722c43e190613104e19e36426ebdf5569e7aeaa964454cc64d2b082150437420a58d90a79e7a0aa514efbfff3eab57af1e6bddd431b02c8bbd7bf7aa1d3b760cf9dcb40af59e9e1e317dfaf4090f3ffc70795f5f9fb42c6b4c12a394b21b1b1b3bafbcf2ca761cb5f7cc7759008140c05b5555f5359fcf779bdfef5763d1bb2884909665450dc3580bfc08a7eb36067b7eda0859b06001d3a74fd78195c033c0598087b1a76541c2e721a5acb46d3b309413d346c8e6cd9b939b16d08df356b8187b26faa48a6bd8b6ddc710959bb476590c6858a1c4672cb68e54d864ca7492625c5443ad44aec2e7f3118b9dd431f8b148ab71f1b5d75ea3a4a4c4130c06dddddddda2afaf6fccb590847151eddab5cb7cf4d147e389dd99d1b2ce39e79c7ee3a26ddb63dab8d8dadafae4a38f3efa50625f668c8bf7dd775fbcaeae6ecdae5dbbde3874e85085aeeb1e31d6ecef806ddb564b4b4b07703699322e161414b06edd3ab56eddba2e1c197214d0d275fd2c4252cbd2851091841b62d0481b21e1709844450c9c40ba1ec6669705098baf52ca66880185692364f7eeddcc98312359199381e0afb186fefbcecfcf27128964c6b83863c60c945284c361d78e1d3bdcb66dd3d1d131e644881002d33469686830972f5f9e941d99d1b2745d777b3c9e2f5e72c9255799a6698f455b168e96a55f78e1851b962f5fbe9e449ac1604f4e2b211b366c50b5b5b507dadbdbff1608048ae2f1b89b2178cb720022d1428cfafa7a1ba8648881e9692364e6cc995c7bedb516b0056804ca0177baae9f6550802ea554b66d674686ecdab52b591113c7853bd66d59966ddb0619362e82330689e3a8bf63a5ab3a1ec96e3a738172c761ac47c60ffbdec7637b4719c60919651895849c247226db9403c731348c14f2919221a7052104adadad1228080402aeaeae2e2984c80a992484108661a88686065d08116588f274541202e0f7fb27e4e7e7ff72c284093312ba7c56b49244d449a4babafac96f7ce31b8f3030141814462d21f7dd775fd7942953beb67dfbf6a99d9d9d2596656585295f08816559768a3fe428d94ec8d2a54b59b56a958993131f05f271e45d56b4129cb19821840867cc1f924eac5ab50a9c9b8ae1bc6182ec21230995202373093b23802185618e420cb9eea352edede93926934165eb2767d4dee2e26294526cd9b2456cd8b0411ac6a04363338e8450a7bebe5e2554f5cc587bd38d7038ecaea9a939b7aaaaaa3012896493fc10b66d5b4d4d4d6dafbefaea61ce60f4fb097fb264c9127efef39f9fc62507609a66797e7efe8352ca595eaf17b247a80bdbb663c160f027c0c33856ef918d7eafacaca4a1a1a1f0e8d1a3de482422a2d1a8d075ddb8fcf2cbfb18620ad7c9b06cd9324a4a4a8e02d700938032b22b705b0171b7db5d6e18c6d1a19c382c42962d5be6292d2d5d5b565676594272d9e170f843e0cb38898e3aa7f1f056ae5c090331c2dd89eb659b2bd8300c23c299705099a629955213344d3b0b48469b848099c01e1c07d5e93ebc64026932c62b9bc848be3c4356db874548381c3e7e324c158bc5bc38ddcb41d2d7df67f33450c3aaf3b0083959ac956ddb9263f3d2d3d9c5642321c3c2a81c188e658c1332ca907142dc19afc1e8c219893ab9f762b4da4a64811b615a1034503fdc86f56117b691620bfde3bfc0c2dfc3d042cb720be924a49f849716e3bdb01caf5be2366c8a8a3d7c420a2a04e4d90a6528621797d3da1aa1cd52e85183d89fdb885eb681380965604609ecee4e63edb204e9214408a46dca7228bc773ee72d9acc055e8d85122e9282a9273b65820fa6158361531f3579775a31af4d29e2fd8e183df7be4f647777d69bde8785d327c48c23224151d9f466d95faee1bfce2d67e6604f15804732cbe36156b187dbaafd341f8ef0649ec66fdf0d70f8a583843501961a3bc40c8b903e7c0acb8058103e781136de4f61a0a5e0dc0a669ecea3f348a67cb290fbefba80db3f33891fe8162fbfda4c72fead3141ca500951000b8ffcc6cf960945bcf1001cdae34ca0e1e1844766296c4b61db0a4b2994022500211002a426909ac475fc30d3ab31694e254f3c5dc7e2a5efb1fcd7fb69c4b167e57cfefb500991f75ccc9485d6f65bdcbfbc792e0a671af914580a3b6e61e8367a632f47767773784f0f6d2d7d043b6284f35c70561ebe73fd949d5fc6e4e9c55495fba870493c9a18a88f0026e5f36f3f9ecf3fe4bbb8f3e9ddd4e3182e739a945313229cf80261c5e51dd3a8f9ce6c7ee4d198e894258e51604b4df5e956744f0fcdcfede783c71bd819b368c3310c8670e68bd719485e71013ea0e8a6f39875fbf95c3eab8c4bbc927c2106c647255e2e5e71098fb784f9da6bcdd47b35a2ba95bba47c2c21791a442de8a140a18744c18edff91fa9e3db9a9692eaac004d424105ed65b37aae7a70d3b35b8334006d4000e8c021248663b94d9dfb2369fbf23eb397bf3fb397376e3a8fb9df9bc36d930b982585f33f0228f372e1e397f2fdea67f9ba6e71c82389c67394928f1d27479df7585dd3fc44a1f6c62abf6bdd1d9e63c800c82b82e90b50776f523d37fc2ab4354883807ae03d9c55630ee01013c46921111c726289ed10d029042dc0ee67f6f2d2dc17b9635b07eb554ad72405727201f35ff92cb70065713b7733b34e2024d5aa1eb811ff25a2f1dbf20f2bca8f6f4b76e104c5d5f7c3dd6fc0e40bd08c3e05f42868c621a10fa755243d8827d39214602b852520ecd1683f1ae5c36bdfe47b1f74f08bd403dd92fc4bcfe6ba697e2e000a4f56f75cc03137a5be95101940eb0d1496f9f88e4772776abbb015ea48dc133cfa8535dd2cb82b71627fe86dd27f3cd4d5779402e21696df4de4608803dfdfca836d11de4af5ace4bba87c643ed703a5621407689c0efa09e9b909c403cef681ebc99b90c77fba044b530fb614f6fe5e5a17bfee59d75531abfd24d74bfa4086eda0ea359c94b8973fe2c0abcdacb0ed810001af46de45657c0a98a29cf0d26c097c18342440e3f550fc8cb3a3fd465c530ab9c125b83ff54025a4aaefe4e0dc17f84553c4b3bdd45fd03782f55240ac3bcedfdb63fcb67faf80420f155f9ac66c72b4db9200d5cf393f1e9c8328f430df2d5973ec511a91c973f58b5fe0b95e83bf9f555eb2c3eff78747ba72af7c446720ca2bfd3b14b804de4f4fe47cc04f0ea65d1ff386dd7201555e8d678fd92f04d6d4b976f8a6e7a2ca11d6fb6a6a6a9add6ef7888713be759858b74e8352031a9726707fa280b3812272508ef43ff8835fa2a0c8cd1382c4a02f8180eeea0e7ee99988f015291ccda9bba6a62636d273987812352bf512b31447fa2b2c90856efc3832243709d9f4cfb826e673b3142c4e2dec3388def5176da3955fa14bd11f9663e7e7e78fb8a12f39f0f3695808e2294502671e2e37d995333228c8b995f08fe54c724b7e985a60d8988fede4ede79bb46d3e8fcb48040e9b30bc64c6e122cf8526a134f9db56d8e178ff1a8a39450680acef4274c570f519fc9f61130147c5792fc0be6f6f6153698167afdbed8e4b29873ce5693a90a7512a0525c9df96c26a8dd08333d6c939038a8c5970de6f38e4ff194bde3ec29a884947678c8eeb37f112d0545c5cbc4fd3b4e440ef8cbe910dd7915fe0667eff0ee1b4dcad1d1ce1582b40ce2019c06c037d97ff8187be3283f74b3cd41c8e500fecaeaeaeeef8b84510471a93f229714bae4edd173589bdd8c4411cdb58b2ebca1952925a8a8d935c19f8e96e5e07b624eef2e8f9e79f7f467ddbea1e10ff0bcf2f427a24b334415db2ccb4b0f7f570b83dc61101bd2a073d89a96aa3c279e3ba8170e22ecdcaca4aef89a78d0c9abee89001f0d9c94cf46afc777fa180b049f48583ec0082ca592839e756ac3e991e6fe338920084659d997b5ebf18aa9e75b68fde88cfe7e26a2958942c570a5ac31c7db89ead3899b97de4a250cf7405001efb147ce133cef6772f42f83dccf7481e4c3da6374ef8a77b780f382c1c07987ec2857200191fe96ebe0a2efb0a886b9cdfff53cb451ec9e3405ef2184b616fefa471f587bc0bb42867c6ba9cebae20c3841cb81ece790ef883f33b7233177a246b85e0bcd4e39afb68bff3cfbc0e1cc27180252775c939648c90e012284de487beb808f9d9a9d47a258f4b416dea711d317a57ed60d3ce2e3e948203b6a2931c5e012e2384bc77f500192d5fc65deea3ce2bf989382eecb4374ee4378dfcf5f106de96827db6a2951c951d496484907f7ad9f90e2ec15be0e6f36ec9d3380ea77ef4c689ac6f62cb9d7fe26501fb6c45234e5044ce6956a9c8a896a5e02c4df018c79111b731df6c65e757dee645609f721249735690a722a3843cbd9b8e8321965bea5899a09c94858826e800f625be739e0cc82021f7d6c2b7fe4aecfa4dbcb4a79b27535526af86fbdfab98f7bbcb9907484b41d919b31764161923e47b5ba1cc8bdad24ed757dfe1a1963e7e9f5aae09bc574d65c9cfeaf857a0b44b47cb73e59effe37864b4cbead2513e17e6bb015a96fd8de55d3a5b53cbdd92c2ebce61d9f7e7b008288e9ae3848c3862a6e31afef57ef63e5ccfd2b0c947a9e5f92e26fc470df7947999468ec662a522e38424a080d80fb6b1f5b9fd2cd52d82c9c71e36d11b82f49678f82403b158394b4ada08494e4283f37087e3c9b381de5bde61d3a666be6b9a447b747a9fdfcf9f3eb3815f3586083010a6aa12ff99aeea8f1aa46d60a8699a3671e2c4e22baeb8a2fcf6db6f374a4b4b6ddb1eda184e0ac1ae964ef9c10b4fbc531cfae3d3cda1f8d45bf7f9dfa9ad2d6a9f397346f7e73ef739dfecd9b32bdd6eb77df0e0c1981022428ed9b4d24288104254545414af5fbffebaaaaaaa3abfdf1f95520eeb414d9c34894fd7fe58b6f7463cdece4eb14dc517959496868a8b8bfbdc6eb795b23cf66660238e5d2b67c628696b2145454545f3e6cd5b98b6eb1516503da9f2a4658661d8dddddd79c0361c67558c1c6929a345a80f099665c50f1f3e5c8a331d949b1c2103864948228c3463537f0b215c96657971727f732a606e585d56281452baae1f8c46a3d5baaebb1273659d11082144341a8d0583c120391e753268ac5ebd5a5fbd7af5ddc00ca00a279bf64cc2064252ca1edbb6738a94614d1c80f34022c07ee00867befb528069db762f39e6b01aae9625185884385373f62413496db24f86a88f1ba39d9290840017524af737bff9cd0be6cd9be79b3367ceb9050505166476b42c84c8bad1ba10826834aa0b216a841027f42ca724c4344d9452bacbe572af58b1e21edbb693339266db5b396a5058580810370c43eaba6e92129f7c4a429a9b9bed8e8e8e8d6d6d6de78442a1024065cb7a50a31cc2e5727976eedcd9c4406ac5a05673d670a698a9022ac8d2c1e42886e976bb038661b400d1c11022189828c633a2551b9b48ae241407aca1ca81f1d6917e1c33edc8ff0311504d2a89d602380000000049454e44ae426082 + + + + + + + +
+ + + + ShapeItem1 + + + + + ReportHeader1 + + + + + + + + + + + + + + + + + ShapeItem2 + + + + + ReportHeader1 + + + + + + + + + + + + + + + + + TextItem9 + + + + + ReportHeader1 + + + + + + + REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem10 + + + + + ReportHeader1 + + + + + + + HEADER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + + DataBand1 + + + + TextItem3 + + + + + DataBand1 + + + + + + + $D{orders.OrderDate} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem4 + + + + + DataBand1 + + + + + + + $D{orders.OrderID} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem12 + + + + + DataBand1 + + + + + + + DATA BAND + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem16 + + + + + DataBand1 + + + + + + + OrderID + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem17 + + + + + DataBand1 + + + + + + + Order Date + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + orders + + + + + + + + + + + + + GroupBandHeader1 + + + + TextItem2 + + + + + GroupBandHeader1 + + + + + + + $D{orders.CompanyName} + + + + + + + + + + + + + + + + + + + + + + + + + + + + ShapeItem3 + + + + + GroupBandHeader1 + + + + + + + + + + + + + + + + + TextItem11 + + + + + GroupBandHeader1 + + + + + + + GROUP HEADER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + CompanyName + + + + + + + + + SubDetailBand1 + + + + TextItem5 + + + + + SubDetailBand1 + + + + + + + $D{orderitems.ProductName} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem6 + + + + + SubDetailBand1 + + + + + + + $D{orderitems.Quantity} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem7 + + + + + SubDetailBand1 + + + + + + + $S{line("SubDetailBand1")} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem13 + + + + + SubDetailBand1 + + + + + + + SUBDETAIL BAND + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + DataBand1 + + + + orderitems + + + + + + + + + SubDetailFooterBand1 + + + + TextItem8 + + + + + SubDetailFooterBand1 + + + + + + + $S{SUM($D{orderitems.Quantity},"SubDetailBand1")} + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem14 + + + + + SubDetailFooterBand1 + + + + + + + SUBDETAIL FOOTER + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextItem15 + + + + + SubDetailFooterBand1 + + + + + + + Total + + + + + + + + + + + + + + + + + + + + + + + + + + + + ShapeItem4 + + + + + SubDetailFooterBand1 + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + SubDetailBand1 + + + + + + + + + PageFooter1 + + + + TextItem18 + + + + + PageFooter1 + + + + + + + Page $V{#PAGE} from $V{#PAGE_COUNT} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + + PageHeader18 + + + + TextItem19 + + + + + PageHeader18 + + + + + + + Page $V{#PAGE} from $V{#PAGE_COUNT} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReportPage1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + datasources + + + + northwind + QSQLITE + ./demo_reports/northwind.db + + + + + + + + + + + orders + Select * from orders +inner join customers on customers.customerid = orders.customerid order by companyname +limit 50 + northwind + + + + + + orderitems + Select * from orderitems + inner join products on products.productid = orderitems.productid +where orderid = $D{orders.orderid} + northwind + orders + + + + + + + + + ReportPage1_DataBand1.afterRender.connect(SB1AfterData); +ReportPage1_SubDetailBand1.afterRender.connect(SB2AfterData); +ReportPage1_GroupBandHeader1.afterRender.connect(SB3AfterData); + +var firstLevel = "&nbsp;&nbsp;&nbsp;&nbsp;"; +var secondLevel = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; + +function SB1AfterData(){ + addTableOfContentsItem(getField("orders.OrderID"),firstLevel+getField("orders.OrderID")); +} + +function SB2AfterData(){ + addTableOfContentsItem(getField("orders.OrderID")+getField("orderItems.ProductName"), secondLevel+"<i>"+getField("orderItems.ProductName")+"</i>"); +} + +function SB3AfterData(){ + addTableOfContentsItem(getField("orders.CompanyName"), "<b>"+getField("orders.CompanyName")+"</b>"); +} + + + +
+
diff --git a/demo_r1/demo_reports/demo_db.db b/demo_r1/demo_reports/demo_db.db new file mode 100644 index 0000000..ed18d13 Binary files /dev/null and b/demo_r1/demo_reports/demo_db.db differ diff --git a/demo_r1/demo_reports/test_customers.lrxml b/demo_r1/demo_reports/test_customers.lrxml deleted file mode 100644 index f726672..0000000 --- a/demo_r1/demo_reports/test_customers.lrxml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - page1 - - - - - - - - ReportPage1 - - - - DataBand1 - - - - TextItem1 - - - - - DataBand1 - - - - - - - $D{customers.CompanyName} - - - - - - - - - - - - - - - - - - - - - ReportPage1 - - - - - - - - - - customers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - datasources - - - - test - QSQLITE - /home/alex/Work/C++Projects/LimeReport/demo_r1/demo_reports/northwind.db - - - - - - - - - - customers - Select * from customers - test - - - - - - - - - diff --git a/demo_r1/global.h b/demo_r1/global.h new file mode 100644 index 0000000..e5e79a2 --- /dev/null +++ b/demo_r1/global.h @@ -0,0 +1,6 @@ +#ifndef GLOBAL_H +#define GLOBAL_H +#include +QString test = "ttttt"; + +#endif // GLOBAL_H diff --git a/demo_r1/mainicon.rc b/demo_r1/mainicon.rc index 83c0128..ef4125c 100644 --- a/demo_r1/mainicon.rc +++ b/demo_r1/mainicon.rc @@ -1 +1 @@ -DI_ICON1 ICON "main.ico" +IDI_ICON1 ICON "main.ico" diff --git a/demo_r1/mainwindow.cpp b/demo_r1/mainwindow.cpp index 6deb868..05488ce 100644 --- a/demo_r1/mainwindow.cpp +++ b/demo_r1/mainwindow.cpp @@ -37,6 +37,15 @@ #include #include #include +#include + +#ifdef BUILD_WITH_EASY_PROFILER +#include "easy/profiler.h" +#else +# define EASY_BLOCK(...) +# define EASY_END_BLOCK +# define EASY_PROFILER_ENABLE +#endif MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -95,8 +104,8 @@ MainWindow::MainWindow(QWidget *parent) : report->dataManager()->addModel("string_list",stringListModel,true); QStringList strList; strList<<"value1"<<"value2"; - QScriptValue value = qScriptValueFromSequence(report->scriptManager()->scriptEngine(),strList); - report->scriptManager()->scriptEngine()->globalObject().setProperty("test_list",value); + //QScriptValue value = qScriptValueFromSequence(report->scriptManager()->scriptEngine(),strList); + //report->scriptManager()->scriptEngine()->globalObject().setProperty("test_list",value); } @@ -110,22 +119,43 @@ MainWindow::~MainWindow() void MainWindow::on_pushButton_clicked() { + EASY_PROFILER_ENABLE; + EASY_BLOCK("design report"); report->dataManager()->clearUserVariables(); if (!ui->leVariableName->text().isEmpty() && !ui->leVariableValue->text().isEmpty()){ report->dataManager()->setReportVariable(ui->leVariableName->text(), ui->leVariableValue->text()); } report->setShowProgressDialog(false); report->designReport(); + EASY_END_BLOCK; +#ifdef BUILD_WITH_EASY_PROFILER + profiler::dumpBlocksToFile("test.prof"); +#endif } void MainWindow::on_pushButton_2_clicked() { QString fileName = QFileDialog::getOpenFileName(this,"Select report file",QApplication::applicationDirPath()+"/demo_reports/","*.lrxml"); if (!fileName.isEmpty()) { + EASY_PROFILER_ENABLE; + EASY_BLOCK("Load file"); report->loadFromFile(fileName); + EASY_END_BLOCK; + EASY_BLOCK("Set report variable"); if (!ui->leVariableName->text().isEmpty() && !ui->leVariableValue->text().isEmpty()){ report->dataManager()->setReportVariable(ui->leVariableName->text(), ui->leVariableValue->text()); } + EASY_END_BLOCK; +#ifdef BUILD_WITH_EASY_PROFILER + profiler::dumpBlocksToFile("test.prof"); +#endif +// QPrinter* printer = new QPrinter; +// QPrintDialog dialog(printer); +// if (dialog.exec()){ +// QMap printers; +// printers.insert("default",printer); +// report->printReport(printers); +// } report->previewReport(); } } diff --git a/demo_r2/demo_r2.pro b/demo_r2/demo_r2.pro index 707649b..c75365b 100644 --- a/demo_r2/demo_r2.pro +++ b/demo_r2/demo_r2.pro @@ -1,7 +1,12 @@ include(../common.pri) QT += core gui -TARGET = LRDemo_r2 +CONFIG(release, debug|release){ + TARGET = LRDemo_r2 +} else { + TARGET = LRDemo_r2d +} + TEMPLATE = app SOURCES += main.cpp\ @@ -17,6 +22,7 @@ DEPENDPATH += $$PWD/../include RESOURCES += \ demo_r2.qrc + EXTRA_DIR += $$PWD/demo_reports DEST_DIR = $${DEST_BINS} REPORTS_DIR = $${DEST_DIR} @@ -49,8 +55,13 @@ win32 { REPORTS_DIR ~= s,/,\\,g RC_FILE += mainicon.rc - - QMAKE_POST_LINK += $$QMAKE_COPY_DIR \"$$EXTRA_DIR\" \"$$REPORTS_DIR\\demo_reports\" $$escape_expand(\\n\\t) + greaterThan(QT_MAJOR_VERSION, 4) { + QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$shell_quote($$EXTRA_DIR\\*) $$shell_quote($$REPORTS_DIR\\demo_reports) $$escape_expand(\\n\\t) + } + lessThan(QT_MAJOR_VERSION, 5){ + QMAKE_POST_LINK += $$QMAKE_COPY_DIR $$quote($$EXTRA_DIR\\*) $$quote($$REPORTS_DIR\\demo_reports) $$escape_expand(\\n\\t) + } + #QMAKE_POST_LINK += $$QMAKE_COPY_DIR \"$$EXTRA_DIR\" \"$$REPORTS_DIR\\demo_reports\" $$escape_expand(\\n\\t) } } diff --git a/demo_r2/demo_reports/change_item_from_script.lrxml b/demo_r2/demo_reports/change_item_from_script.lrxml index 2e79dbc..63d93d4 100644 --- a/demo_r2/demo_reports/change_item_from_script.lrxml +++ b/demo_r2/demo_reports/change_item_from_script.lrxml @@ -1,35 +1,37 @@ + - + - + page1 - - - - - - - + + + + + + + ReportPage1 - + - + DataBand1 - + - + TextItem2 - + - - + + DataBand1 - - - - - + + + + + + $S{ var selectedItemBegin = '<span style="background:black; color:red; font-weight:bold ">'; @@ -45,152 +47,208 @@ if ($D{customers.CustomerID}=="ANTON"){ '<span>Customer: </span>'+customer; } - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + ReportPage1 - - - - - + + + + + + - - + + + customers - - - - - - - + + + + + + + + + + - + ReportHeader1 - + - + TextItem1 - + - - + + ReportHeader1 - - - - - + + + + + + $S{ -var color = new QColor('#DEB887'); -var font = new QFont('Times New Roman',26,false,true); +var color = LimeReport.color('#DEB887'); +var font = LimeReport.font('Times New Roman',26,false,true); THIS.backgroundColor = color; -THIS.fontColor = QColor('red'); +THIS.fontColor = LimeReport.color('red'); THIS.font = font; 'Test'} - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + TextItem3 - + - - + + ReportHeader1 - - - - - + + + + + + <p> <span>test1</span> <span style="background:red">test</span> </p> - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + ReportPage1 - - - - - + + + + + + - - - + + + + + - - + + - - - - - - - - - + + + + + + + + + + + + + + + + + + - + datasources - + test QSQLITE - ./demo_reports/northwind.db + /home/alex/Work/C++Projects/LimeReport/build/5.6.2/linux64/release/demo_r1/demo_reports/northwind.db - + - + + - + customers Select * from customers limit 5 @@ -200,12 +258,21 @@ THIS.font = font; - + TestName TestValue + + + + + + + + + diff --git a/demo_r2/images/ZoomIn.png b/demo_r2/images/ZoomIn.png index ecbff88..541ea22 100644 Binary files a/demo_r2/images/ZoomIn.png and b/demo_r2/images/ZoomIn.png differ diff --git a/demo_r2/images/ZoomOut.png b/demo_r2/images/ZoomOut.png index da1e2ef..bdbff2a 100644 Binary files a/demo_r2/images/ZoomOut.png and b/demo_r2/images/ZoomOut.png differ diff --git a/demo_r2/main.cpp b/demo_r2/main.cpp index b48f94e..dac3ecc 100644 --- a/demo_r2/main.cpp +++ b/demo_r2/main.cpp @@ -4,6 +4,7 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); + MainWindow w; w.show(); diff --git a/demo_r2/mainicon.rc b/demo_r2/mainicon.rc index 83c0128..ef4125c 100644 --- a/demo_r2/mainicon.rc +++ b/demo_r2/mainicon.rc @@ -1 +1 @@ -DI_ICON1 ICON "main.ico" +IDI_ICON1 ICON "main.ico" diff --git a/demo_r2/mainwindow.cpp b/demo_r2/mainwindow.cpp index 5ad3ac4..6f2aa7b 100644 --- a/demo_r2/mainwindow.cpp +++ b/demo_r2/mainwindow.cpp @@ -16,7 +16,7 @@ MainWindow::MainWindow(QWidget *parent) : m_pageNavigator = new QSpinBox(this); m_pageNavigator->setPrefix(tr("Page :")); - ui->toolBar->insertWidget(ui->actionZoomIn,m_scalePercent); + ui->toolBar->insertWidget(ui->actionZoom_Out,m_scalePercent); ui->toolBar->insertWidget(ui->actionNext_Page,m_pageNavigator); connect(m_scalePercent, SIGNAL(currentIndexChanged(QString)), this, SLOT(scaleComboboxChanged(QString))); connect(m_pageNavigator, SIGNAL(valueChanged(int)), this, SLOT(slotPageNavigatorChanged(int))); @@ -50,10 +50,21 @@ MainWindow::MainWindow(QWidget *parent) : resize(screenWidth*0.8, screenHeight*0.8); move(x, y); - if (QFile::exists(QApplication::applicationDirPath()+"/demo_reports/categories.lrxml")){ - m_report.loadFromFile(QApplication::applicationDirPath()+"/demo_reports/categories.lrxml"); - m_preview->refreshPages(); + + if (ui->treeWidget->topLevelItemCount()>0){ + int index = 0; + while (indextreeWidget->topLevelItemCount()){ + if (ui->treeWidget->topLevelItem(index)->childCount()>0) + ++index; + else { + m_report.loadFromFile(ui->treeWidget->topLevelItem(index)->data(0,Qt::UserRole).toString()); + ui->treeWidget->setCurrentItem(ui->treeWidget->topLevelItem(index)); + break; + } + } + } + m_preview->refreshPages(); } diff --git a/demo_r2/mainwindow.ui b/demo_r2/mainwindow.ui index 436974c..75c02b0 100644 --- a/demo_r2/mainwindow.ui +++ b/demo_r2/mainwindow.ui @@ -17,14 +17,17 @@ :/report/images/logo32:/report/images/logo32 + + false + - + Qt::Horizontal - + @@ -107,7 +110,7 @@ 5 - + 0 @@ -247,6 +250,9 @@ toolBar + + Qt::ToolButtonTextBesideIcon + TopToolBarArea @@ -302,7 +308,13 @@ :/images/images/ZoomIn.png:/images/images/ZoomIn.png - Zoom In + + + + + + + Zoom in @@ -311,7 +323,10 @@ :/images/images/ZoomOut.png:/images/images/ZoomOut.png - Zoom Out + + + + Zoom out @@ -347,6 +362,9 @@ :/images/images/First.png:/images/images/First.png + + + First Page @@ -356,6 +374,9 @@ :/images/images/Prev.png:/images/images/Prev.png + + + Prior Page @@ -365,6 +386,9 @@ :/images/images/Next.png:/images/images/Next.png + + + Next Page @@ -374,14 +398,17 @@ :/images/images/Last.png:/images/images/Last.png + + + Last Page - + diff --git a/designer/designer.pro b/designer/designer.pro index 68bf6b6..3f9cb8e 100644 --- a/designer/designer.pro +++ b/designer/designer.pro @@ -1,14 +1,25 @@ include(../common.pri) QT += core gui -TARGET = LRDesigner +contains(CONFIG,release) { + TARGET = LRDesigner +} else { + TARGET = LRDesignerd +} TEMPLATE = app -SOURCES += main.cpp +HEADERS += \ + designersettingmanager.h + +SOURCES += main.cpp \ + designersettingmanager.cpp INCLUDEPATH += $$PWD/../include DEPENDPATH += $$PWD/../include +RESOURCES += $$PWD/../3rdparty/dark_style_sheet/qdarkstyle/style.qrc +RESOURCES += $$PWD/../3rdparty/light_style_sheet/qlightstyle/lightstyle.qrc + DEST_DIR = $${DEST_BINS} REPORTS_DIR = $${DEST_DIR} @@ -17,22 +28,6 @@ macx{ } unix:{ - LIBS += -L$${DEST_LIBS} - CONFIG(debug, debug|release) { - LIBS += -llimereportd - } else { - LIBS += -llimereport - } - !contains(CONFIG, static_build){ - contains(CONFIG,zint){ - LIBS += -L$${DEST_LIBS} - CONFIG(debug, debug|release) { - LIBS += -lQtZintd - } else { - LIBS += -lQtZint - } - } - } DESTDIR = $$DEST_DIR linux{ #Link share lib to ../lib rpath @@ -52,22 +47,21 @@ win32 { DESTDIR = $$DEST_DIR RC_FILE += mainicon.rc - !contains(CONFIG, static_build){ - contains(CONFIG,zint){ - LIBS += -L$${DEST_LIBS} - CONFIG(debug, debug|release) { - LIBS += -lQtZintd - } else { - LIBS += -lQtZint - } - } - } - - LIBS += -L$${DEST_LIBS} - CONFIG(debug, debug|release) { - LIBS += -llimereportd - } else { - LIBS += -llimereport - } } +LIBS += -L$${DEST_LIBS} +CONFIG(debug, debug|release) { + LIBS += -llimereportd +} else { + LIBS += -llimereport +} + +!contains(CONFIG, static_build){ + contains(CONFIG,zint){ + CONFIG(debug, debug|release) { + LIBS += -L$${DEST_LIBS} -lQtZintd + } else { + LIBS += -L$${DEST_LIBS} -lQtZint + } + } +} diff --git a/designer/designersettingmanager.cpp b/designer/designersettingmanager.cpp new file mode 100644 index 0000000..550772e --- /dev/null +++ b/designer/designersettingmanager.cpp @@ -0,0 +1,42 @@ +#include "designersettingmanager.h" +#include + +DesignerSettingManager::DesignerSettingManager(QObject *parent) : QObject(parent) +{ + m_setting = new QSettings("LimeReport",QCoreApplication::applicationName()); +} + +DesignerSettingManager::~DesignerSettingManager() +{ + delete m_setting; +} + +void DesignerSettingManager::getAvailableLanguages(QList* languages) +{ + languages->append(QLocale::Russian); + languages->append(QLocale::English); + languages->append(QLocale::Arabic); + languages->append(QLocale::French); + languages->append(QLocale::Chinese); + languages->append(QLocale::Spanish); +} + +QLocale::Language DesignerSettingManager::getCurrentDefaultLanguage() +{ + m_setting->beginGroup("ReportDesigner"); + QVariant v = m_setting->value("DesignerLanguage"); + m_setting->endGroup(); + if (v.isValid()){ + return static_cast(v.toInt()) ; + } else { + return QLocale::system().language(); + } +} + +void DesignerSettingManager::currentDefaultLanguageChanged(QLocale::Language language) +{ + QMessageBox::information(0, tr("Warning") , tr("The language will change after the application is restarted")); + m_setting->beginGroup("ReportDesigner"); + m_setting->setValue("DesignerLanguage", (int)language); + m_setting->endGroup(); +} diff --git a/designer/designersettingmanager.h b/designer/designersettingmanager.h new file mode 100644 index 0000000..4c1d28c --- /dev/null +++ b/designer/designersettingmanager.h @@ -0,0 +1,24 @@ +#ifndef DESIGNERSETTINGMANAGER_H +#define DESIGNERSETTINGMANAGER_H + +#include +#include +#include +#include + +class DesignerSettingManager : public QObject +{ + Q_OBJECT +public: + explicit DesignerSettingManager(QObject *parent = 0); + ~DesignerSettingManager(); + void setApplicationInstance(QApplication* application); +public slots: + void getAvailableLanguages(QList* languages); + QLocale::Language getCurrentDefaultLanguage(); + void currentDefaultLanguageChanged(QLocale::Language language); +private: + QSettings* m_setting; +}; + +#endif // DESIGNERSETTINGMANAGER_H diff --git a/designer/main.cpp b/designer/main.cpp index 9132b47..8d06579 100644 --- a/designer/main.cpp +++ b/designer/main.cpp @@ -1,25 +1,53 @@ #include #include #include +#include +#include "designersettingmanager.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); + DesignerSettingManager manager; QTranslator limeReportTranslator; + QTranslator qtBaseTranslator; + QTranslator qtDesignerTranslator; + QTranslator qtLinguistTranslator; + QString translationPath = QApplication::applicationDirPath(); - translationPath.append("/languages"); - limeReportTranslator.load("limereport_"+QLocale::system().name(),translationPath); - a.installTranslator(&limeReportTranslator); + translationPath.append("/translations"); + Qt::LayoutDirection layoutDirection = QLocale::system().textDirection(); - QTranslator qtTranslator; - qtTranslator.load("qt_" + QLocale::system().name(),translationPath); - a.installTranslator(&qtTranslator); + QString designerTranslation = QLocale(manager.getCurrentDefaultLanguage()).name(); + + if (limeReportTranslator.load("limereport_"+designerTranslation, translationPath)){ + qtBaseTranslator.load("qtbase_" + designerTranslation, translationPath); + qtDesignerTranslator.load("designer_"+designerTranslation,translationPath); + + a.installTranslator(&qtBaseTranslator); + a.installTranslator(&qtDesignerTranslator); + a.installTranslator(&limeReportTranslator); + + Qt::LayoutDirection layoutDirection = QLocale(manager.getCurrentDefaultLanguage()).textDirection(); + a.setLayoutDirection(layoutDirection); + } LimeReport::ReportEngine report; + report.setPreviewLayoutDirection(layoutDirection); + if (a.arguments().count()>1){ report.loadFromFile(a.arguments().at(1)); } + QObject::connect(&report, SIGNAL(getAvailableDesignerLanguages(QList*)), + &manager, SLOT(getAvailableLanguages(QList*))); + + QObject::connect(&report, SIGNAL(getCurrentDefaultDesignerLanguage()), + &manager, SLOT(getCurrentDefaultLanguage())); + + QObject::connect(&report, SIGNAL(currentDefaultDesignerLanguageChanged(QLocale::Language)), + &manager, SLOT(currentDefaultLanguageChanged(QLocale::Language))); + report.designReport(); return a.exec(); } + diff --git a/designer/mainicon.rc b/designer/mainicon.rc index 83c0128..ef4125c 100644 --- a/designer/mainicon.rc +++ b/designer/mainicon.rc @@ -1 +1 @@ -DI_ICON1 ICON "main.ico" +IDI_ICON1 ICON "main.ico" diff --git a/designer_plugin/designer_plugin.pro b/designer_plugin/designer_plugin.pro new file mode 100644 index 0000000..219a796 --- /dev/null +++ b/designer_plugin/designer_plugin.pro @@ -0,0 +1,46 @@ +QT += core gui + +include(../common.pri) +include(../limereport/limereport.pri) +include(../limereport/designer.pri) + +contains(CONFIG,release) { + TARGET = designer_plugin +} else { + TARGET = designer_plugind +} + +TEMPLATE = lib +CONFIG += plugin + +HEADERS += \ + lrdesignerplugin.h +SOURCES += \ + lrdesignerplugin.cpp + +INCLUDEPATH += $$PWD/../include +DEPENDPATH += $$PWD/../include + +macx{ + CONFIG += lib_bundle + CONFIG += -dll +} + +DESTDIR = $${DEST_LIBS} +unix { + target.path = $${DESTDIR} + INSTALLS = target +} + + +contains(CONFIG,zint){ + message(zint) + INCLUDEPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt + DEPENDPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt + LIBS += -L$${DEST_LIBS} + CONFIG(debug, debug|release){ + LIBS += -lQtZintd + } else { + LIBS += -lQtZint + } +} diff --git a/designer_plugin/lrdesignerplugin.cpp b/designer_plugin/lrdesignerplugin.cpp new file mode 100644 index 0000000..96b6f4a --- /dev/null +++ b/designer_plugin/lrdesignerplugin.cpp @@ -0,0 +1,17 @@ +#include "lrdesignerplugin.h" + +#include +#include "lrreportdesignwindow.h" + +ReportDesignerFactoryPlugin::~ReportDesignerFactoryPlugin() { +} + +LimeReport::ReportDesignWindowInterface* ReportDesignerFactoryPlugin::getDesignerWindow(LimeReport::ReportEnginePrivateInterface* report, QWidget* parent, QSettings* settings) +{ + return new LimeReport::ReportDesignWindow(report, parent, settings); +} + +#if QT_VERSION < 0x050000 +Q_EXPORT_PLUGIN2(LimeReportPluginInterface, ReportDesignerFactoryPlugin) +#endif + diff --git a/designer_plugin/lrdesignerplugin.h b/designer_plugin/lrdesignerplugin.h new file mode 100644 index 0000000..d23f147 --- /dev/null +++ b/designer_plugin/lrdesignerplugin.h @@ -0,0 +1,19 @@ +#ifndef LRDESIGNERPLUGIN_H +#define LRDESIGNERPLUGIN_H + +#include +#include + +class ReportDesignerFactoryPlugin : public QObject, public LimeReportDesignerPluginInterface { + Q_OBJECT +#if QT_VERSION >= 0x050000 + Q_PLUGIN_METADATA(IID "ru.limereport.DersignerFactoryInterface") +#endif + Q_INTERFACES( LimeReportDesignerPluginInterface ) + +public: + ~ReportDesignerFactoryPlugin(); + LimeReport::ReportDesignWindowInterface* getDesignerWindow(LimeReport::ReportEnginePrivateInterface* report, QWidget* parent, QSettings* settings); +}; + +#endif diff --git a/include/lrdatasourceintf.h b/include/lrdatasourceintf.h new file mode 100644 index 0000000..26f7a65 --- /dev/null +++ b/include/lrdatasourceintf.h @@ -0,0 +1,48 @@ +#ifndef LRDATASOURCEINTF_H +#define LRDATASOURCEINTF_H +#include +#include +namespace LimeReport { + +class IDataSource { +public: + enum DatasourceMode{DESIGN_MODE,RENDER_MODE}; + typedef QSharedPointer Ptr; + virtual ~IDataSource() {} + virtual bool next() = 0; + virtual bool hasNext() = 0; + virtual bool prior() = 0; + virtual void first() = 0; + virtual void last() = 0; + virtual bool bof() = 0; + virtual bool eof() = 0; + virtual QVariant data(const QString& columnName) = 0; + virtual QVariant dataByRowIndex(const QString& columnName, int rowIndex) = 0; + virtual QVariant dataByKeyField(const QString& columnName, const QString& keyColumnName, QVariant keyData) = 0; + virtual int columnCount() = 0; + virtual QString columnNameByIndex(int columnIndex) = 0; + virtual int columnIndexByName(QString name) = 0; + virtual bool isInvalid() const = 0; + virtual QString lastError() = 0; + virtual QAbstractItemModel* model() = 0; +}; + +class IDataSourceHolder { +public: + virtual ~IDataSourceHolder(){} + virtual IDataSource* dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE) = 0; + virtual QString lastError() const = 0; + virtual bool isInvalid() const = 0; + virtual bool isOwned() const = 0; + virtual bool isEditable() const = 0; + virtual bool isRemovable() const = 0; + virtual void invalidate(IDataSource::DatasourceMode mode, bool dbWillBeClosed = false) = 0; + virtual void update() = 0; + virtual void clearErrors() = 0; +}; + +} // namespace LimeReport + +#endif // LRDATASOURCEINTF_H + + diff --git a/include/lrdatasourcemanagerintf.h b/include/lrdatasourcemanagerintf.h index e3a6ce7..040dd1d 100644 --- a/include/lrdatasourcemanagerintf.h +++ b/include/lrdatasourcemanagerintf.h @@ -31,6 +31,8 @@ #define LRDATASOURCEMANAGERINTF_H #include "lrcallbackdatasourceintf.h" +#include "lrglobal.h" +#include "lrdatasourceintf.h" class QVariant; class QString; @@ -39,12 +41,14 @@ namespace LimeReport{ class IDbCredentialsProvider{ public: + virtual ~IDbCredentialsProvider(){} virtual QString getUserName(const QString& connectionName) = 0; virtual QString getPassword(const QString& connectionName) = 0; }; class IDataSourceManager{ public: + virtual ~IDataSourceManager(){} virtual void setReportVariable(const QString& name, const QVariant& value) = 0; virtual void setDefaultDatabasePath(const QString &defaultDatabasePath) = 0; virtual void deleteVariable(const QString& name) = 0; @@ -56,8 +60,14 @@ public: virtual void clearUserVariables()=0; virtual ICallbackDatasource* createCallbackDatasource(const QString& name) = 0; virtual void registerDbCredentialsProvider(IDbCredentialsProvider* provider) = 0; - //virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; + virtual QStringList variableNames() = 0; + virtual bool variableIsMandatory(const QString& name) = 0; + virtual VariableDataType variableDataType(const QString& name) = 0; + virtual bool variableIsSystem(const QString& name) = 0; + virtual IDataSource* dataSource(const QString& name) = 0; + virtual IDataSourceHolder* dataSourceHolder(const QString& name) = 0; }; } #endif // LRDATASOURCEMANAGERINTF_H + diff --git a/include/lrglobal.cpp b/include/lrglobal.cpp index b4eb854..55ab31b 100644 --- a/include/lrglobal.cpp +++ b/include/lrglobal.cpp @@ -76,4 +76,13 @@ QVector normalizeCaptures(const QRegExp& reg){ return result; } +bool isColorDark(QColor color){ + qreal darkness = 1-(0.299*color.red() + 0.587*color.green() + 0.114*color.blue())/255; + if(darkness<0.5){ + return false; + } else { + return true; + } +} + } //namespace LimeReport diff --git a/include/lrglobal.h b/include/lrglobal.h index ea8b279..da6ab47 100644 --- a/include/lrglobal.h +++ b/include/lrglobal.h @@ -52,8 +52,8 @@ namespace LimeReport { namespace Const{ - int const RESIZE_HANDLE_SIZE = 10; - int const SELECTION_PEN_SIZE = 4; + int const RESIZE_HANDLE_SIZE = 5; + int const SELECTION_PEN_SIZE = 1; int const MINIMUM_ITEM_WIDTH = 2*RESIZE_HANDLE_SIZE; int const MINIMUM_ITEM_HEIGHT = 2*RESIZE_HANDLE_SIZE; double const RESIZE_ZONE_OPACITY = 0.5; @@ -75,25 +75,31 @@ namespace Const{ const qreal BAND_NAME_TEXT_OPACITY = 0.6; const qreal SELECTION_OPACITY = 0.3; const QString FIELD_RX = "\\$D\\s*\\{\\s*([^{}]*)\\s*\\}"; - const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; - const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\s*\\}"; - const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; + const QString VARIABLE_RX = "\\$V\\s*\\{\\s*(?:([^\\{\\},]*)|(?:([^\\{\\}]*)\\s*,\\s*([^\\{\\}]*)))\\s*\\}"; + const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(?:(%1)|(?:(%1)\\s*,\\s*([^\\{\\}]*)))\\s*\\}"; + const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*((?:(?:\\\")|(?:))(?:(?:\\$(?:(?:D\\{\\s*\\w*..*\\})|(?:V\\{\\s*\\w*\\s*\\})|(?:S\\{.+\\})))|(?:\\w*))(?:(?:\\\")|(?:)))(?:(?:\\s*,\\s*(?:\\\"(\\w*)\\\"))|(?:))(?:(?:\\s*,\\s*(?:(\\w*)))|(?:))\\)"; - const int DATASOURCE_INDEX = 3;//4; - const int VALUE_INDEX = 2; //2; - const int EXPRESSION_ARGUMENT_INDEX = 1;//3; + const int DATASOURCE_INDEX = 3; + const int VALUE_INDEX = 2; + const int EXPRESSION_ARGUMENT_INDEX = 1; const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; const int SCENE_MARGIN = 50; + const QString FUNCTION_MANAGER_NAME = "LimeReport"; + const QString DATAFUNCTIONS_MANAGER_NAME = "DatasourceFunctions"; + const QString EOW("~!@#$%^&*()+{}|:\"<>?,/;'[]\\-="); + const int DEFAULT_TAB_INDENTION = 4; + const int DOCKWIDGET_MARGINS = 4; } QString extractClassName(QString className); QString escapeSimbols(const QString& value); QString replaceHTMLSymbols(const QString &value); QVector normalizeCaptures(const QRegExp ®); + bool isColorDark(QColor color); enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols}; - enum RenderPass {FirstPass, SecondPass}; + enum RenderPass {FirstPass = 1, SecondPass = 2}; enum ArrangeType {AsNeeded, Force}; enum ScaleType {FitWidth, FitPage, OneToOne, Percents}; enum PreviewHint{ShowAllPreviewBars = 0, @@ -108,7 +114,7 @@ namespace Const{ class ReportError : public std::runtime_error{ public: - ReportError(const QString& message):std::runtime_error(message.toStdString()){} + ReportError(const QString& message); }; class ReportSettings{ @@ -121,12 +127,38 @@ namespace Const{ bool m_suppressAbsentFieldsAndVarsWarnings; }; -#ifdef HAVE_QT4 + class IExternalPainter{ + public: + virtual void paintByExternalPainter(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem* options) = 0; + virtual ~IExternalPainter(); + }; + + class IPainterProxy{ + public: + virtual void setExternalPainter(IExternalPainter* externalPainter) = 0; + virtual ~IPainterProxy(); + }; + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) typedef QStyleOptionViewItemV4 StyleOptionViewItem; #else typedef QStyleOptionViewItem StyleOptionViewItem; #endif +#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) + Q_NAMESPACE +#endif + class Enums + { + public: + enum VariableDataType {Undefined, String, Bool, Int, Real, Date, Time, DateTime}; + Q_ENUMS(VariableDataType) + private: + Enums(){} + Q_GADGET + }; + + typedef Enums::VariableDataType VariableDataType; } // namespace LimeReport diff --git a/include/lrpreparedpagesintf.h b/include/lrpreparedpagesintf.h new file mode 100644 index 0000000..a079a9a --- /dev/null +++ b/include/lrpreparedpagesintf.h @@ -0,0 +1,17 @@ +#ifndef LRPREPAREDPAGESINTF_H +#define LRPREPAREDPAGESINTF_H +#include "lrglobal.h" +namespace LimeReport { +class LIMEREPORT_EXPORT IPreparedPages{ +public: + virtual ~IPreparedPages(){}; + virtual bool loadFromFile(const QString& fileName) = 0; + virtual bool loadFromString(const QString data) = 0; + virtual bool loadFromByteArray(QByteArray* data) = 0; + virtual bool saveToFile(const QString& fileName) = 0; + virtual QString saveToString() = 0; + virtual QByteArray saveToByteArray() = 0; + virtual void clear() = 0; +}; +} //namespace LimeReport +#endif // LRPREPAREDPAGESINTF_H diff --git a/include/lrpreviewreportwidget.h b/include/lrpreviewreportwidget.h index 74c0be6..1e24e9b 100644 --- a/include/lrpreviewreportwidget.h +++ b/include/lrpreviewreportwidget.h @@ -3,6 +3,7 @@ #include #include +#include #include "lrglobal.h" #include "lrpreparedpagesintf.h" @@ -14,6 +15,8 @@ class PreviewReportWidget; class PreviewReportWidgetPrivate; class ReportEnginePrivate; +class ReportEngine; +class PageDesignIntf; class LIMEREPORT_EXPORT PreviewReportWidget : public QWidget { @@ -22,11 +25,22 @@ class LIMEREPORT_EXPORT PreviewReportWidget : public QWidget friend class PreviewReportWindow; friend class PreviewReportWidgetPrivate; public: - explicit PreviewReportWidget(ReportEnginePrivate *report, QWidget *parent = 0); - ~PreviewReportWidget(); + explicit PreviewReportWidget(ReportEngine *report, QWidget *parent = 0); + ~PreviewReportWidget(); + QList aviableExporters(); + bool exportReport(QString exporterName, const QMap& params = QMap()); ScaleType scaleType() const; int scalePercent() const; void setScaleType(const ScaleType &scaleType, int percent = 0); + void setPreviewPageBackgroundColor(QColor color); + QColor previewPageBackgroundColor(); + QPrinter *defaultPrinter() const; + void setDefaultPrinter(QPrinter *defaultPrinter); + void startInsertTextItem(); + void activateItemSelectionMode(); + void deleteSelectedItems(); + void activateCurrentPage(); + public slots: void refreshPages(); void zoomIn(); @@ -50,6 +64,7 @@ signals: void pageChanged(int page); void scalePercentChanged(int percent); void pagesSet(int pageCount); + void itemInserted(LimeReport::PageDesignIntf* report, QPointF pos, const QString& ItemType); void onSave(bool& saved, LimeReport::IPreparedPages* pages); private slots: void slotSliderMoved(int value); @@ -66,7 +81,10 @@ private: PreviewReportWidgetPrivate* d_ptr; ScaleType m_scaleType; int m_scalePercent; - QTimer m_resizeTimer; + QTimer m_resizeTimer; + QColor m_previewPageBackgroundColor; + QPrinter* m_defaultPrinter; + void printPages(QPrinter *printer); }; } // namespace LimeReport diff --git a/include/lrrenderengine.h b/include/lrrenderengine.h new file mode 100644 index 0000000..ccbecd4 --- /dev/null +++ b/include/lrrenderengine.h @@ -0,0 +1,91 @@ +#ifndef LRRENDERENGINE_H +#define LRRENDERENGINE_H + +#include +#include +#include + +#include "lrglobal.h" +#include "lrdatasourcemanagerintf.h" +#include "lrscriptenginemanagerintf.h" +#include "lrpreviewreportwidget.h" + +namespace LimeReport{ + +class PrintRange{ +public: + int fromPage() const { return m_fromPage;} + int toPage() const { return m_toPage;} + QPrintDialog::PrintRange rangeType() const { return m_rangeType;} + PrintRange(QAbstractPrintDialog::PrintRange rangeType=QPrintDialog::AllPages, int fromPage=0, int toPage=0); + void setRangeType(QAbstractPrintDialog::PrintRange rangeType){ m_rangeType=rangeType;} + void setFromPage(int fromPage){ m_fromPage = fromPage;} + void setToPage(int toPage){ m_toPage = toPage;} +private: + QPrintDialog::PrintRange m_rangeType; + int m_fromPage; + int m_toPage; +}; + +class DataSourceManager; +class PageDesignIntf; +class PageItemDesignIntf; +class PreviewReportWidget; + +typedef QList< QSharedPointer > ReportPages; + +class RenderEnginePrivate; + +class LIMEREPORT_EXPORT RenderEngine: public QObject{ + Q_OBJECT + friend class PreviewReportWidget; +public: + static void setSettings(QSettings *value){m_settings=value;} +public: + explicit RenderEngine(QObject *parent = 0); + explicit RenderEngine(RenderEnginePrivate* dd, QObject *parent = 0); + ~RenderEngine(); + bool printReport(QPrinter *printer=0); + bool printPages(ReportPages pages, QPrinter *printer); + void printToFile(const QString& fileName); + PageDesignIntf *createPreviewScene(QObject *parent = 0); + bool printToPDF(const QString& fileName); + void previewReport(PreviewHints hints = PreviewBarsUserSetting); + IDataSourceManager* dataManager(); + IScriptEngineManager* scriptManager(); + bool loadFromFile(const QString& fileName, bool autoLoadPreviewOnChange = false); + bool loadFromByteArray(QByteArray *data); + bool loadFromString(const QString& data); + QString reportFileName(); + void setReportFileName(const QString& fileName); + QString lastError(); + PreviewReportWidget *createPreviewWidget(QWidget *parent = 0); + void setPreviewWindowTitle(const QString& title); + void setPreviewWindowIcon(const QIcon& icon); + void setResultEditable(bool value); + bool resultIsEditable(); + bool isBusy(); + void setPassPharse(QString& passPharse); + QList aviableLanguages(); + bool setReportLanguage(QLocale::Language language); + Qt::LayoutDirection previewLayoutDirection(); + void setPreviewLayoutDirection(const Qt::LayoutDirection& previewLayoutDirection); + QSettings* settings(){ return m_settings;} +signals: + void renderStarted(); + void renderFinished(); + void renderPageFinished(int renderedPageCount); + void onLoad(bool& loaded); +public slots: + void cancelRender(); +protected: + QObject* d_ptr; +private: + static QSettings* m_settings; + void init(); +private: + Q_DECLARE_PRIVATE(RenderEngine) +}; + +} // namespace LimeReport +#endif // LRRENDERENGINE_H diff --git a/include/lrreportdesignwindowintrerface.h b/include/lrreportdesignwindowintrerface.h new file mode 100644 index 0000000..858881e --- /dev/null +++ b/include/lrreportdesignwindowintrerface.h @@ -0,0 +1,23 @@ +#ifndef LRREPORTDESIGNWINDOWINTRERFACE_H +#define LRREPORTDESIGNWINDOWINTRERFACE_H + +#include +#include + +namespace LimeReport { + +class ReportDesignWindowInterface: public QMainWindow{ +public: + ReportDesignWindowInterface(QWidget* parent = 0): QMainWindow(parent){} + virtual bool checkNeedToSave() = 0; + virtual void showModal() = 0; + virtual void showNonModal() = 0; + virtual void setSettings(QSettings* value) = 0; + virtual QSettings* settings() = 0; + virtual void restoreSetting() = 0; + virtual void setShowProgressDialog(bool value) = 0; +}; + +} // namespace LimeReport + +#endif // LRREPORTDESIGNWINDOWINTRERFACE_H diff --git a/include/lrreportengine.h b/include/lrreportengine.h index 8296abc..a4c314f 100644 --- a/include/lrreportengine.h +++ b/include/lrreportengine.h @@ -33,14 +33,17 @@ #include #include #include +//#include #include "lrglobal.h" #include "lrdatasourcemanagerintf.h" #include "lrscriptenginemanagerintf.h" #include "lrpreviewreportwidget.h" +#include "lrreportdesignwindowintrerface.h" #include "lrpreparedpagesintf.h" class QPrinter; +class QGraphicsScene; namespace LimeReport { @@ -59,28 +62,107 @@ private: int m_toPage; }; +class LIMEREPORT_EXPORT ItemGeometry{ +public: + enum Type{Millimeters, Pixels}; + ItemGeometry(qreal x, qreal y, qreal width, qreal height, Qt::Alignment anchor, Type type = Millimeters) + :m_x(x), m_y(y), m_width(width), m_height(height), m_type(type), m_anchor(anchor){} + ItemGeometry(): m_x(0), m_y(0), m_width(0), m_height(0), m_type(Millimeters){} + + qreal x() const; + void setX(const qreal &x); + + qreal y() const; + void setY(const qreal &y); + + qreal width() const; + void setWidth(const qreal &width); + + qreal height() const; + void setHeight(const qreal &height); + + Type type() const; + void setType(const Type &type); + + Qt::Alignment anchor() const; + void setAnchor(const Qt::Alignment &anchor); + +private: + qreal m_x; + qreal m_y; + qreal m_width; + qreal m_height; + Type m_type; + Qt::Alignment m_anchor; +}; + +class LIMEREPORT_EXPORT WatermarkSetting{ +public: + WatermarkSetting(const QString& text, const ItemGeometry& geometry, const QFont& font) + : m_text(text), m_font(font), m_opacity(50), m_geometry(geometry), m_color(QColor(Qt::black)){} + WatermarkSetting(): m_font(QFont()), m_opacity(50), m_geometry(ItemGeometry()){} + QString text() const; + void setText(const QString &text); + + QFont font() const; + void setFont(const QFont &font); + + int opacity() const; + void setOpacity(const int &opacity); + + ItemGeometry geometry() const; + void setGeometry(const ItemGeometry &geometry); + + QColor color() const; + void setColor(const QColor &color); + +private: + QString m_text; + QFont m_font; + int m_opacity; + ItemGeometry m_geometry; + QColor m_color; +}; + +class ItemBuilder{ + virtual void setProperty(QString name, QVariant value) = 0; + virtual QVariant property(QString name) = 0; + virtual void setGeometry(ItemGeometry geometry) = 0; + virtual ItemGeometry geometry() = 0; +}; + + class DataSourceManager; class ReportEnginePrivate; class PageDesignIntf; class PageItemDesignIntf; +class ReportDesignWidget; +class PreviewReportWidget; class PreparedPages; typedef QList< QSharedPointer > ReportPages; class LIMEREPORT_EXPORT ReportEngine : public QObject{ Q_OBJECT + friend class ReportDesignWidget; + friend class PreviewReportWidget; + friend class TranslationEditor; public: static void setSettings(QSettings *value){m_settings=value;} public: explicit ReportEngine(QObject *parent = 0); ~ReportEngine(); bool printReport(QPrinter *printer=0); + bool printReport(QMap printers, bool printToAllPrinters = false); bool printPages(ReportPages pages, QPrinter *printer); void printToFile(const QString& fileName); - PageDesignIntf *createPreviewScene(QObject *parent = 0); + QGraphicsScene* createPreviewScene(QObject *parent = 0); bool printToPDF(const QString& fileName); + bool exportReport(QString exporterName, const QString &fileName = "", const QMap& params = QMap()); void previewReport(PreviewHints hints = PreviewBarsUserSetting); + void previewReport(QPrinter* printer, PreviewHints hints = PreviewBarsUserSetting); void designReport(); + ReportDesignWindowInterface* getDesignerWindow(); void setShowProgressDialog(bool value); IDataSourceManager* dataManager(); IScriptEngineManager* scriptManager(); @@ -89,7 +171,6 @@ public: bool loadFromString(const QString& data); QString reportFileName(); void setReportFileName(const QString& fileName); - bool saveToFile(); bool saveToFile(const QString& fileName); QByteArray saveToByteArray(); QString saveToString(); @@ -100,6 +181,7 @@ public: PreviewReportWidget *createPreviewWidget(QWidget *parent = 0); void setPreviewWindowTitle(const QString& title); void setPreviewWindowIcon(const QIcon& icon); + void setPreviewPageBackgroundColor(QColor color); void setResultEditable(bool value); bool resultIsEditable(); void setSaveToFileVisible(bool value); @@ -109,23 +191,41 @@ public: void setPrintVisible(bool value); bool printIsVisible(); bool isBusy(); - void setPassPharse(QString& passPharse); + void setPassPhrase(QString& passPhrase); + QList availableLanguages(); + bool setReportLanguage(QLocale::Language language); Qt::LayoutDirection previewLayoutDirection(); void setPreviewLayoutDirection(const Qt::LayoutDirection& previewLayoutDirection); + QList designerLanguages(); + QLocale::Language currentDesignerLanguage(); ScaleType previewScaleType(); int previewScalePercent(); void setPreviewScaleType(const ScaleType &previewScaleType, int percent = 0); + void addWatermark(const WatermarkSetting& watermarkSetting); + void clearWatermarks(); IPreparedPages* preparedPages(); bool showPreparedPages(PreviewHints hints = PreviewBarsUserSetting); bool prepareReportPages(); + bool printPreparedPages(); signals: + void cleared(); void renderStarted(); void renderFinished(); void renderPageFinished(int renderedPageCount); + void onSave(bool& saved); + void onSaveAs(bool& saved); void onLoad(bool& loaded); - void onSave(); void onSavePreview(bool& saved, LimeReport::IPreparedPages* pages); void saveFinished(); + void loadFinished(); + void printedToPDF(QString fileName); + + void getAvailableDesignerLanguages(QList* languages); + void currentDefaultDesignerLanguageChanged(QLocale::Language); + QLocale::Language getCurrentDefaultDesignerLanguage(); + + void externalPaint(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem*); + public slots: void cancelRender(); protected: diff --git a/include/lrscriptenginemanagerintf.h b/include/lrscriptenginemanagerintf.h index d7662ff..a8a7c63 100644 --- a/include/lrscriptenginemanagerintf.h +++ b/include/lrscriptenginemanagerintf.h @@ -29,21 +29,58 @@ ****************************************************************************/ #ifndef LRSCRIPTENGINEMANAGERINTF_H #define LRSCRIPTENGINEMANAGERINTF_H +#include "qglobal.h" +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + #ifndef USE_QTSCRIPTENGINE + #ifndef USE_QJSENGINE + #define USE_QJSENGINE + #endif + #endif +#else + #ifndef USE_QTSCRIPTENGINE + #define USE_QTSCRIPTENGINE + #endif +#endif + +#ifdef USE_QJSENGINE +#include +#else #include +#endif namespace LimeReport{ +#ifdef USE_QJSENGINE + typedef QJSEngine ScriptEngineType; + typedef QJSValue ScriptValueType; + template + static inline QJSValue getJSValue(QJSEngine &e, T *p) + { + QJSValue res = e.newQObject(p); + QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership); + return res; + } +#else + typedef QScriptEngine ScriptEngineType; + typedef QScriptValue ScriptValueType; +#endif + class IScriptEngineManager{ public: - virtual QScriptEngine* scriptEngine() = 0; - virtual bool addFunction(const QString& name, QScriptEngine::FunctionSignature function, + virtual ScriptEngineType* scriptEngine() = 0; +#ifdef USE_QTSCRIPTENGINE + virtual bool addFunction(const QString& name, ScriptEngineType::FunctionSignature function, const QString& category="", const QString& description="") = 0; +#endif virtual bool addFunction(const QString &name, const QString& script, const QString &category="", const QString &description="") = 0; virtual const QString& lastError() const = 0; + virtual ScriptValueType moveQObjectToScript(QObject* object, const QString objectName) = 0; virtual ~IScriptEngineManager(){} + }; } //namespace LimeReport + #endif // LRSCRIPTENGINEMANAGERINTF_H diff --git a/limereport.pro b/limereport.pro index f954fae..9e33bcc 100644 --- a/limereport.pro +++ b/limereport.pro @@ -16,5 +16,11 @@ SUBDIRS += \ limereport \ demo_r1 \ demo_r2 \ + console \ designer +!contains(CONFIG, embedded_designer){ +!contains(CONFIG, static_build){ +SUBDIRS += designer_plugin +} +} diff --git a/limereport/bands/lrdataband.cpp b/limereport/bands/lrdataband.cpp index 29cea5e..7119440 100644 --- a/limereport/bands/lrdataband.cpp +++ b/limereport/bands/lrdataband.cpp @@ -87,7 +87,12 @@ QColor DataBand::bandColor() const void DataBand::preparePopUpMenu(QMenu &menu) { BandDesignIntf::preparePopUpMenu(menu); - QAction* currAction = menu.addAction(tr("Keep footer together")); + + QAction* currAction = menu.addAction(tr("Use alternate background color")); + currAction->setCheckable(true); + currAction->setChecked(useAlternateBackgroundColor()); + + currAction = menu.addAction(tr("Keep footer together")); currAction->setCheckable(true); currAction->setChecked(keepFooterTogether()); @@ -126,6 +131,10 @@ void DataBand::processPopUpAction(QAction *action) setProperty("sliceLastRow",action->isChecked()); } + if (action->text().compare(tr("Use alternate background color")) == 0){ + setProperty("useAlternateBackgroundColor",action->isChecked()); + } + if (action->text().compare(tr("Start new page")) == 0){ setProperty("startNewPage",action->isChecked()); } @@ -133,7 +142,6 @@ void DataBand::processPopUpAction(QAction *action) if (action->text().compare(tr("Start from new page")) == 0){ setProperty("startFromNewPage",action->isChecked()); } - } BaseDesignIntf *DataBand::createSameTypeItem(QObject *owner, QGraphicsItem *parent) diff --git a/limereport/bands/lrdataband.h b/limereport/bands/lrdataband.h index 4045d3a..fc6e4ad 100644 --- a/limereport/bands/lrdataband.h +++ b/limereport/bands/lrdataband.h @@ -48,6 +48,7 @@ class DataBand : public DataBandDesignIntf Q_PROPERTY(bool startNewPage READ startNewPage WRITE setStartNewPage) Q_PROPERTY(bool startFromNewPage READ startFromNewPage WRITE setStartFromNewPage) Q_PROPERTY(QColor alternateBackgroundColor READ alternateBackgroundColor WRITE setAlternateBackgroundColor) + Q_PROPERTY(bool useAlternateBackgroundColor READ useAlternateBackgroundColor WRITE setUseAlternateBackgroundColor) public: DataBand(QObject* owner = 0, QGraphicsItem* parent=0); bool isUnique() const; @@ -87,7 +88,7 @@ class DataFooterBand : public BandDesignIntf Q_OBJECT Q_PROPERTY(int columnsCount READ columnsCount WRITE setColumnsCount) Q_PROPERTY(BandColumnsLayoutType columnsFillDirection READ columnsFillDirection WRITE setColumnsFillDirection) - Q_PROPERTY(bool printAlways READ printAlways() WRITE setPrintAlways()) + Q_PROPERTY(bool printAlways READ printAlways WRITE setPrintAlways) public: DataFooterBand(QObject* owner=0, QGraphicsItem* parent=0); bool isUnique() const {return false;} diff --git a/limereport/bands/lrpagefooter.cpp b/limereport/bands/lrpagefooter.cpp index 2b1c3b1..8ee5959 100644 --- a/limereport/bands/lrpagefooter.cpp +++ b/limereport/bands/lrpagefooter.cpp @@ -30,6 +30,7 @@ #include "lrpagefooter.h" #include "lrdesignelementsfactory.h" #include "lrglobal.h" +#include "lrpagedesignintf.h" const QString xmlTag ="PageFooter"; @@ -63,7 +64,30 @@ BaseDesignIntf *PageFooter::createSameTypeItem(QObject *owner, QGraphicsItem *pa QColor PageFooter::bandColor() const { - return QColor(246,120,12); + return QColor(246,120,12); +} + +void PageFooter::preparePopUpMenu(QMenu &menu) +{ + QAction* action = menu.addAction(tr("Print on first page")); + action->setCheckable(true); + action->setChecked(printOnFirstPage()); + + action = menu.addAction(tr("Print on last page")); + action->setCheckable(true); + action->setChecked(printOnLastPage()); + +} + +void PageFooter::processPopUpAction(QAction *action) +{ + if (action->text().compare(tr("Print on first page")) == 0){ + page()->setPropertyToSelectedItems("printOnFirstPage",action->isChecked()); + } + if (action->text().compare(tr("Print on last page")) == 0){ + page()->setPropertyToSelectedItems("printOnLastPage",action->isChecked()); + } + BandDesignIntf::processPopUpAction(action); } bool PageFooter::printOnFirstPage() const @@ -73,7 +97,12 @@ bool PageFooter::printOnFirstPage() const void PageFooter::setPrintOnFirstPage(bool printOnFirstPage) { - m_printOnFirstPage = printOnFirstPage; + if (m_printOnFirstPage != printOnFirstPage){ + bool oldValue = m_printOnFirstPage; + m_printOnFirstPage = printOnFirstPage; + update(); + notify("printOnFirstPage",oldValue,printOnFirstPage); + } } bool PageFooter::printOnLastPage() const @@ -83,7 +112,12 @@ bool PageFooter::printOnLastPage() const void PageFooter::setPrintOnLastPage(bool printOnLastPage) { - m_printOnLastPage = printOnLastPage; + if (m_printOnLastPage != printOnLastPage){ + bool oldValue = m_printOnLastPage; + m_printOnLastPage = printOnLastPage; + update(); + notify("printOnLastPage",oldValue,printOnLastPage); + } } } // namespace LimeReport diff --git a/limereport/bands/lrpagefooter.h b/limereport/bands/lrpagefooter.h index d6678a3..3422b60 100644 --- a/limereport/bands/lrpagefooter.h +++ b/limereport/bands/lrpagefooter.h @@ -35,7 +35,7 @@ #include namespace LimeReport{ -class PageFooter : public LimeReport::BandDesignIntf +class PageFooter : public BandDesignIntf { Q_OBJECT Q_PROPERTY(bool printOnFirstPage READ printOnFirstPage WRITE setPrintOnFirstPage) @@ -50,7 +50,9 @@ public: void setPrintOnFirstPage(bool printOnFirstPage); protected: - QColor bandColor() const; + QColor bandColor() const; + void preparePopUpMenu(QMenu &menu); + void processPopUpAction(QAction *action); private: bool m_printOnFirstPage; bool m_printOnLastPage; diff --git a/limereport/bands/lrreportheader.cpp b/limereport/bands/lrreportheader.cpp index 5b853b7..e08f418 100644 --- a/limereport/bands/lrreportheader.cpp +++ b/limereport/bands/lrreportheader.cpp @@ -46,7 +46,7 @@ bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instanc namespace LimeReport { ReportHeader::ReportHeader(QObject *owner, QGraphicsItem *parent) - : BandDesignIntf(LimeReport::BandDesignIntf::ReportHeader,xmlTag,owner,parent) { + : BandDesignIntf(LimeReport::BandDesignIntf::ReportHeader,xmlTag,owner,parent), m_printBeforePageHeader(false) { setBandTypeText(tr("Report Header")); setMarkerColor(bandColor()); } @@ -60,5 +60,18 @@ QColor ReportHeader::bandColor() const return QColor(152,69,167); } +bool ReportHeader::printBeforePageHeader() const +{ + return m_printBeforePageHeader; +} + +void ReportHeader::setPrintBeforePageHeader(bool printBeforePageHeader) +{ + if (m_printBeforePageHeader != printBeforePageHeader){ + m_printBeforePageHeader = printBeforePageHeader; + notify("printBeforePageHeader",!m_printBeforePageHeader,m_printBeforePageHeader); + } +} + } diff --git a/limereport/bands/lrreportheader.h b/limereport/bands/lrreportheader.h index bc70667..d532ff9 100644 --- a/limereport/bands/lrreportheader.h +++ b/limereport/bands/lrreportheader.h @@ -39,11 +39,15 @@ class ReportHeader : public LimeReport::BandDesignIntf { Q_OBJECT Q_PROPERTY(bool splittable READ isSplittable WRITE setSplittable ) + Q_PROPERTY(bool printBeforePageHeader READ printBeforePageHeader WRITE setPrintBeforePageHeader) public: ReportHeader(QObject* owner = 0, QGraphicsItem *parent=0); virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); + bool printBeforePageHeader() const; + void setPrintBeforePageHeader(bool printBeforePageHeader); protected: QColor bandColor() const; + bool m_printBeforePageHeader; }; } #endif // LRREPORTHEADER_H diff --git a/limereport/bands/lrsubdetailband.h b/limereport/bands/lrsubdetailband.h index 72967b3..bbcdc88 100644 --- a/limereport/bands/lrsubdetailband.h +++ b/limereport/bands/lrsubdetailband.h @@ -43,6 +43,7 @@ class SubDetailBand : public DataBandDesignIntf Q_PROPERTY(BandColumnsLayoutType columnsFillDirection READ columnsFillDirection WRITE setColumnsFillDirection) Q_PROPERTY(bool keepFooterTogether READ keepFooterTogether WRITE setKeepFooterTogether) Q_PROPERTY(QColor alternateBackgroundColor READ alternateBackgroundColor WRITE setAlternateBackgroundColor) + Q_PROPERTY(bool useAlternateBackgroundColor READ useAlternateBackgroundColor WRITE setUseAlternateBackgroundColor) public: SubDetailBand(QObject* owner = 0, QGraphicsItem* parent=0); bool isUnique() const {return false;} diff --git a/limereport/databrowser/lrdatabrowser.cpp b/limereport/databrowser/lrdatabrowser.cpp index ef0e556..2deebd6 100644 --- a/limereport/databrowser/lrdatabrowser.cpp +++ b/limereport/databrowser/lrdatabrowser.cpp @@ -46,7 +46,6 @@ #include "lrconnectiondialog.h" #include "lrreportengine_p.h" #include "lrvariabledialog.h" -#include "lrdatabrowsertree.h" namespace LimeReport{ @@ -64,6 +63,8 @@ DataBrowser::DataBrowser(QWidget *parent) : connect(ui->changeConnection,SIGNAL(clicked()),this,SLOT(slotChangeConnection())); connect(ui->pbConnect,SIGNAL(clicked()),this,SLOT(slotChangeConnectionState())); + ui->verticalLayout_2->setMargin(Const::DOCKWIDGET_MARGINS); + ui->dataTree->setHeaderLabel(tr("Datasources")); ui->pbConnect->setEnabled(false); } @@ -96,31 +97,10 @@ void DataBrowser::slotAddConnection() void DataBrowser::slotSQLEditingFinished(SQLEditResult result) { if (result.dialogMode==SQLEditDialog::AddMode) { - switch (result.resultMode) { - case SQLEditResult::Query: - addQuery(result); - break; - case SQLEditResult::SubQuery: - addSubQuery(result); - break; - case SQLEditResult::SubProxy: - addProxy(result); - default: - break; - } + addDatasource(result); } else { - switch(result.resultMode){ - case SQLEditResult::Query: - changeQuery(result); - break; - case SQLEditResult::SubQuery: - changeSubQuery(result); - break; - case SQLEditResult::SubProxy: - changeProxy(result); - } + applyChanges(result); } - updateDataTree(); } @@ -237,7 +217,7 @@ void DataBrowser::updateVariablesTree() } } - foreach(QString variableName,m_report->dataManager()->namesOfUserVariables()){ + foreach(QString variableName,m_report->dataManager()->userVariableNames()){ if (!m_report->dataManager()->variableNames().contains(variableName)){ QStringList values; values<dataManager()->variable(variableName).toString()+"]" @@ -277,7 +257,7 @@ QSettings *DataBrowser::settings() if (m_settings){ return m_settings; } else { - m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_settings = new QSettings("LimeReport",QCoreApplication::applicationName()); m_ownedSettings = true; return m_settings; } @@ -617,8 +597,8 @@ void DataBrowser::changeQuery(SQLEditResult result) { try { m_report->dataManager()->removeDatasource(result.oldDatasourceName); - m_report->dataManager()->addQuery(result.datasourceName, result.sql, result.connectionName); - }catch(ReportError &exception){ + addQuery(result); + } catch(ReportError &exception){ qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); - m_report->dataManager()->addSubQuery(result.datasourceName, result.sql, result.connectionName, result.masterDatasource); - }catch(ReportError &exception){ + addSubQuery(result); + } catch(ReportError &exception){ qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); - m_report->dataManager()->addProxy(result.datasourceName,result.masterDatasource,result.childDataSource,result.fieldMap); + addProxy(result); } catch(ReportError &exception){ qDebug()<dataManager()->addCSV( + result.datasourceName, + result.csv, + result.separator, + result.firstRowIsHeader + ); + } catch(ReportError &exception){ + qDebug()<dataManager()->removeDatasource(result.oldDatasourceName); + addCSV(result); + } catch(ReportError &exception){ + qDebug()<dataManager()->isQuery(datasourceName)) return SQLEditResult::Query; + if (m_report->dataManager()->isSubQuery(datasourceName)) return SQLEditResult::SubQuery; + if (m_report->dataManager()->isProxy(datasourceName)) return SQLEditResult::SubProxy; + if (m_report->dataManager()->isCSV(datasourceName)) return SQLEditResult::CSVText; + return SQLEditResult::Undefined; +} + + +void DataBrowser::applyChanges(SQLEditResult result) +{ + if (result.resultMode == currentDatasourceType(result.datasourceName)){ + switch(result.resultMode){ + case SQLEditResult::Query: + changeQuery(result); + break; + case SQLEditResult::SubQuery: + changeSubQuery(result); + break; + case SQLEditResult::SubProxy: + changeProxy(result); + break; + case SQLEditResult::CSVText: + changeCSV(result); + break; + default: break; + } + } else { + removeDatasource(result.datasourceName); + addDatasource(result); + } + activateItem(result.datasourceName, DataBrowserTree::Table); +} + +void DataBrowser::addDatasource(SQLEditResult result) +{ + switch (result.resultMode) { + case SQLEditResult::Query: + addQuery(result); + break; + case SQLEditResult::SubQuery: + addSubQuery(result); + break; + case SQLEditResult::SubProxy: + addProxy(result); + break; + case SQLEditResult::CSVText: + addCSV(result); + break; + default: + break; + } + activateItem(result.datasourceName, DataBrowserTree::Table); +} + +void DataBrowser::activateItem(const QString& name, DataBrowserTree::NodeType type){ + QTreeWidgetItem* item = findByNameAndType(name, type); + item->treeWidget()->setCurrentItem(item); +} + void DataBrowser::addConnectionDesc(ConnectionDesc *connection) { m_report->dataManager()->addConnectionDesc(connection); updateDataTree(); + activateItem(connection->name(), DataBrowserTree::Connection); } void DataBrowser::changeConnectionDesc(ConnectionDesc *connection) { if (connection->autoconnect()) m_report->dataManager()->connectConnection(connection->name()); updateDataTree(); + activateItem(connection->name(), DataBrowserTree::Connection); } bool DataBrowser::checkConnectionDesc(ConnectionDesc *connection) diff --git a/limereport/databrowser/lrdatabrowser.h b/limereport/databrowser/lrdatabrowser.h index 7d0a91e..f0c5144 100644 --- a/limereport/databrowser/lrdatabrowser.h +++ b/limereport/databrowser/lrdatabrowser.h @@ -37,6 +37,7 @@ #include "lrreportdesignwidget.h" #include "lrsqleditdialog.h" +#include "lrdatabrowsertree.h" namespace LimeReport{ @@ -105,11 +106,18 @@ private: void changeSubQuery(SQLEditResult result); void addProxy(SQLEditResult result); void changeProxy(SQLEditResult result); + void addCSV(SQLEditResult result); + void changeCSV(SQLEditResult result); + + SQLEditResult::ResultMode currentDatasourceType(const QString& datasourceName); + void applyChanges(SQLEditResult result); + void addDatasource(SQLEditResult result); void addConnectionDesc(ConnectionDesc *connection); void changeConnectionDesc(ConnectionDesc *connection); bool checkConnectionDesc(ConnectionDesc *connection); bool containsDefaultConnection(); + void activateItem(const QString &name, DataBrowserTree::NodeType type); private: Ui::DataBrowser* ui; diff --git a/limereport/databrowser/lrsqleditdialog.cpp b/limereport/databrowser/lrsqleditdialog.cpp index 90ad426..d53bc3d 100644 --- a/limereport/databrowser/lrsqleditdialog.cpp +++ b/limereport/databrowser/lrsqleditdialog.cpp @@ -78,7 +78,7 @@ QSettings *SQLEditDialog::settings(){ if (m_settings){ return m_settings; } else { - m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_settings = new QSettings("LimeReport",QCoreApplication::applicationName()); m_ownedSettings = true; return m_settings; } @@ -86,7 +86,7 @@ QSettings *SQLEditDialog::settings(){ void SQLEditDialog::setSettings(QSettings *value, bool owned){ if (m_settings && m_ownedSettings) delete m_settings; - m_settings=value; + m_settings = value; m_ownedSettings = owned; } @@ -94,24 +94,29 @@ void SQLEditDialog::accept() { SQLEditResult result; - if (!ui->cbSubdetail->isChecked()){ + if (ui->tabWidget->currentIndex() == 1){ + result.resultMode = SQLEditResult::CSVText; + } else if (!ui->cbSubdetail->isChecked()){ result.resultMode=SQLEditResult::Query; } else { - if (ui->rbSubQuery->isChecked()) result.resultMode=SQLEditResult::SubQuery; + if (ui->rbSubQuery->isChecked()) result.resultMode = SQLEditResult::SubQuery; else result.resultMode=SQLEditResult::SubProxy; } result.connectionName = ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()); result.datasourceName=ui->leDatasourceName->text(); - result.sql=ui->textEditSQL->toPlainText(); - result.dialogMode=m_dialogMode; - result.oldDatasourceName=m_oldDatasourceName; + result.sql = ui->sqlText->toPlainText(); + result.csv = ui->csvText->toPlainText(); + result.dialogMode = m_dialogMode; + result.oldDatasourceName = m_oldDatasourceName; result.subdetail = ui->cbSubdetail->isChecked(); result.masterDatasource=ui->leMaster->text(); result.childDataSource=ui->leChild->text(); + result.separator = ui->leSeparator->text(); + result.firstRowIsHeader = ui->cbUseFirstRowAsHeader->isChecked(); - if (ui->fieldsMap->rowCount()>0){ - for(int i=0;ifieldsMap->rowCount();++i){ + if (ui->fieldsMap->rowCount() > 0){ + for(int i=0; i< ui->fieldsMap->rowCount(); ++i){ LimeReport::FieldsCorrelation fieldsCorrelation; fieldsCorrelation.master = ui->fieldsMap->item(i,0) ? ui->fieldsMap->item(i,0)->data(Qt::DisplayRole).toString() : ""; fieldsCorrelation.detail = ui->fieldsMap->item(i,1) ? ui->fieldsMap->item(i,1)->data(Qt::DisplayRole).toString() : ""; @@ -148,7 +153,7 @@ void SQLEditDialog::hideEvent(QHideEvent *) void SQLEditDialog::check() { if (ui->leDatasourceName->text().isEmpty()) throw LimeReport::ReportError(tr("Datasource Name is empty!")); - if (ui->textEditSQL->toPlainText().isEmpty() && (!ui->rbProxy) ) throw LimeReport::ReportError(tr("SQL is empty!")); + if (ui->sqlText->toPlainText().isEmpty() && (!ui->rbProxy) ) throw LimeReport::ReportError(tr("SQL is empty!")); if (m_dialogMode==AddMode){ if (m_datasources->containsDatasource(ui->leDatasourceName->text())){ throw LimeReport::ReportError(QString(tr("Datasource with name: \"%1\" already exists!")).arg(ui->leDatasourceName->text())); @@ -179,11 +184,13 @@ void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, Q { m_datasources=dataSources; if (!datasourceName.isEmpty()){ - ui->cbSubdetail->setEnabled(false); - initQueryMode(); + ui->cbSubdetail->setEnabled(true); m_oldDatasourceName=datasourceName; ui->leDatasourceName->setText(datasourceName); - ui->textEditSQL->setText(dataSources->queryText(datasourceName)); + ui->sqlText->setText(dataSources->queryText(datasourceName)); + if (dataSources->isQuery(datasourceName)){ + initQueryMode(); + } if (dataSources->isSubQuery(datasourceName)){ initSubQueryMode(); ui->leMaster->setText(dataSources->subQueryByName(datasourceName)->master()); @@ -201,6 +208,12 @@ void SQLEditDialog::setDataSources(LimeReport::DataSourceManager *dataSources, Q curIndex++; } } + if (dataSources->isCSV(datasourceName)){ + ui->csvText->setPlainText(dataSources->csvByName(datasourceName)->csvText()); + ui->leSeparator->setText(dataSources->csvByName(datasourceName)->separator()); + ui->cbUseFirstRowAsHeader->setChecked(dataSources->csvByName(datasourceName)->firstRowIsHeader()); + initCSVMode(); + } } } @@ -254,6 +267,7 @@ void SQLEditDialog::on_pbAddField_clicked() ui->fieldsMap->setRowCount(ui->fieldsMap->rowCount()+1); } + void SQLEditDialog::initQueryMode() { ui->gbSQL->setVisible(true); @@ -264,6 +278,7 @@ void SQLEditDialog::initQueryMode() ui->cbSubdetail->setChecked(false); ui->leMaster->setVisible(false); ui->lbMaster->setVisible(false); + ui->tabWidget->removeTab(1); } void SQLEditDialog::initSubQueryMode() @@ -278,7 +293,7 @@ void SQLEditDialog::initSubQueryMode() ui->leMaster->setVisible(true); ui->leMaster->setEnabled(true); ui->lbMaster->setVisible(true); - + ui->tabWidget->removeTab(1); } void SQLEditDialog::initProxyMode() @@ -294,6 +309,12 @@ void SQLEditDialog::initProxyMode() ui->leMaster->setEnabled(true); ui->lbMaster->setVisible(true); ui->cbSubdetail->setEnabled(false); + ui->tabWidget->removeTab(1); +} + +void SQLEditDialog::initCSVMode() +{ + ui->tabWidget->removeTab(0); } void SQLEditDialog::slotPreviewData() @@ -304,7 +325,7 @@ void SQLEditDialog::slotPreviewData() } m_previewModel = m_datasources->previewSQL( ConnectionDesc::connectionNameForReport(ui->cbbConnection->currentText()), - ui->textEditSQL->toPlainText(), + ui->sqlText->toPlainText(), ui->leMaster->text() ); if (m_previewModel){ diff --git a/limereport/databrowser/lrsqleditdialog.h b/limereport/databrowser/lrsqleditdialog.h index 7773acd..28dcffd 100644 --- a/limereport/databrowser/lrsqleditdialog.h +++ b/limereport/databrowser/lrsqleditdialog.h @@ -77,6 +77,7 @@ private slots: void initQueryMode(); void initSubQueryMode(); void initProxyMode(); + void initCSVMode(); void slotPreviewData(); void slotHidePreview(); private: @@ -96,17 +97,20 @@ private: }; struct SQLEditResult{ - enum ResultMode{Query,SubQuery,SubProxy}; + enum ResultMode{Query, SubQuery, SubProxy, CSVText, Undefined}; QString connectionName; QString datasourceName; QString oldDatasourceName; QString sql; + QString csv; bool subdetail; ResultMode resultMode; QString masterDatasource; QString childDataSource; SQLEditDialog::SQLDialogMode dialogMode; QList fieldMap; + QString separator; + bool firstRowIsHeader; }; } // namespace LimeReport diff --git a/limereport/databrowser/lrsqleditdialog.ui b/limereport/databrowser/lrsqleditdialog.ui index e1353aa..f0abfbe 100644 --- a/limereport/databrowser/lrsqleditdialog.ui +++ b/limereport/databrowser/lrsqleditdialog.ui @@ -6,8 +6,8 @@ 0 0 - 411 - 617 + 422 + 622 @@ -21,30 +21,6 @@ - - - - - - Connection - - - - - - - - 0 - 0 - - - - Qt::NoFocus - - - - - @@ -498,253 +474,351 @@ - - - - - Subdetail - - - - - + + + 0 + + + + SQL + + - - - Master datasource + + + + + Connection + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + + + + + + + + + Subdetail + + + + + + + + + Master datasource + + + + + + + false + + + + + + + + + false + + + Subquery mode + + + + + + + false + + + Filter mode + + + + + + + + + SQL + + + 4 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Preview + + + + + + + Hide Preview + + + + + + - - - false + + + QFrame::NoFrame + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Child datasource + + + + + + + + + + + + + + + Fields map + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + 2 + + + + + + + + + + + ... + + + + :/databrowser/images/add.png:/databrowser/images/add.png + + + true + + + + + + + ... + + + + :/databrowser/images/remove.png:/databrowser/images/remove.png + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Data preview + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + - - - - - false - - - Subquery mode - - - - - - - false - - - Filter mode - - - - - - - - - SQL - - - - 4 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Preview - - - - - - - Hide Preview - - - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - Child datasource - - - - - - - - - - - - - - - Fields map - - - - 4 - - - 4 - - - 4 - - - 4 - - - - - 2 - - - - - - - - - - - ... - - - - :/databrowser/images/add.png:/databrowser/images/add.png - - - true - - - - - - - ... - - - - :/databrowser/images/remove.png:/databrowser/images/remove.png - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - Data preview - - - - 2 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - + + + + CSV + + + + + + + + Separator + + + + + + + + 0 + 0 + + + + + 30 + 16777215 + + + + ; + + + + + + + Use first row as header + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + @@ -787,39 +861,14 @@ - leDatasourceName - cbSubdetail - leMaster - rbSubQuery - rbProxy - textEditSQL - leChild - fieldsMap - pbAddField - pbDelField pushButton_2 pushButton + - - leDatasourceName - textChanged(QString) - LimeReport::SQLEditDialog - slotDataSourceNameEditing() - - - 259 - 54 - - - 289 - 32 - - - pushButton clicked() diff --git a/limereport/databrowser/lrvariabledialog.cpp b/limereport/databrowser/lrvariabledialog.cpp index 4cebd55..7c5b1a0 100644 --- a/limereport/databrowser/lrvariabledialog.cpp +++ b/limereport/databrowser/lrvariabledialog.cpp @@ -30,8 +30,10 @@ #include "lrvariabledialog.h" #include "ui_lrvariabledialog.h" #include "lrglobal.h" +#include "lrvariablesholder.h" #include #include +#include LRVariableDialog::LRVariableDialog(QWidget *parent) : QDialog(parent), @@ -42,8 +44,14 @@ LRVariableDialog::LRVariableDialog(QWidget *parent) : m_oldVariableName("") { ui->setupUi(this); - ui->cbbType->setVisible(false); - ui->lblType->setVisible(false); + + static int enumIndex = LimeReport::Enums::staticMetaObject.indexOfEnumerator("VariableDataType"); + QMetaEnum enumerator = LimeReport::Enums::staticMetaObject.enumerator(enumIndex); + for (int i = 0; icbbType->addItem(enumerator.key(i)); + } + //ui->cbbType->setVisible(false); + //ui->lblType->setVisible(false); } LRVariableDialog::~LRVariableDialog() @@ -66,28 +74,45 @@ void LRVariableDialog::setVariableName(const QString &value) void LRVariableDialog::showEvent(QShowEvent *) { ui->leName->setText(m_variableName); + static int enumIndex = LimeReport::Enums::staticMetaObject.indexOfEnumerator("VariableDataType"); + QMetaEnum enumerator = LimeReport::Enums::staticMetaObject.enumerator(enumIndex); if (!m_variableName.isEmpty()&&m_variablesContainer&&m_variablesContainer->containsVariable(m_variableName)){ - ui->leValue->setText(m_variablesContainer->variable(m_variableName).toString()); + ui->leValue->setPlainText(m_variablesContainer->variable(m_variableName).toString()); +#ifdef HAVE_QT5 + ui->cbbType->setCurrentText(enumerator.valueToKey(m_variablesContainer->variableDataType(m_variableName))); +#endif +#ifdef HAVE_QT4 + ui->cbbType->setCurrentIndex(ui->cbbType->findText(enumerator.valueToKey(m_variablesContainer->variableDataType(m_variableName)))); +#endif + ui->cbbMandatory->setChecked(m_variablesContainer->variableIsMandatory(m_variableName)); } } void LRVariableDialog::accept() { try{ - if (m_variablesContainer&&!ui->leName->text().isEmpty()){ - if (m_changeMode){ - if (m_oldVariableName==ui->leName->text()){ - m_variablesContainer->changeVariable(m_oldVariableName,value()); + static int enumIndex = LimeReport::Enums::staticMetaObject.indexOfEnumerator("VariableDataType"); + QMetaEnum enumerator = LimeReport::Enums::staticMetaObject.enumerator(enumIndex); + + if (m_variablesContainer&&!ui->leName->text().isEmpty()){ + if (m_changeMode){ + if (m_oldVariableName==ui->leName->text()){ + m_variablesContainer->changeVariable(m_oldVariableName,value()); + } else { + m_variablesContainer->deleteVariable(m_oldVariableName); + m_variablesContainer->addVariable(ui->leName->text(),value(), LimeReport::VarDesc::Report); + } } else { - m_variablesContainer->deleteVariable(m_oldVariableName); m_variablesContainer->addVariable(ui->leName->text(),value(), LimeReport::VarDesc::Report); } - } else { - m_variablesContainer->addVariable(ui->leName->text(),value(), LimeReport::VarDesc::Report); + m_variablesContainer->setVarableMandatory(ui->leName->text(),ui->cbbMandatory->isChecked()); + m_variablesContainer->setVariableDataType( + ui->leName->text(), + LimeReport::VariableDataType(enumerator.keysToValue(ui->cbbType->currentText().toLatin1())) + ); + emit signalVariableAccepted(ui->leName->text()); + QDialog::accept(); } - emit signalVariableAccepted(ui->leName->text()); - QDialog::accept(); - } } catch (LimeReport::ReportError &exception){ QMessageBox::critical(this,tr("Attention"),exception.what()); } @@ -95,5 +120,5 @@ void LRVariableDialog::accept() QVariant LRVariableDialog::value() { - return ui->leValue->text(); + return ui->leValue->toPlainText(); } diff --git a/limereport/databrowser/lrvariabledialog.ui b/limereport/databrowser/lrvariabledialog.ui index df97830..08bf6c7 100644 --- a/limereport/databrowser/lrvariabledialog.ui +++ b/limereport/databrowser/lrvariabledialog.ui @@ -6,8 +6,8 @@ 0 0 - 218 - 126 + 328 + 222 @@ -18,35 +18,8 @@ :/databrowser/images/value:/databrowser/images/value - - 2 - - - 4 - - - 4 - - - 4 - - - 4 - - - - 7 - - - 5 - - - 4 - - - 8 - + @@ -65,10 +38,7 @@ - - - - + @@ -77,8 +47,18 @@ + + + + + + + Mandatory + + + @@ -93,6 +73,7 @@ + diff --git a/limereport/designer.pri b/limereport/designer.pri new file mode 100644 index 0000000..1c7e279 --- /dev/null +++ b/limereport/designer.pri @@ -0,0 +1,109 @@ +include(../common.pri) +DEFINES+=HAVE_REPORT_DESIGNER + +contains(CONFIG,dialogdesigner){ + include($$REPORT_PATH/dialogdesigner/dialogdesigner.pri) +} + +INCLUDEPATH += $$REPORT_PATH/objectinspector \ + $$REPORT_PATH/databrowser + +SOURCES += \ + $$REPORT_PATH/databrowser/lrdatabrowser.cpp \ + $$REPORT_PATH/databrowser/lrsqleditdialog.cpp \ + $$REPORT_PATH/databrowser/lrconnectiondialog.cpp \ + $$REPORT_PATH/databrowser/lrvariabledialog.cpp \ + $$REPORT_PATH/databrowser/lrdatabrowsertree.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrstringpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrrectproptem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrintpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrenumpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrboolpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrflagspropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrfontpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrimagepropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrqrealpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.cpp \ + $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrfonteditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrimageeditor.cpp \ + $$REPORT_PATH/objectinspector/editors/lrcoloreditor.cpp \ + $$REPORT_PATH/objectinspector/lrbasedesignobjectmodel.cpp \ + $$REPORT_PATH/objectinspector/lrobjectinspectorwidget.cpp \ + $$REPORT_PATH/objectinspector/lrobjectitemmodel.cpp \ + $$REPORT_PATH/objectinspector/lrobjectpropitem.cpp \ + $$REPORT_PATH/objectinspector/lrpropertydelegate.cpp \ + $$REPORT_PATH/objectsbrowser/lrobjectbrowser.cpp \ + $$REPORT_PATH/scriptbrowser/lrscriptbrowser.cpp \ + $$REPORT_PATH/items/lrsubitemparentpropitem.cpp \ + $$REPORT_PATH/items/lralignpropitem.cpp \ + $$REPORT_PATH/items/editors/lritemsaligneditorwidget.cpp \ + $$REPORT_PATH/translationeditor/translationeditor.cpp \ + $$REPORT_PATH/translationeditor/languageselectdialog.cpp \ + $$REPORT_PATH/lrreportdesignwidget.cpp \ + $$REPORT_PATH/lrreportdesignwindow.cpp + +HEADERS += \ + $$REPORT_PATH/databrowser/lrdatabrowser.h \ + $$REPORT_PATH/databrowser/lrsqleditdialog.h \ + $$REPORT_PATH/databrowser/lrconnectiondialog.h \ + $$REPORT_PATH/databrowser/lrvariabledialog.h \ + $$REPORT_PATH/databrowser/lrdatabrowsertree.h \ + $$REPORT_PATH/scriptbrowser/lrscriptbrowser.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrstringpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrrectproptem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrfontpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrimagepropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrintpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrenumpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrboolpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrflagspropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrqrealpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrmarginpropitem.h \ + $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrimageeditor.h \ + $$REPORT_PATH/objectinspector/editors/lrcoloreditor.h \ + $$REPORT_PATH/objectinspector/editors/lrfonteditor.h \ + $$REPORT_PATH/objectinspector/lrbasedesignobjectmodel.h \ + $$REPORT_PATH/objectinspector/lrobjectinspectorwidget.h \ + $$REPORT_PATH/objectinspector/lrobjectitemmodel.h \ + $$REPORT_PATH/objectinspector/lrobjectpropitem.h \ + $$REPORT_PATH/objectinspector/lrpropertydelegate.h \ + $$REPORT_PATH/objectsbrowser/lrobjectbrowser.h \ + $$REPORT_PATH/translationeditor/translationeditor.h \ + $$REPORT_PATH/translationeditor/languageselectdialog.h \ + $$REPORT_PATH/items/editors/lritemsaligneditorwidget.h \ + $$REPORT_PATH/items/lrsubitemparentpropitem.h \ + $$REPORT_PATH/items/lralignpropitem.h \ + $$REPORT_PATH/lrreportdesignwidget.h \ + $$REPORT_PATH/lrreportdesignwindow.h + +FORMS += \ + $$REPORT_PATH/databrowser/lrsqleditdialog.ui \ + $$REPORT_PATH/databrowser/lrconnectiondialog.ui \ + $$REPORT_PATH/databrowser/lrdatabrowser.ui \ + $$REPORT_PATH/databrowser/lrvariabledialog.ui \ + $$REPORT_PATH/objectinspector/editors/ltextitempropertyeditor.ui \ + $$REPORT_PATH/scriptbrowser/lrscriptbrowser.ui \ + $$REPORT_PATH/translationeditor/translationeditor.ui \ + $$REPORT_PATH/translationeditor/languageselectdialog.ui + +RESOURCES += \ + $$REPORT_PATH/objectinspector/lobjectinspector.qrc \ + $$REPORT_PATH/databrowser/lrdatabrowser.qrc \ + $$REPORT_PATH/scriptbrowser/lrscriptbrowser.qrc \ + $$REPORT_PATH/translationeditor/translationeditor.qrc diff --git a/limereport/dialogdesigner/3rdparty/designer/pluginmanager_p.h b/limereport/dialogdesigner/3rdparty/designer/pluginmanager_p.h new file mode 100644 index 0000000..1706182 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/designer/pluginmanager_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information +** to ensure GNU General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. In addition, as a special +** exception, Nokia gives you certain additional rights. These rights +** are described in the Nokia Qt GPL Exception version 1.3, included in +** the file GPL_EXCEPTION.txt in this package. +** +** Qt for Windows(R) Licensees +** As a special exception, Nokia, as the sole copyright holder for Qt +** Designer, grants users of the Qt/Eclipse Integration plug-in the +** right for the Qt/Eclipse Integration to link to functionality +** provided by Qt Designer and its related libraries. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Designer. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef PLUGINMANAGER_H +#define PLUGINMANAGER_H + +#include "shared_global_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class QDesignerFormEditorInterface; +class QDesignerCustomWidgetInterface; +class QDesignerPluginManagerPrivate; + +class QDESIGNER_SHARED_EXPORT QDesignerPluginManager: public QObject +{ + Q_OBJECT +public: + explicit QDesignerPluginManager(QDesignerFormEditorInterface *core); + virtual ~QDesignerPluginManager(); + + QDesignerFormEditorInterface *core() const; + + QObject *instance(const QString &plugin) const; + + QStringList registeredPlugins() const; + + QStringList findPlugins(const QString &path); + + QStringList pluginPaths() const; + void setPluginPaths(const QStringList &plugin_paths); + + QStringList disabledPlugins() const; + void setDisabledPlugins(const QStringList &disabled_plugins); + + QStringList failedPlugins() const; + QString failureReason(const QString &pluginName) const; + + QList instances() const; + QList registeredCustomWidgets() const; + + bool registerNewPlugins(); + +public slots: + bool syncSettings(); + void ensureInitialized(); + +private: + void updateRegisteredPlugins(); + void registerPath(const QString &path); + void registerPlugin(const QString &plugin); + +private: + static QStringList defaultPluginPaths(); + + QDesignerPluginManagerPrivate *m_d; +}; + +QT_END_NAMESPACE + +#endif // PLUGINMANAGER_H diff --git a/limereport/dialogdesigner/3rdparty/designer/qdesigner_integration_p.h b/limereport/dialogdesigner/3rdparty/designer/qdesigner_integration_p.h new file mode 100644 index 0000000..6c76d10 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/designer/qdesigner_integration_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information +** to ensure GNU General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. In addition, as a special +** exception, Nokia gives you certain additional rights. These rights +** are described in the Nokia Qt GPL Exception version 1.3, included in +** the file GPL_EXCEPTION.txt in this package. +** +** Qt for Windows(R) Licensees +** As a special exception, Nokia, as the sole copyright holder for Qt +** Designer, grants users of the Qt/Eclipse Integration plug-in the +** right for the Qt/Eclipse Integration to link to functionality +** provided by Qt Designer and its related libraries. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Designer. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QDESIGNER_INTEGRATION_H +#define QDESIGNER_INTEGRATION_H + +#include "shared_global_p.h" +#include + +#include + +QT_BEGIN_NAMESPACE + +class QDesignerFormEditorInterface; +class QDesignerFormWindowInterface; +class QDesignerResourceBrowserInterface; + +class QVariant; +class QWidget; + +namespace qdesigner_internal { + +struct Selection; +class QDesignerIntegrationPrivate; + +class QDESIGNER_SHARED_EXPORT QDesignerIntegration: public QDesignerIntegrationInterface +{ + Q_OBJECT +public: + explicit QDesignerIntegration(QDesignerFormEditorInterface *core, QObject *parent = 0); + virtual ~QDesignerIntegration(); + + static void requestHelp(const QDesignerFormEditorInterface *core, const QString &manual, const QString &document); + + virtual QWidget *containerWindow(QWidget *widget) const; + + // Load plugins into widget database and factory. + static void initializePlugins(QDesignerFormEditorInterface *formEditor); + void emitObjectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName); + + // Create a resource browser specific to integration. Language integration takes precedence + virtual QDesignerResourceBrowserInterface *createResourceBrowser(QWidget *parent = 0); + +signals: + void propertyChanged(QDesignerFormWindowInterface *formWindow, const QString &name, const QVariant &value); + void objectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName); + void helpRequested(const QString &manual, const QString &document); + +public slots: + virtual void updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling); + // Additional signals of designer property editor +// virtual void updatePropertyComment(const QString &name, const QString &value); + virtual void resetProperty(const QString &name); + virtual void addDynamicProperty(const QString &name, const QVariant &value); + virtual void removeDynamicProperty(const QString &name); + + + virtual void updateActiveFormWindow(QDesignerFormWindowInterface *formWindow); + virtual void setupFormWindow(QDesignerFormWindowInterface *formWindow); + virtual void updateSelection(); + virtual void updateGeometry(); + virtual void activateWidget(QWidget *widget); + + void updateCustomWidgetPlugins(); + +private slots: + void updatePropertyPrivate(const QString &name, const QVariant &value); + +private: + void initialize(); + void getSelection(Selection &s); + QObject *propertyEditorObject(); + + QDesignerIntegrationPrivate *m_d; +}; + +} // namespace qdesigner_internal + +QT_END_NAMESPACE + +#endif // QDESIGNER_INTEGRATION_H diff --git a/limereport/dialogdesigner/3rdparty/designer/shared_global_p.h b/limereport/dialogdesigner/3rdparty/designer/shared_global_p.h new file mode 100644 index 0000000..3b9ff24 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/designer/shared_global_p.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information +** to ensure GNU General Public Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. In addition, as a special +** exception, Nokia gives you certain additional rights. These rights +** are described in the Nokia Qt GPL Exception version 1.3, included in +** the file GPL_EXCEPTION.txt in this package. +** +** Qt for Windows(R) Licensees +** As a special exception, Nokia, as the sole copyright holder for Qt +** Designer, grants users of the Qt/Eclipse Integration plug-in the +** right for the Qt/Eclipse Integration to link to functionality +** provided by Qt Designer and its related libraries. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of Qt Designer. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#ifndef SHARED_GLOBAL_H +#define SHARED_GLOBAL_H + +#include + +#ifdef QT_DESIGNER_STATIC +#define QDESIGNER_SHARED_EXTERN +#define QDESIGNER_SHARED_IMPORT +#else +#define QDESIGNER_SHARED_EXTERN Q_DECL_EXPORT +#define QDESIGNER_SHARED_IMPORT Q_DECL_IMPORT +#endif + +#ifndef QT_NO_SHARED_EXPORT +# ifdef QDESIGNER_SHARED_LIBRARY +# define QDESIGNER_SHARED_EXPORT QDESIGNER_SHARED_EXTERN +# else +# define QDESIGNER_SHARED_EXPORT QDESIGNER_SHARED_IMPORT +# endif +#else +# define QDESIGNER_SHARED_EXPORT +#endif + +#endif // SHARED_GLOBAL_H diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/README.txt b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/README.txt new file mode 100644 index 0000000..f5351ea --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/README.txt @@ -0,0 +1,10 @@ +This is a new Designer integration, started on 28.02.2008. + +The reason for it is the introduction of layout caching +in Qt 4.4, which unearthed a lot of mainwindow-size related +bugs in Designer and all integrations. + +The goal of it is to have a closed layout chain from +integration top level to form window. + +Friedemann diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/designerintegration.pri b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/designerintegration.pri new file mode 100644 index 0000000..f3a02f6 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/designerintegration.pri @@ -0,0 +1,11 @@ +INCLUDEPATH *= $$PWD $$PWD/.. + +SOURCES += $$PWD/widgethost.cpp \ + $$PWD/sizehandlerect.cpp \ + $$PWD/formresizer.cpp + +HEADERS += $$PWD/widgethost.h \ + $$PWD/sizehandlerect.h \ + $$PWD/formresizer.h \ + $$PWD/widgethostconstants.h \ + $$PWD/../namespace_global.h diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/formresizer.cpp b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/formresizer.cpp new file mode 100644 index 0000000..e0d88ed --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/formresizer.cpp @@ -0,0 +1,198 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "formresizer.h" +#include "sizehandlerect.h" +#include "widgethostconstants.h" + +#include + +#include + +#include +#include +#include +#include +#include + +enum { debugFormResizer = 0 }; + +using namespace SharedTools::Internal; + +FormResizer::FormResizer(QWidget *parent) : + QWidget(parent), + m_frame(new QFrame), + m_formWindow(0) +{ + // Make the resize grip of a mainwindow form find us as resizable window. + setWindowFlags(windowFlags() | Qt::SubWindow); + setBackgroundRole(QPalette::Base); + + QVBoxLayout *handleLayout = new QVBoxLayout(this); + handleLayout->setMargin(SELECTION_MARGIN); + handleLayout->addWidget(m_frame); + + m_frame->setFrameStyle(QFrame::Panel | QFrame::Raised); + QVBoxLayout *layout = new QVBoxLayout(m_frame); + layout->setMargin(0); + // handles + m_handles.reserve(SizeHandleRect::Left); + for (int i = SizeHandleRect::LeftTop; i <= SizeHandleRect::Left; ++i) { + SizeHandleRect *shr = new SizeHandleRect(this, static_cast(i), this); + connect(shr, SIGNAL(mouseButtonReleased(QRect,QRect)), this, SIGNAL(formWindowSizeChanged(QRect,QRect))); + m_handles.push_back(shr); + } + setState(SelectionHandleActive); + updateGeometry(); +} + +void FormResizer::updateGeometry() +{ + const QRect &geom = m_frame->geometry(); + + if (debugFormResizer) + qDebug() << "FormResizer::updateGeometry() " << size() << " frame " << geom; + + const int w = SELECTION_HANDLE_SIZE; + const int h = SELECTION_HANDLE_SIZE; + + const Handles::iterator hend = m_handles.end(); + for (Handles::iterator it = m_handles.begin(); it != hend; ++it) { + SizeHandleRect *hndl = *it;; + switch (hndl->dir()) { + case SizeHandleRect::LeftTop: + hndl->move(geom.x() - w / 2, geom.y() - h / 2); + break; + case SizeHandleRect::Top: + hndl->move(geom.x() + geom.width() / 2 - w / 2, geom.y() - h / 2); + break; + case SizeHandleRect::RightTop: + hndl->move(geom.x() + geom.width() - w / 2, geom.y() - h / 2); + break; + case SizeHandleRect::Right: + hndl->move(geom.x() + geom.width() - w / 2, geom.y() + geom.height() / 2 - h / 2); + break; + case SizeHandleRect::RightBottom: + hndl->move(geom.x() + geom.width() - w / 2, geom.y() + geom.height() - h / 2); + break; + case SizeHandleRect::Bottom: + hndl->move(geom.x() + geom.width() / 2 - w / 2, geom.y() + geom.height() - h / 2); + break; + case SizeHandleRect::LeftBottom: + hndl->move(geom.x() - w / 2, geom.y() + geom.height() - h / 2); + break; + case SizeHandleRect::Left: + hndl->move(geom.x() - w / 2, geom.y() + geom.height() / 2 - h / 2); + break; + default: + break; + } + } +} + +void FormResizer::update() +{ + const Handles::iterator hend = m_handles.end(); + for (Handles::iterator it = m_handles.begin(); it != hend; ++it) { + (*it)->update(); + } +} + +void FormResizer::setState(SelectionHandleState st) +{ + if (debugFormResizer) + qDebug() << "FormResizer::setState " << st; + + const Handles::iterator hend = m_handles.end(); + for (Handles::iterator it = m_handles.begin(); it != hend; ++it) + (*it)->setState(st); +} + +void FormResizer::setFormWindow(QDesignerFormWindowInterface *fw) +{ + if (debugFormResizer) + qDebug() << "FormResizer::setFormWindow " << fw; + QVBoxLayout *layout = qobject_cast(m_frame->layout()); + Q_ASSERT(layout); + if (layout->count()) + delete layout->takeAt(0); + m_formWindow = fw; + + if (m_formWindow) + layout->addWidget(m_formWindow); + mainContainerChanged(); + connect(fw, SIGNAL(mainContainerChanged(QWidget*)), this, SLOT(mainContainerChanged())); +} + +void FormResizer::resizeEvent(QResizeEvent *event) +{ + if (debugFormResizer) + qDebug() << ">FormResizer::resizeEvent" << event->size(); + updateGeometry(); + QWidget::resizeEvent(event); + if (debugFormResizer) + qDebug() << "lineWidth(); + const QMargins frameMargins = m_frame->contentsMargins(); + const int margin = 2* SELECTION_MARGIN; + QSize size = QSize( margin, margin ); + size += QSize( qMax( frameMargins.left(), lineWidth ), qMax( frameMargins.top(), lineWidth ) ); + size += QSize( qMax( frameMargins.right(), lineWidth ), qMax( frameMargins.bottom(), lineWidth ) ); + return size; +} + +QWidget *FormResizer::mainContainer() +{ + if (m_formWindow) + return m_formWindow->mainContainer(); + return 0; +} + +void FormResizer::mainContainerChanged() +{ + const QSize maxWidgetSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (const QWidget *mc = mainContainer()) { + // Set Maximum size which is not handled via a hint (as opposed to minimum size) + const QSize maxWidgetSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + const QSize formMaxSize = mc->maximumSize(); + QSize newMaxSize = maxWidgetSize; + if (formMaxSize != maxWidgetSize) + newMaxSize = formMaxSize + decorationSize(); + if (debugFormResizer) + qDebug() << "FormResizer::mainContainerChanged" << mc << " Size " << mc->size()<< newMaxSize; + setMaximumSize(newMaxSize); + resize(decorationSize() + mc->size()); + } else { + setMaximumSize(maxWidgetSize); + } +} diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/formresizer.h b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/formresizer.h new file mode 100644 index 0000000..c7bd689 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/formresizer.h @@ -0,0 +1,99 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ +#ifndef FORMRESIZER_H +#define FORMRESIZER_H + +#include "namespace_global.h" + +#include "widgethostconstants.h" + +#include +#include + +QT_FORWARD_DECLARE_CLASS(QDesignerFormWindowInterface) +QT_FORWARD_DECLARE_CLASS(QFrame) + +namespace SharedTools { +namespace Internal { + +class SizeHandleRect; + +/* A window to embed a form window interface as follows: + * + * Widget + * | + * +---+----+ + * | | + * | | + * Handles QVBoxLayout [margin: SELECTION_MARGIN] + * | + * Frame [margin: lineWidth] + * | + * QVBoxLayout + * | + * QDesignerFormWindowInterface + * + * Can be embedded into a QScrollArea. */ + +class FormResizer : public QWidget +{ + Q_OBJECT +public: + + FormResizer(QWidget *parent = 0); + + void updateGeometry(); + void setState(SelectionHandleState st); + void update(); + + void setFormWindow(QDesignerFormWindowInterface *fw); + +signals: + void formWindowSizeChanged(const QRect &oldGeo, const QRect &newGeo); + +protected: + virtual void resizeEvent(QResizeEvent *event); + +private slots: + void mainContainerChanged(); + +private: + QSize decorationSize() const; + QWidget *mainContainer(); + + QFrame *m_frame; + typedef QVector Handles; + Handles m_handles; + QDesignerFormWindowInterface * m_formWindow; +}; + +} +} // namespace SharedTools + +#endif // FORMRESIZER_H diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/sizehandlerect.cpp b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/sizehandlerect.cpp new file mode 100644 index 0000000..4247769 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/sizehandlerect.cpp @@ -0,0 +1,188 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ +#include "sizehandlerect.h" +#include "widgethostconstants.h" + +#include + +#include +#include +#include +#include + +enum { debugSizeHandle = 0 }; + +using namespace SharedTools::Internal; + +SizeHandleRect::SizeHandleRect(QWidget *parent, Direction d, QWidget *resizable) : + QWidget(parent), + m_dir(d), + m_resizable(resizable), + m_state(SelectionHandleOff) +{ + setBackgroundRole(QPalette::Text); + setAutoFillBackground(true); + + setFixedSize(SELECTION_HANDLE_SIZE, SELECTION_HANDLE_SIZE); + setMouseTracking(false); + updateCursor(); +} + +void SizeHandleRect::updateCursor() +{ + switch (m_dir) { + case Right: + case RightTop: + setCursor(Qt::SizeHorCursor); + return; + case RightBottom: + setCursor(Qt::SizeFDiagCursor); + return; + case LeftBottom: + case Bottom: + setCursor(Qt::SizeVerCursor); + return; + default: + break; + } + + setCursor(Qt::ArrowCursor); +} + +void SizeHandleRect::paintEvent(QPaintEvent *) +{ + switch (m_state) { + case SelectionHandleOff: + break; + case SelectionHandleInactive: { + QPainter p(this); + p.setPen(Qt::red); + p.drawRect(0, 0, width() - 1, height() - 1); + } + break; + case SelectionHandleActive: { + QPainter p(this); + p.setPen(Qt::blue); + p.drawRect(0, 0, width() - 1, height() - 1); + } + break; + } +} + +void SizeHandleRect::mousePressEvent(QMouseEvent *e) +{ + e->accept(); + + if (e->button() != Qt::LeftButton) + return; + + m_startSize = m_curSize = m_resizable->size(); + m_startPos = m_curPos = m_resizable->mapFromGlobal(e->globalPos()); + if (debugSizeHandle) + qDebug() << "SizeHandleRect::mousePressEvent" << m_startSize << m_startPos << m_curPos; + +} + +void SizeHandleRect::mouseMoveEvent(QMouseEvent *e) +{ + if (!(e->buttons() & Qt::LeftButton)) + return; + + // Try resize with delta against start position. + // We don't take little deltas in consecutive move events as this + // causes the handle and the mouse cursor to become out of sync + // once a min/maxSize limit is hit. When the cursor reenters the valid + // areas, it will now snap to it. + m_curPos = m_resizable->mapFromGlobal(e->globalPos()); + QSize delta = QSize(m_curPos.x() - m_startPos.x(), m_curPos.y() - m_startPos.y()); + switch (m_dir) { + case Right: + case RightTop: // Only width + delta.setHeight(0); + break; + case RightBottom: // All dimensions + break; + case LeftBottom: + case Bottom: // Only height + delta.setWidth(0); + break; + default: + delta = QSize(0, 0); + break; + } + if (delta != QSize(0, 0)) + tryResize(delta); +} + +void SizeHandleRect::mouseReleaseEvent(QMouseEvent *e) +{ + if (e->button() != Qt::LeftButton) + return; + + e->accept(); + if (m_startSize != m_curSize) { + const QRect startRect = QRect(0, 0, m_startPos.x(), m_startPos.y()); + const QRect newRect = QRect(0, 0, m_curPos.x(), m_curPos.y()); + if (debugSizeHandle) + qDebug() << "SizeHandleRect::mouseReleaseEvent" << startRect << newRect; + emit mouseButtonReleased(startRect, newRect); + } +} + +void SizeHandleRect::tryResize(const QSize &delta) +{ + // Try resize with delta against start position + QSize newSize = m_startSize + delta; + newSize = newSize.expandedTo(m_resizable->minimumSizeHint()); + newSize = newSize.expandedTo(m_resizable->minimumSize()); + newSize = newSize.boundedTo(m_resizable->maximumSize()); + if (newSize == m_resizable->size()) + return; + if (debugSizeHandle) + qDebug() << "SizeHandleRect::tryResize by (" << m_startSize << '+' << delta << ')' << newSize; + m_resizable->resize(newSize); + m_curSize = m_resizable->size(); +} + +void SizeHandleRect::setState(SelectionHandleState st) +{ + if (st == m_state) + return; + switch (st) { + case SelectionHandleOff: + hide(); + break; + case SelectionHandleInactive: + case SelectionHandleActive: + show(); + raise(); + break; + } + m_state = st; +} diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/sizehandlerect.h b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/sizehandlerect.h new file mode 100644 index 0000000..c916b00 --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/sizehandlerect.h @@ -0,0 +1,82 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ +#ifndef SIZEHANDLERECT_H +#define SIZEHANDLERECT_H + +#include "namespace_global.h" + +#include "widgethostconstants.h" + +#include +#include + +namespace SharedTools { +namespace Internal { + +class SizeHandleRect : public QWidget +{ + Q_OBJECT +public: + enum Direction { LeftTop, Top, RightTop, Right, RightBottom, Bottom, LeftBottom, Left }; + + SizeHandleRect(QWidget *parent, Direction d, QWidget *resizable); + + Direction dir() const { return m_dir; } + void updateCursor(); + void setState(SelectionHandleState st); + +signals: + + void mouseButtonReleased(const QRect &, const QRect &); + +protected: + void paintEvent(QPaintEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + +private: + void tryResize(const QSize &delta); + +private: + const Direction m_dir; + QPoint m_startPos; + QPoint m_curPos; + QSize m_startSize; + QSize m_curSize; + QWidget *m_resizable; + SelectionHandleState m_state; +}; + +} +} // namespace SharedTools + + +#endif // SIZEHANDLERECT_H + diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethost.cpp b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethost.cpp new file mode 100644 index 0000000..b78eb4b --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethost.cpp @@ -0,0 +1,111 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "widgethost.h" +#include "formresizer.h" +#include "widgethostconstants.h" + +#include +#include + +#include +#include +#include +#include +#include + +using namespace SharedTools; + +// ---------- WidgetHost +WidgetHost::WidgetHost(QWidget *parent, QDesignerFormWindowInterface *formWindow) : + QScrollArea(parent), + m_formWindow(0), + m_formResizer(new Internal::FormResizer) +{ + setWidget(m_formResizer); + // Re-set flag (gets cleared by QScrollArea): Make the resize grip of a mainwindow form find the resizer as resizable window. + m_formResizer->setWindowFlags(m_formResizer->windowFlags() | Qt::SubWindow); + setFormWindow(formWindow); +} + +WidgetHost::~WidgetHost() +{ + if (m_formWindow) + delete m_formWindow; +} + +void WidgetHost::setFormWindow(QDesignerFormWindowInterface *fw) +{ + m_formWindow = fw; + if (!fw) + return; + + m_formResizer->setFormWindow(fw); + + setBackgroundRole(QPalette::Base); + m_formWindow->setAutoFillBackground(true); + m_formWindow->setBackgroundRole(QPalette::Background); + + connect(m_formResizer, SIGNAL(formWindowSizeChanged(QRect, QRect)), + this, SLOT(fwSizeWasChanged(QRect, QRect))); + connect(m_formWindow, SIGNAL(destroyed(QObject*)), this, SLOT(formWindowDeleted(QObject*))); +} + +QSize WidgetHost::formWindowSize() const +{ + if (!m_formWindow || !m_formWindow->mainContainer()) + return QSize(); + return m_formWindow->mainContainer()->size(); +} + +void WidgetHost::fwSizeWasChanged(const QRect &, const QRect &) +{ + // newGeo is the mouse coordinates, thus moving the Right will actually emit wrong height + emit formWindowSizeChanged(formWindowSize().width(), formWindowSize().height()); +} + +void WidgetHost::formWindowDeleted(QObject *object) +{ + if (object == m_formWindow) m_formWindow = 0; +} + +void WidgetHost::updateFormWindowSelectionHandles(bool active) +{ + Internal::SelectionHandleState state = Internal::SelectionHandleOff; + const QDesignerFormWindowCursorInterface *cursor = m_formWindow->cursor(); + if (cursor->isWidgetSelected(m_formWindow->mainContainer())) + state = active ? Internal::SelectionHandleActive : Internal::SelectionHandleInactive; + + m_formResizer->setState(state); +} + +QWidget *WidgetHost::integrationContainer() const +{ + return m_formResizer; +} diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethost.h b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethost.h new file mode 100644 index 0000000..82b9fef --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethost.h @@ -0,0 +1,80 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef WIDGETHOST_H +#define WIDGETHOST_H + +#include "namespace_global.h" + +#include + +QT_FORWARD_DECLARE_CLASS(QDesignerFormWindowInterface) + +namespace SharedTools { + +namespace Internal { + class FormResizer; +} + +/* A scroll area that embeds a Designer form window */ + +class WidgetHost : public QScrollArea +{ + Q_OBJECT +public: + WidgetHost(QWidget *parent = 0, QDesignerFormWindowInterface *formWindow = 0); + virtual ~WidgetHost(); + // Show handles if active and main container is selected. + void updateFormWindowSelectionHandles(bool active); + + inline QDesignerFormWindowInterface *formWindow() const { return m_formWindow; } + + QWidget *integrationContainer() const; + +protected: + void setFormWindow(QDesignerFormWindowInterface *fw); + +signals: + void formWindowSizeChanged(int, int); + +private slots: + void fwSizeWasChanged(const QRect &, const QRect &); + void formWindowDeleted(QObject* object); + +private: + QSize formWindowSize() const; + + QDesignerFormWindowInterface *m_formWindow; + Internal::FormResizer *m_formResizer; + QSize m_oldFakeWidgetSize; +}; + +} // namespace SharedTools + +#endif // WIDGETHOST_H diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethostconstants.h b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethostconstants.h new file mode 100644 index 0000000..b1f7fff --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/designerintegrationv2/widgethostconstants.h @@ -0,0 +1,41 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef WIDGETHOST_CONSTANTS_H +#define WIDGETHOST_CONSTANTS_H + +namespace SharedTools { + namespace Internal { + enum { SELECTION_HANDLE_SIZE = 6, SELECTION_MARGIN = 10 }; + enum SelectionHandleState { SelectionHandleOff, SelectionHandleInactive, SelectionHandleActive }; + } +} + +#endif // WIDGETHOST_CONSTANTS_H + diff --git a/limereport/dialogdesigner/3rdparty/qtcreator/namespace_global.h b/limereport/dialogdesigner/3rdparty/qtcreator/namespace_global.h new file mode 100644 index 0000000..7b6ba3f --- /dev/null +++ b/limereport/dialogdesigner/3rdparty/qtcreator/namespace_global.h @@ -0,0 +1,48 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef NAMESPACE_GLOBAL_H +#define NAMESPACE_GLOBAL_H + +#include + +#if QT_VERSION < 0x040400 +# define QT_ADD_NAMESPACE(name) ::name +# define QT_USE_NAMESPACE +# define QT_BEGIN_NAMESPACE +# define QT_END_NAMESPACE +# define QT_BEGIN_INCLUDE_NAMESPACE +# define QT_END_INCLUDE_NAMESPACE +# define QT_BEGIN_MOC_NAMESPACE +# define QT_END_MOC_NAMESPACE +# define QT_FORWARD_DECLARE_CLASS(name) class name; +# define QT_MANGLE_NAMESPACE(name) name +#endif + +#endif // NAMESPACE_GLOBAL_H diff --git a/limereport/dialogdesigner/dialogdesigner.pri b/limereport/dialogdesigner/dialogdesigner.pri new file mode 100644 index 0000000..960b7c3 --- /dev/null +++ b/limereport/dialogdesigner/dialogdesigner.pri @@ -0,0 +1,27 @@ +include(../../common.pri) +include($$PWD/3rdparty/qtcreator/designerintegrationv2/designerintegration.pri) +INCLUDEPATH *= $$PWD/3rdparty/designer +greaterThan(QT_MAJOR_VERSION, 4) { + contains(QT,uitools){ + DEFINES += HAVE_QTDESIGNER_INTEGRATION + } +} +lessThan(QT_MAJOR_VERSION, 5){ + contains(CONFIG,uitools){ + DEFINES += HAVE_QTDESIGNER_INTEGRATION + } +} + +greaterThan(QT_MAJOR_VERSION, 4) { + QT *= designer designercomponents-private + +} else { + CONFIG *= designer + qtAddLibrary( QtDesignerComponents ) +} + +SOURCES += $$PWD/lrdialogdesigner.cpp +HEADERS += $$PWD/lrdialogdesigner.h + +RESOURCES += \ + $$PWD/dialogdesigner.qrc diff --git a/limereport/dialogdesigner/dialogdesigner.qrc b/limereport/dialogdesigner/dialogdesigner.qrc new file mode 100644 index 0000000..3911131 --- /dev/null +++ b/limereport/dialogdesigner/dialogdesigner.qrc @@ -0,0 +1,12 @@ + + + images/buddytool.png + images/editform.png + images/signalslottool.png + images/tabordertool.png + images/widgettool.png + + + templates/Dialog.ui + + diff --git a/limereport/dialogdesigner/images/buddytool.png b/limereport/dialogdesigner/images/buddytool.png new file mode 100644 index 0000000..4cd968b Binary files /dev/null and b/limereport/dialogdesigner/images/buddytool.png differ diff --git a/limereport/dialogdesigner/images/editform.png b/limereport/dialogdesigner/images/editform.png new file mode 100644 index 0000000..452fcd8 Binary files /dev/null and b/limereport/dialogdesigner/images/editform.png differ diff --git a/limereport/dialogdesigner/images/signalslottool.png b/limereport/dialogdesigner/images/signalslottool.png new file mode 100644 index 0000000..e80fd1c Binary files /dev/null and b/limereport/dialogdesigner/images/signalslottool.png differ diff --git a/limereport/dialogdesigner/images/tabordertool.png b/limereport/dialogdesigner/images/tabordertool.png new file mode 100644 index 0000000..7e6e2de Binary files /dev/null and b/limereport/dialogdesigner/images/tabordertool.png differ diff --git a/limereport/dialogdesigner/images/widgettool.png b/limereport/dialogdesigner/images/widgettool.png new file mode 100644 index 0000000..a52224e Binary files /dev/null and b/limereport/dialogdesigner/images/widgettool.png differ diff --git a/limereport/dialogdesigner/lrdialogdesigner.cpp b/limereport/dialogdesigner/lrdialogdesigner.cpp new file mode 100644 index 0000000..82a08d0 --- /dev/null +++ b/limereport/dialogdesigner/lrdialogdesigner.cpp @@ -0,0 +1,358 @@ +#include "lrdialogdesigner.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_QT5 +#include +#endif +#if HAVE_QT4 +#include "qdesigner_integration_p.h" +#include +#endif +#include "pluginmanager_p.h" +#include "widgethost.h" +#include + +namespace LimeReport{ + +DialogDesignerManager::DialogDesignerManager(QObject *parent) : QObject(parent) +{ + QDesignerComponents::initializeResources(); + m_formEditor = QDesignerComponents::createFormEditor(this); + QDesignerComponents::initializePlugins(m_formEditor); + QDesignerComponents::createTaskMenu(m_formEditor, this); + + m_editWidgetsAction = new QAction(tr("Edit Widgets"), this); + m_editWidgetsAction->setIcon(QIcon(":/images/images/widgettool.png")); + m_editWidgetsAction->setEnabled(false); + connect(m_editWidgetsAction, SIGNAL(triggered()), this, SLOT(slotEditWidgets())); + connect(m_formEditor->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), + this, SLOT(slotActiveFormWindowChanged(QDesignerFormWindowInterface*)) ); + + m_modes = new QActionGroup(this); + m_modes->setExclusive(true); + m_modes->addAction(m_editWidgetsAction); + + foreach ( QObject* o, QPluginLoader::staticInstances() << m_formEditor->pluginManager()->instances() ) + { + if ( QDesignerFormEditorPluginInterface* fep = qobject_cast( o ) ) + { + if ( !fep->isInitialized() ) + fep->initialize( m_formEditor ); + fep->action()->setCheckable( true ); + fep->action()->setIcon(QIcon(iconPathByName(fep->action()->objectName()))); + m_modes->addAction(fep->action()); + } + } + + m_widgetBox = QDesignerComponents::createWidgetBox(m_formEditor, 0); + m_widgetBox->setWindowTitle(tr("Widget Box")); + m_widgetBox->setObjectName(QLatin1String("WidgetBox")); + m_formEditor->setWidgetBox(m_widgetBox); + m_formEditor->setTopLevel(m_widgetBox); + m_designerToolWindows.append(m_widgetBox); + connect(m_widgetBox, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)) ); + + m_objectInspector = QDesignerComponents::createObjectInspector(m_formEditor, 0); + m_objectInspector->setWindowTitle(tr("Object Inspector")); + m_objectInspector->setObjectName(QLatin1String("ObjectInspector")); + m_formEditor->setObjectInspector(m_objectInspector); + m_designerToolWindows.append(m_objectInspector); + connect(m_objectInspector, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)) ); + + m_propertyEditor = QDesignerComponents::createPropertyEditor(m_formEditor, 0); + m_propertyEditor->setWindowTitle(tr("Property Editor")); + m_propertyEditor->setObjectName(QLatin1String("PropertyEditor")); + m_formEditor->setPropertyEditor(m_propertyEditor); + m_designerToolWindows.append(m_propertyEditor); + connect(m_propertyEditor, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)) ); + + m_signalSlotEditor = QDesignerComponents::createSignalSlotEditor(m_formEditor, 0); + m_signalSlotEditor->setWindowTitle(tr("Signals && Slots Editor")); + m_signalSlotEditor->setObjectName(QLatin1String("SignalsAndSlotsEditor")); + + m_designerToolWindows.append(m_signalSlotEditor); + connect(m_signalSlotEditor, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)) ); + + m_resourcesEditor = QDesignerComponents::createResourceEditor(m_formEditor, 0); + m_resourcesEditor->setWindowTitle(tr("Resource Editor")); + m_resourcesEditor->setObjectName(QLatin1String("ResourceEditor")); + m_designerToolWindows.append(m_resourcesEditor); + connect(m_resourcesEditor, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)) ); + + m_actionEditor = QDesignerComponents::createActionEditor(m_formEditor, 0); + m_actionEditor->setWindowTitle(tr("Action Editor")); + m_actionEditor->setObjectName("ActionEditor"); + m_formEditor->setActionEditor(m_actionEditor); + m_designerToolWindows.append(m_actionEditor); + connect(m_actionEditor, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)) ); + +#ifdef HAVE_QT4 + m_designerIntegration = new qdesigner_internal::QDesignerIntegration(m_formEditor,this); +#endif +#ifdef HAVE_QT5 + m_designerIntegration = new QDesignerIntegration(m_formEditor,this); +#endif + m_formEditor->setIntegration(m_designerIntegration); + +} + +DialogDesignerManager::~DialogDesignerManager() +{ + for (int i = 0; isetIconSize(QSize(16,16)); + m_formEditor->formWindowManager()->actionCopy()->setIcon(QIcon(":/report/images/copy")); + tb->addAction(m_formEditor->formWindowManager()->actionCopy()); + m_formEditor->formWindowManager()->actionPaste()->setIcon(QIcon(":/report/images/paste")); + tb->addAction(m_formEditor->formWindowManager()->actionPaste()); + m_formEditor->formWindowManager()->actionCut()->setIcon(QIcon(":/report/images/cut")); + tb->addAction(m_formEditor->formWindowManager()->actionCut()); + m_formEditor->formWindowManager()->actionUndo()->setIcon(QIcon(":/report/images/undo")); + tb->addAction(m_formEditor->formWindowManager()->actionUndo()); + m_formEditor->formWindowManager()->actionRedo()->setIcon(QIcon(":/report/images/redo")); + tb->addAction(m_formEditor->formWindowManager()->actionRedo()); + + tb->addActions(m_modes->actions()); + + tb->addAction(m_formEditor->formWindowManager()->actionHorizontalLayout()); + tb->addAction(m_formEditor->formWindowManager()->actionVerticalLayout()); + tb->addAction(m_formEditor->formWindowManager()->actionSplitHorizontal()); + tb->addAction(m_formEditor->formWindowManager()->actionSplitVertical()); + tb->addAction(m_formEditor->formWindowManager()->actionGridLayout()); + m_formEditor->formWindowManager()->actionFormLayout()->setIcon(QIcon(":/images/images/editform.png")); + tb->addAction(m_formEditor->formWindowManager()->actionFormLayout()); + tb->addAction(m_formEditor->formWindowManager()->actionBreakLayout()); + tb->addAction(m_formEditor->formWindowManager()->actionAdjustSize()); +} + +QWidget *DialogDesignerManager::createFormEditor(const QString &content) +{ + QDesignerFormWindowInterface* wnd = m_formEditor->formWindowManager()->createFormWindow(0, Qt::Window); + wnd->setContents(content); + m_formEditor->formWindowManager()->setActiveFormWindow(wnd); + m_formEditor->objectInspector()->setFormWindow(wnd); + wnd->editWidgets(); + + DialogDesigner* dialogDesigner = new DialogDesigner(wnd, m_formEditor); + + connect(dialogDesigner, SIGNAL(dialogChanged(QString)), this, SIGNAL(dialogChanged(QString))); + connect(dialogDesigner, SIGNAL(dialogNameChanged(QString,QString)), this, SIGNAL(dialogNameChanged(QString,QString))); + connect(dialogDesigner, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*))); + + m_dialogDesigners.append(dialogDesigner); + + return dialogDesigner; + +} + +QByteArray DialogDesignerManager::getDialogDescription(QWidget *form) +{ + QByteArray result; + DialogDesigner* dialogDesigner = dynamic_cast(form); + Q_ASSERT(dialogDesigner != NULL); + //SharedTools::WidgetHost* wh = dynamic_cast(form); + if (dialogDesigner){ + result = dialogDesigner->dialogContent(); + //wh->formWindow()->setDirty(false); + } + return result; +} + +void DialogDesignerManager::setActiveEditor(QWidget *widget) +{ + SharedTools::WidgetHost* wh = dynamic_cast(widget); + if (wh){ + m_formEditor->formWindowManager()->setActiveFormWindow(wh->formWindow()); + } +} + +void DialogDesignerManager::setDirty(bool value) +{ + foreach(DialogDesigner* dialogDesigner, m_dialogDesigners){ + dialogDesigner->setChanged(value); + } +} + +QWidget* DialogDesignerManager::widgetBox() const +{ + return m_widgetBox; +} + +QWidget* DialogDesignerManager::actionEditor() const +{ + return m_actionEditor; +} + +QWidget* DialogDesignerManager::propertyEditor() const +{ + return m_propertyEditor; +} + +QWidget* DialogDesignerManager::objectInspector() const +{ + return m_objectInspector; +} + +QWidget *DialogDesignerManager::signalSlotEditor() const +{ + return m_signalSlotEditor; +} + +QWidget *DialogDesignerManager::resourcesEditor() const +{ + return m_resourcesEditor; +} + +void DialogDesignerManager::slotObjectDestroyed(QObject* object) +{ + + QList::Iterator it = m_dialogDesigners.begin(); + while(it!=m_dialogDesigners.end()){ + if (*it == object){ + it = m_dialogDesigners.erase(it); + return; + } else { + ++it; + } + } + + for ( int i = 0; iformWindowManager()->formWindowCount(); ++i){ + m_formEditor->formWindowManager()->formWindow(i)->editWidgets(); + } +} + +void DialogDesignerManager::slotActiveFormWindowChanged(QDesignerFormWindowInterface *formWindow) +{ + if (formWindow){ + m_editWidgetsAction->setEnabled(true); + m_activeWindowName = formWindow->objectName(); + } +} + +QString DialogDesignerManager::iconPathByName(const QString &name) +{ + if (name.compare("__qt_edit_signals_slots_action") == 0) + return ":/images/images/signalslottool.png"; + if (name.compare("__qt_edit_buddies_action") == 0) + return ":/images/images/buddytool.png"; + if (name.compare("_qt_edit_tab_order_action") == 0) + return ":/images/images/tabordertool.png"; + return ""; +} + +DialogDesigner::DialogDesigner(QDesignerFormWindowInterface* wnd, QDesignerFormEditorInterface* formEditor, QWidget *parent, Qt::WindowFlags flags) + :QWidget(parent, flags), m_formEditor(formEditor) +{ + m_dialogName = wnd->mainContainer()->objectName(); + connect(wnd, SIGNAL(changed()), this, SLOT(slotDialogChanged())); + + m_designerHolder = new SharedTools::WidgetHost(this,wnd); + m_designerHolder->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); + m_designerHolder->setFocusProxy( wnd ); + + QVBoxLayout* l = new QVBoxLayout(this); + l->addWidget(m_designerHolder); + setLayout(l); + +} + +DialogDesigner::~DialogDesigner(){} + +QString DialogDesigner::dialogName() const +{ + return m_dialogName; +} + +void DialogDesigner::setDialogName(const QString &dialogName) +{ + m_dialogName = dialogName; +} + +bool DialogDesigner::isChanged() +{ + return m_designerHolder->formWindow()->isDirty(); +} + +void DialogDesigner::setChanged(bool value) +{ + m_designerHolder->formWindow()->setDirty(value); +} + +QByteArray DialogDesigner::dialogContent() +{ + if (m_designerHolder && m_designerHolder->formWindow()) + return m_designerHolder->formWindow()->contents().toUtf8(); + return QByteArray(); +} + +void DialogDesigner::undo() +{ + Q_ASSERT(m_formEditor != NULL); + if (m_formEditor){ + m_formEditor->formWindowManager()->actionUndo()->trigger(); + } +} + +void DialogDesigner::redo() +{ + Q_ASSERT(m_formEditor != NULL); + if (m_formEditor){ + m_formEditor->formWindowManager()->actionRedo()->trigger(); + } +} + +void DialogDesigner::slotMainContainerNameChanged(QString newName) +{ + if (m_dialogName.compare(newName) != 0){ + emit dialogNameChanged(m_dialogName, newName); + m_dialogName = newName; + } +} + +void DialogDesigner::slotDialogChanged() +{ + Q_ASSERT(m_designerHolder != NULL); + if (m_designerHolder && m_designerHolder->formWindow()){ + if ( m_designerHolder->formWindow()->mainContainer()->objectName().compare(m_dialogName) !=0 ){ + emit dialogNameChanged(m_dialogName, m_designerHolder->formWindow()->mainContainer()->objectName()); + m_dialogName = m_designerHolder->formWindow()->mainContainer()->objectName(); + } + emit dialogChanged(m_dialogName); + m_designerHolder->formWindow()->setDirty(false); + } +} + +} diff --git a/limereport/dialogdesigner/lrdialogdesigner.h b/limereport/dialogdesigner/lrdialogdesigner.h new file mode 100644 index 0000000..a5c33bc --- /dev/null +++ b/limereport/dialogdesigner/lrdialogdesigner.h @@ -0,0 +1,93 @@ +#ifndef DIALOGDESIGNER_H +#define DIALOGDESIGNER_H + +#include +#include +#include +#include + +class QDesignerFormEditorInterface; +class QDesignerFormWindowInterface; +class QDesignerIntegrationInterface; +class QDesignerWidgetBoxInterface; +class QDesignerActionEditorInterface; +class QDesignerPropertyEditorInterface; +class QDesignerObjectInspectorInterface; +class QDesignerFormWindowManagerInterface; + +namespace SharedTools{ + class WidgetHost; +} + +namespace LimeReport{ + +class DialogDesigner : public QWidget{ + Q_OBJECT +public: + DialogDesigner(QDesignerFormWindowInterface *wnd, QDesignerFormEditorInterface* formEditor, QWidget *parent = NULL, Qt::WindowFlags flags = Qt::WindowFlags()); + ~DialogDesigner(); + QString dialogName() const; + void setDialogName(const QString &dialogName); + bool isChanged(); + void setChanged(bool value); + QByteArray dialogContent(); +public slots: + void undo(); + void redo(); +signals: + void dialogChanged(QString dialogName); + void dialogNameChanged(QString oldName, QString newName); +private slots: + void slotMainContainerNameChanged(QString newName); + void slotDialogChanged(); +private: + QString m_dialogName; + SharedTools::WidgetHost* m_designerHolder; + QDesignerFormEditorInterface* m_formEditor; +}; + +class DialogDesignerManager : public QObject +{ + Q_OBJECT +public: + explicit DialogDesignerManager(QObject *parent = 0); + ~DialogDesignerManager(); + void initToolBar(QToolBar* tb); + QWidget* createFormEditor(const QString& content); + QByteArray getDialogDescription(QWidget* form); + void setActiveEditor(QWidget* widget); + void setDirty(bool value); + QWidget* widgetBox() const; + QWidget* actionEditor() const; + QWidget* propertyEditor() const; + QWidget* objectInspector() const; + QWidget* signalSlotEditor() const; + QWidget* resourcesEditor() const; +signals: + void dialogChanged(QString dialogName); + void dialogNameChanged(QString oldName, QString newName); +private slots: + void slotObjectDestroyed(QObject* object); + void slotEditWidgets(); + void slotActiveFormWindowChanged(QDesignerFormWindowInterface *formWindow); +private: + QString iconPathByName(const QString& name); +private: + QDesignerFormEditorInterface* m_formEditor; + QDesignerIntegrationInterface* m_designerIntegration; + QDesignerWidgetBoxInterface* m_widgetBox; + QDesignerActionEditorInterface* m_actionEditor; + QDesignerPropertyEditorInterface* m_propertyEditor; + QDesignerObjectInspectorInterface* m_objectInspector; + QWidget* m_signalSlotEditor; + QWidget* m_resourcesEditor; + QVector m_designerToolWindows; + QAction* m_editWidgetsAction; + QActionGroup* m_modes; + QString m_activeWindowName; + QList m_dialogDesigners; +}; + +} // namespace LimeReport + +#endif // DIALOGDESIGNER_H diff --git a/limereport/dialogdesigner/templates/Dialog.ui b/limereport/dialogdesigner/templates/Dialog.ui new file mode 100644 index 0000000..6eb9e5f --- /dev/null +++ b/limereport/dialogdesigner/templates/Dialog.ui @@ -0,0 +1,18 @@ + + $ClassName$ + + + + 0 + 0 + 400 + 300 + + + + $ClassName$ + + + + + diff --git a/limereport/exporters/lrpdfexporter.cpp b/limereport/exporters/lrpdfexporter.cpp new file mode 100644 index 0000000..d97bf7b --- /dev/null +++ b/limereport/exporters/lrpdfexporter.cpp @@ -0,0 +1,38 @@ +#include + +#include "lrpdfexporter.h" +#include "lrexportersfactory.h" +#include "lrreportengine_p.h" + +namespace{ + +LimeReport::ReportExporterInterface* createPDFExporter(LimeReport::ReportEnginePrivate* parent){ + return new LimeReport::PDFExporter(parent); +} + +bool VARIABLE_IS_NOT_USED registred = LimeReport::ExportersFactory::instance().registerCreator("PDF", LimeReport::ExporterAttribs(QObject::tr("Export to PDF"), "PDFExporter"), createPDFExporter); + +} + +namespace LimeReport{ + +PDFExporter::PDFExporter(ReportEnginePrivate *parent) : QObject(parent), m_reportEngine(parent) +{} + +bool PDFExporter::exportPages(ReportPages pages, const QString &fileName, const QMap ¶ms) +{ + Q_UNUSED(params); + if (!fileName.isEmpty()){ + QPrinter printer; + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + if (!pages.isEmpty()){ + m_reportEngine->printReport(pages, printer); + } + m_reportEngine->emitPrintedToPDF(fileName); + return true; + } + return false; +} + +} diff --git a/limereport/exporters/lrpdfexporter.h b/limereport/exporters/lrpdfexporter.h new file mode 100644 index 0000000..225c80b --- /dev/null +++ b/limereport/exporters/lrpdfexporter.h @@ -0,0 +1,35 @@ +#ifndef LRPDFEXPORTER_H +#define LRPDFEXPORTER_H + +#include +#include "lrexporterintf.h" + +namespace LimeReport{ +class ReportEnginePrivate; + +class PDFExporter : public QObject, public ReportExporterInterface +{ + Q_OBJECT +public: + explicit PDFExporter(ReportEnginePrivate *parent = nullptr); + // ReportExporterInterface interface + bool exportPages(ReportPages pages, const QString &fileName, const QMap ¶ms); + QString exporterName() + { + return "PDF"; + } + QString exporterFileExt() + { + return "pdf"; + } + QString hint() + { + return tr("Export to PDF"); + } +private: + ReportEnginePrivate* m_reportEngine; +}; + +} //namespace LimeReport + +#endif // LRPDFEXPORTER_H diff --git a/limereport/images/addDialog.png b/limereport/images/addDialog.png new file mode 100644 index 0000000..6023700 Binary files /dev/null and b/limereport/images/addDialog.png differ diff --git a/limereport/images/copy3.png b/limereport/images/copy3.png new file mode 100644 index 0000000..928dcf1 Binary files /dev/null and b/limereport/images/copy3.png differ diff --git a/limereport/images/deleteDialog.png b/limereport/images/deleteDialog.png new file mode 100644 index 0000000..5391490 Binary files /dev/null and b/limereport/images/deleteDialog.png differ diff --git a/limereport/images/designer.png b/limereport/images/designer.png new file mode 100644 index 0000000..90c7744 Binary files /dev/null and b/limereport/images/designer.png differ diff --git a/limereport/images/lock.png b/limereport/images/lock.png new file mode 100644 index 0000000..5485df1 Binary files /dev/null and b/limereport/images/lock.png differ diff --git a/limereport/images/object.png b/limereport/images/object.png new file mode 100644 index 0000000..807c2a8 Binary files /dev/null and b/limereport/images/object.png differ diff --git a/limereport/images/paste2.png b/limereport/images/paste2.png new file mode 100644 index 0000000..11399d9 Binary files /dev/null and b/limereport/images/paste2.png differ diff --git a/limereport/images/property.png b/limereport/images/property.png new file mode 100644 index 0000000..4e4efaa Binary files /dev/null and b/limereport/images/property.png differ diff --git a/limereport/images/save.png b/limereport/images/save.png index e6fe0b2..2b31666 100644 Binary files a/limereport/images/save.png and b/limereport/images/save.png differ diff --git a/limereport/images/signal.png b/limereport/images/signal.png new file mode 100644 index 0000000..864c27d Binary files /dev/null and b/limereport/images/signal.png differ diff --git a/limereport/images/toBack.png b/limereport/images/toBack.png index 883ae19..1fc9fe1 100644 Binary files a/limereport/images/toBack.png and b/limereport/images/toBack.png differ diff --git a/limereport/images/toBottom.png b/limereport/images/toBottom.png index 73c104d..3f9fe61 100644 Binary files a/limereport/images/toBottom.png and b/limereport/images/toBottom.png differ diff --git a/limereport/images/toCenter.png b/limereport/images/toCenter.png index 6cb7660..95a5bdd 100644 Binary files a/limereport/images/toCenter.png and b/limereport/images/toCenter.png differ diff --git a/limereport/images/toFront.png b/limereport/images/toFront.png index 8d04661..f6666ba 100644 Binary files a/limereport/images/toFront.png and b/limereport/images/toFront.png differ diff --git a/limereport/images/toLeft1.png b/limereport/images/toLeft1.png index 1890060..88cc447 100644 Binary files a/limereport/images/toLeft1.png and b/limereport/images/toLeft1.png differ diff --git a/limereport/images/toRight.png b/limereport/images/toRight.png index e4946f4..14b348f 100644 Binary files a/limereport/images/toRight.png and b/limereport/images/toRight.png differ diff --git a/limereport/images/toSameHeight.png b/limereport/images/toSameHeight.png index 5cb3ff4..d46e0c3 100644 Binary files a/limereport/images/toSameHeight.png and b/limereport/images/toSameHeight.png differ diff --git a/limereport/images/toSameWidth.png b/limereport/images/toSameWidth.png index 52b1e8e..c32f646 100644 Binary files a/limereport/images/toSameWidth.png and b/limereport/images/toSameWidth.png differ diff --git a/limereport/images/toTop.png b/limereport/images/toTop.png index 7b91b8e..58c25e4 100644 Binary files a/limereport/images/toTop.png and b/limereport/images/toTop.png differ diff --git a/limereport/images/toVCernter.png b/limereport/images/toVCernter.png index 3e0689b..79f2fe0 100644 Binary files a/limereport/images/toVCernter.png and b/limereport/images/toVCernter.png differ diff --git a/limereport/images/unlock.png b/limereport/images/unlock.png new file mode 100644 index 0000000..72d1314 Binary files /dev/null and b/limereport/images/unlock.png differ diff --git a/limereport/images/vlayuot_4_24.png b/limereport/images/vlayuot_4_24.png new file mode 100644 index 0000000..8f83e79 Binary files /dev/null and b/limereport/images/vlayuot_4_24.png differ diff --git a/limereport/images/zoom_in1.png b/limereport/images/zoom_in1.png index 4e6fc7a..e26b6ec 100644 Binary files a/limereport/images/zoom_in1.png and b/limereport/images/zoom_in1.png differ diff --git a/limereport/images/zoom_out1.png b/limereport/images/zoom_out1.png index cce6ea2..ad1ab69 100644 Binary files a/limereport/images/zoom_out1.png and b/limereport/images/zoom_out1.png differ diff --git a/limereport/items/editors/lrfonteditorwidget.cpp b/limereport/items/editors/lrfonteditorwidget.cpp index a2d7dbc..5d1a306 100644 --- a/limereport/items/editors/lrfonteditorwidget.cpp +++ b/limereport/items/editors/lrfonteditorwidget.cpp @@ -31,23 +31,9 @@ namespace LimeReport{ -FontEditorWidget::FontEditorWidget(ReportDesignWidget *reportEditor, const QString &title, QWidget *parent) - : ItemEditorWidget(reportEditor,title,parent), m_ignoreSlots(false) { - initEditor(); -} - -FontEditorWidget::FontEditorWidget(ReportDesignWidget *reportEditor, QWidget *parent) - :ItemEditorWidget(reportEditor,parent), m_ignoreSlots(false) { - initEditor(); -} - -FontEditorWidget::FontEditorWidget(PageDesignIntf *page, const QString &title, QWidget *parent) - :ItemEditorWidget(page,title,parent), m_ignoreSlots(false) { - initEditor(); -} - -FontEditorWidget::FontEditorWidget(LimeReport::PageDesignIntf *page, QWidget *parent) - :ItemEditorWidget(page,parent), m_ignoreSlots(false){ +FontEditorWidget::FontEditorWidget(const QString& title, QWidget* parent) + :ItemEditorWidget(title, parent), m_ignoreSlots(false) +{ initEditor(); } @@ -101,10 +87,6 @@ void FontEditorWidget::initEditor() connect(m_fontUnderline,SIGNAL(toggled(bool)),this,SLOT(slotFontAttribsChanged(bool))); addAction(m_fontUnderline); - if (reportEditor()){ - connect(reportEditor(),SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), - this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); - } } void FontEditorWidget::updateValues(const QFont& font) @@ -118,35 +100,32 @@ void FontEditorWidget::updateValues(const QFont& font) m_ignoreSlots=false; } - -void FontEditorWidget::slotFontChanged(const QFont &font) +bool FontEditorWidget::ignoreSlots() const { - if (reportEditor() && !m_ignoreSlots) reportEditor()->setFont(font); - if (page()) page()->setFont(font); + return m_ignoreSlots; +} + + +void FontEditorWidget::slotFontChanged(const QFont& /*font*/) +{ + //if (page()) page()->setFont(font); } void FontEditorWidget::slotFontSizeChanged(const QString &value) { if (m_ignoreSlots) return; - - QFont resFont(fontNameEditor()->currentFont()); - resFont.setPointSize(value.toInt()); - - if (reportEditor()) reportEditor()->setFont(resFont); - if (page()) page()->setFont(resFont); + m_resFont = fontNameEditor()->currentFont(); + m_resFont.setPointSize(value.toInt()); } void FontEditorWidget::slotFontAttribsChanged(bool) { if (m_ignoreSlots) return; - - QFont resFont(m_fontNameEditor->currentFont()); - resFont.setBold(m_fontBold->isChecked()); - resFont.setItalic(m_fontItalic->isChecked()); - resFont.setUnderline(m_fontUnderline->isChecked()); - if (reportEditor()) reportEditor()->setFont(resFont); - if (page()) page()->setFont(resFont); - + m_resFont = m_fontNameEditor->currentFont(); + m_resFont.setPointSize(m_fontSizeEditor->currentText().toInt()); + m_resFont.setBold(m_fontBold->isChecked()); + m_resFont.setItalic(m_fontItalic->isChecked()); + m_resFont.setUnderline(m_fontUnderline->isChecked()); } void FontEditorWidget::slotPropertyChanged(const QString &objectName, const QString &property, const QVariant& oldValue, const QVariant& newValue) @@ -159,4 +138,52 @@ void FontEditorWidget::slotPropertyChanged(const QString &objectName, const QStr } +void FontEditorWidgetForPage::slotFontChanged(const QFont& font) +{ + m_page->setFont(font); +} + +void FontEditorWidgetForPage::slotFontSizeChanged(const QString& value) +{ + FontEditorWidget::slotFontSizeChanged(value); + m_page->setFont(resFont()); +} + +void FontEditorWidgetForPage::slotFontAttribsChanged(bool value) +{ + FontEditorWidget::slotFontAttribsChanged(value); + m_page->setFont(resFont()); +} + +#ifdef HAVE_REPORT_DESIGNER +void FontEditorWidgetForDesigner::initEditor() +{ + connect(m_reportEditor,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); +} + +void FontEditorWidgetForDesigner::slotFontChanged(const QFont& font) +{ + if (!ignoreSlots()) m_reportEditor->setFont(font); +} + +void FontEditorWidgetForDesigner::slotFontSizeChanged(const QString& value) +{ + if (!ignoreSlots()){ + FontEditorWidget::slotFontSizeChanged(value); + m_reportEditor->setFont(resFont()); + } +} + +void FontEditorWidgetForDesigner::slotFontAttribsChanged(bool value) +{ + if (!ignoreSlots()){ + FontEditorWidget::slotFontAttribsChanged(value); + m_reportEditor->setFont(resFont()); + } +} + +#endif + + } //namespace LimeReport diff --git a/limereport/items/editors/lrfonteditorwidget.h b/limereport/items/editors/lrfonteditorwidget.h index 23f9ab7..f8f9b96 100644 --- a/limereport/items/editors/lrfonteditorwidget.h +++ b/limereport/items/editors/lrfonteditorwidget.h @@ -35,7 +35,10 @@ #include #include +#ifdef HAVE_REPORT_DESIGNER #include "lrreportdesignwidget.h" +#endif + #include "lritemeditorwidget.h" namespace LimeReport{ @@ -43,20 +46,21 @@ namespace LimeReport{ class FontEditorWidget :public ItemEditorWidget{ Q_OBJECT public: - explicit FontEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); - explicit FontEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); - explicit FontEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); - explicit FontEditorWidget(PageDesignIntf* page, QWidget *parent = 0); + explicit FontEditorWidget(const QString &title, QWidget *parent = 0); + bool ignoreSlots() const; protected: void setItemEvent(BaseDesignIntf *item); QFontComboBox* fontNameEditor(){return m_fontNameEditor;} -private slots: - void slotFontChanged(const QFont& font); - void slotFontSizeChanged(const QString& value); - void slotFontAttribsChanged(bool); - void slotPropertyChanged(const QString& objectName, const QString& property, const QVariant &oldValue, const QVariant &newValue); -private: void initEditor(); +protected slots: + virtual void slotFontChanged(const QFont&); + virtual void slotFontSizeChanged(const QString& value); + virtual void slotFontAttribsChanged(bool); + void slotPropertyChanged(const QString& objectName, const QString& property, const QVariant &oldValue, const QVariant &newValue); +protected: + QFont resFont(){return m_resFont;} +private: + void updateValues(const QFont &font); QFontComboBox* m_fontNameEditor; @@ -68,9 +72,41 @@ private: QAction* m_fontUnderline; bool m_ignoreSlots; + QFont m_resFont; }; +class FontEditorWidgetForPage : public FontEditorWidget{ + Q_OBJECT +public: + explicit FontEditorWidgetForPage(PageDesignIntf* page, const QString &title, QWidget *parent = 0) + : FontEditorWidget(title, parent), m_page(page){} +protected slots: + virtual void slotFontChanged(const QFont& font); + virtual void slotFontSizeChanged(const QString& value); + virtual void slotFontAttribsChanged(bool value); +private: + PageDesignIntf* m_page; +}; + +#ifdef HAVE_REPORT_DESIGNER +class FontEditorWidgetForDesigner : public FontEditorWidget{ + Q_OBJECT +public: + explicit FontEditorWidgetForDesigner(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0) + : FontEditorWidget(title, parent), m_reportEditor(reportEditor){initEditor();} + +protected: + void initEditor(); +protected slots: + virtual void slotFontChanged(const QFont& font); + virtual void slotFontSizeChanged(const QString& value); + virtual void slotFontAttribsChanged(bool value); +private: + ReportDesignWidget* m_reportEditor; +}; +#endif + } //namespace LimeReport #endif // LRFONTEDITORWIDGET_H diff --git a/limereport/items/editors/lritemeditorwidget.cpp b/limereport/items/editors/lritemeditorwidget.cpp index d335697..d81af5e 100644 --- a/limereport/items/editors/lritemeditorwidget.cpp +++ b/limereport/items/editors/lritemeditorwidget.cpp @@ -31,26 +31,6 @@ namespace LimeReport{ -ItemEditorWidget::ItemEditorWidget(ReportDesignWidget* reportEditor, const QString& title, QWidget* parent) - :QToolBar(title,parent), m_reportEditor(reportEditor), m_item(0), m_page(0) -{ -} - -ItemEditorWidget::ItemEditorWidget(ReportDesignWidget* reportEditor, QWidget* parent) - :QToolBar(parent), m_reportEditor(reportEditor), m_item(0), m_page(0) -{ -} - -ItemEditorWidget::ItemEditorWidget(PageDesignIntf* page, const QString& title, QWidget* parent) - :QToolBar(title,parent), m_reportEditor(0), m_item(0), m_page(page) -{ -} - -ItemEditorWidget::ItemEditorWidget(PageDesignIntf* page, QWidget* parent) - :QToolBar(parent), m_reportEditor(0), m_item(0), m_page(page) -{ -} - void ItemEditorWidget::setItem(BaseDesignIntf* item) { if (m_item!=item){ diff --git a/limereport/items/editors/lritemeditorwidget.h b/limereport/items/editors/lritemeditorwidget.h index 5214756..733eac0 100644 --- a/limereport/items/editors/lritemeditorwidget.h +++ b/limereport/items/editors/lritemeditorwidget.h @@ -31,7 +31,11 @@ #define LRITEMEDITORWIDGET_H #include + +#ifdef HAVE_REPORT_DESIGNER #include "lrreportdesignwidget.h" +#endif +#include "lrpagedesignintf.h" namespace LimeReport { @@ -39,26 +43,18 @@ class ItemEditorWidget : public QToolBar { Q_OBJECT public: - explicit ItemEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); - explicit ItemEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); - explicit ItemEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); - explicit ItemEditorWidget(PageDesignIntf* page, QWidget *parent = 0); - + explicit ItemEditorWidget(const QString &title, QWidget *parent = 0) + : QToolBar(title, parent), m_item(0){} void setItem(BaseDesignIntf *item); - void setReportEditor(ReportDesignWidget* editor){m_reportEditor = editor;} protected: virtual void setItemEvent(BaseDesignIntf*){} virtual void properyChangedEvent(const QString& propertName, const QVariant& oldValue, const QVariant& newValue); BaseDesignIntf* item(){return m_item;} - ReportDesignWidget* reportEditor(){return m_reportEditor;} - PageDesignIntf* page(){return m_page;} private slots: void slotItemDestroyed(QObject* item); void slotPropertyChanged(const QString& propertName, const QVariant& oldValue, const QVariant& newValue); private: - ReportDesignWidget* m_reportEditor; BaseDesignIntf* m_item; - PageDesignIntf* m_page; }; } // namespace LimeReport diff --git a/limereport/items/editors/lritemsaligneditorwidget.cpp b/limereport/items/editors/lritemsaligneditorwidget.cpp index e4c681f..5595928 100644 --- a/limereport/items/editors/lritemsaligneditorwidget.cpp +++ b/limereport/items/editors/lritemsaligneditorwidget.cpp @@ -55,9 +55,9 @@ ItemsAlignmentEditorWidget::ItemsAlignmentEditorWidget(PageDesignIntf* page, QWi initEditor(); } -void ItemsAlignmentEditorWidget::slotBrinToFront() +void ItemsAlignmentEditorWidget::slotBringToFront() { - if (m_reportEditor) m_reportEditor->brinToFront(); + if (m_reportEditor) m_reportEditor->bringToFront(); if (m_page) m_page->bringToFront(); } @@ -119,7 +119,7 @@ void ItemsAlignmentEditorWidget::initEditor() { m_bringToFront = new QAction(tr("Bring to top"),this); m_bringToFront->setIcon(QIcon(":/report/images/bringToTop")); - connect(m_bringToFront,SIGNAL(triggered()),this,SLOT(slotBrinToFront())); + connect(m_bringToFront,SIGNAL(triggered()),this,SLOT(slotBringToFront())); addAction(m_bringToFront); m_sendToBack = new QAction(tr("Send to back"),this); diff --git a/limereport/items/editors/lritemsaligneditorwidget.h b/limereport/items/editors/lritemsaligneditorwidget.h index 3dda383..5231d2f 100644 --- a/limereport/items/editors/lritemsaligneditorwidget.h +++ b/limereport/items/editors/lritemsaligneditorwidget.h @@ -45,7 +45,7 @@ public: explicit ItemsAlignmentEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); explicit ItemsAlignmentEditorWidget(PageDesignIntf* page, QWidget *parent = 0); private slots: - void slotBrinToFront(); + void slotBringToFront(); void slotSendToBack(); void slotAlignToLeft(); void slotAlignToRight(); diff --git a/limereport/items/editors/lritemsborderseditorwidget.cpp b/limereport/items/editors/lritemsborderseditorwidget.cpp index afdf766..44cc897 100644 --- a/limereport/items/editors/lritemsborderseditorwidget.cpp +++ b/limereport/items/editors/lritemsborderseditorwidget.cpp @@ -32,18 +32,6 @@ namespace LimeReport{ -ItemsBordersEditorWidget::ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, const QString& title, QWidget* parent) - : ItemEditorWidget(reportEditor,title,parent), m_changing(false) -{ - initEditor(); -} - -ItemsBordersEditorWidget::ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, QWidget* parent) - : ItemEditorWidget(reportEditor,parent), m_changing(false) -{ - initEditor(); -} - void ItemsBordersEditorWidget::setItemEvent(BaseDesignIntf* item) { QVariant borders=item->property("borders"); @@ -65,8 +53,6 @@ void ItemsBordersEditorWidget::properyChangedEvent(const QString& property, cons void ItemsBordersEditorWidget::noBordesClicked() { - if (reportEditor()) - reportEditor()->setBorders(0); updateValues(0); } @@ -78,14 +64,11 @@ void ItemsBordersEditorWidget::allBordesClicked() BaseDesignIntf::BottomLine; updateValues((BaseDesignIntf::BorderLines)borders); - if (reportEditor()) - reportEditor()->setBorders((BaseDesignIntf::BorderLines)borders); } void ItemsBordersEditorWidget::buttonClicked(bool) { - if (!m_changing&&reportEditor()) - reportEditor()->setBorders(createBorders()); + } void ItemsBordersEditorWidget::initEditor() @@ -151,4 +134,29 @@ BaseDesignIntf::BorderLines ItemsBordersEditorWidget::createBorders() return (BaseDesignIntf::BorderLines)borders; } +bool ItemsBordersEditorWidget::changing() const +{ + return m_changing; +} + +#ifdef HAVE_REPORT_DESIGNER +void ItemsBordersEditorWidgetForDesigner::buttonClicked(bool) +{ + if (!changing()) + m_reportEditor->setBorders(createBorders()); +} + +void ItemsBordersEditorWidgetForDesigner::noBordesClicked() +{ + m_reportEditor->setBorders(0); + ItemsBordersEditorWidget::noBordesClicked(); +} + +void ItemsBordersEditorWidgetForDesigner::allBordesClicked() +{ + ItemsBordersEditorWidget::allBordesClicked(); + m_reportEditor->setBorders(createBorders()); +} +#endif + } //namespace LimeReport diff --git a/limereport/items/editors/lritemsborderseditorwidget.h b/limereport/items/editors/lritemsborderseditorwidget.h index 296107e..998251c 100644 --- a/limereport/items/editors/lritemsborderseditorwidget.h +++ b/limereport/items/editors/lritemsborderseditorwidget.h @@ -40,19 +40,22 @@ class ItemsBordersEditorWidget : public ItemEditorWidget { Q_OBJECT public: - explicit ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); - explicit ItemsBordersEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); -private slots: - void noBordesClicked(); - void allBordesClicked(); - void buttonClicked(bool); + explicit ItemsBordersEditorWidget(const QString &title, QWidget *parent = 0) + : ItemEditorWidget(title, parent), m_changing(false), m_borders(0){ + initEditor(); + } + bool changing() const; +protected slots: + virtual void noBordesClicked(); + virtual void allBordesClicked(); + virtual void buttonClicked(bool); protected: void setItemEvent(BaseDesignIntf *item); void properyChangedEvent(const QString &property, const QVariant &oldValue, const QVariant &newValue); + BaseDesignIntf::BorderLines createBorders(); private: void initEditor(); void updateValues(BaseDesignIntf::BorderLines borders); - BaseDesignIntf::BorderLines createBorders(); QAction* m_noLines; QAction* m_leftLine; QAction* m_rightLine; @@ -60,8 +63,24 @@ private: QAction* m_bottomLine; QAction* m_allLines; bool m_changing; + int m_borders; }; +#ifdef HAVE_REPORT_DESIGNER +class ItemsBordersEditorWidgetForDesigner : public ItemsBordersEditorWidget{ + Q_OBJECT +public: + explicit ItemsBordersEditorWidgetForDesigner(ReportDesignWidget* reportEditor, const QString &title="", QWidget *parent = 0) + : ItemsBordersEditorWidget(title,parent), m_reportEditor(reportEditor){} +protected slots: + void buttonClicked(bool); + void noBordesClicked(); + void allBordesClicked(); +private: + ReportDesignWidget* m_reportEditor; +}; +#endif + }//namespace LimeReport #endif // LRITEMSBORDERSEDITORWIDGET_H diff --git a/limereport/items/editors/lrtextalignmenteditorwidget.cpp b/limereport/items/editors/lrtextalignmenteditorwidget.cpp index 50da901..8874d13 100644 --- a/limereport/items/editors/lrtextalignmenteditorwidget.cpp +++ b/limereport/items/editors/lrtextalignmenteditorwidget.cpp @@ -30,27 +30,8 @@ #include "lrtextalignmenteditorwidget.h" namespace LimeReport{ - -TextAlignmentEditorWidget::TextAlignmentEditorWidget(ReportDesignWidget *reportEditor, const QString &title, QWidget *parent) - :ItemEditorWidget(reportEditor,title,parent), m_textAttibutesIsChanging(false) -{ - initEditor(); -} - -TextAlignmentEditorWidget::TextAlignmentEditorWidget(ReportDesignWidget *reportEditor, QWidget *parent) - :ItemEditorWidget(reportEditor,parent), m_textAttibutesIsChanging(false) -{ - initEditor(); -} - -TextAlignmentEditorWidget::TextAlignmentEditorWidget(PageDesignIntf* page, const QString& title, QWidget* parent) - :ItemEditorWidget(page,title,parent), m_textAttibutesIsChanging(false) -{ - initEditor(); -} - -TextAlignmentEditorWidget::TextAlignmentEditorWidget(PageDesignIntf* page, QWidget* parent) - :ItemEditorWidget(page,parent), m_textAttibutesIsChanging(false) +TextAlignmentEditorWidget::TextAlignmentEditorWidget(const QString& title, QWidget* parent) + :ItemEditorWidget(title, parent), m_textAttibutesIsChanging(false), m_flag(0) { initEditor(); } @@ -109,15 +90,6 @@ void TextAlignmentEditorWidget::initEditor() m_textAliginBottom->setCheckable(true); connect(m_textAliginBottom,SIGNAL(toggled(bool)),this,SLOT(slotTextVAttribsChanged(bool))); addAction(m_textAliginBottom); - - if (reportEditor()){ - connect(reportEditor(),SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), - this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); - } - if (page()){ - connect(page(),SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), - this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); - } setEnabled(false); } @@ -157,17 +129,11 @@ void TextAlignmentEditorWidget::slotTextHAttribsChanged(bool) m_textAliginRight->setChecked(sender()==m_textAliginRight); m_textAliginJustify->setChecked(sender()==m_textAliginJustify); - int flag = 0; - if (sender()==m_textAliginLeft) flag |= Qt::AlignLeft; - if (sender()==m_textAliginHCenter) flag |= Qt::AlignHCenter; - if (sender()==m_textAliginRight) flag |= Qt::AlignRight; - if (sender()==m_textAliginJustify) flag |= Qt::AlignJustify; - - if (reportEditor()) reportEditor()->setTextAlign(true,Qt::AlignmentFlag(flag)); - if (page()) { - //page()->setTextAlign(createAlignment()); - page()->changeSelectedGrpoupTextAlignPropperty(true,Qt::AlignmentFlag(flag)); - } + m_flag = 0; + if (sender()==m_textAliginLeft) m_flag |= Qt::AlignLeft; + if (sender()==m_textAliginHCenter) m_flag |= Qt::AlignHCenter; + if (sender()==m_textAliginRight) m_flag |= Qt::AlignRight; + if (sender()==m_textAliginJustify) m_flag |= Qt::AlignJustify; m_textAttibutesIsChanging = false; } @@ -180,13 +146,10 @@ void TextAlignmentEditorWidget::slotTextVAttribsChanged(bool) m_textAliginVCenter->setChecked(sender()==m_textAliginVCenter); m_textAliginBottom->setChecked(sender()==m_textAliginBottom); - int flag = 0; - if (sender()==m_textAliginTop) flag |= Qt::AlignTop; - if (sender()==m_textAliginVCenter) flag |= Qt::AlignVCenter; - if (sender()==m_textAliginBottom) flag |= Qt::AlignBottom; - - if (reportEditor()) reportEditor()->setTextAlign(false,Qt::AlignmentFlag(flag)); - if (page()) page()->changeSelectedGrpoupTextAlignPropperty(false,Qt::AlignmentFlag(flag) ); + m_flag = 0; + if (sender()==m_textAliginTop) m_flag |= Qt::AlignTop; + if (sender()==m_textAliginVCenter) m_flag |= Qt::AlignVCenter; + if (sender()==m_textAliginBottom) m_flag |= Qt::AlignBottom; m_textAttibutesIsChanging = false; } @@ -200,5 +163,62 @@ void TextAlignmentEditorWidget::slotPropertyChanged(const QString &objectName, c } } +int TextAlignmentEditorWidget::flag() const +{ + return m_flag; +} + +void TextAlignmentEditorWidgetForPage::initEditor() +{ + TextAlignmentEditorWidget::initEditor(); + connect(m_page,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); +} + +void TextAlignmentEditorWidgetForPage::slotTextHAttribsChanged(bool value) +{ + + TextAlignmentEditorWidget::slotTextHAttribsChanged(value); + if (m_textAttibutesIsChanging) return; + m_textAttibutesIsChanging = true; + m_page->changeSelectedGrpoupTextAlignPropperty(true,Qt::AlignmentFlag(flag())); + m_textAttibutesIsChanging = false; +} + +void TextAlignmentEditorWidgetForPage::slotTextVAttribsChanged(bool value) +{ + TextAlignmentEditorWidget::slotTextVAttribsChanged(value); + if (m_textAttibutesIsChanging) return; + m_textAttibutesIsChanging = true; + m_page->changeSelectedGrpoupTextAlignPropperty(false,Qt::AlignmentFlag(flag()) ); + m_textAttibutesIsChanging = false; +} + +#ifdef HAVE_REPORT_DESIGNER +void TextAlignmentEditorWidgetForDesigner::initEditor() +{ + connect(m_reportEditor,SIGNAL(itemPropertyChanged(QString,QString,QVariant,QVariant)), + this,SLOT(slotPropertyChanged(QString,QString,QVariant,QVariant))); + +} + +void TextAlignmentEditorWidgetForDesigner::slotTextHAttribsChanged(bool value) +{ + TextAlignmentEditorWidget::slotTextHAttribsChanged(value); + if (m_textAttibutesIsChanging) return; + m_textAttibutesIsChanging = true; + m_reportEditor->setTextAlign(true,Qt::AlignmentFlag(flag())); + m_textAttibutesIsChanging = false; +} + +void TextAlignmentEditorWidgetForDesigner::slotTextVAttribsChanged(bool value) +{ + TextAlignmentEditorWidget::slotTextVAttribsChanged(value); + if (m_textAttibutesIsChanging) return; + m_textAttibutesIsChanging = true; + m_reportEditor->setTextAlign(false,Qt::AlignmentFlag(flag())); + m_textAttibutesIsChanging = false; +} +#endif } //namespace LimeReport diff --git a/limereport/items/editors/lrtextalignmenteditorwidget.h b/limereport/items/editors/lrtextalignmenteditorwidget.h index 93fd39d..4590be3 100644 --- a/limereport/items/editors/lrtextalignmenteditorwidget.h +++ b/limereport/items/editors/lrtextalignmenteditorwidget.h @@ -41,23 +41,20 @@ class TextAlignmentEditorWidget:public ItemEditorWidget { Q_OBJECT public: - explicit TextAlignmentEditorWidget(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0); - explicit TextAlignmentEditorWidget(ReportDesignWidget* reportEditor, QWidget *parent = 0); - explicit TextAlignmentEditorWidget(PageDesignIntf* page, const QString &title, QWidget *parent = 0); - explicit TextAlignmentEditorWidget(PageDesignIntf* page, QWidget *parent = 0); + explicit TextAlignmentEditorWidget(const QString &title, QWidget *parent = 0); + int flag() const; protected: void setItemEvent(BaseDesignIntf *item); -private: void initEditor(); + bool m_textAttibutesIsChanging; +private: void updateValues(const Qt::Alignment& align); Qt::Alignment createAlignment(); -private slots: - void slotTextHAttribsChanged(bool); - void slotTextVAttribsChanged(bool); - void slotPropertyChanged(const QString& objectName, const QString& property, const QVariant &oldValue, const QVariant &newValue); +protected slots: + virtual void slotTextHAttribsChanged(bool); + virtual void slotTextVAttribsChanged(bool); + virtual void slotPropertyChanged(const QString& objectName, const QString& property, const QVariant &oldValue, const QVariant &newValue); private: - bool m_textAttibutesIsChanging; - QAction* m_textAliginLeft; QAction* m_textAliginRight; QAction* m_textAliginHCenter; @@ -65,9 +62,39 @@ private: QAction* m_textAliginTop; QAction* m_textAliginBottom; QAction* m_textAliginVCenter; - + int m_flag; }; +class TextAlignmentEditorWidgetForPage: public TextAlignmentEditorWidget{ + Q_OBJECT +public: + TextAlignmentEditorWidgetForPage(PageDesignIntf* page, const QString &title, QWidget *parent = 0) + :TextAlignmentEditorWidget(title, parent), m_page(page){} +protected: + void initEditor(); +protected slots: + void slotTextHAttribsChanged(bool value); + void slotTextVAttribsChanged(bool value); +private: + PageDesignIntf* m_page; +}; + +#ifdef HAVE_REPORT_DESIGNER +class TextAlignmentEditorWidgetForDesigner: public TextAlignmentEditorWidget{ + Q_OBJECT +public: + TextAlignmentEditorWidgetForDesigner(ReportDesignWidget* reportEditor, const QString &title, QWidget *parent = 0) + :TextAlignmentEditorWidget(title, parent), m_reportEditor(reportEditor){initEditor();} +protected: + void initEditor(); +protected slots: + void slotTextHAttribsChanged(bool value); + void slotTextVAttribsChanged(bool value); +private: + ReportDesignWidget* m_reportEditor; +}; +#endif + } //namespace LimeReport #endif // LRTEXTALIGNMENTEDITORWIDGET_H diff --git a/limereport/items/images/pie_chart2.png b/limereport/items/images/pie_chart2.png new file mode 100644 index 0000000..9973e57 Binary files /dev/null and b/limereport/items/images/pie_chart2.png differ diff --git a/limereport/items/items.qrc b/limereport/items/items.qrc index 99c7d25..8543e28 100644 --- a/limereport/items/items.qrc +++ b/limereport/items/items.qrc @@ -41,6 +41,7 @@ images/imageItem4.png images/shapes7.png images/barcode5.png + images/pie_chart2.png images/DataHeaderBand.png images/DataFooterBand.png diff --git a/limereport/items/lrabstractlayout.cpp b/limereport/items/lrabstractlayout.cpp new file mode 100644 index 0000000..02d8e97 --- /dev/null +++ b/limereport/items/lrabstractlayout.cpp @@ -0,0 +1,382 @@ +#include "lrabstractlayout.h" + +namespace LimeReport { + +AbstractLayout::AbstractLayout(QString xmlTag, QObject* owner, QGraphicsItem* parent) + : LayoutDesignIntf(xmlTag, owner, parent), m_isRelocating(false), m_layoutType(Layout), + m_hideEmptyItems(false), m_layoutSpacing(0) +{ + setPossibleResizeDirectionFlags(AllDirections); + m_layoutMarker = new LayoutMarker(this); + m_layoutMarker->setParentItem(this); + m_layoutMarker->setColor(Qt::red); + m_layoutMarker->setHeight(height()); + m_layoutMarker->setZValue(1); +} + +AbstractLayout::~AbstractLayout() +{ + if (m_layoutMarker) { + delete m_layoutMarker; m_layoutMarker=0; + } +} + +QList& AbstractLayout::layoutsChildren() +{ + return m_children; +} + +bool AbstractLayout::isRelocating() const +{ + return m_isRelocating; +} + +void AbstractLayout::setIsRelocating(bool isRelocating) +{ + m_isRelocating = isRelocating; +} + +AbstractLayout::LayoutType AbstractLayout::layoutType() const +{ + return m_layoutType; +} + +void AbstractLayout::setLayoutType(const LayoutType& layoutType) +{ + m_layoutType = layoutType; +} + +void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize) +{ + + placeItemInLayout(item); + + m_children.append(item); + item->setParentItem(this); + item->setParent(this); + item->setFixedPos(true); + item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); + + connect( + item, SIGNAL(destroyed(QObject*)), + this, SLOT(slotOnChildDestroy(QObject*)) + ); + connect( + item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), + this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF)) + ); + connect( + item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)), + this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*)) + ); + connect( + item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)), + this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool)) + ); + + if (updateSize){ + relocateChildren(); + updateLayoutSize(); + } +} + +void AbstractLayout::restoreChild(BaseDesignIntf* item) +{ + if (m_children.contains(item)) return; + + m_isRelocating=true; + + insertItemInLayout(item); + + connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); + connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), + this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))); + connect(item, SIGNAL(itemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)), + this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign))); + + item->setFixedPos(true); + item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); + item->setParent(this); + item->setParentItem(this); + + updateLayoutSize(); + m_isRelocating=false; +} + +bool AbstractLayout::isEmpty() const +{ + bool isEmpty = true; + bool allItemsIsText = true; + foreach (QGraphicsItem* qgItem, childItems()) { + ContentItemDesignIntf* item = dynamic_cast(qgItem); + if (item && !item->content().isEmpty()) isEmpty = false; + if (!item && dynamic_cast(qgItem)) + allItemsIsText = false; + } + return (isEmpty && allItemsIsText); +} + +void AbstractLayout::paintChild(BaseDesignIntf *child, QPointF parentPos, QPainter *painter) +{ + if (!child->childBaseItems().isEmpty()){ + foreach (BaseDesignIntf* item, child->childBaseItems()) { + paintChild(item, child->pos(),painter); + } + } + painter->drawRect( + QRectF(parentPos.x()+child->pos().x(), parentPos.y()+child->pos().y(), + child->rect().bottomRight().rx(), + child->rect().bottomRight().ry() + ) + ); +} + +void AbstractLayout::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + if (isSelected()){ + painter->save(); + painter->setPen(Qt::red); + foreach( BaseDesignIntf* item, m_children){ + paintChild(item, QPointF(0,0), painter); + } + painter->restore(); + } + LayoutDesignIntf::paint(painter, option, widget); +} + +int AbstractLayout::childrenCount() +{ + return m_children.size(); +} + +void AbstractLayout::beforeDelete() +{ +#ifdef HAVE_QT5 + foreach (QObject *item, children()) { +#else + foreach (QObject *item, QObject::children()) { +#endif + BaseDesignIntf *bi = dynamic_cast(item); + if (bi) { + bi->setParentItem(parentItem()); + bi->setParent(parent()); + bi->setVisible(true); + bi->setPos(mapToParent(bi->pos())); + bi->setFixedPos(false); + bi->setPossibleResizeDirectionFlags(AllDirections); + } + } + m_children.clear(); +} + +void AbstractLayout::childAddedEvent(BaseDesignIntf* child) +{ + addChild(child,false); +} + +void AbstractLayout::geometryChangedEvent(QRectF newRect, QRectF) +{ + layoutMarker()->setHeight(newRect.height()); + relocateChildren(); + if (!isRelocating()){ + divideSpace(); + } +} + +void AbstractLayout::initMode(BaseDesignIntf::ItemMode mode) +{ + BaseDesignIntf::initMode(mode); + if ((mode==PreviewMode)||(mode==PrintMode)){ + layoutMarker()->setVisible(false); + } else { + layoutMarker()->setVisible(true); + } +} + +void AbstractLayout::setBorderLinesFlags(BaseDesignIntf::BorderLines flags) +{ + BaseDesignIntf::setBorderLinesFlags(flags); + if (flags!=0) + relocateChildren(); +} + +void AbstractLayout::collectionLoadFinished(const QString& collectionName) +{ + ItemDesignIntf::collectionLoadFinished(collectionName); + if (collectionName.compare("children",Qt::CaseInsensitive)==0){ +#ifdef HAVE_QT5 + foreach(QObject* obj, children()){ +#else + foreach(QObject* obj,QObject::children()){ +#endif + BaseDesignIntf* item = dynamic_cast(obj); + if (item) { + addChild(item,false); + } + } + } +} + +void AbstractLayout::objectLoadFinished() +{ + layoutMarker()->setHeight(height()); + LayoutDesignIntf::objectLoadFinished(); +} + +bool AbstractLayout::isNeedUpdateSize(RenderPass pass) const +{ + Q_UNUSED(pass) + return true; +} + +QVariant AbstractLayout::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) +{ + if (change == QGraphicsItem::ItemSelectedHasChanged){ + setIsRelocating(true); + foreach(BaseDesignIntf* item, layoutsChildren()){ + item->setVisible(!value.toBool()); + } + setIsRelocating(false); + } + return LayoutDesignIntf::itemChange(change, value); +} + +void AbstractLayout::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) +{ + setIsRelocating(true); + ItemDesignIntf::updateItemSize(dataManager, pass, maxHeight); + foreach(QGraphicsItem *child, childItems()){ + BaseDesignIntf* item = dynamic_cast(child); + if (item && item->isNeedUpdateSize(pass)) + item->updateItemSize(dataManager, pass, maxHeight); + } + updateLayoutSize(); + relocateChildren(); + setIsRelocating(false); + BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); +} + +void AbstractLayout::rebuildChildrenIfNeeded(){ + if (layoutsChildren().count() < childItems().size()-1){ + layoutsChildren().clear(); + foreach (BaseDesignIntf* childItem, childBaseItems()) { + layoutsChildren().append(childItem); + } + sortChildren(); + } +} + +BaseDesignIntf *AbstractLayout::findNext(BaseDesignIntf *item) +{ + rebuildChildrenIfNeeded(); + for (int i=0; ii+1){ return layoutsChildren()[i+1];} + } + return 0; +} + +BaseDesignIntf *AbstractLayout::findPrior(BaseDesignIntf *item) +{ + rebuildChildrenIfNeeded(); + for (int i=0; i(child)); + if (m_children.count()<2){ + beforeDelete(); + } else { + relocateChildren(); + updateLayoutSize(); + } +} + +void AbstractLayout::slotOnChildGeometryChanged(QObject* item, QRectF newGeometry, QRectF oldGeometry) +{ + if (!m_isRelocating && !isLoading()){ + if (m_layoutType == Layout){ + relocateChildren(); + updateLayoutSize(); + } else { + m_isRelocating = true; + qreal delta = newGeometry.width()-oldGeometry.width(); + BaseDesignIntf* resizingItem = findNext(dynamic_cast(item)); + if (resizingItem) { + resizingItem->setWidth(resizingItem->width()-delta); + resizingItem->setPos(resizingItem->pos().x()+delta,resizingItem->pos().y()); + } + updateLayoutSize(); + m_isRelocating = false; + } + } +} + +void AbstractLayout::slotOnChildItemAlignChanged(BaseDesignIntf* item, const BaseDesignIntf::ItemAlign&, const BaseDesignIntf::ItemAlign&) +{ + item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight); +} + +void AbstractLayout::slotOnChildVisibleHasChanged(BaseDesignIntf*) +{ + relocateChildren(); + if (m_layoutType == Table && !m_isRelocating){ + divideSpace(); + } +} + +void AbstractLayout::slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value) +{ + item->setZValue(value ? item->zValue()+1 : item->zValue()-1); +} + +int AbstractLayout::layoutSpacing() const +{ + return m_layoutSpacing; +} + +void AbstractLayout::setLayoutSpacing(int layoutSpacing) +{ + if (m_layoutSpacing != layoutSpacing){ + int oldValue = m_layoutSpacing; + m_layoutSpacing = layoutSpacing; + if (!isLoading()){ + int delta = (m_layoutSpacing - oldValue) * (m_children.count()-1); + notify("layoutSpacing", oldValue, m_layoutSpacing); + setWidth(width() + delta); + } + relocateChildren(); + } +} + +bool AbstractLayout::hideEmptyItems() const +{ + return m_hideEmptyItems; +} + +void AbstractLayout::setHideEmptyItems(bool hideEmptyItems) +{ + m_hideEmptyItems = hideEmptyItems; + + if (m_hideEmptyItems != hideEmptyItems){ + m_hideEmptyItems = hideEmptyItems; + notify("hideEmptyItems", !m_hideEmptyItems, m_hideEmptyItems); + } +} + +QObject* AbstractLayout::at(int index) +{ + rebuildChildrenIfNeeded(); + if (layoutsChildren().size() > index) return layoutsChildren()[index]; + return 0; +} + +LayoutMarker* AbstractLayout::layoutMarker() const +{ + return m_layoutMarker; +} + +} // namespace LimeReport diff --git a/limereport/items/lrabstractlayout.h b/limereport/items/lrabstractlayout.h new file mode 100644 index 0000000..1324ff7 --- /dev/null +++ b/limereport/items/lrabstractlayout.h @@ -0,0 +1,76 @@ +#ifndef LRABSTRACTLAYOUT_H +#define LRABSTRACTLAYOUT_H + +#include "lritemdesignintf.h" +#include "lrlayoutmarker.h" + +namespace LimeReport{ +class AbstractLayout: public LayoutDesignIntf +{ + Q_OBJECT + Q_ENUMS(LayoutType) + Q_PROPERTY(bool hideEmptyItems READ hideEmptyItems WRITE setHideEmptyItems) + Q_PROPERTY(int layoutSpacing READ layoutSpacing WRITE setLayoutSpacing) +public: + enum LayoutType{Layout,Table}; + AbstractLayout(QString xmlTag, QObject *owner = 0, QGraphicsItem *parent = 0); + ~AbstractLayout(); + QList& layoutsChildren(); + LayoutMarker* layoutMarker() const; + bool isRelocating() const; + void setIsRelocating(bool isRelocating); + LayoutType layoutType() const; + void setLayoutType(const LayoutType& layoutType); + + void addChild(BaseDesignIntf *item,bool updateSize=true); + void restoreChild(BaseDesignIntf *item); + bool isEmpty() const; + void paintChild(BaseDesignIntf* child, QPointF parentPos, QPainter* painter); + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); + + bool hideEmptyItems() const; + void setHideEmptyItems(bool hideEmptyItems); + Q_INVOKABLE QObject* at(int index); + int childrenCount(); + int layoutSpacing() const; + void setLayoutSpacing(int layoutSpacing); + qreal layoutSpacingMM(){ return m_layoutSpacing * unitFactor();} +protected: + void beforeDelete(); + void childAddedEvent(BaseDesignIntf *child); + void geometryChangedEvent(QRectF newRect, QRectF); + void initMode(ItemMode mode); + void setBorderLinesFlags(BorderLines flags); + void collectionLoadFinished(const QString &collectionName); + void objectLoadFinished(); + bool isNeedUpdateSize(RenderPass pass) const; + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight); + void rebuildChildrenIfNeeded(); +private: + virtual void sortChildren() = 0; + virtual void divideSpace() = 0; + virtual void updateLayoutSize() = 0; + virtual void relocateChildren() = 0; + virtual BaseDesignIntf* findNext(BaseDesignIntf *item); + virtual BaseDesignIntf* findPrior(BaseDesignIntf *item); + virtual void placeItemInLayout(BaseDesignIntf* item) = 0; + virtual void insertItemInLayout(BaseDesignIntf* item) = 0; +private slots: + void slotOnChildDestroy(QObject *child); + void slotOnChildGeometryChanged(QObject*item, QRectF newGeometry, QRectF oldGeometry); + void slotOnChildItemAlignChanged(BaseDesignIntf* item, const ItemAlign&, const ItemAlign&); + void slotOnChildVisibleHasChanged(BaseDesignIntf*); + void slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value); +private: + QList m_children; + bool m_isRelocating; + LayoutMarker* m_layoutMarker; + LayoutType m_layoutType; + bool m_hideEmptyItems; + int m_layoutSpacing; +}; + +} // namespace LimeReport + +#endif // LRABSTRACTLAYOUT_H diff --git a/limereport/items/lrbarcodeitem.cpp b/limereport/items/lrbarcodeitem.cpp index ad63ac0..9161c20 100644 --- a/limereport/items/lrbarcodeitem.cpp +++ b/limereport/items/lrbarcodeitem.cpp @@ -49,7 +49,7 @@ BarcodeItem::BarcodeItem(QObject* owner,QGraphicsItem* parent) : ContentItemDesignIntf(xmlTag,owner,parent),m_designTestValue("1"), m_barcodeType(CODE128), m_foregroundColor(Qt::black), m_backgroundColor(Qt::white), m_whitespace(10), m_angle(Angle0), m_barcodeWidth(0), m_securityLevel(0), m_pdf417CodeWords(928), m_inputMode(UNICODE_INPUT_MODE), - m_option3(0) + m_hideText(false), m_option3(0), m_hideIfEmpty(false) {} BarcodeItem::~BarcodeItem() @@ -102,7 +102,7 @@ void BarcodeItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *opti break; } - bc.render(*ppainter,bcRect,Zint::QZint::KeepAspectRatio); + bc.render(*ppainter,bcRect); ppainter->restore(); ItemDesignIntf::paint(ppainter,option,widget); } @@ -315,6 +315,24 @@ void BarcodeItem::setOption3(int option3) } } +bool BarcodeItem::hideIfEmpty() const +{ + return m_hideIfEmpty; +} + +void BarcodeItem::setHideIfEmpty(bool hideIfEmpty) +{ + if (m_hideIfEmpty != hideIfEmpty){ + m_hideIfEmpty = hideIfEmpty; + notify("hideIfEmpty",!m_hideIfEmpty, m_hideIfEmpty); + } +} + +bool BarcodeItem::isEmpty() const +{ + return m_content.isEmpty(); +} + void BarcodeItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) { if (content().isEmpty()) @@ -338,19 +356,17 @@ void BarcodeItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass } } } - } - else - { - switch(pass) - { - case FirstPass: - setContent(expandUserVariables(content(),pass,NoEscapeSymbols, dataManager)); - setContent(expandDataFields(content(), NoEscapeSymbols, dataManager)); - break; - default:; + } else { + switch(pass){ + case FirstPass: + setContent(expandUserVariables(content(),pass,NoEscapeSymbols, dataManager)); + setContent(expandDataFields(content(), NoEscapeSymbols, dataManager)); + break; + default:; } } BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); + if (isEmpty() && hideIfEmpty()) setVisible(false); } bool BarcodeItem::isNeedUpdateSize(RenderPass pass) const diff --git a/limereport/items/lrbarcodeitem.h b/limereport/items/lrbarcodeitem.h index e80b468..3badbd5 100644 --- a/limereport/items/lrbarcodeitem.h +++ b/limereport/items/lrbarcodeitem.h @@ -30,7 +30,6 @@ #ifndef LRBARCODEITEM_H #define LRBARCODEITEM_H #include "lritemdesignintf.h" -#include namespace LimeReport{ @@ -54,11 +53,8 @@ class BarcodeItem : public LimeReport::ContentItemDesignIntf { Q_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode) Q_PROPERTY(bool hideText READ hideText WRITE setHideText) Q_PROPERTY(int option3 READ option3 WRITE setOption3) + Q_PROPERTY(bool hideIfEmpty READ hideIfEmpty WRITE setHideIfEmpty) public: -// enum BarcodeType {QRCODE=58,CODE128=20,DATAMATRIX=71,MAXICODE=57,MICROPDF417=84}; -// enum BarcodeType {CODE_11=1,C25MATRIX=2,QRCODE=58,CODE128=20,DATAMATRIX=71,MAXICODE=57,MICROPDF417=84, -// EAN=13,PDF417=55, TELEPEN_NUM=87,ITF14=89, KIX=90, MICROQR=97, -// EAN14=72,CHANNEL=140,CODEONE=141,GRIDMATRIX=142}; enum BarcodeType { CODE11 =1, C25MATRIX =2, @@ -69,6 +65,7 @@ public: CODE39 =8, EXCODE39 =9, EANX =13, + EANX_CHK =14, EAN128 =16, CODABAR =18, CODE128 =20, @@ -119,18 +116,32 @@ public: ITALYPOST =94, DPD =96, MICROQR =97, + HIBC_128 =98, + HIBC_39 =99, + HIBC_DM =102, + HIBC_QR =104, + HIBC_PDF =106, + HIBC_MICPDF =108, + HIBC_BLOCKF =110, + HIBC_AZTEC =112, + DOTCODE =115, + HANXIN =116, TELEPEN_NUM =128, CODE32 =129, - EANX_CC =130, - EAN128_CC =131, - RSS14_CC =132, - RSS_LTD_CC =133, - RSS_EXP_CC =134, - UPCA_CC =135, - UPCE_CC =136, - RSS14STACK_CC =137, - RSS14_OMNI_CC =138, - RSS_EXPSTACK_CC =139 +// EANX_CC =130, +// EAN128_CC =131, +// RSS14_CC =132, +// RSS_LTD_CC =133, +// RSS_EXP_CC =134, +// UPCA_CC =135, +// UPCE_CC =136, +// RSS14STACK_CC =137, +// RSS14_OMNI_CC =138, +// RSS_EXPSTACK_CC =139, + CHANNEL =140, + CODEONE =141, + GRIDMATRIX =142, + UPNQR =143 }; enum AngleType{Angle0,Angle90,Angle180,Angle270}; @@ -181,8 +192,11 @@ public: int option3() const; void setOption3(int option3); + bool hideIfEmpty() const; + void setHideIfEmpty(bool hideIfEmpty); + bool isEmpty() const; + private: - Zint::QZint m_bc; QString m_content; QString m_datasource; QString m_field; @@ -198,6 +212,7 @@ private: InputMode m_inputMode; bool m_hideText; int m_option3; + bool m_hideIfEmpty; }; } diff --git a/limereport/items/lrchartitem.cpp b/limereport/items/lrchartitem.cpp new file mode 100644 index 0000000..171d45c --- /dev/null +++ b/limereport/items/lrchartitem.cpp @@ -0,0 +1,1111 @@ +#include "lrchartitem.h" +#include +#include + +#include "lrdesignelementsfactory.h" +#include "lrchartitemeditor.h" +#include "lrdatasourcemanager.h" +#include "lrpagedesignintf.h" +#include "lrreportengine_p.h" +#include "lrdatadesignintf.h" + +namespace{ + +const QString xmlTag = "ChartItem"; + +LimeReport::BaseDesignIntf * createChartItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new LimeReport::ChartItem(owner,parent); +} +bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, LimeReport::ItemAttribs(QObject::tr("Chart Item"),"Item"), createChartItem + ); +} + +namespace LimeReport{ + +QColor generateColor() +{ + int red = (qrand()%(256 - 1)) + 1; + int green = (qrand()%(256 - 1)) + 1; + int blue = (qrand()%(256 - 1)) + 1;; + return QColor(red,green,blue); +} + +QColor color_map[39] = { + QColor(51,102,204), QColor(220,57,18), QColor(225, 153, 0), QColor(16, 150, 24), QColor(153,0,153), + QColor(0,153,198), QColor(221, 68, 119), + QColor(255,0,0), QColor(0,0,139), QColor(0,205,0), QColor(233,30,99), QColor(255,255,0), QColor(244,67,54), + QColor(156,39,176), QColor(103,58,183), QColor(63,81,181), QColor(33,153,243), + QColor(0,150,136), QColor(78,175,80), QColor(139,195,74), QColor(205,228,57), + QColor(0,139,0), QColor(0,0,255), QColor(255,235,59), QColor(255,193,7), + QColor(255,152,0), QColor(255,87,34), QColor(121,85,72), QColor(158,158,158), + QColor(96,125,139), QColor(241,153,185), QColor(64,64,64), + QColor(188,229,218), QColor(139,0,0), QColor(139,139,0), QColor(171, 130, 255), + QColor(139, 123, 139), QColor(255, 0, 255), QColor(139, 69, 19) +}; + +QString SeriesItem::name() const +{ + return m_name; +} + +void SeriesItem::setName(const QString &name) +{ + m_name = name; +} + +QString SeriesItem::valuesColumn() const +{ + return m_valuesColumn; +} + +void SeriesItem::setValuesColumn(const QString &valuesColumn) +{ + m_valuesColumn = valuesColumn; +} + +QString SeriesItem::labelsColumn() const +{ + return m_labelsColumn; +} + +void SeriesItem::setLabelsColumn(const QString &labelsColumn) +{ + m_labelsColumn = labelsColumn; +} + +SeriesItem *SeriesItem::clone() +{ + SeriesItem* result = new SeriesItem(); + for (int i = 0; i < this->metaObject()->propertyCount(); ++i){ + result->setProperty(this->metaObject()->property(i).name(),property(this->metaObject()->property(i).name())); + } + return result; +} + +void SeriesItem::fillSeriesData(IDataSource *dataSource) +{ + if (dataSource){ + dataSource->first(); + int currentColorIndex = 0; + while(!dataSource->eof()){ + if (!m_labelsColumn.isEmpty()) + m_data.labels().append(dataSource->data(m_labelsColumn).toString()); + m_data.values().append(dataSource->data(m_valuesColumn).toDouble()); + m_data.colors().append((currentColorIndex<32)?color_map[currentColorIndex]:generateColor()); + dataSource->next(); + currentColorIndex++; + } + } +} + +QColor SeriesItem::color() const +{ + return m_color; +} + +void SeriesItem::setColor(const QColor &color) +{ + m_color = color; +} + +SeriesItem::SeriesItemPreferredType SeriesItem::preferredType() const +{ + return m_preferredType; +} + +void SeriesItem::setPreferredType(const SeriesItemPreferredType& type) +{ + m_preferredType = type; +} + +ChartItem::ChartItem(QObject *owner, QGraphicsItem *parent) + : ItemDesignIntf(xmlTag, owner, parent), m_legendBorder(true), + m_legendAlign(LegendAlignCenter), m_titleAlign(TitleAlignCenter), + m_chartType(Pie), m_labelsField("") +{ + m_labels<<"First"<<"Second"<<"Thrid"; + m_chart = new PieChart(this); +} + +ChartItem::~ChartItem() +{ + foreach (SeriesItem* series, m_series) { + delete series; + } + m_series.clear(); + delete m_chart; +} + +ChartItem::TitleAlign ChartItem::titleAlign() const +{ + return m_titleAlign; +} + +void ChartItem::setTitleAlign(const TitleAlign &titleAlign) +{ + if (m_titleAlign != titleAlign){ + TitleAlign oldValue = m_titleAlign; + m_titleAlign = titleAlign; + notify("titleAlign",oldValue,m_titleAlign); + update(); + } +} + +void ChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->save(); + setupPainter(painter); + painter->setFont(transformToSceneFont(painter->font())); + painter->setRenderHint(QPainter::Antialiasing,true); + painter->setRenderHint(QPainter::TextAntialiasing,true); + qreal borderMargin = (rect().height()*0.01>10)?(10):(rect().height()*0.01); + qreal maxTitleHeight = rect().height()*0.2; + + QFont tmpFont = painter->font(); + + qreal titleOffset = !m_title.isEmpty()?(((painter->fontMetrics().height()+borderMargin*2)fontMetrics().height()+borderMargin*2): + (maxTitleHeight)):0; + + QRectF titleRect = QRectF(borderMargin,borderMargin,rect().width()-borderMargin*2,titleOffset); + QRectF legendRect = m_chart->calcChartLegendRect(painter->font(), rect(), false, borderMargin, titleOffset); + QRectF diagramRect = rect().adjusted(borderMargin,titleOffset+borderMargin, + -(legendRect.width()+borderMargin*2),-borderMargin); + + paintChartTitle(painter, titleRect); + m_chart->paintChartLegend(painter,legendRect); + m_chart->paintChart(painter,diagramRect); + + painter->restore(); + ItemDesignIntf::paint(painter,option,widget); +} + +BaseDesignIntf *ChartItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) +{ + ChartItem* result = new ChartItem(owner,parent); + foreach (SeriesItem* series, m_series) { + result->m_series.append(series->clone()); + } + return result; +} + +QObject *ChartItem::createElement(const QString &collectionName, const QString &elementType) +{ + Q_UNUSED(elementType); + if (collectionName.compare("series")==0){ + SeriesItem* seriesItem = new SeriesItem(); + m_series.append(seriesItem); + return seriesItem; + } + return 0; +} + +int ChartItem::elementsCount(const QString &collectionName) +{ + if (collectionName.compare("series")==0) + return m_series.count(); + return 0; +} + +QObject *ChartItem::elementAt(const QString &collectionName, int index) +{ + if (collectionName.compare("series")==0) + return m_series.at(index); + return 0; +} + +void ChartItem::updateItemSize(DataSourceManager *dataManager, RenderPass , int ) +{ + if (dataManager && dataManager->dataSource(m_datasource)){ + IDataSource* ds = dataManager->dataSource(m_datasource); + foreach (SeriesItem* series, m_series) { + series->setLabelsColumn(m_labelsField); + series->fillSeriesData(ds); + } + fillLabels(ds); + } +} + +void ChartItem::fillLabels(IDataSource *dataSource) +{ + m_labels.clear(); + if (dataSource && !m_labelsField.isEmpty()){ + dataSource->first(); + while(!dataSource->eof()){ + m_labels.append(dataSource->data(m_labelsField).toString()); + dataSource->next(); + } + } +} + +QWidget *ChartItem::defaultEditor() +{ + QSettings* l_settings = (page()->settings() != 0) ? + page()->settings() : + (page()->reportEditor()!=0) ? page()->reportEditor()->settings() : 0; + QWidget* editor = new ChartItemEditor(this,page(),l_settings); + editor->setAttribute(Qt::WA_DeleteOnClose); + return editor; +} + +QList ChartItem::labels() const +{ + return m_labels; +} + +void ChartItem::setLabels(const QList &labels) +{ + m_labels = labels; +} + +QString ChartItem::labelsField() const +{ + return m_labelsField; +} + +void ChartItem::setLabelsField(const QString &labelsField) +{ + m_labelsField = labelsField; +} + +ChartItem::ChartType ChartItem::chartType() const +{ + return m_chartType; +} + +void ChartItem::setChartType(const ChartType &chartType) +{ + if (m_chartType != chartType){ + ChartType oldValue = m_chartType; + m_chartType = chartType; + delete m_chart; + switch (m_chartType) { + case Pie: + m_chart = new PieChart(this); + break; + case VerticalBar: + m_chart = new VerticalBarChart(this); + break; + case HorizontalBar: + m_chart = new HorizontalBarChart(this); + break; + } + notify("chartType",oldValue,m_chartType); + update(); + } +} + +QString ChartItem::datasource() const +{ + return m_datasource; +} + +void ChartItem::setDatasource(const QString &datasource) +{ + m_datasource = datasource; +} + +void ChartItem::paintChartTitle(QPainter *painter, QRectF titleRect) +{ + painter->save(); + QFont tmpFont = painter->font(); + QFontMetrics fm(tmpFont); + while ((fm.height()>titleRect.height() || fm.width(m_title)>titleRect.width()) + && tmpFont.pixelSize()>1) { + tmpFont.setPixelSize(tmpFont.pixelSize()-1); + fm = QFontMetrics(tmpFont); + } + painter->setFont(tmpFont); + Qt::AlignmentFlag align = Qt::AlignCenter; + switch (m_titleAlign) { + case TitleAlignLeft: + align = Qt::AlignLeft; + break; + case TitleAlignCenter: + align = Qt::AlignCenter; + break; + case TitleAlignRight: + align = Qt::AlignRight; + break; + } + painter->drawText(titleRect, align, m_title); + painter->restore(); +} + + +ChartItem::LegendAlign ChartItem::legendAlign() const +{ + return m_legendAlign; +} + +void ChartItem::setLegendAlign(const LegendAlign &legendAlign) +{ + if (m_legendAlign != legendAlign){ + LegendAlign oldValue = m_legendAlign; + m_legendAlign = legendAlign; + notify("legendAlign",oldValue,m_legendAlign); + update(); + } +} + +bool ChartItem::drawLegendBorder() const +{ + return m_legendBorder; +} + +void ChartItem::setDrawLegendBorder(bool legendBorder) +{ + if (m_legendBorder!=legendBorder){ + m_legendBorder = legendBorder; + notify("legendBorder",!m_legendBorder,m_legendBorder); + update(); + } +} + +QString ChartItem::chartTitle() const +{ + return m_title; +} + +void ChartItem::setChartTitle(const QString &title) +{ + if (m_title != title){ + QString oldValue = m_title; + m_title = title; + update(); + notify("chartTitle",oldValue,title); + } +} + +QList &ChartItem::series() +{ + return m_series; +} + +void ChartItem::setSeries(const QList &series) +{ + m_series = series; +} + +bool ChartItem::isSeriesExists(const QString &name) +{ + foreach (SeriesItem* series, m_series) { + if (series->name().compare(name)==0) return true; + } + return false; +} + +AbstractChart::AbstractChart(ChartItem *chartItem) + :m_chartItem(chartItem) +{ + m_designLabels<legendAlign()) { + case ChartItem::LegendAlignTop: + legendTopMargin = titleOffset+borderMargin; + legendBottomMargin = parentRect.height()-(legendSize.height()+titleOffset); + break; + case ChartItem::LegendAlignCenter: + legendTopMargin = titleOffset+(parentRect.height()-titleOffset-legendSize.height())/2; + legendBottomMargin = (parentRect.height()-titleOffset-legendSize.height())/2; + break; + case ChartItem::LegendAlignBottom: + legendTopMargin = parentRect.height()-(legendSize.height()+titleOffset); + legendBottomMargin = borderMargin; + break; + } + + qreal rightOffset = !takeAllRect?((legendSize.width()>parentRect.width()/2-borderMargin)? + (parentRect.width()/2): + (parentRect.width()-legendSize.width())):0; + + QRectF legendRect = parentRect.adjusted( + rightOffset, + (legendSize.height()>(parentRect.height()-titleOffset))?(titleOffset):(legendTopMargin), + -borderMargin, + (legendSize.height()>(parentRect.height()-titleOffset))?(0):(-legendBottomMargin) + ); + + return legendRect; +} + +void AbstractChart::prepareLegendToPaint(QRectF &legendRect, QPainter *painter) +{ + QFont tmpFont = painter->font(); + QSizeF legendSize = calcChartLegendSize(tmpFont); + + if ((legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width())){ + while ( (legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width()) + && tmpFont.pixelSize()>1) + { + tmpFont.setPixelSize(tmpFont.pixelSize()-1); + painter->setFont(tmpFont); + legendSize = calcChartLegendSize(tmpFont); + } + painter->setFont(tmpFont); + legendRect = calcChartLegendRect(tmpFont, legendRect, true, 0, 0); + } +} + +void PieChart::drawPercent(QPainter *painter, QRectF chartRect, qreal startAngle, qreal angle) +{ + painter->save(); + + QPointF center(chartRect.left()+chartRect.width()/2,chartRect.top()+chartRect.height()/2); + qreal percent = angle/3.6; +#ifdef HAVE_QT4 + qreal radAngle = (angle/2+startAngle)*(M_PI/180); +#endif +#ifdef HAVE_QT5 + qreal radAngle = qDegreesToRadians(angle/2+startAngle); +#endif + qreal radius = painter->fontMetrics().width("99,9%"); + qreal border = chartRect.height()*0.02; + qreal length = (chartRect.height())/2-(radius/2+border); + qreal x,y; + x = length*qCos(radAngle); + y = length*qSin(radAngle); + QPointF endPoint(center.x()+x,center.y()-y); + painter->setPen(Qt::white); + QRectF textRect(endPoint.x()-(radius/2),endPoint.y()-(radius/2),radius,radius); + + qreal arcLength = 3.14 * length * angle / 180; + if (arcLength >= radius) + painter->drawText(textRect,Qt::AlignCenter,QString::number(percent,'f',1)+"%"); + painter->restore(); + +} + +void PieChart::paintChart(QPainter *painter, QRectF chartRect) +{ + painter->save(); + QPen pen(Qt::white); + pen.setWidthF(2); + painter->setPen(pen); + + QBrush brush(Qt::transparent); + painter->setBrush(brush); + painter->setBackground(QBrush(Qt::NoBrush)); + + QRectF tmpRect = chartRect; + if (chartRect.height()>chartRect.width()){ + tmpRect.setHeight(chartRect.width()); + tmpRect.adjust(0,(chartRect.bottom()-tmpRect.bottom())/2, + 0,(chartRect.bottom()-tmpRect.bottom())/2); + } else { + tmpRect.setWidth(chartRect.height()); + } + + chartRect = tmpRect; + painter->drawRect(chartRect); + + if (!m_chartItem->series().isEmpty()&&!m_chartItem->series().at(0)->data()->values().isEmpty()){ + SeriesItem* si = m_chartItem->series().at(0); + qreal sum = 0; + foreach(qreal value, si->data()->values()){ + sum+=value; + } + qreal onePercent = sum / 100; + qreal currentDegree = 0; + for(int i=0; idata()->values().count(); ++i){ + qreal value = si->data()->values().at(i); + qreal sectorDegree = (value/onePercent)*3.6; + painter->setBrush(si->data()->colors().at(i)); + painter->drawPie(chartRect,currentDegree*16,sectorDegree*16); + drawPercent(painter, chartRect, currentDegree, sectorDegree); + currentDegree += sectorDegree; + } + } else { + painter->setBrush(color_map[0]); + painter->drawPie(chartRect,0,260*16); + drawPercent(painter, chartRect, 0, 260); + painter->setBrush(color_map[1]); + painter->drawPie(chartRect,260*16,40*16); + drawPercent(painter, chartRect, 260, 40); + painter->setBrush(color_map[2]); + painter->drawPie(chartRect,300*16,60*16); + drawPercent(painter, chartRect, 300, 60); + } + + pen.setWidthF(1); + pen.setColor(Qt::gray); + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawEllipse(chartRect); + painter->restore(); +} + +void PieChart::paintChartLegend(QPainter *painter, QRectF legendRect) +{ + prepareLegendToPaint(legendRect, painter); + + int indicatorSize = painter->fontMetrics().height()/2; + painter->setRenderHint(QPainter::Antialiasing,false); + + if (m_chartItem->drawLegendBorder()) + painter->drawRect(legendRect); + + painter->setRenderHint(QPainter::Antialiasing,true); + QRectF indicatorsRect = legendRect.adjusted(painter->fontMetrics().height()/2,painter->fontMetrics().height()/2,0,0); + + if (!m_chartItem->series().isEmpty() && !m_chartItem->series().at(0)->data()->labels().isEmpty()){ + qreal cw = 0; + SeriesItem* si = m_chartItem->series().at(0); + for (int i=0;idata()->labels().count();++i){ + QString label = si->data()->labels().at(i); + painter->setPen(Qt::black); + painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); + painter->setPen(si->data()->colors().at(i)); + painter->setBrush(si->data()->colors().at(i)); + painter->drawEllipse( + indicatorsRect.adjusted( + 0, + cw+indicatorSize/2, + -(indicatorsRect.width()-indicatorSize), + -(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2)) + ) + ); + cw += painter->fontMetrics().height(); + } + } else { + qreal cw = 0; + for (int i=0;isetPen(Qt::black); + painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); + painter->setBrush(color_map[i]); + painter->setPen(color_map[i]); + painter->drawEllipse( + indicatorsRect.adjusted( + 0, + cw+indicatorSize/2, + -(indicatorsRect.width()-indicatorSize), + -(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2)) + ) + ); + cw += painter->fontMetrics().height(); + } + + } +} + +QSizeF PieChart::calcChartLegendSize(const QFont &font) +{ + QFontMetrics fm(font); + + qreal cw = 0; + qreal maxWidth = 0; + + if (!m_chartItem->series().isEmpty() && !m_chartItem->series().at(0)->data()->labels().isEmpty()){ + SeriesItem* si = m_chartItem->series().at(0); + foreach(QString label, si->data()->labels()){ + cw += fm.height(); + if (maxWidthfontMetrics().width(QString::number(delta))+4; +} + +qreal VerticalBarChart::valuesVMargin(QPainter *painter) +{ + return painter->fontMetrics().height(); +} + +QRectF VerticalBarChart::labelsRect(QPainter *painter, QRectF labelsRect) +{ + qreal maxWidth = 0; + + foreach (QString label, m_chartItem->labels()) { + if (painter->fontMetrics().width(label)>maxWidth) + maxWidth = painter->fontMetrics().width(label); + } + + if (maxWidth+vPadding(m_chartItem->rect())> labelsRect.height()) + return labelsRect; + else + return labelsRect.adjusted(0,(labelsRect.height()-(maxWidth+vPadding(m_chartItem->rect()))),0,0); +} + +void VerticalBarChart::paintChart(QPainter *painter, QRectF chartRect) +{ + QRectF calcRect = labelsRect(painter, chartRect.adjusted( + hPadding(chartRect)*2+valuesHMargin(painter), + chartRect.height()*0.5, + -(hPadding(chartRect)*2), + -vPadding(chartRect) + )); + + qreal barsShift = calcRect.height(); + paintVerticalGrid(painter, chartRect.adjusted( + hPadding(chartRect), + vPadding(chartRect)+valuesVMargin(painter), + -hPadding(chartRect),-(vPadding(chartRect)+barsShift) )); + + paintVerticalBars(painter, chartRect.adjusted( + hPadding(chartRect)*2+valuesHMargin(painter), + vPadding(chartRect)+valuesVMargin(painter), + -(hPadding(chartRect)*2), + -(vPadding(chartRect)+barsShift) )); + paintSerialLines(painter, chartRect.adjusted( + hPadding(chartRect)*2+valuesHMargin(painter), + vPadding(chartRect)+valuesVMargin(painter), + -(hPadding(chartRect)*2), + -(vPadding(chartRect)+barsShift) )); + paintLabels(painter,calcRect); +} + + +void VerticalBarChart::paintVerticalGrid(QPainter *painter, QRectF gridRect) +{ + int delta = int(maxValue()-minValue()); + delta = genNextValue(delta); + + painter->setRenderHint(QPainter::Antialiasing,false); + qreal vStep = gridRect.height() / 4; + + for (int i=0;i<5;i++){ + painter->drawText(QRectF(gridRect.bottomLeft()-QPointF(0,vStep*i+painter->fontMetrics().height()), + QSizeF(valuesHMargin(painter),painter->fontMetrics().height())), + QString::number(minValue()+i*delta/4)); + painter->drawLine(gridRect.bottomLeft()-QPointF(-valuesHMargin(painter),vStep*i), + gridRect.bottomRight()-QPointF(0,vStep*i)); + } + + painter->setRenderHint(QPainter::Antialiasing,true); +} + + + +void VerticalBarChart::paintVerticalBars(QPainter *painter, QRectF barsRect) +{ + + int delta = int(maxValue()-minValue()); + delta = genNextValue(delta); + + int barSeriesCount = 0; + foreach(SeriesItem* series, m_chartItem->series()){ + if (series->preferredType() == SeriesItem::Bar) barSeriesCount++; + } + + barSeriesCount = (m_chartItem->itemMode()==DesignMode) ? seriesCount() : barSeriesCount; + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing,false); + + qreal vStep = barsRect.height() / delta; + qreal hStep = (barsRect.width() / valuesCount()) / (barSeriesCount == 0 ? 1 : barSeriesCount); + qreal topShift = (delta - (maxValue()-minValue())) * vStep +barsRect.top(); + + if (!m_chartItem->series().isEmpty() && !m_chartItem->series().at(0)->data()->labels().isEmpty()){ + int curSeries = 0; + foreach (SeriesItem* series, m_chartItem->series()) { + if (series->preferredType() == SeriesItem::Bar){ + qreal curHOffset = curSeries*hStep+barsRect.left(); + painter->setBrush(series->color()); + foreach (qreal value, series->data()->values()) { + painter->drawRect(QRectF(curHOffset, maxValue()*vStep+topShift, hStep, -value*vStep)); + curHOffset+=hStep*barSeriesCount; + } + curSeries++; + } + } + } else { + qreal curHOffset = barsRect.left(); + int curColor = 0; + for (int i=0; i<9; ++i){ + if (curColor==3) curColor=0; + painter->setBrush(color_map[curColor]); + painter->drawRect(QRectF(curHOffset, maxValue()*vStep+barsRect.top(), hStep, -designValues()[i]*vStep)); + curHOffset+=hStep; + curColor++; + } + } + painter->restore(); +} + +void VerticalBarChart::paintSerialLines(QPainter* painter, QRectF barsRect) +{ + painter->save(); + painter->setRenderHint(QPainter::Antialiasing,true); + int delta = int(maxValue()-minValue()); + delta = genNextValue(delta); + + qreal vStep = barsRect.height() / delta; + qreal hStep = (barsRect.width() / valuesCount()); + qreal topShift = (delta - (maxValue()-minValue())) * vStep +barsRect.top(); + + if (!m_chartItem->series().isEmpty() && !m_chartItem->series().at(0)->data()->labels().isEmpty()){ + foreach (SeriesItem* series, m_chartItem->series()) { + if (series->preferredType() == SeriesItem::Line){ + QPen pen(series->color()); + pen.setWidth(4); + painter->setPen(pen); + for (int i = 0; i < series->data()->values().count()-1; ++i ){ + QPoint startPoint = QPoint((i+1)*hStep + barsRect.left()-hStep/2, + (maxValue()*vStep+topShift) - series->data()->values().at(i)*vStep + ); + QPoint endPoint = QPoint((i+2)*hStep + barsRect.left()-hStep/2, + (maxValue()*vStep+topShift) - series->data()->values().at(i+1)*vStep + ); + painter->drawLine(startPoint, endPoint); + QRect startPointRect(startPoint,startPoint); + QRect endPointRect(endPoint,endPoint); + int radius = 4; + painter->setBrush(series->color()); + painter->drawEllipse(startPointRect.adjusted(radius,radius,-radius,-radius)); + painter->drawEllipse(endPointRect.adjusted(radius,radius,-radius,-radius)); + + } + } + } + } + painter->restore(); +} + + + +void VerticalBarChart::paintLabels(QPainter *painter, QRectF labelsRect) +{ + painter->save(); + qreal hStep = (labelsRect.width() / valuesCount()); + + if (!m_chartItem->labels().isEmpty()){ + painter->rotate(270); + painter->translate(-(labelsRect.top()+labelsRect.height()),labelsRect.left()); + foreach (QString label, m_chartItem->labels()) { + painter->drawText(QRectF(QPoint(0,0), + QSize(labelsRect.height()-4,hStep)),Qt::AlignVCenter|Qt::AlignRight,label); + painter->translate(0,hStep); + } + painter->rotate(-270); + } + painter->restore(); +} + +AbstractSeriesChart::AbstractSeriesChart(ChartItem *chartItem) + :AbstractChart(chartItem) +{ + m_designValues[0] = 10; + m_designValues[1] = 35; + m_designValues[2] = 15; + m_designValues[3] = 5; + m_designValues[4] = 20; + m_designValues[5] = 10; + m_designValues[6] = 40; + m_designValues[7] = 20; + m_designValues[8] = 5; +} + +qreal AbstractSeriesChart::maxValue() +{ + if (m_chartItem->itemMode()==DesignMode) return 40; + qreal maxValue = 0; + foreach(SeriesItem* series, m_chartItem->series()){ + foreach(qreal value, series->data()->values()){ + if (value>maxValue) maxValue=value; + } + } + return maxValue; +} + +qreal AbstractSeriesChart::minValue() +{ + if (m_chartItem->itemMode()==DesignMode) return 0; + qreal minValue = 0; + foreach(SeriesItem* series, m_chartItem->series()){ + foreach(qreal value, series->data()->values()){ + if (valueitemMode()==DesignMode) return 3; + return (m_chartItem->series().isEmpty())?(0):(m_chartItem->series().at(0)->data()->labels().count()); +} + +int AbstractSeriesChart::seriesCount() +{ + if (m_chartItem->itemMode()==DesignMode) return 3; + return m_chartItem->series().count(); +} + +QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font) +{ + QFontMetrics fm(font); + + qreal cw = 0; + qreal maxWidth = 0; + + if (!m_chartItem->series().isEmpty()){ + foreach(SeriesItem* series, m_chartItem->series()){ + cw += fm.height(); + if (maxWidthname())) + maxWidth = fm.width(series->name())+10; + } + } else { + foreach(QString label, m_designLabels){ + cw += fm.height(); + if (maxWidthfontMetrics().width(QString::number(delta))+4; +} + +qreal HorizontalBarChart::valuesVMargin(QPainter *painter) +{ + return painter->fontMetrics().height(); +} + +void HorizontalBarChart::paintChart(QPainter *painter, QRectF chartRect) +{ + QRectF calcRect = labelsRect(painter, chartRect.adjusted( + hPadding(chartRect), + vPadding(chartRect)*2, + -(chartRect.width()*0.5), + -(vPadding(chartRect)*2+valuesVMargin(painter)) + )); + + qreal barsShift = calcRect.width(); + + paintHorizontalGrid(painter, chartRect.adjusted( + hPadding(chartRect)+barsShift, + vPadding(chartRect), + -(hPadding(chartRect)),-vPadding(chartRect))); + paintHorizontalBars(painter, chartRect.adjusted( + hPadding(chartRect)+barsShift, + vPadding(chartRect)*2, + -(hPadding(chartRect)), + -(vPadding(chartRect)*2) )); + + paintLabels(painter,calcRect); +} + +void HorizontalBarChart::paintHorizontalGrid(QPainter *painter, QRectF gridRect) +{ + painter->save(); + int delta = int(maxValue()-minValue()); + delta = genNextValue(delta); + + painter->setRenderHint(QPainter::Antialiasing,false); + qreal hStep = (gridRect.width()-painter->fontMetrics().width(QString::number(maxValue()))) / 4; + + painter->setFont(adaptValuesFont(hStep-4,painter->font())); + + for (int i=0;i<5;i++){ + painter->drawText(QRectF(gridRect.left()+4+hStep*i,gridRect.bottom()-painter->fontMetrics().height(), + hStep,painter->fontMetrics().height()), + QString::number(minValue()+i*delta/4)); + painter->drawLine( gridRect.left()+hStep*i, gridRect.bottom(), + gridRect.left()+hStep*i, gridRect.top()); + + } + painter->restore(); +} + +void HorizontalBarChart::paintHorizontalBars(QPainter *painter, QRectF barsRect) +{ + painter->save(); + painter->setRenderHint(QPainter::Antialiasing,false); + int delta = int(maxValue()-minValue()); + delta = genNextValue(delta); + + qreal vStep = (barsRect.height()-painter->fontMetrics().height()) / valuesCount() / seriesCount(); + qreal hStep = (barsRect.width()-painter->fontMetrics().width(QString::number(maxValue()))) / delta; + + if (!m_chartItem->series().isEmpty() && !m_chartItem->series().at(0)->data()->labels().isEmpty()){ + int curSeries = 0; + foreach (SeriesItem* series, m_chartItem->series()) { + qreal curVOffset = curSeries*vStep+barsRect.top(); + painter->setBrush(series->color()); + foreach (qreal value, series->data()->values()) { + painter->drawRect(QRectF((-minValue()*hStep)+barsRect.left(), curVOffset, value*hStep, vStep)); + curVOffset+=vStep*seriesCount(); + } + curSeries++; + } + } else { + qreal curVOffset = barsRect.top(); + int curColor = 0; + for (int i=0; i<9; ++i){ + if (curColor==3) curColor=0; + painter->setBrush(color_map[curColor]); + painter->drawRect(QRectF(barsRect.left(), curVOffset, designValues()[i]*hStep, vStep)); + curVOffset+=vStep; + curColor++; + } + } + painter->restore(); +} + +QRectF HorizontalBarChart::labelsRect(QPainter *painter, QRectF labelsRect) +{ + qreal maxWidth = 0; + + foreach (QString label, m_chartItem->labels()) { + if (painter->fontMetrics().width(label)>maxWidth) + maxWidth = painter->fontMetrics().width(label); + } + + if (maxWidth+hPadding(m_chartItem->rect())*2> labelsRect.width()) + return labelsRect; + else + return labelsRect.adjusted(0,0,-(labelsRect.width()-(maxWidth+hPadding(m_chartItem->rect())*2)),0); +} + +QFont HorizontalBarChart::adaptLabelsFont(QRectF rect, QFont font) +{ + QString maxWord; + QFontMetrics fm(font); + + foreach(QString label, m_chartItem->labels()){ + foreach (QString currentWord, label.split(QRegExp("\\W+"))){ + if (fm.width(maxWord)rect.width() && tmpFont.pixelSize()>1){ + tmpFont.setPixelSize(tmpFont.pixelSize()-1); + QFontMetricsF tmpFM(tmpFont); + curWidth = tmpFM.width(maxWord); + } + return tmpFont; +} + +QFont HorizontalBarChart::adaptValuesFont(qreal width, QFont font) +{ + QString strValue = QString::number(maxValue()); + QFont tmpFont = font; + QScopedPointer fm(new QFontMetricsF(tmpFont)); + qreal curWidth = fm->width(strValue); + while (curWidth>width && tmpFont.pixelSize()>1){ + tmpFont.setPixelSize(tmpFont.pixelSize()-1); + fm.reset(new QFontMetricsF(tmpFont)); + curWidth = fm->width(strValue); + } + return tmpFont; +} + +void HorizontalBarChart::paintLabels(QPainter *painter, QRectF labelsRect) +{ + painter->save(); + painter->setFont(adaptLabelsFont(labelsRect.adjusted(0,0,-hPadding(m_chartItem->rect()),0), + painter->font())); + qreal vStep = (labelsRect.height() / valuesCount()); + int curLabel = 0; + + painter->translate(labelsRect.topLeft()); + if (!m_chartItem->labels().isEmpty()){ + foreach (QString label, m_chartItem->labels()) { + painter->drawText(QRectF(QPoint(0,vStep*curLabel), + QSize(labelsRect.width()-hPadding(m_chartItem->rect()),vStep)), + Qt::AlignVCenter | Qt::AlignRight | Qt::TextWordWrap,label); + + curLabel++; + } + } + painter->restore(); +} + +qreal AbstractBarChart::hPadding(QRectF chartRect) +{ + return (chartRect.width()*0.02); +} + +qreal AbstractBarChart::vPadding(QRectF chartRect) +{ + return (chartRect.height()*0.02); +} + +void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect) +{ + prepareLegendToPaint(legendRect, painter); + int indicatorSize = painter->fontMetrics().height()/2; + painter->setPen(Qt::black); + painter->setRenderHint(QPainter::Antialiasing,false); + if (m_chartItem->drawLegendBorder()) + painter->drawRect(legendRect); + painter->setRenderHint(QPainter::Antialiasing,true); + QRectF indicatorsRect = legendRect.adjusted(painter->fontMetrics().height()/2,painter->fontMetrics().height()/2,0,0); + + if (!m_chartItem->series().isEmpty()){ + qreal cw = 0; + foreach(SeriesItem* series, m_chartItem->series()){ + QString label = series->name(); + painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); + painter->setBrush(series->color()); + painter->drawEllipse( + indicatorsRect.adjusted( + 0, + cw+indicatorSize/2, + -(indicatorsRect.width()-indicatorSize), + -(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2)) + ) + ); + cw += painter->fontMetrics().height(); + } + } else { + qreal cw = 0; + for (int i=0;idrawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); + painter->setBrush(color_map[i]); + painter->drawEllipse( + indicatorsRect.adjusted( + 0, + cw+indicatorSize/2, + -(indicatorsRect.width()-indicatorSize), + -(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2)) + ) + ); + cw += painter->fontMetrics().height(); + } + + } +} + +} // namespace LimeReport diff --git a/limereport/items/lrchartitem.h b/limereport/items/lrchartitem.h new file mode 100644 index 0000000..3419d20 --- /dev/null +++ b/limereport/items/lrchartitem.h @@ -0,0 +1,216 @@ +#ifndef LRCHARTITEM_H +#define LRCHARTITEM_H +#include "lritemdesignintf.h" +#include "lrglobal.h" + +namespace LimeReport{ + +QColor generateColor(); +extern QColor color_map[39]; + +class IDataSource; + +class SeriesItemData : public QObject{ + Q_OBJECT +public: + QList& values(){ return m_values;} + QList& labels(){ return m_labels;} + QList& colors() { return m_colors;} +private: + QList m_values; + QList m_labels; + QList m_colors; +}; + +class SeriesItem : public QObject{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString valuesColumn READ valuesColumn WRITE setValuesColumn ) + Q_PROPERTY(QString labelsColumn READ labelsColumn WRITE setLabelsColumn ) + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(SeriesItemPreferredType preferredType READ preferredType WRITE setPreferredType) + Q_ENUMS(SeriesItemPreferredType) +public: + enum SeriesItemPreferredType {Bar, Line}; + SeriesItem(QObject* parent = 0) : QObject(parent), m_preferredType(Bar){} + QString name() const; + void setName(const QString &name); + QString valuesColumn() const; + void setValuesColumn(const QString &valuesColumn); + QString labelsColumn() const; + void setLabelsColumn(const QString &labelsColumn); + SeriesItem* clone(); + void fillSeriesData(IDataSource* dataSource); + SeriesItemData* data(){ return &m_data;} + QColor color() const; + void setColor(const QColor &color); + SeriesItemPreferredType preferredType() const; + void setPreferredType(const SeriesItemPreferredType& preferredType); +private: + QString m_name; + QString m_valuesColumn; + QString m_labelsColumn; + SeriesItemData m_data; + QColor m_color; + SeriesItemPreferredType m_preferredType; +}; + +class ChartItem; + +class AbstractChart { +public: + AbstractChart(ChartItem* chartItem); + virtual ~AbstractChart(){} + virtual void paintChart(QPainter *painter, QRectF rect) = 0; + virtual void paintChartLegend(QPainter *painter, QRectF legendRect) =0; + virtual QSizeF calcChartLegendSize(const QFont &font) = 0; + virtual QRectF calcChartLegendRect(const QFont& font, const QRectF& parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset); +protected: + virtual void prepareLegendToPaint(QRectF& legendRect, QPainter *painter); +protected: + ChartItem* m_chartItem; + QList m_designLabels; +}; + +class AbstractSeriesChart: public AbstractChart{ +public: + AbstractSeriesChart(ChartItem* chartItem); +protected: + qreal maxValue(); + qreal minValue(); + int valuesCount(); + int seriesCount(); + QSizeF calcChartLegendSize(const QFont &font); + qreal* designValues(){ return m_designValues;} +private: + qreal m_designValues [9]; +}; + +class PieChart : public AbstractChart{ +public: + PieChart(ChartItem* chartItem):AbstractChart(chartItem){} + QSizeF calcChartLegendSize(const QFont &font); + void paintChart(QPainter *painter, QRectF chartRect); + void paintChartLegend(QPainter *painter, QRectF legendRect); +protected: + void drawPercent(QPainter *painter, QRectF chartRect, qreal startAngle, qreal angle); +}; + +class AbstractBarChart: public AbstractSeriesChart{ +public: + AbstractBarChart(ChartItem* chartItem):AbstractSeriesChart(chartItem){} + qreal hPadding(QRectF chartRect); + qreal vPadding(QRectF chartRect); + void paintChartLegend(QPainter *painter, QRectF legendRect); +}; + +class HorizontalBarChart: public AbstractBarChart{ +public: + HorizontalBarChart(ChartItem* chartItem):AbstractBarChart(chartItem){} + qreal valuesHMargin(QPainter *painter); + qreal valuesVMargin(QPainter *painter); + void paintChart(QPainter *painter, QRectF chartRect); + void paintHorizontalGrid(QPainter *painter, QRectF gridRect); + void paintHorizontalBars(QPainter *painter, QRectF barsRect); + QRectF labelsRect(QPainter* painter, QRectF labelsRect); + void paintLabels(QPainter *painter, QRectF labelsRect); +protected: + QFont adaptLabelsFont(QRectF rect, QFont font); + QFont adaptValuesFont(qreal width, QFont font); +}; + +class VerticalBarChart: public AbstractBarChart{ +public: + VerticalBarChart(ChartItem* chartItem):AbstractBarChart(chartItem){} + qreal valuesHMargin(QPainter *painter); + qreal valuesVMargin(QPainter *painter); + QRectF labelsRect(QPainter* painter, QRectF labelsRect); + void paintChart(QPainter *painter, QRectF chartRect); + void paintVerticalGrid(QPainter *painter, QRectF gridRect); + void paintVerticalBars(QPainter *painter, QRectF barsRect); + void paintSerialLines(QPainter *painter, QRectF barsRect); + void paintLabels(QPainter *painter, QRectF labelsRect); +}; + +class ChartItem : public LimeReport::ItemDesignIntf +{ + Q_OBJECT + Q_ENUMS(LegendAlign) + Q_ENUMS(TitleAlign) + Q_ENUMS(ChartType) + Q_PROPERTY(ACollectionProperty series READ fakeCollectionReader) + Q_PROPERTY(QString datasource READ datasource WRITE setDatasource) + Q_PROPERTY(QString chartTitle READ chartTitle WRITE setChartTitle) + Q_PROPERTY(bool drawLegendBorder READ drawLegendBorder WRITE setDrawLegendBorder) + Q_PROPERTY(LegendAlign legendAlign READ legendAlign WRITE setLegendAlign) + Q_PROPERTY(TitleAlign titleAlign READ titleAlign WRITE setTitleAlign) + Q_PROPERTY(ChartType chartType READ chartType WRITE setChartType) + Q_PROPERTY(QString labelsField READ labelsField WRITE setLabelsField) + friend class AbstractChart; +public: + + enum LegendAlign{LegendAlignTop,LegendAlignCenter,LegendAlignBottom}; + enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight}; + enum ChartType{Pie, VerticalBar, HorizontalBar}; + + ChartItem(QObject* owner, QGraphicsItem* parent); + ~ChartItem(); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + QList &series(); + void setSeries(const QList &series); + bool isSeriesExists(const QString& name); + + QString datasource() const; + void setDatasource(const QString &datasource); + + QString chartTitle() const; + void setChartTitle(const QString &chartTitle); + + bool drawLegendBorder() const; + void setDrawLegendBorder(bool drawLegendBorder); + + LegendAlign legendAlign() const; + void setLegendAlign(const LegendAlign &legendAlign); + + TitleAlign titleAlign() const; + void setTitleAlign(const TitleAlign &titleAlign); + + ChartType chartType() const; + void setChartType(const ChartType &chartType); + + QString labelsField() const; + void setLabelsField(const QString &labelsField); + + QList labels() const; + void setLabels(const QList &labels); + +protected: + void paintChartTitle(QPainter* painter, QRectF titleRect); + virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); + //ICollectionContainer + QObject* createElement(const QString& collectionName,const QString& elementType); + int elementsCount(const QString& collectionName); + QObject* elementAt(const QString& collectionName,int index); + void collectionLoadFinished(const QString& collectionName){Q_UNUSED(collectionName)} + void updateItemSize(DataSourceManager *dataManager, RenderPass, int); + void fillLabels(IDataSource* dataSource); + QWidget* defaultEditor(); + +private: + QList m_series; +// QList< QPointer > m_series; + QString m_datasource; + QPixmap m_chartImage; + QString m_title; + AbstractChart* m_chart; + bool m_legendBorder; + LegendAlign m_legendAlign; + TitleAlign m_titleAlign; + ChartType m_chartType; + QString m_labelsField; + QList m_labels; +}; + +} //namespace LimeReport +#endif // LRCHARTITEM_H diff --git a/limereport/items/lrchartitemeditor.cpp b/limereport/items/lrchartitemeditor.cpp new file mode 100644 index 0000000..f772632 --- /dev/null +++ b/limereport/items/lrchartitemeditor.cpp @@ -0,0 +1,294 @@ +#include "lrchartitemeditor.h" +#include "ui_lrchartitemeditor.h" +#include "lrchartitem.h" +#include "lrpagedesignintf.h" +#include + +ChartItemEditor::ChartItemEditor(LimeReport::ChartItem *item, LimeReport::PageDesignIntf *page, QSettings *settings, QWidget *parent): + QWidget(parent), ui(new Ui::ChartItemEditor), m_charItem(item), m_page(page), + m_settings(settings), m_ownedSettings(false), m_isReadingSetting(false) +{ + ui->setupUi(this); + QHBoxLayout* colorLayout = new QHBoxLayout(); + colorLayout->setMargin(0); + m_colorButton = new QToolButton(); + m_colorButton->setText("..."); + m_colorButton->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + m_colorIndicator = new ColorIndicator(); + m_colorIndicator->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + ui->colorWidget->setLayout(colorLayout); + colorLayout->addWidget(m_colorIndicator); + colorLayout->addWidget(m_colorButton); + colorLayout->insertStretch(0); + readSetting(); + init(); + connect(m_colorButton, SIGNAL(clicked(bool)), this, SLOT(slotChangeSeriesColor())); +} + +ChartItemEditor::~ChartItemEditor() +{ +#ifdef Q_OS_WIN + writeSetting(); +#endif +#ifdef Q_OS_MAC + writeSetting(); +#endif + delete ui; +} + +QSettings* ChartItemEditor::settings() +{ + if (m_settings){ + return m_settings; + } else { + m_settings = new QSettings("LimeReport",QCoreApplication::applicationName()); + m_ownedSettings = true; + return m_settings; + } +} + +void ChartItemEditor::readSetting() +{ + if (settings()==0) return; + + m_isReadingSetting = true; + + settings()->beginGroup("ChartItemEditor"); + QVariant v = settings()->value("Geometry"); + if (v.isValid()){ + restoreGeometry(v.toByteArray()); + } + v = settings()->value("State"); + if (v.isValid()){ + ui->splitter->restoreState(v.toByteArray()); + } + + settings()->endGroup(); + + m_isReadingSetting = false; +} + +void ChartItemEditor::writeSetting() +{ + if (settings()!=0){ + settings()->beginGroup("ChartItemEditor"); + settings()->setValue("Geometry",saveGeometry()); + settings()->setValue("State",ui->splitter->saveState()); + settings()->endGroup(); + } +} + +void ChartItemEditor::rebuildTable() +{ + ui->tableWidget->clearContents(); + ui->tableWidget->setRowCount(m_charItem->series().count()); + for( int i=0;iseries().count();++i){ + QTableWidgetItem* newRow = new QTableWidgetItem(m_charItem->series().at(i)->name()); + ui->tableWidget->setItem(i,0,newRow); + } +} + +void ChartItemEditor::init() +{ + m_initing = true; + + ui->tableWidget->setColumnCount(1); + ui->tableWidget->setRowCount(m_charItem->series().count()); + ui->tableWidget->horizontalHeader()->setStretchLastSection(true); + ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem(tr("Series name"))); + + rebuildTable(); + + if (!m_charItem->datasource().isEmpty()){ + if (m_page && m_page->datasourceManager()){ + LimeReport::IDataSource* ds = m_page->datasourceManager()->dataSource(m_charItem->datasource()); + if (ds){ + for (int i=0;icolumnCount();++i){ + ui->valuesFieldComboBox->addItem(ds->columnNameByIndex(i)); + ui->labelsFieldComboBox->addItem(ds->columnNameByIndex(i)); + } + } + } + + } + + static int enumIndex = LimeReport::SeriesItem::staticMetaObject.indexOfEnumerator("SeriesItemPreferredType"); + QMetaEnum enumerator = LimeReport::SeriesItem::staticMetaObject.enumerator(enumIndex); + for (int i = 0; iseriesTypeComboBox->addItem(enumerator.key(i)); + } + +#ifdef HAVE_QT5 + ui->labelsFieldComboBox->setCurrentText(m_charItem->labelsField()); +#endif +#ifdef HAVE_QT4 + ui->labelsFieldComboBox->setCurrentIndex(ui->labelsFieldComboBox->findText( m_charItem->labelsField())); +#endif + if (!m_charItem->series().isEmpty()){ + enableSeriesEditor(); + ui->tableWidget->selectRow(0); + } else { + disableSeriesEditor(); + } + + m_initing = false; +} + +void ChartItemEditor::enableSeriesEditor() +{ + ui->seriesNameLineEdit->setEnabled(true); + ui->valuesFieldComboBox->setEnabled(true); + ui->seriesTypeComboBox->setEnabled(true); + m_colorButton->setEnabled(true); + m_colorIndicator->setEnabled(true); +} + +void ChartItemEditor::disableSeriesEditor() +{ + ui->seriesNameLineEdit->setText(""); + ui->seriesNameLineEdit->setDisabled(true); + ui->valuesFieldComboBox->setDisabled(true); + m_colorButton->setDisabled(true); + m_colorIndicator->setDisabled(true); +#ifdef HAVE_QT5 + ui->valuesFieldComboBox->setCurrentText(""); +#endif +#ifdef HAVE_QT4 + ui->valuesFieldComboBox->setEditText(""); +#endif + ui->seriesTypeComboBox->setDisabled(true); +} + +LimeReport::SeriesItem *ChartItemEditor::currentSeries() +{ + int curRow = ui->tableWidget->currentRow(); + if ((curRow>-1) && !m_charItem->series().isEmpty() && m_charItem->series().count()>curRow){ + return m_charItem->series().at(curRow); + } + return 0; +} + +void ChartItemEditor::resizeEvent(QResizeEvent *) +{ +#ifdef Q_OS_UNIX + writeSetting(); +#endif +} + +void ChartItemEditor::moveEvent(QMoveEvent *) +{ +#ifdef Q_OS_UNIX + writeSetting(); +#endif +} + +void ChartItemEditor::on_splitter_splitterMoved(int , int ) +{ +#ifdef Q_OS_UNIX + writeSetting(); +#endif +} + + +void ChartItemEditor::on_pbOk_clicked() +{ + close(); +} + +void ChartItemEditor::slotAddSeries() +{ + LimeReport::SeriesItem* series = new LimeReport::SeriesItem(); + int curSeriesNumber = m_charItem->series().count(); + while (m_charItem->isSeriesExists("Series"+QString::number(curSeriesNumber))) curSeriesNumber++; + series->setName("Series"+QString::number(curSeriesNumber)); + series->setValuesColumn(""); + series->setLabelsColumn(""); + series->setColor((m_charItem->series().count()<32)?LimeReport::color_map[m_charItem->series().count()]:LimeReport::generateColor()); + m_charItem->series().append(series); + ui->tableWidget->setRowCount(m_charItem->series().count()); + ui->tableWidget->setItem(m_charItem->series().count()-1, 0, new QTableWidgetItem(series->name())); + ui->tableWidget->selectRow(m_charItem->series().count()-1); +#ifdef HAVE_QT5 + ui->valuesFieldComboBox->setCurrentText(""); +#endif +#ifdef HAVE_QT4 + ui->valuesFieldComboBox->setEditText(""); +#endif +} + +void ChartItemEditor::slotDeleteSeries() +{ + QList itemsToRemove; + foreach(QModelIndex index,ui->tableWidget->selectionModel()->selectedRows()){ + itemsToRemove.append(m_charItem->series().at(index.row())); + }; + foreach (LimeReport::SeriesItem* series, itemsToRemove){ + m_charItem->series().removeOne(series); + delete series; + } + rebuildTable(); + disableSeriesEditor(); +} + +void ChartItemEditor::on_tableWidget_itemSelectionChanged() +{ + if (ui->tableWidget->selectionModel()->hasSelection()){ + LimeReport::SeriesItem* series = m_charItem->series().at(ui->tableWidget->selectionModel()->currentIndex().row()); + ui->seriesNameLineEdit->setText(series->name()); +#ifdef HAVE_QT5 + ui->valuesFieldComboBox->setCurrentText(series->valuesColumn()); +#endif +#ifdef HAVE_QT4 + ui->valuesFieldComboBox->setCurrentIndex(ui->valuesFieldComboBox->findText(series->valuesColumn())); +#endif + m_colorIndicator->setColor(series->color()); + static int enumIndex = LimeReport::SeriesItem::staticMetaObject.indexOfEnumerator("SeriesItemPreferredType"); + QMetaEnum enumerator = LimeReport::SeriesItem::staticMetaObject.enumerator(enumIndex); +#ifdef HAVE_QT5 + ui->seriesTypeComboBox->setCurrentText(enumerator.valueToKey(series->preferredType())); +#endif +#ifdef HAVE_QT4 + ui->seriesTypeComboBox->setCurrentIndex(ui->seriesTypeComboBox->findText(enumerator.valueToKey(series->preferredType()))); +#endif + enableSeriesEditor(); + } +} + +void ChartItemEditor::on_seriesNameLineEdit_textChanged(const QString &arg1) +{ + if (currentSeries()){ + currentSeries()->setName(arg1); + ui->tableWidget->currentItem()->setText(arg1); + } +} + +void ChartItemEditor::on_valuesFieldComboBox_currentTextChanged(const QString &arg1) +{ + if (currentSeries()){ + currentSeries()->setValuesColumn(arg1); + } +} + +void ChartItemEditor::on_labelsFieldComboBox_currentTextChanged(const QString &arg1) +{ + if (!m_initing) + m_charItem->setLabelsField(arg1); +} + +void ChartItemEditor::slotChangeSeriesColor() +{ + QColorDialog colorDialog; + if (colorDialog.exec()){ + currentSeries()->setColor(colorDialog.selectedColor()); + m_colorIndicator->setColor(colorDialog.selectedColor()); + } +} + +void ChartItemEditor::on_seriesTypeComboBox_currentIndexChanged(const QString &arg1) +{ + static int enumIndex = LimeReport::SeriesItem::staticMetaObject.indexOfEnumerator("SeriesItemPreferredType"); + QMetaEnum enumerator = LimeReport::SeriesItem::staticMetaObject.enumerator(enumIndex); + if (currentSeries()){ + currentSeries()->setPreferredType(static_cast(enumerator.keysToValue(arg1.toLatin1()))); + } +} diff --git a/limereport/items/lrchartitemeditor.h b/limereport/items/lrchartitemeditor.h new file mode 100644 index 0000000..a406fc8 --- /dev/null +++ b/limereport/items/lrchartitemeditor.h @@ -0,0 +1,59 @@ +#ifndef CHARITEMEDITOR_H +#define CHARITEMEDITOR_H + +#include +#include "lrchartitem.h" +#include "lrcolorindicator.h" +#include +#include + +namespace Ui { +class ChartItemEditor; +} + +class ChartItemEditor : public QWidget +{ + Q_OBJECT +public: + ChartItemEditor(LimeReport::ChartItem* item, LimeReport::PageDesignIntf* page, + QSettings* settings=0, QWidget *parent = 0); + ~ChartItemEditor(); +public: + QSettings *settings(); + void rebuildTable(); + +protected: + void resizeEvent(QResizeEvent *); + void moveEvent(QMoveEvent *); +private slots: + void on_splitter_splitterMoved(int, int); + void on_pbOk_clicked(); + void slotAddSeries(); + void slotDeleteSeries(); + void on_tableWidget_itemSelectionChanged(); + void on_seriesNameLineEdit_textChanged(const QString &arg1); + void on_valuesFieldComboBox_currentTextChanged(const QString &arg1); + void on_labelsFieldComboBox_currentTextChanged(const QString &arg1); + void slotChangeSeriesColor(); + void on_seriesTypeComboBox_currentIndexChanged(const QString &arg1); + +private: + void readSetting(); + void writeSetting(); + void init(); + void enableSeriesEditor(); + void disableSeriesEditor(); + LimeReport::SeriesItem* currentSeries(); +private: + Ui::ChartItemEditor *ui; + LimeReport::ChartItem* m_charItem; + LimeReport::PageDesignIntf* m_page; + QSettings* m_settings; + bool m_ownedSettings; + bool m_isReadingSetting; + QToolButton* m_colorButton; + ColorIndicator* m_colorIndicator; + bool m_initing; +}; + +#endif // CHARITEMEDITOR_H diff --git a/limereport/items/lrchartitemeditor.ui b/limereport/items/lrchartitemeditor.ui new file mode 100644 index 0000000..a745777 --- /dev/null +++ b/limereport/items/lrchartitemeditor.ui @@ -0,0 +1,233 @@ + + + ChartItemEditor + + + + 0 + 0 + 380 + 268 + + + + Series editor + + + + + + + 0 + 0 + + + + Series + + + + + + Qt::Horizontal + + + + + 4 + + + + + + + + + + Add + + + + + + + Delete + + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + 4 + + + 2 + + + 2 + + + 2 + + + + + Name + + + + + + + + + + Values field + + + + + + + true + + + + + + + Color + + + + + + + + + + Type + + + + + + + + + + + + + + + + + + 16777215 + 10 + + + + QFrame::HLine + + + + + + + + + + + + Labels field + + + + + + + true + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Ok + + + + + + + + + + + + + pbAddSeries + clicked() + ChartItemEditor + slotAddSeries() + + + 57 + 136 + + + 8 + 75 + + + + + pbDeleteSeries + clicked() + ChartItemEditor + slotDeleteSeries() + + + 142 + 136 + + + 372 + 137 + + + + + + slotAddSeries() + slotDeleteSeries() + + diff --git a/limereport/items/lrhorizontallayout.cpp b/limereport/items/lrhorizontallayout.cpp index d93e545..f4f51ef 100644 --- a/limereport/items/lrhorizontallayout.cpp +++ b/limereport/items/lrhorizontallayout.cpp @@ -55,88 +55,28 @@ bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instanc namespace LimeReport { -bool lessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ +bool horizontalLessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ return c1->pos().x()pos().x(); } - HorizontalLayout::HorizontalLayout(QObject *owner, QGraphicsItem *parent) - : LayoutDesignIntf(xmlTag, owner, parent),m_isRelocating(false),m_layoutType(Layout) -{ - setPossibleResizeDirectionFlags(AllDirections); - m_layoutMarker = new LayoutMarker(this); - m_layoutMarker->setParentItem(this); - m_layoutMarker->setColor(Qt::red); - m_layoutMarker->setHeight(height()); - m_layoutMarker->setZValue(1); -} + : AbstractLayout(xmlTag, owner, parent) +{} HorizontalLayout::~HorizontalLayout() -{ - if (m_layoutMarker) { - delete m_layoutMarker; m_layoutMarker=0; - } -} +{} BaseDesignIntf *HorizontalLayout::createSameTypeItem(QObject *owner, QGraphicsItem *parent) { return new LimeReport::HorizontalLayout(owner, parent); } -void HorizontalLayout::hoverEnterEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - LayoutDesignIntf::hoverEnterEvent(event); -// if ((itemMode() & LayoutEditMode) || isSelected()){ -// setChildVisibility(false); -// } -} - -void HorizontalLayout::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - LayoutDesignIntf::hoverLeaveEvent(event); -// setChildVisibility(true); -} - -void HorizontalLayout::geometryChangedEvent(QRectF newRect, QRectF ) -{ - m_layoutMarker->setHeight(newRect.height()); - relocateChildren(); - if (/*m_layoutType == Table && */!m_isRelocating){ - divideSpace(); - } -} - -void HorizontalLayout::setChildVisibility(bool value){ - foreach(QGraphicsItem* child,childItems()){ - BaseDesignIntf* item = dynamic_cast(child); - if(item) - item->setVisible(value); - } -} - -int HorizontalLayout::childrenCount() -{ - return m_children.size(); -} - -void HorizontalLayout::initMode(BaseDesignIntf::ItemMode mode) -{ - BaseDesignIntf::initMode(mode); - if ((mode==PreviewMode)||(mode==PrintMode)){ - m_layoutMarker->setVisible(false); - } else { - m_layoutMarker->setVisible(true); - } -} - bool HorizontalLayout::canBeSplitted(int height) const { foreach(QGraphicsItem* qgItem,childItems()){ BaseDesignIntf* item=dynamic_cast(qgItem); if (item) - if (!item->canBeSplitted(height-item->pos().y())) return false; + if (!item->canBeSplitted(height - item->pos().y())) return false; } return true; } @@ -198,405 +138,107 @@ void HorizontalLayout::setItemAlign(const BaseDesignIntf::ItemAlign &itemAlign) BaseDesignIntf::setItemAlign(itemAlign); } -void HorizontalLayout::setBorderLinesFlags(BaseDesignIntf::BorderLines flags) +void HorizontalLayout::sortChildren() { - BaseDesignIntf::setBorderLinesFlags(flags); - if (flags!=0) - relocateChildren(); -} - -QVariant HorizontalLayout::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) -{ - if (change == QGraphicsItem::ItemSelectedHasChanged){ - m_isRelocating = true; - foreach(BaseDesignIntf* item, m_children){ - item->setVisible(!value.toBool()); - } - m_isRelocating = false; - } - return LayoutDesignIntf::itemChange(change, value); -} - -void HorizontalLayout::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ - if (isSelected()){ - foreach( BaseDesignIntf* item, m_children){ - ppainter->save(); - ppainter->setPen(Qt::red); - ppainter->drawRect( - QRectF(item->pos().x(),item->pos().y(), - item->rect().bottomRight().rx(), - item->rect().bottomRight().ry() - ) - ); - ppainter->restore(); - } - } - LayoutDesignIntf::paint(ppainter, option, widget); -} - -void HorizontalLayout::restoreChild(BaseDesignIntf* item){ - if (m_children.contains(item)) return; - - m_isRelocating=true; - foreach (BaseDesignIntf* child, childBaseItems()) { - if (child->pos()==item->pos()){ - int index = m_children.indexOf(child)-1; - m_children.insert(index,item); - child->setPos(item->pos().x()+item->width(),0); - break; - } - } - - connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); - connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), - this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))); - connect(item, SIGNAL(itemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)), - this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign))); - - item->setFixedPos(true); - item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); - item->setParent(this); - item->setParentItem(this); - - updateLayoutSize(); - m_isRelocating=false; -} - -bool HorizontalLayout::isEmpty() const -{ - bool isEmpty = true; - bool allItemsIsText = true; - foreach (QGraphicsItem* qgItem, childItems()) { - ContentItemDesignIntf* item = dynamic_cast(qgItem); - if (item && !item->content().isEmpty()) isEmpty = false; - if (!item && dynamic_cast(qgItem)) - allItemsIsText = false; - } - return (isEmpty && allItemsIsText); -} - -void HorizontalLayout::addChild(BaseDesignIntf *item, bool updateSize) -{ - if (m_children.count() > 0) - item->setPos(m_children.last()->pos().x() + m_children.last()->width(), 0); - else - item->setPos(0, 0); - - m_children.append(item); - item->setParentItem(this); - item->setParent(this); - item->setFixedPos(true); - item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); - - connect( - item, SIGNAL(destroyed(QObject*)), - this, SLOT(slotOnChildDestroy(QObject*)) - ); - connect( - item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), - this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF)) - ); - connect( - item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)), - this,SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*)) - ); - connect( - item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)), - this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool)) - ); - - if (updateSize){ - relocateChildren(); - updateLayoutSize(); - } -} - -void HorizontalLayout::collectionLoadFinished(const QString &collectionName) -{ - ItemDesignIntf::collectionLoadFinished(collectionName); - if (collectionName.compare("children",Qt::CaseInsensitive)==0){ -#ifdef HAVE_QT5 - foreach(QObject* obj,children()){ -#else - foreach(QObject* obj,QObject::children()){ -#endif - BaseDesignIntf* item = dynamic_cast(obj); - if (item) { - addChild(item,false); - } - } - } -} - -void HorizontalLayout::objectLoadFinished() -{ - m_layoutMarker->setHeight(height()); - LayoutDesignIntf::objectLoadFinished(); + qSort(layoutsChildren().begin(),layoutsChildren().end(),horizontalLessThen); } void HorizontalLayout::updateLayoutSize() { int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; - int w = spaceBorder*2; + qreal w = spaceBorder*2; qreal h = 0; - foreach(BaseDesignIntf* item, m_children){ + int visibleItemCount = 0; + foreach(BaseDesignIntf* item, layoutsChildren()){ + if (item->isEmpty() && hideEmptyItems()) item->setVisible(false); if (item->isVisible()){ if (hheight()) h=item->height(); w+=item->width(); + visibleItemCount++; + } + } + if (h>0) setHeight(h+spaceBorder*2); + if (layoutType() == Layout) + setWidth(w + layoutSpacingMM() * (visibleItemCount-1)); + else{ + relocateChildren(); + if (!isRelocating()){ + divideSpace(); } } - if (h>0) setHeight(h+spaceBorder*2); - setWidth(w); } void HorizontalLayout::relocateChildren() { int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; - if (m_children.count()isVisible() || itemMode() == DesignMode){ item->setPos(curX,spaceBorder); - curX+=item->width(); + curX += item->width() + layoutSpacingMM(); item->setHeight(height()-(spaceBorder * 2)); } } - m_isRelocating = false; -} - -void HorizontalLayout::beforeDelete() -{ - m_children.clear(); -#ifdef HAVE_QT5 - foreach (QObject *item, children()) { -#else - foreach (QObject *item, QObject::children()) { -#endif - BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { - bdItem->setParentItem(parentItem()); - bdItem->setParent(parent()); - bdItem->setVisible(true); - bdItem->setPos(mapToParent(bdItem->pos())); - bdItem->setFixedPos(false); - bdItem->setPossibleResizeDirectionFlags(AllDirections); - } - } -} - -void HorizontalLayout::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) -{ - m_isRelocating=true; - ItemDesignIntf::updateItemSize(dataManager, pass, maxHeight); - foreach(QGraphicsItem *child, childItems()){ - BaseDesignIntf* item = dynamic_cast(child); - if (item) item->updateItemSize(dataManager, pass, maxHeight); - } - updateLayoutSize(); - relocateChildren(); - m_isRelocating=false; - BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); -} - -bool HorizontalLayout::isNeedUpdateSize(RenderPass pass) const -{ - foreach (QGraphicsItem *child, childItems()) { - BaseDesignIntf* item = dynamic_cast(child); - if (item && item->isNeedUpdateSize(pass)) - return true; - } - return false; -} - -void HorizontalLayout::childAddedEvent(BaseDesignIntf *child) -{ - addChild(child,false); -} - -void HorizontalLayout::slotOnChildDestroy(QObject* child) -{ - m_children.removeAll(static_cast(child)); - if (m_children.count()<2){ - beforeDelete(); -// deleteLater(); - } else { - relocateChildren(); - updateLayoutSize(); - } -} - -BaseDesignIntf* HorizontalLayout::findNext(BaseDesignIntf* item){ - if (m_children.count()i+1){ return m_children[i+1];} - } - return 0; -} - -BaseDesignIntf* HorizontalLayout::findPrior(BaseDesignIntf* item){ - if (m_children.count()isVisible() || itemMode() == DesignMode ){ itemsSumSize += item->width(); visibleItemsCount++; } } - qreal delta = (width() - (itemsSumSize+spaceBorder*2)) / (visibleItemsCount!=0 ? visibleItemsCount : 1); - for (int i=0; iisVisible() || itemMode() == DesignMode) - m_children[i]->setWidth(m_children[i]->width()+delta); - if ((i+1)isVisible() || itemMode() == DesignMode) - m_children[i+1]->setPos(m_children[i+1]->pos().x()+delta*(i+1),m_children[i+1]->pos().y()); + itemsSumSize += layoutSpacingMM() * (visibleItemsCount-1); + + if (itemMode() == DesignMode && !layoutsChildren().isEmpty()){ + qreal delta = (width() - (itemsSumSize+spaceBorder*2)); + layoutsChildren().last()->setWidth(layoutsChildren().last()->width()+delta); + } else { + qreal delta = (width() - (itemsSumSize+spaceBorder*2)) / (visibleItemsCount!=0 ? visibleItemsCount : 1); + for (int i=0; iisVisible() || itemMode() == DesignMode) + layoutsChildren()[i]->setWidth(layoutsChildren()[i]->width()+delta); + if ((i+1)isVisible() || itemMode() == DesignMode) + layoutsChildren()[i+1]->setPos(layoutsChildren()[i+1]->pos().x()+delta*(i+1),layoutsChildren()[i+1]->pos().y()); + } } - m_isRelocating = false; + setIsRelocating(false); } -void HorizontalLayout::slotOnChildGeometryChanged(QObject *item, QRectF newGeometry, QRectF oldGeometry) + +void HorizontalLayout::placeItemInLayout(BaseDesignIntf* item) { - if (!m_isRelocating){ - //setHeight(newGeometry.height()); - if (m_layoutType == Layout){ - relocateChildren(); - updateLayoutSize(); - } else { - m_isRelocating = true; - qreal delta = newGeometry.width()-oldGeometry.width(); - BaseDesignIntf* resizingItem = findNext(dynamic_cast(item)); - if (resizingItem) { - resizingItem->setWidth(resizingItem->width()-delta); - resizingItem->setPos(resizingItem->pos().x()+delta,resizingItem->pos().y()); - } - updateLayoutSize(); - m_isRelocating = false; + if (layoutsChildren().count() > 0) + item->setPos(layoutsChildren().last()->pos().x() + layoutsChildren().last()->width(), 0); + else + item->setPos(0, 0); +} + +void HorizontalLayout::insertItemInLayout(BaseDesignIntf* item) +{ + foreach (BaseDesignIntf* child, childBaseItems()) { + if (child->pos() == item->pos()){ + int index = layoutsChildren().indexOf(child)-1; + layoutsChildren().insert(index, item); + child->setPos(item->pos().x()+item->width(), 0); + break; } } } -void HorizontalLayout::slotOnChildItemAlignChanged(BaseDesignIntf *item, const BaseDesignIntf::ItemAlign &, const BaseDesignIntf::ItemAlign&) -{ - item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight); -} - -void HorizontalLayout::slotOnChildVisibleHasChanged(BaseDesignIntf *) -{ - relocateChildren(); - if (m_layoutType == Table && !m_isRelocating){ - divideSpace(); - } -} - -void HorizontalLayout::slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value) -{ - item->setZValue(value ? item->zValue()+1 : item->zValue()-1); -} - -HorizontalLayout::LayoutType HorizontalLayout::layoutType() const -{ - return m_layoutType; -} - -void HorizontalLayout::setLayoutType(const LayoutType &layoutType) -{ - if (m_layoutType != layoutType){ - LayoutType oldValue = m_layoutType; - m_layoutType = layoutType; - notify("layoutType",oldValue,layoutType); - } - -} - -LayoutMarker::LayoutMarker(HorizontalLayout *layout, QGraphicsItem *parent) - :QGraphicsItem(parent), m_rect(0,0,30,30), m_color(Qt::red), m_layout(layout){ - setFlag(QGraphicsItem::ItemIsMovable); -} - -void LayoutMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->save(); - painter->setOpacity(Const::LAYOUT_MARKER_OPACITY); - painter->fillRect(boundingRect(),m_color); - - painter->setRenderHint(QPainter::Antialiasing); - qreal size = (boundingRect().width()isSelected()){ - painter->setOpacity(1); - QRectF r = QRectF(0,0,size,size); - painter->setBrush(Qt::white); - painter->setPen(Qt::white); - painter->drawEllipse(r.adjusted(5,5,-5,-5)); - painter->setBrush(m_color); - painter->drawEllipse(r.adjusted(7,7,-7,-7)); - } - painter->restore(); -} - -void LayoutMarker::setHeight(qreal height) -{ - if (m_rect.height()!=height){ - prepareGeometryChange(); - m_rect.setHeight(height); - } -} - -void LayoutMarker::setWidth(qreal width) -{ - if (m_rect.width()!=width){ - prepareGeometryChange(); - m_rect.setWidth(width); - } -} - -void LayoutMarker::setColor(QColor color) -{ - if (m_color!=color){ - m_color = color; - update(boundingRect()); - } -} - -void LayoutMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if (event->button()==Qt::LeftButton) { - if (!(event->modifiers() & Qt::ControlModifier)) - m_layout->scene()->clearSelection(); - m_layout->setSelected(true); - //m_layout->setChildVisibility(false); - update(0,0,boundingRect().width(),boundingRect().width()); - } -} - } // namespace LimeReport diff --git a/limereport/items/lrhorizontallayout.h b/limereport/items/lrhorizontallayout.h index 5bfaddc..fcd9e93 100644 --- a/limereport/items/lrhorizontallayout.h +++ b/limereport/items/lrhorizontallayout.h @@ -30,89 +30,39 @@ #ifndef LRHORIZONTALLAYOUT_H #define LRHORIZONTALLAYOUT_H #include "lritemdesignintf.h" +#include "lrlayoutmarker.h" +#include "lrabstractlayout.h" namespace LimeReport { -class HorizontalLayout; - -class LayoutMarker : public QGraphicsItem{ -public: - explicit LayoutMarker(HorizontalLayout* layout, QGraphicsItem *parent=0); - virtual QRectF boundingRect() const{return m_rect;} - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - void setHeight(qreal height); - void setWidth(qreal width); - void setColor(QColor color); - qreal width(){return m_rect.width();} - qreal height(){return m_rect.height();} -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event); -private: - QRectF m_rect; - QColor m_color; - HorizontalLayout* m_layout; -}; - -class HorizontalLayout : public LayoutDesignIntf +class HorizontalLayout : public AbstractLayout { Q_OBJECT - Q_ENUMS(LayoutType) Q_PROPERTY(LayoutType layoutType READ layoutType WRITE setLayoutType) public: friend class LayoutMarker; - enum LayoutType{Layout,Table}; + friend class BaseDesignIntf; + HorizontalLayout(QObject *owner = 0, QGraphicsItem *parent = 0); ~HorizontalLayout(); BaseDesignIntf *createSameTypeItem(QObject *owner = 0, QGraphicsItem *parent = 0); - void hoverEnterEvent(QGraphicsSceneHoverEvent *event); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - void geometryChangedEvent(QRectF newRect, QRectF); - void addChild(BaseDesignIntf *item,bool updateSize=true); - friend class BaseDesignIntf; - void restoreChild(BaseDesignIntf *item); - bool isEmpty() const; - LayoutType layoutType() const; - void setLayoutType(const LayoutType &layoutType); bool isSplittable() const { return true;} + bool canContainChildren() const { return true;} + protected: - void collectionLoadFinished(const QString &collectionName); - void objectLoadFinished(); void updateLayoutSize(); void relocateChildren(); - BaseDesignIntf *findNext(BaseDesignIntf *item); - BaseDesignIntf *findPrior(BaseDesignIntf *item); - void beforeDelete(); - void updateItemSize(DataSourceManager *dataManager, RenderPass pass, int maxHeight); - bool isNeedUpdateSize(RenderPass pass) const; - void childAddedEvent(BaseDesignIntf *child); - void setChildVisibility(bool value); - int childrenCount(); - void initMode(ItemMode mode); - bool canBeSplitted(int height) const; BaseDesignIntf* cloneUpperPart(int height, QObject* owner=0, QGraphicsItem* parent=0); BaseDesignIntf* cloneBottomPart(int height, QObject *owner=0, QGraphicsItem *parent=0); - void setItemAlign(const ItemAlign &itemAlign); - void setBorderLinesFlags(BorderLines flags); - QVariant itemChange(GraphicsItemChange change, const QVariant &value); - void paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget); -private slots: - void slotOnChildDestroy(QObject *child); - void slotOnChildGeometryChanged(QObject*item, QRectF newGeometry, QRectF oldGeometry); - void slotOnChildItemAlignChanged(BaseDesignIntf* item, const ItemAlign&, const ItemAlign&); - void slotOnChildVisibleHasChanged(BaseDesignIntf*); - void slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value); - //void slotOnPosChanged(QObject*, QPointF newPos, QPointF ); private: + void sortChildren(); void divideSpace(); -private: - QList m_children; - bool m_isRelocating; - LayoutMarker* m_layoutMarker; - LayoutType m_layoutType; + void placeItemInLayout(BaseDesignIntf* item); + void insertItemInLayout(BaseDesignIntf* item); }; } //namespace LimeReport diff --git a/limereport/items/lrimageitem.cpp b/limereport/items/lrimageitem.cpp index c180bfc..c3fce2f 100644 --- a/limereport/items/lrimageitem.cpp +++ b/limereport/items/lrimageitem.cpp @@ -31,6 +31,7 @@ #include "lrdesignelementsfactory.h" #include "lrglobal.h" #include "lrdatasourcemanager.h" +#include "lrpagedesignintf.h" namespace{ @@ -47,45 +48,89 @@ bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instanc namespace LimeReport{ ImageItem::ImageItem(QObject* owner,QGraphicsItem* parent) - :ItemDesignIntf(xmlTag,owner,parent),m_autoSize(false), m_scale(true), m_keepAspectRatio(true), m_center(true), m_format(Binary){} + :ItemDesignIntf(xmlTag,owner,parent), m_useExternalPainter(false), m_externalPainter(0), + m_autoSize(false), m_scale(true), + m_keepAspectRatio(true), m_center(true), m_format(Binary){} BaseDesignIntf *ImageItem::createSameTypeItem(QObject *owner, QGraphicsItem *parent) { - return new ImageItem(owner,parent); + ImageItem* result = new ImageItem(owner,parent); + result->setExternalPainter(m_externalPainter); + return result; +} + +void ImageItem::loadPictureFromVariant(QVariant& data){ + if (data.isValid()){ + if (data.type()==QVariant::Image){ + m_picture = data.value(); + } else { + switch (m_format) { + default: + case Binary: + m_picture.loadFromData(data.toByteArray()); + break; + case Hex: + m_picture.loadFromData(QByteArray::fromHex(data.toByteArray())); + break; + case Base64: + m_picture.loadFromData(QByteArray::fromBase64(data.toByteArray())); + break; + } + } + + } +} + +void ImageItem::preparePopUpMenu(QMenu &menu) +{ + QAction* action = menu.addAction(tr("Watermark")); + action->setCheckable(true); + action->setChecked(isWatermark()); +} + +void ImageItem::processPopUpAction(QAction *action) +{ + if (action->text().compare(tr("Watermark")) == 0){ + page()->setPropertyToSelectedItems("watermark",action->isChecked()); + } + ItemDesignIntf::processPopUpAction(action); +} + +bool ImageItem::useExternalPainter() const +{ + return m_useExternalPainter; +} + +void ImageItem::setUseExternalPainter(bool value) +{ + if (m_useExternalPainter != value){ + m_useExternalPainter = value; + notify("useExternalPainter",!value, value); + update(); + } } void ImageItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) { - if (m_picture.isNull()){ - if (!m_datasource.isEmpty() && !m_field.isEmpty()){ - IDataSource* ds = dataManager->dataSource(m_datasource); + if (m_picture.isNull()){ + if (!m_datasource.isEmpty() && !m_field.isEmpty()){ + IDataSource* ds = dataManager->dataSource(m_datasource); if (ds) { QVariant data = ds->data(m_field); - if (data.isValid()){ - if (data.type()==QVariant::Image){ - m_picture = data.value(); - } else { - switch (m_format) { - case Binary: - m_picture.loadFromData(data.toByteArray()); - break; - case Hex: - m_picture.loadFromData(QByteArray::fromHex(data.toByteArray())); - break; - case Base64: - m_picture.loadFromData(QByteArray::fromBase64(data.toByteArray())); - break; - } - - } - - } + loadPictureFromVariant(data); } } else if (!m_resourcePath.isEmpty()){ m_resourcePath = expandUserVariables(m_resourcePath, pass, NoEscapeSymbols, dataManager); m_resourcePath = expandDataFields(m_resourcePath, NoEscapeSymbols, dataManager); m_picture = QImage(m_resourcePath); + } else if (!m_variable.isEmpty()){ + QVariant data = dataManager->variable(m_variable); + if (data.type() == QVariant::String){ + m_picture = QImage(data.toString()); + } else if (data.type() == QVariant::Image){ + loadPictureFromVariant(data); + } } } if (m_autoSize){ @@ -114,6 +159,16 @@ qreal ImageItem::minHeight() const{ } } +void ImageItem::setVariable(const QString& content) +{ + if (m_variable!=content){ + QString oldValue = m_variable; + m_variable=content; + update(); + notify("variable", oldValue, m_variable); + } +} + bool ImageItem::center() const { return m_center; @@ -259,10 +314,13 @@ void ImageItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option ppainter->setPen(Qt::black); if (!datasource().isEmpty() && !field().isEmpty()) text = datasource()+"."+field(); - else text = tr("Image"); + else if (m_useExternalPainter) text = tr("Ext."); else text = tr("Image"); ppainter->drawText(rect().adjusted(4,4,-4,-4), Qt::AlignCenter, text ); } else { - ppainter->drawImage(point,img); + if (m_externalPainter && m_useExternalPainter) + m_externalPainter->paintByExternalPainter(this->patternName(), ppainter, option); + else + ppainter->drawImage(point,img); } ItemDesignIntf::paint(ppainter,option,widget); ppainter->restore(); diff --git a/limereport/items/lrimageitem.h b/limereport/items/lrimageitem.h index 77ea8db..5d474e2 100644 --- a/limereport/items/lrimageitem.h +++ b/limereport/items/lrimageitem.h @@ -33,7 +33,7 @@ namespace LimeReport{ -class ImageItem : public LimeReport::ItemDesignIntf +class ImageItem : public ItemDesignIntf, public IPainterProxy { Q_OBJECT Q_ENUMS(Format) @@ -47,7 +47,10 @@ class ImageItem : public LimeReport::ItemDesignIntf Q_PROPERTY(bool keepAspectRatio READ keepAspectRatio WRITE setKeepAspectRatio) Q_PROPERTY(bool center READ center WRITE setCenter) Q_PROPERTY(QString resourcePath READ resourcePath WRITE setResourcePath) + Q_PROPERTY(QString variable READ variable WRITE setVariable) Q_PROPERTY(bool watermark READ isWatermark WRITE setWatermark) + Q_PROPERTY(bool useExternalPainter READ useExternalPainter WRITE setUseExternalPainter) + public: enum Format { Binary = 0, @@ -76,16 +79,28 @@ public: void setCenter(bool center); Format format() const; void setFormat(Format format); - qreal minHeight() const; + QString variable(){ return m_variable;} + void setVariable(const QString& variable); + + void setExternalPainter(IExternalPainter* externalPainter){ m_externalPainter = externalPainter;} + + bool useExternalPainter() const; + void setUseExternalPainter(bool value); + protected: BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); void updateItemSize(DataSourceManager *dataManager, RenderPass pass, int maxHeight); bool isNeedUpdateSize(RenderPass) const; bool drawDesignBorders() const {return m_picture.isNull();} + void loadPictureFromVariant(QVariant& data); + void preparePopUpMenu(QMenu &menu); + void processPopUpAction(QAction *action); private: QImage m_picture; + bool m_useExternalPainter; + IExternalPainter* m_externalPainter; QString m_resourcePath; QString m_datasource; QString m_field; @@ -94,6 +109,8 @@ private: bool m_keepAspectRatio; bool m_center; Format m_format; + QString m_variable; + }; } diff --git a/limereport/items/lrlayoutmarker.cpp b/limereport/items/lrlayoutmarker.cpp new file mode 100644 index 0000000..48b534c --- /dev/null +++ b/limereport/items/lrlayoutmarker.cpp @@ -0,0 +1,69 @@ +#include "lrlayoutmarker.h" +#include +#include + +namespace LimeReport{ + +LayoutMarker::LayoutMarker(BaseDesignIntf* layout, QGraphicsItem *parent) + :QGraphicsItem(parent), m_rect(0,0,30,30), m_color(Qt::red), m_layout(layout){ + setFlag(QGraphicsItem::ItemIsMovable); +} + +void LayoutMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->save(); + painter->setOpacity(Const::LAYOUT_MARKER_OPACITY); + painter->fillRect(boundingRect(),m_color); + + painter->setRenderHint(QPainter::Antialiasing); + qreal size = (boundingRect().width()isSelected()){ + painter->setOpacity(1); + QRectF r = QRectF(0,0,size,size); + painter->setBrush(Qt::white); + painter->setPen(Qt::white); + painter->drawEllipse(r.adjusted(5,5,-5,-5)); + painter->setBrush(m_color); + painter->drawEllipse(r.adjusted(7,7,-7,-7)); + } + painter->restore(); +} + +void LayoutMarker::setHeight(qreal height) +{ + if (m_rect.height()!=height){ + prepareGeometryChange(); + m_rect.setHeight(height); + } +} + +void LayoutMarker::setWidth(qreal width) +{ + if (m_rect.width()!=width){ + prepareGeometryChange(); + m_rect.setWidth(width); + } +} + +void LayoutMarker::setColor(QColor color) +{ + if (m_color!=color){ + m_color = color; + update(boundingRect()); + } +} + +void LayoutMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button()==Qt::LeftButton) { + if (!(event->modifiers() & Qt::ControlModifier)) + m_layout->scene()->clearSelection(); + m_layout->setSelected(true); + //m_layout->setChildVisibility(false); + update(0,0,boundingRect().width(),boundingRect().width()); + } +} + + +} // namespace LimeReport diff --git a/limereport/items/lrlayoutmarker.h b/limereport/items/lrlayoutmarker.h new file mode 100644 index 0000000..3eb65b0 --- /dev/null +++ b/limereport/items/lrlayoutmarker.h @@ -0,0 +1,28 @@ +#ifndef LRLAYOUTMARKER_H +#define LRLAYOUTMARKER_H + +#include +#include "lrbanddesignintf.h" + +namespace LimeReport{ + +class LayoutMarker : public QGraphicsItem{ +public: + explicit LayoutMarker(BaseDesignIntf* layout, QGraphicsItem *parent=0); + virtual QRectF boundingRect() const{return m_rect;} + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + void setHeight(qreal height); + void setWidth(qreal width); + void setColor(QColor color); + qreal width(){return m_rect.width();} + qreal height(){return m_rect.height();} +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); +private: + QRectF m_rect; + QColor m_color; + BaseDesignIntf* m_layout; +}; + +} // namespace LimeReport +#endif // LRLAYOUTMARKER_H diff --git a/limereport/items/lrshapeitem.cpp b/limereport/items/lrshapeitem.cpp index a1b37d9..182ea9e 100644 --- a/limereport/items/lrshapeitem.cpp +++ b/limereport/items/lrshapeitem.cpp @@ -83,12 +83,17 @@ void ShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QPen pen(m_shapeColor); pen.setWidthF(m_lineWidth); pen.setStyle(m_penStyle); + pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); QBrush brush(m_shapeBrushColor,m_shapeBrushType); brush.setTransform(painter->worldTransform().inverted()); painter->setBrush(brush); painter->setBackground(QBrush(Qt::NoBrush)); painter->setOpacity(qreal(m_opacity)/100); + QRectF rectangleRect = rect().adjusted((lineWidth() / 2), + (lineWidth() / 2), + -(lineWidth() / 2), + -(lineWidth() / 2)); switch (m_shape){ case HorizontalLine: @@ -102,11 +107,11 @@ void ShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->drawEllipse(rect()); break; case Rectangle: - if (m_cornerRadius!=0){ + if (m_cornerRadius != 0){ painter->setRenderHint(QPainter::Antialiasing); - painter->drawRoundedRect(rect(),m_cornerRadius,m_cornerRadius); + painter->drawRoundedRect(rectangleRect,m_cornerRadius,m_cornerRadius); } else { - painter->drawRect(rect()); + painter->drawRect(rectangleRect); } break; } diff --git a/limereport/items/lrsubitemparentpropitem.cpp b/limereport/items/lrsubitemparentpropitem.cpp index b02cfa7..61ff802 100644 --- a/limereport/items/lrsubitemparentpropitem.cpp +++ b/limereport/items/lrsubitemparentpropitem.cpp @@ -77,6 +77,7 @@ void LimeReport::ItemLocationPropItem::setPropertyEditorData(QWidget *propertyEd } void LimeReport::ItemLocationPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index){ + Q_UNUSED(propertyEditor) model->setData(index,object()->property(propertyName().toLatin1())); setValueToObject(propertyName(), propertyValue()); } diff --git a/limereport/items/lrtextitem.cpp b/limereport/items/lrtextitem.cpp index eae907f..50de9d5 100644 --- a/limereport/items/lrtextitem.cpp +++ b/limereport/items/lrtextitem.cpp @@ -29,7 +29,6 @@ ****************************************************************************/ #include #include -#include #include #include #include @@ -60,7 +59,7 @@ namespace LimeReport{ TextItem::TextItem(QObject *owner, QGraphicsItem *parent) : ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0), m_trimValue(true), m_allowHTML(false), m_allowHTMLInFields(false), m_replaceCarriageReturns(false), m_followTo(""), m_follower(0), m_textIndent(0), - m_textLayoutDirection(Qt::LayoutDirectionAuto) + m_textLayoutDirection(Qt::LayoutDirectionAuto), m_hideIfEmpty(false), m_fontLetterSpacing(0) { PageItemDesignIntf* pageItem = dynamic_cast(parent); BaseDesignIntf* parentItem = dynamic_cast(parent); @@ -106,6 +105,18 @@ void TextItem::preparePopUpMenu(QMenu &menu) action->setCheckable(true); action->setChecked(stretchToMaxHeight()); + action = menu.addAction(tr("Transparent")); + action->setCheckable(true); + action->setChecked(backgroundMode() == TransparentMode); + + action = menu.addAction(tr("Watermark")); + action->setCheckable(true); + action->setChecked(isWatermark()); + + action = menu.addAction(tr("Hide if empty")); + action->setCheckable(true); + action->setChecked(hideIfEmpty()); + } void TextItem::processPopUpAction(QAction *action) @@ -127,6 +138,22 @@ void TextItem::processPopUpAction(QAction *action) page()->setPropertyToSelectedItems("stretchToMaxHeight",action->isChecked()); } } + if (action->text().compare(tr("Transparent")) == 0){ + if (action->isChecked()){ + setProperty("backgroundMode",TransparentMode); + } else { + setProperty("backgroundMode",OpaqueMode); + } + } + if (action->text().compare(tr("Watermark")) == 0){ + page()->setPropertyToSelectedItems("watermark",action->isChecked()); + } + + if (action->text().compare(tr("Hide if empty")) == 0){ + page()->setPropertyToSelectedItems("hideIfEmpty",action->isChecked()); + } + + ContentItemDesignIntf::processPopUpAction(action); } void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, QWidget* widget) { @@ -312,6 +339,7 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i } } BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); + if (isEmpty() && hideIfEmpty()) setVisible(false); } void TextItem::updateLayout() @@ -333,7 +361,7 @@ void TextItem::updateLayout() bool TextItem::isNeedExpandContent() const { QRegExp rx("$*\\{[^{]*\\}"); - return content().contains(rx); + return content().contains(rx) || isContentBackedUp(); } QString TextItem::replaceBR(QString text) const @@ -481,7 +509,6 @@ TextItem::TextPtr TextItem::textDocument() const QTextOption to; to.setAlignment(m_alignment); to.setTextDirection(m_textLayoutDirection); - //to.setTextDirection(QApplication::layoutDirection()); if (m_autoWidth!=MaxStringLength) if (m_adaptFontToSize && (!(m_autoHeight || m_autoWidth))) @@ -522,6 +549,36 @@ TextItem::TextPtr TextItem::textDocument() const } +int TextItem::fontLetterSpacing() const +{ + return m_fontLetterSpacing; +} + +void TextItem::setFontLetterSpacing(int value) +{ + if (m_fontLetterSpacing != value){ + int oldValue = m_fontLetterSpacing; + m_fontLetterSpacing = value; + QFont curFont = font(); + curFont.setLetterSpacing(QFont::AbsoluteSpacing, m_fontLetterSpacing); + setFont(curFont); + notify("fontLetterSpacing", oldValue, value); + } +} + +bool TextItem::hideIfEmpty() const +{ + return m_hideIfEmpty; +} + +void TextItem::setHideIfEmpty(bool hideEmpty) +{ + if (m_hideIfEmpty != hideEmpty){ + m_hideIfEmpty = hideEmpty; + notify("hideIfEmpty",!m_hideIfEmpty, m_hideIfEmpty); + } +} + bool TextItem::isReplaceCarriageReturns() const { return m_replaceCarriageReturns; @@ -573,6 +630,7 @@ void TextItem::setWatermark(bool watermark) setBackgroundMode(TransparentMode); } BaseDesignIntf::setWatermark(watermark); + } @@ -754,19 +812,35 @@ void TextItem::setAlignment(Qt::Alignment value) void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass) { QString context=content(); - ExpandType expandType = (allowHTML() && !allowHTMLInFields())?ReplaceHTMLSymbols:NoEscapeSymbols; + foreach (QString variableName, dataManager->variableNamesByRenderPass(SecondPass)) { + QRegExp rx(QString(Const::NAMED_VARIABLE_RX).arg(variableName)); + if (context.contains(rx) && pass == FirstPass){ + backupContent(); + break; + } + } + + ExpandType expandType = (allowHTML() && !allowHTMLInFields()) ? ReplaceHTMLSymbols : NoEscapeSymbols; switch(pass){ case FirstPass: - context=expandUserVariables(context, pass, expandType, dataManager); - context=expandScripts(context, dataManager); - context=expandDataFields(context, expandType, dataManager); + if (!fillInSecondPass()){ + context=expandUserVariables(context, pass, expandType, dataManager); + context=expandScripts(context, dataManager); + context=expandDataFields(context, expandType, dataManager); + } else { + context=expandDataFields(context, expandType, dataManager); + } break; - case SecondPass:; + case SecondPass: + if (isContentBackedUp()) { + restoreContent(); + context = content(); + } context=expandUserVariables(context, pass, expandType, dataManager); context=expandScripts(context, dataManager); } - if (expandType == NoEscapeSymbols && !m_varValue.isNull() &&m_valueType!=Default) { + if (expandType == NoEscapeSymbols && !m_varValue.isNull() &&m_valueType != Default) { setContent(formatFieldValue()); } else { setContent(context); @@ -914,8 +988,9 @@ void TextItem::setTextItemFont(QFont value) { if (font()!=value){ QFont oldValue = font(); + value.setLetterSpacing(QFont::AbsoluteSpacing, m_fontLetterSpacing); setFont(value); - update(); + if (!isLoading()) update(); notify("font",oldValue,value); } } diff --git a/limereport/items/lrtextitem.h b/limereport/items/lrtextitem.h index d8fa8cc..aa624eb 100644 --- a/limereport/items/lrtextitem.h +++ b/limereport/items/lrtextitem.h @@ -41,7 +41,7 @@ namespace LimeReport { class Tag; -class TextItem : public LimeReport::ContentItemDesignIntf, IPageInit { +class TextItem : public ContentItemDesignIntf, IPageInit { Q_OBJECT Q_ENUMS(AutoWidth) Q_ENUMS(AngleType) @@ -71,13 +71,16 @@ class TextItem : public LimeReport::ContentItemDesignIntf, IPageInit { Q_PROPERTY(BrushStyle backgroundBrushStyle READ backgroundBrushStyle WRITE setBackgroundBrushStyle) Q_PROPERTY(qreal textIndent READ textIndent WRITE setTextIndent) Q_PROPERTY(Qt::LayoutDirection textLayoutDirection READ textLayoutDirection WRITE setTextLayoutDirection) + Q_PROPERTY(bool fillInSecondPass READ fillInSecondPass WRITE setFillInSecondPass) Q_PROPERTY(bool watermark READ isWatermark WRITE setWatermark) Q_PROPERTY(bool replaceCRwithBR READ isReplaceCarriageReturns WRITE setReplaceCarriageReturns) + Q_PROPERTY(bool hideIfEmpty READ hideIfEmpty WRITE setHideIfEmpty) + Q_PROPERTY(int fontLetterSpacing READ fontLetterSpacing WRITE setFontLetterSpacing) public: - enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength}; - enum AngleType{Angle0,Angle90,Angle180,Angle270,Angle45,Angle315}; - enum ValueType{Default,DateTime,Double}; + enum AutoWidth{NoneAutoWidth, MaxWordLength, MaxStringLength}; + enum AngleType{Angle0, Angle90, Angle180, Angle270, Angle45, Angle315}; + enum ValueType{Default, DateTime, Double}; void Init(); TextItem(QObject* owner=0, QGraphicsItem* parent=0); @@ -106,7 +109,7 @@ public: bool canBeSplitted(int height) const; bool isSplittable() const { return true;} - bool isEmpty() const{return m_strText.trimmed().isEmpty() /*m_text->isEmpty()*/;} + bool isEmpty() const{return m_strText.trimmed().isEmpty();} BaseDesignIntf* cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent); BaseDesignIntf* cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent); BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); @@ -171,6 +174,12 @@ public: bool isReplaceCarriageReturns() const; void setReplaceCarriageReturns(bool isReplaceCarriageReturns); + bool hideIfEmpty() const; + void setHideIfEmpty(bool hideIfEmpty); + + int fontLetterSpacing() const; + void setFontLetterSpacing(int fontLetterSpacing); + protected: void updateLayout(); bool isNeedExpandContent() const; @@ -192,8 +201,6 @@ private: TextPtr textDocument() const; private: QString m_strText; - //QTextLayout m_layout; - //QTextDocument* m_text; Qt::Alignment m_alignment; bool m_autoHeight; AutoWidth m_autoWidth; @@ -216,7 +223,8 @@ private: TextItem* m_follower; qreal m_textIndent; Qt::LayoutDirection m_textLayoutDirection; - + bool m_hideIfEmpty; + int m_fontLetterSpacing; }; } diff --git a/limereport/items/lrtextitemeditor.cpp b/limereport/items/lrtextitemeditor.cpp index 09a0e3a..8299fbc 100644 --- a/limereport/items/lrtextitemeditor.cpp +++ b/limereport/items/lrtextitemeditor.cpp @@ -33,7 +33,7 @@ #include "lrdatasourcemanager.h" #include "lrscriptenginemanager.h" #include "lrdatadesignintf.h" -#include "lrdatasourcemanager.h" +#include "lrscripteditor.h" #include #include @@ -46,10 +46,9 @@ TextItemEditor::TextItemEditor(LimeReport::TextItem *item, LimeReport::PageDesig { ui->setupUi(this); initUI(); - m_teContent->setPlainText(item->content()); - m_teContent->setFocus(); setWindowIcon(QIcon(":/items/images/TextItem")); readSetting(); + connect(ui->codeEditor, SIGNAL(splitterMoved(int,int)), this, SLOT(slotSplitterMoved(int,int)) ); } TextItemEditor::~TextItemEditor() @@ -77,7 +76,7 @@ QSettings*TextItemEditor::settings() if (m_settings){ return m_settings; } else { - m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_settings = new QSettings("LimeReport",QCoreApplication::applicationName()); m_ownedSettings = true; return m_settings; } @@ -97,10 +96,20 @@ void TextItemEditor::moveEvent(QMoveEvent*) #endif } +void TextItemEditor::closeEvent(QCloseEvent* event) +{ + if (settings()!=0){ + settings()->beginGroup("TextItemEditor"); + settings()->setValue("CodeEditorState",ui->codeEditor->saveState()); + settings()->endGroup(); + } + QWidget::closeEvent(event); +} + void TextItemEditor::on_pbOk_clicked() { - if (m_textItem->content()!=m_teContent->toPlainText()){ - m_textItem->setContent(m_teContent->toPlainText()); + if (m_textItem->content()!= ui->codeEditor->toPlainText()){ + m_textItem->setContent(ui->codeEditor->toPlainText()); } close(); } @@ -108,84 +117,17 @@ void TextItemEditor::on_pbOk_clicked() void TextItemEditor::initUI() { QStringList dataWords; - m_teContent = ui->textEdit; - m_completer = new QCompleter(this); - m_teContent->setCompleter(m_completer); - - m_datasourcesMenu = new QMenu(this); LimeReport::DataSourceManager* dm = m_page->datasourceManager(); LimeReport::ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance(); se.setDataManager(dm); - if (dm){ - if (dm->isNeedUpdateDatasourceModel()) - dm->updateDatasourceModel(); - ui->twData->setModel(dm->datasourcesModel()); - ui->twScriptEngine->setModel(se.model()); - - foreach(const QString &dsName,dm->dataSourceNames()){ - foreach(const QString &field, dm->fieldNames(dsName)){ - dataWords<tabWidget->setVisible(false); + ScriptEditor* scriptEditor = dynamic_cast(ui->codeEditor); + if (scriptEditor){ + scriptEditor->setReportPage(m_page); + scriptEditor->setPageBand(findParentBand()); + scriptEditor->setPlainText(m_textItem->content()); } - - foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescriber()) { - dataWords<setModel(new QStringListModel(dataWords,m_completer)); - ui->gbSettings->setVisible(false); - - if (ui->twScriptEngine->selectionModel()){ - connect(ui->twScriptEngine->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(slotScriptItemsSelectionChanged(QModelIndex,QModelIndex))); - } - - BandDesignIntf* band = findParentBand(); - if (band && ui->twData->model() && !band->datasourceName().isEmpty()){ - QModelIndexList nodes = ui->twData->model()->match( - ui->twData->model()->index(0,0), - Qt::DisplayRole, - band->datasourceName(), - 2, - Qt::MatchRecursive - ); - if (!nodes.isEmpty()){ - ui->twData->expand(nodes.at(0).parent()); - ui->twData->expand(nodes.at(0)); - } - } -} - -QStringListModel *TextItemEditor::getDataSources() -{ - LimeReport::DataSourceManager* dm = m_page->datasourceManager(); - QStringList dataSources; - foreach(QString dsName,dm->dataSourceNames()){ - dataSources<datasourceManager(); - foreach(QString field, dm->fieldNames(datasource)){ - fields<(sender()); - m_teContent->insertPlainText(action->whatsThis()); -} - void TextItemEditor::readSetting() { if (settings()==0) return; @@ -210,17 +146,23 @@ void TextItemEditor::readSetting() if (v.isValid()){ restoreGeometry(v.toByteArray()); } - v = settings()->value("State"); + v = settings()->value("CodeEditorState"); if (v.isValid()){ - ui->splitter->restoreState(v.toByteArray()); + ui->codeEditor->restoreState(v.toByteArray()); + } + settings()->endGroup(); + settings()->beginGroup("ScriptEditor"); + QVariant fontName = settings()->value("DefaultFontName"); + if (fontName.isValid()){ + QVariant fontSize = settings()->value("DefaultFontSize"); + ui->codeEditor->setEditorFont(QFont(fontName.toString(),fontSize.toInt())); } - QVariant fontName = settings()->value("FontName"); - if (fontName.isValid()){ - QVariant fontSize = settings()->value("FontSize"); - ui->textEdit->setFont(QFont(fontName.toString(),fontSize.toInt())); - ui->editorFont->setCurrentFont(ui->textEdit->font()); - ui->editorFontSize->setValue(fontSize.toInt()); + QVariant tabIndention = settings()->value("TabIndention"); + if (tabIndention.isValid()){ + ui->codeEditor->setTabIndention(tabIndention.toInt()); + } else { + ui->codeEditor->setTabIndention(LimeReport::Const::DEFAULT_TAB_INDENTION); } settings()->endGroup(); @@ -232,170 +174,14 @@ void TextItemEditor::writeSetting() if (settings()!=0){ settings()->beginGroup("TextItemEditor"); settings()->setValue("Geometry",saveGeometry()); - settings()->setValue("State",ui->splitter->saveState()); + settings()->setValue("CodeEditorState",ui->codeEditor->saveState()); settings()->endGroup(); } } - -CompleaterTextEditor::CompleaterTextEditor(QWidget *parent) - : QTextEdit(parent),m_compleater(0) +void TextItemEditor::slotSplitterMoved(int, int) { -} - -void CompleaterTextEditor::setCompleter(QCompleter *value) -{ - if (value) disconnect(value,0,this,0); - m_compleater = value; - if (!m_compleater) return; - m_compleater->setWidget(this); - m_compleater->setCompletionMode(QCompleter::PopupCompletion); - m_compleater->setCaseSensitivity(Qt::CaseInsensitive); - connect(m_compleater,SIGNAL(activated(QString)),this,SLOT(insertCompletion(QString))); -} - -void CompleaterTextEditor::keyPressEvent(QKeyEvent *e) -{ - if (m_compleater && m_compleater->popup()->isVisible()) { - switch (e->key()) { - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_Escape: - case Qt::Key_Tab: - case Qt::Key_Backtab: - e->ignore(); - return; - default: - break; - } - } - - bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); - if (!m_compleater || !isShortcut) QTextEdit::keyPressEvent(e); - - const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); - if (!m_compleater || (ctrlOrShift && e->text().isEmpty())) - return; - - static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word - bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; - - QString completionPrefix = textUnderCursor(); - - if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 - || eow.contains(e->text().right(1)))) { - m_compleater->popup()->hide(); - return; - } - - if (completionPrefix != m_compleater->completionPrefix()) { - m_compleater->setCompletionPrefix(completionPrefix); - m_compleater->popup()->setCurrentIndex(m_compleater->completionModel()->index(0, 0)); - } - - QRect cr = cursorRect(); - cr.setWidth(m_compleater->popup()->sizeHintForColumn(0) - + m_compleater->popup()->verticalScrollBar()->sizeHint().width()); - m_compleater->complete(cr); - -} - -void CompleaterTextEditor::focusInEvent(QFocusEvent *e) -{ - if (m_compleater) m_compleater->setWidget(this); - QTextEdit::focusInEvent(e); -} - -QString CompleaterTextEditor::textUnderCursor() const -{ - QTextCursor tc = textCursor(); - tc.select(QTextCursor::WordUnderCursor); - return tc.selectedText(); -} - - -void CompleaterTextEditor::insertCompletion(const QString &completion) -{ - if (m_compleater->widget() != this) - return; - QTextCursor tc = textCursor(); - int extra = completion.length() - m_compleater->completionPrefix().length(); - tc.movePosition(QTextCursor::Left); - tc.movePosition(QTextCursor::EndOfWord); - tc.insertText(completion.right(extra)); - setTextCursor(tc); -} - -void TextItemEditor::on_twData_doubleClicked(const QModelIndex &index) -{ - if (!index.isValid()) return; - LimeReport::DataNode* node = static_cast(index.internalPointer()); - if (node->type()==LimeReport::DataNode::Field){ - m_teContent->insertPlainText(QString("$D{%1.%2}").arg(node->parent()->name()).arg(node->name())); - } - if (node->type()==LimeReport::DataNode::Variable){ - m_teContent->insertPlainText(QString("$V{%1}").arg(node->name())); - } -} - -void TextItemEditor::on_twScriptEngine_doubleClicked(const QModelIndex &index) -{ - if (!index.isValid()) return; - LimeReport::ScriptEngineNode* node = static_cast(index.internalPointer()); - if (node->type()==LimeReport::ScriptEngineNode::Function){ - m_teContent->insertPlainText(node->name()+"()"); - } -} - -void TextItemEditor::on_splitter_splitterMoved(int , int ) -{ -#ifdef unix writeSetting(); -#endif -} - -void TextItemEditor::on_editorFont_currentFontChanged(const QFont &f) -{ - if (m_isReadingSetting) return; - QFont tmp = f; - tmp.setPointSize(ui->editorFontSize->value()); - ui->textEdit->setFont(tmp); - settings()->beginGroup("TextItemEditor"); - settings()->setValue("FontName",ui->textEdit->font().family()); - settings()->setValue("FontSize",ui->editorFontSize->value()); - settings()->endGroup(); -} - -void TextItemEditor::on_editorFontSize_valueChanged(int arg1) -{ - if (m_isReadingSetting) return; - ui->textEdit->setFont(QFont(ui->textEdit->font().family(),arg1)); - settings()->beginGroup("TextItemEditor"); - settings()->setValue("FontName",ui->textEdit->font().family()); - settings()->setValue("FontSize",ui->editorFontSize->value()); - settings()->endGroup(); -} - -void TextItemEditor::on_toolButton_clicked(bool checked) -{ - ui->gbSettings->setVisible(checked); -} - - -void TextItemEditor::on_twScriptEngine_activated(const QModelIndex &index) -{ - LimeReport::ScriptEngineNode* node = static_cast(index.internalPointer()); - if (node->type()==LimeReport::ScriptEngineNode::Function){ - ui->lblDescription->setText(node->name()); - } -} - -void TextItemEditor::slotScriptItemsSelectionChanged(const QModelIndex &to, const QModelIndex) -{ - LimeReport::ScriptEngineNode* node = static_cast(to.internalPointer()); - if (node->type()==LimeReport::ScriptEngineNode::Function){ - ui->lblDescription->setText(node->description()); - } } BandDesignIntf *TextItemEditor::findParentBand() diff --git a/limereport/items/lrtextitemeditor.h b/limereport/items/lrtextitemeditor.h index cf02781..b9e2750 100644 --- a/limereport/items/lrtextitemeditor.h +++ b/limereport/items/lrtextitemeditor.h @@ -43,23 +43,23 @@ namespace Ui { class TextItemEditor; } -class CompleaterTextEditor :public QTextEdit -{ - Q_OBJECT -public: - CompleaterTextEditor(QWidget* parent=0); - void setCompleter(QCompleter* value); - QCompleter* compleater() const{ return m_compleater;} -protected: - virtual void keyPressEvent(QKeyEvent *e); - virtual void focusInEvent(QFocusEvent *e); -private: - QString textUnderCursor() const; -private slots: - void insertCompletion(const QString& completion); -private: - QCompleter* m_compleater; -}; +//class CompleaterTextEditor :public QTextEdit +//{ +// Q_OBJECT +//public: +// CompleaterTextEditor(QWidget* parent=0); +// void setCompleter(QCompleter* value); +// QCompleter* compleater() const{ return m_compleater;} +//protected: +// virtual void keyPressEvent(QKeyEvent *e); +// virtual void focusInEvent(QFocusEvent *e); +//private: +// QString textUnderCursor() const; +//private slots: +// void insertCompletion(const QString& completion); +//private: +// QCompleter* m_compleater; +//}; class TextItemEditor : public QWidget { @@ -69,37 +69,24 @@ public: QSettings* settings=0, QWidget *parent = 0); ~TextItemEditor(); void setSettings(QSettings* value); - QSettings* settings(); + QSettings* settings(); protected: void resizeEvent(QResizeEvent *); void moveEvent(QMoveEvent *); + void closeEvent(QCloseEvent *event); BandDesignIntf* findParentBand(); private slots: void on_pbOk_clicked(); void on_pbCancel_clicked(); - void slotFieldSelected(); - void on_twData_doubleClicked(const QModelIndex &index); - void on_twScriptEngine_doubleClicked(const QModelIndex &index); - void on_splitter_splitterMoved(int, int); - void on_editorFont_currentFontChanged(const QFont &f); - void on_editorFontSize_valueChanged(int arg1); - void on_toolButton_clicked(bool checked); - void on_twScriptEngine_activated(const QModelIndex &index); - void slotScriptItemsSelectionChanged(const QModelIndex &to, const QModelIndex); + void slotSplitterMoved(int, int); private: void initUI(); void readSetting(); void writeSetting(); - QStringListModel* getDataSources(); - QStringListModel* getPrefixes(); - QStringListModel* getColumns(QString datasource); private: Ui::TextItemEditor *ui; LimeReport::TextItem* m_textItem; LimeReport::PageDesignIntf* m_page; - QMenu* m_datasourcesMenu; - CompleaterTextEditor* m_teContent; - QCompleter* m_completer; QSettings* m_settings; bool m_ownedSettings; bool m_isReadingSetting; diff --git a/limereport/items/lrtextitemeditor.ui b/limereport/items/lrtextitemeditor.ui index 9030fdb..403ea63 100644 --- a/limereport/items/lrtextitemeditor.ui +++ b/limereport/items/lrtextitemeditor.ui @@ -9,8 +9,8 @@ 0 0 - 539 - 436 + 457 + 366 @@ -33,9 +33,6 @@ Content - - 2 - 2 @@ -49,151 +46,20 @@ 2 - - - - 0 - 0 - + + + + 0 + 0 + - - Qt::Horizontal - - - - - 12 - - - - - - QTabWidget::South - - - 0 - - - - Data - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - false - - - - - - - - Functions - - - - - - Qt::Vertical - - - - false - - - - - - - - - - - - - - - - Editor settings - - - - - - - - Editor font - - - - - - - - - - 11 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - ... - - - - :/items/images/settings.png:/items/images/settings.png - - - true - - - true - - - @@ -233,9 +99,10 @@ - CompleaterTextEditor - QTextEdit -
lrtextitemeditor.h
+ LimeReport::ScriptEditor + QWidget +
lrscripteditor.h
+ 1
@@ -244,6 +111,7 @@ + diff --git a/limereport/items/lrverticallayout.cpp b/limereport/items/lrverticallayout.cpp new file mode 100644 index 0000000..51cb533 --- /dev/null +++ b/limereport/items/lrverticallayout.cpp @@ -0,0 +1,199 @@ +#include "lrverticallayout.h" + +#include "lrbasedesignintf.h" +#include "lrdesignelementsfactory.h" + +const QString xmlTag = "VLayout"; + +namespace { + +LimeReport::BaseDesignIntf *createVLayout(QObject *owner, LimeReport::BaseDesignIntf *parent) +{ + return new LimeReport::VerticalLayout(owner, parent); +} +bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("VLayout"), LimeReport::Const::bandTAG), + createVLayout + ); +} + +namespace LimeReport{ + +bool verticalLessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ + return c1->pos().y()pos().y(); +} + +VerticalLayout::VerticalLayout(QObject* owner, QGraphicsItem* parent) + : AbstractLayout(xmlTag, owner, parent) +{} + +VerticalLayout::~VerticalLayout() +{} + +BaseDesignIntf* VerticalLayout::createSameTypeItem(QObject* owner, QGraphicsItem* parent) +{ + return new LimeReport::VerticalLayout(owner, parent); +} + +void VerticalLayout::updateLayoutSize() +{ + int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; + int h = spaceBorder*2; + qreal w = 0; + int visibleItemCount = 0; + foreach(BaseDesignIntf* item, layoutsChildren()){ + if (item->isEmpty() && hideEmptyItems()) item->setVisible(false); + if (item->isVisible()){ + if (w < item->width()) w = item->width(); + h+=item->height(); + visibleItemCount++; + } + } + if (w>0) setWidth(w+spaceBorder*2); + setHeight(h + layoutSpacingMM() *(visibleItemCount-1)); +} + +void VerticalLayout::relocateChildren() +{ + int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; + if (layoutsChildren().count() < childItems().size() - 1){ + layoutsChildren().clear(); + foreach (BaseDesignIntf* item, childBaseItems()) { + layoutsChildren().append(item); + } + } + qSort(layoutsChildren().begin(),layoutsChildren().end(), verticalLessThen); + qreal curY = spaceBorder; + setIsRelocating(true); + foreach (BaseDesignIntf* item, layoutsChildren()) { + if (item->isVisible() || itemMode() == DesignMode){ + item->setPos(spaceBorder, curY); + curY+=item->height() + layoutSpacingMM(); + item->setWidth(width() - (spaceBorder * 2)); + } + } + setIsRelocating(false); +} + +bool VerticalLayout::canBeSplitted(int height) const +{ + if (childItems().isEmpty()) return false; + BaseDesignIntf* item = dynamic_cast(childItems().at(0)); + if (item){ + if (item->height() > height ) + return item->canBeSplitted(height); + else return true; + } + return false; +} + +BaseDesignIntf* VerticalLayout::cloneUpperPart(int height, QObject* owner, QGraphicsItem* parent) +{ + VerticalLayout* upperPart = dynamic_cast(createSameTypeItem(owner,parent)); + upperPart->initFromItem(this); + foreach(BaseDesignIntf* item, childBaseItems()){ + if ((item->geometry().bottom() <= height) ){ + item->cloneItem(item->itemMode(),upperPart,upperPart); + } else { + if ((item->geometry().top() < height) && ( item->geometry().bottom() > height)){ + int sliceHeight = height - item->geometry().top(); + if (item->isSplittable() && item->canBeSplitted(sliceHeight)){ + item->cloneUpperPart(sliceHeight,upperPart,upperPart); + } + } + } + } + + upperPart->setHeight(height); + + return upperPart; +} + +BaseDesignIntf* VerticalLayout::cloneBottomPart(int height, QObject* owner, QGraphicsItem* parent) +{ + VerticalLayout* bottomPart = dynamic_cast(createSameTypeItem(owner,parent)); + bottomPart->initFromItem(this); + + foreach(BaseDesignIntf* item,childBaseItems()){ + if ((item->geometry().top() < height) && ( item->geometry().bottom() > height )){ + int sliceHeight = height - item->geometry().top(); + if (item->canBeSplitted(sliceHeight)){ + BaseDesignIntf* tmpItem = item->cloneBottomPart(sliceHeight, bottomPart, bottomPart); + tmpItem->setPos(tmpItem->pos().x(),0); + tmpItem->setHeight(sliceHeight); + } else { + item->cloneItem(item->itemMode(), bottomPart, bottomPart); + item->setPos(item->pos().x(), 0); + } + } else { + if (item->geometry().top() >= height){ + BaseDesignIntf* tmpItem = item->cloneItem(item->itemMode(), bottomPart, bottomPart); + tmpItem->setPos(item->pos().x(), item->pos().y() - height); + } + } + } + + if (!bottomPart->isEmpty()){ + int currentHeight = 0; + foreach (BaseDesignIntf* item, bottomPart->childBaseItems()) { + currentHeight+=item->height(); + } + bottomPart->setHeight(currentHeight); + } + return bottomPart; +} + +void VerticalLayout::sortChildren() +{ + qSort(layoutsChildren().begin(),layoutsChildren().end(),verticalLessThen); +} + +void VerticalLayout::divideSpace() +{ + setIsRelocating(true); + qreal itemsSumSize = 0; + int visibleItemsCount = 0; + int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; + + foreach(BaseDesignIntf* item, layoutsChildren()){ + if (item->isVisible() || itemMode() == DesignMode ){ + itemsSumSize += item->height(); + visibleItemsCount++; + } + } + + itemsSumSize += layoutSpacingMM() * (visibleItemsCount - 1); + qreal delta = (height() - (itemsSumSize+spaceBorder*2)) / (visibleItemsCount!=0 ? visibleItemsCount : 1); + + for (int i=0; iisVisible() || itemMode() == DesignMode) + layoutsChildren()[i]->setHeight(layoutsChildren()[i]->height()+delta); + if ((i+1)isVisible() || itemMode() == DesignMode) + layoutsChildren()[i+1]->setPos(layoutsChildren()[i+1]->pos().x(), layoutsChildren()[i+1]->pos().y()+delta*(i+1)); + } + setIsRelocating(false); +} + +void VerticalLayout::placeItemInLayout(BaseDesignIntf* item) +{ + if (layoutsChildren().count() > 0) + item->setPos(0, layoutsChildren().last()->pos().y() + layoutsChildren().last()->height()); + else + item->setPos(0, 0); +} + +void VerticalLayout::insertItemInLayout(BaseDesignIntf* item) +{ + foreach (BaseDesignIntf* child, childBaseItems()) { + if (child->pos() == item->pos()){ + int index = layoutsChildren().indexOf(child)-1; + layoutsChildren().insert(index, item); + child->setPos(0, item->pos().y()+item->height()); + break; + } + } +} + +} // namespace LimeReport diff --git a/limereport/items/lrverticallayout.h b/limereport/items/lrverticallayout.h new file mode 100644 index 0000000..90ecb0a --- /dev/null +++ b/limereport/items/lrverticallayout.h @@ -0,0 +1,34 @@ +#ifndef LRVERTICALLAYOUT_H +#define LRVERTICALLAYOUT_H + +#include "lritemdesignintf.h" +#include "lrlayoutmarker.h" +#include "lrabstractlayout.h" + +namespace LimeReport{ + +class VerticalLayout : public AbstractLayout +{ + Q_OBJECT +public: + friend class BaseDesignIntf; + VerticalLayout(QObject *owner = 0, QGraphicsItem *parent = 0); + ~VerticalLayout(); + // BaseDesignIntf interface + BaseDesignIntf*createSameTypeItem(QObject* owner, QGraphicsItem* parent); + bool isSplittable() const { return true;} +protected: + void updateLayoutSize(); + void relocateChildren(); + bool canBeSplitted(int height) const; + BaseDesignIntf* cloneUpperPart(int height, QObject* owner=0, QGraphicsItem* parent=0); + BaseDesignIntf* cloneBottomPart(int height, QObject *owner=0, QGraphicsItem *parent=0); +private: + void sortChildren(); + void divideSpace(); + void placeItemInLayout(BaseDesignIntf* item); + void insertItemInLayout(BaseDesignIntf* item); +}; + +} // namespace LimeReport +#endif // LRVERTICALLAYOUT_H diff --git a/limereport/limereport.pri b/limereport/limereport.pri index e96070b..e039138 100644 --- a/limereport/limereport.pri +++ b/limereport/limereport.pri @@ -1,5 +1,9 @@ include(../common.pri) +contains(CONFIG, embedded_designer){ + include(designer.pri) +} + DEFINES += INSPECT_BASEDESIGN INCLUDEPATH += \ @@ -7,8 +11,7 @@ INCLUDEPATH += \ $$REPORT_PATH/items \ $$REPORT_PATH/bands \ $$REPORT_PATH/base \ - $$REPORT_PATH/objectinspector \ - $$REPORT_PATH/databrowser + $$REPORT_PATH/scripteditor SOURCES += \ $$REPORT_PATH/bands/lrpageheader.cpp \ @@ -19,54 +22,26 @@ SOURCES += \ $$REPORT_PATH/bands/lrgroupbands.cpp \ $$REPORT_PATH/bands/lrsubdetailband.cpp \ $$REPORT_PATH/bands/lrtearoffband.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrstringpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrrectproptem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrintpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrenumpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrboolpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrflagspropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrfontpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrimagepropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrqrealpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.cpp \ - $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.cpp \ - $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.cpp \ - $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.cpp \ - $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.cpp \ - $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.cpp \ - $$REPORT_PATH/objectinspector/editors/lrfonteditor.cpp \ - $$REPORT_PATH/objectinspector/editors/lrimageeditor.cpp \ - $$REPORT_PATH/objectinspector/editors/lrcoloreditor.cpp \ - $$REPORT_PATH/objectinspector/lrbasedesignobjectmodel.cpp \ - $$REPORT_PATH/objectinspector/lrobjectinspectorwidget.cpp \ - $$REPORT_PATH/objectinspector/lrobjectitemmodel.cpp \ - $$REPORT_PATH/objectinspector/lrobjectpropitem.cpp \ - $$REPORT_PATH/objectinspector/lrpropertydelegate.cpp \ - $$REPORT_PATH/objectsbrowser/lrobjectbrowser.cpp \ - $$REPORT_PATH/databrowser/lrdatabrowser.cpp \ - $$REPORT_PATH/databrowser/lrsqleditdialog.cpp \ - $$REPORT_PATH/databrowser/lrconnectiondialog.cpp \ - $$REPORT_PATH/databrowser/lrvariabledialog.cpp \ - $$REPORT_PATH/databrowser/lrdatabrowsertree.cpp \ $$REPORT_PATH/serializators/lrxmlqrectserializator.cpp \ $$REPORT_PATH/serializators/lrxmlbasetypesserializators.cpp \ $$REPORT_PATH/serializators/lrxmlreader.cpp \ $$REPORT_PATH/serializators/lrxmlwriter.cpp \ - $$REPORT_PATH/items/lrsubitemparentpropitem.cpp \ - $$REPORT_PATH/items/lralignpropitem.cpp \ + $$REPORT_PATH/scripteditor/lrscripteditor.cpp \ + $$REPORT_PATH/scripteditor/lrcodeeditor.cpp \ + $$REPORT_PATH/scripteditor/lrscripthighlighter.cpp \ $$REPORT_PATH/items/lrhorizontallayout.cpp \ $$REPORT_PATH/items/editors/lritemeditorwidget.cpp \ $$REPORT_PATH/items/editors/lrfonteditorwidget.cpp \ $$REPORT_PATH/items/editors/lrtextalignmenteditorwidget.cpp \ - $$REPORT_PATH/items/editors/lritemsaligneditorwidget.cpp \ $$REPORT_PATH/items/editors/lritemsborderseditorwidget.cpp \ $$REPORT_PATH/items/lrsimpletagparser.cpp \ $$REPORT_PATH/items/lrimageitem.cpp \ $$REPORT_PATH/items/lrtextitemeditor.cpp \ $$REPORT_PATH/items/lrshapeitem.cpp \ $$REPORT_PATH/items/lrtextitem.cpp \ + $$REPORT_PATH/items/lrverticallayout.cpp \ + $$REPORT_PATH/items/lrlayoutmarker.cpp \ + $$REPORT_PATH/items/lrabstractlayout.cpp \ $$REPORT_PATH/lrbanddesignintf.cpp \ $$REPORT_PATH/lrpageitemdesignintf.cpp \ $$REPORT_PATH/lrpagedesignintf.cpp \ @@ -74,11 +49,9 @@ SOURCES += \ $$REPORT_PATH/lrglobal.cpp \ $$REPORT_PATH/lritemdesignintf.cpp \ $$REPORT_PATH/lrdatadesignintf.cpp \ - $$REPORT_PATH/lrreportdesignwidget.cpp \ $$REPORT_PATH/lrbasedesignintf.cpp \ $$REPORT_PATH/lrreportengine.cpp \ $$REPORT_PATH/lrdatasourcemanager.cpp \ - $$REPORT_PATH/lrreportdesignwindow.cpp \ $$REPORT_PATH/lrreportrender.cpp \ $$REPORT_PATH/lrscriptenginemanager.cpp \ $$REPORT_PATH/lrpreviewreportwindow.cpp \ @@ -86,12 +59,17 @@ SOURCES += \ $$REPORT_PATH/lrgraphicsviewzoom.cpp \ $$REPORT_PATH/lrvariablesholder.cpp \ $$REPORT_PATH/lrgroupfunctions.cpp \ - $$REPORT_PATH/lrsimplecrypt.cpp \ + $$REPORT_PATH/lrsimplecrypt.cpp \ $$REPORT_PATH/lraboutdialog.cpp \ $$REPORT_PATH/lrsettingdialog.cpp \ - $$REPORT_PATH/scriptbrowser/lrscriptbrowser.cpp \ - $$REPORT_PATH/lrpreparedpages.cpp \ - $$REPORT_PATH/lritemscontainerdesignitf.cpp + $$REPORT_PATH/lritemscontainerdesignitf.cpp \ + $$REPORT_PATH/lrcolorindicator.cpp \ + $$REPORT_PATH/items/lrchartitem.cpp \ + $$REPORT_PATH/items/lrchartitemeditor.cpp \ + $$REPORT_PATH/lrreporttranslation.cpp \ + $$REPORT_PATH/exporters/lrpdfexporter.cpp \ + $$REPORT_PATH/lrpreparedpages.cpp + contains(CONFIG, staticlib){ SOURCES += $$REPORT_PATH/lrfactoryinitializer.cpp @@ -113,11 +91,6 @@ HEADERS += \ $$REPORT_PATH/bands/lrtearoffband.h \ $$REPORT_PATH/bands/lrsubdetailband.h \ $$REPORT_PATH/bands/lrgroupbands.h \ - $$REPORT_PATH/databrowser/lrdatabrowser.h \ - $$REPORT_PATH/databrowser/lrsqleditdialog.h \ - $$REPORT_PATH/databrowser/lrconnectiondialog.h \ - $$REPORT_PATH/databrowser/lrvariabledialog.h \ - $$REPORT_PATH/databrowser/lrdatabrowsertree.h \ $$REPORT_PATH/serializators/lrserializatorintf.h \ $$REPORT_PATH/serializators/lrstorageintf.h \ $$REPORT_PATH/serializators/lrxmlqrectserializator.h \ @@ -125,46 +98,20 @@ HEADERS += \ $$REPORT_PATH/serializators/lrxmlbasetypesserializators.h \ $$REPORT_PATH/serializators/lrxmlreader.h \ $$REPORT_PATH/serializators/lrxmlwriter.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrstringpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrrectproptem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrfontpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrimagepropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrintpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrenumpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrboolpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrflagspropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrqrealpropitem.h \ - $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.h \ - $$REPORT_PATH/objectinspector/editors/lrtextitempropertyeditor.h \ - $$REPORT_PATH/objectinspector/editors/lrcomboboxeditor.h \ - $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.h \ - $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.h \ - $$REPORT_PATH/objectinspector/editors/lrimageeditor.h \ - $$REPORT_PATH/objectinspector/editors/lrcoloreditor.h \ - $$REPORT_PATH/objectinspector/editors/lrfonteditor.h \ - $$REPORT_PATH/objectinspector/lrbasedesignobjectmodel.h \ - $$REPORT_PATH/objectinspector/lrobjectinspectorwidget.h \ - $$REPORT_PATH/objectinspector/lrobjectitemmodel.h \ - $$REPORT_PATH/objectinspector/lrobjectpropitem.h \ - $$REPORT_PATH/objectinspector/lrpropertydelegate.h \ - $$REPORT_PATH/objectsbrowser/lrobjectbrowser.h \ + $$REPORT_PATH/scripteditor/lrscripteditor.h \ + $$REPORT_PATH/scripteditor/lrcodeeditor.h \ + $$REPORT_PATH/scripteditor/lrscripthighlighter.h \ $$REPORT_PATH/items/editors/lritemeditorwidget.h \ $$REPORT_PATH/items/editors/lrfonteditorwidget.h \ - $$REPORT_PATH/items/editors/lrtextalignmenteditorwidget.h \ - $$REPORT_PATH/items/editors/lritemsaligneditorwidget.h \ - $$REPORT_PATH/items/editors/lritemsborderseditorwidget.h \ $$REPORT_PATH/items/lrtextitem.h \ - $$REPORT_PATH/items/lrsubitemparentpropitem.h \ - $$REPORT_PATH/items/lralignpropitem.h \ $$REPORT_PATH/items/lrhorizontallayout.h \ $$REPORT_PATH/items/lrtextitemeditor.h \ $$REPORT_PATH/items/lrshapeitem.h \ $$REPORT_PATH/items/lrimageitem.h \ $$REPORT_PATH/items/lrsimpletagparser.h \ - $$REPORT_PATH/lrfactoryinitializer.h \ + $$REPORT_PATH/items/lrverticallayout.h \ + $$REPORT_PATH/items/lrlayoutmarker.h \ + $$REPORT_PATH/items/lrabstractlayout.h \ $$REPORT_PATH/lrbanddesignintf.h \ $$REPORT_PATH/lrpageitemdesignintf.h \ $$REPORT_PATH/lrbandsmanager.h \ @@ -172,10 +119,8 @@ HEADERS += \ $$REPORT_PATH/lrdatadesignintf.h \ $$REPORT_PATH/lrcollection.h \ $$REPORT_PATH/lrpagedesignintf.h \ - $$REPORT_PATH/lrreportdesignwidget.h \ $$REPORT_PATH/lrreportengine_p.h \ - $$REPORT_PATH/lrdatasourcemanager.h \ - $$REPORT_PATH/lrreportdesignwindow.h \ + $$REPORT_PATH/lrdatasourcemanager.h \ $$REPORT_PATH/lrreportrender.h \ $$REPORT_PATH/lrpreviewreportwindow.h \ $$REPORT_PATH/lrpreviewreportwidget.h \ @@ -188,17 +133,28 @@ HEADERS += \ $$REPORT_PATH/lrvariablesholder.h \ $$REPORT_PATH/lrgroupfunctions.h \ $$REPORT_PATH/lrreportengine.h \ + $$REPORT_PATH/lrdatasourceintf.h \ $$REPORT_PATH/lrdatasourcemanagerintf.h \ $$REPORT_PATH/lrscriptenginemanagerintf.h \ - $$REPORT_PATH/lrsimplecrypt.h \ + $$REPORT_PATH/lrsimplecrypt.h \ $$REPORT_PATH/lraboutdialog.h \ $$REPORT_PATH/lrcallbackdatasourceintf.h \ $$REPORT_PATH/lrsettingdialog.h \ $$REPORT_PATH/lrpreviewreportwidget_p.h \ - $$REPORT_PATH/scriptbrowser/lrscriptbrowser.h \ + $$REPORT_PATH/lritemscontainerdesignitf.h \ + $$REPORT_PATH/lrcolorindicator.h \ + $$REPORT_PATH/items/lrchartitem.h \ + $$REPORT_PATH/items/lrchartitemeditor.h \ + $$REPORT_PATH/items/editors/lrtextalignmenteditorwidget.h \ + $$REPORT_PATH/items/editors/lritemsborderseditorwidget.h \ + $$REPORT_PATH/lrreporttranslation.h \ + $$REPORT_PATH/lrreportdesignwindowintrerface.h \ + $$REPORT_PATH/lrexporterintf.h \ + $$REPORT_PATH/lrexportersfactory.h \ + $$REPORT_PATH/exporters/lrpdfexporter.h \ $$REPORT_PATH/lrpreparedpages.h \ - $$REPORT_PATH/lrpreparedpagesintf.h \ - $$REPORT_PATH/lritemscontainerdesignitf.h + $$REPORT_PATH/lrpreparedpagesintf.h + contains(CONFIG, staticlib){ HEADERS += $$REPORT_PATH/lrfactoryinitializer.h @@ -209,22 +165,15 @@ contains(CONFIG,zint){ } FORMS += \ - $$REPORT_PATH/databrowser/lrsqleditdialog.ui \ - $$REPORT_PATH/databrowser/lrconnectiondialog.ui \ - $$REPORT_PATH/databrowser/lrdatabrowser.ui \ - $$REPORT_PATH/databrowser/lrvariabledialog.ui \ - $$REPORT_PATH/objectinspector/editors/ltextitempropertyeditor.ui \ $$REPORT_PATH/lrpreviewreportwindow.ui \ $$REPORT_PATH/lrpreviewreportwidget.ui \ $$REPORT_PATH/items/lrtextitemeditor.ui \ $$REPORT_PATH/lraboutdialog.ui \ $$REPORT_PATH/lrsettingdialog.ui \ - $$REPORT_PATH/scriptbrowser/lrscriptbrowser.ui \ + $$REPORT_PATH/items/lrchartitemeditor.ui \ + $$REPORT_PATH/scripteditor/lrscripteditor.ui RESOURCES += \ - $$REPORT_PATH/objectinspector/lobjectinspector.qrc \ - $$REPORT_PATH/databrowser/lrdatabrowser.qrc \ $$REPORT_PATH/report.qrc \ - $$REPORT_PATH/items/items.qrc \ - $$REPORT_PATH/scriptbrowser/lrscriptbrowser.qrc + $$REPORT_PATH/items/items.qrc diff --git a/limereport/limereport.pro b/limereport/limereport.pro index bdfcd42..d1ac03d 100644 --- a/limereport/limereport.pro +++ b/limereport/limereport.pro @@ -1,13 +1,9 @@ -#TARGET = limereport - - -CONFIG(debug, debug|release) { +CONFIG(debug, debug|release){ TARGET = limereportd } else { TARGET = limereport } - TEMPLATE = lib contains(CONFIG, static_build){ @@ -38,12 +34,14 @@ contains(CONFIG, staticlib){ EXTRA_FILES += \ $$PWD/lrglobal.h \ + $$PWD/lrdatasourceintf.h \ $$PWD/lrdatasourcemanagerintf.h \ $$PWD/lrreportengine.h \ $$PWD/lrscriptenginemanagerintf.h \ $$PWD/lrcallbackdatasourceintf.h \ - $$PWD/lrpreparedpagesintf.h \ - $$PWD/lrpreviewreportwidget.h + $$PWD/lrpreviewreportwidget.h \ + $$PWD/lrreportdesignwindowintrerface.h \ + $$PWD/lrpreparedpagesintf.h include(limereport.pri) @@ -88,19 +86,16 @@ win32 { contains(CONFIG,zint){ message(zint) - INCLUDEPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt4 - DEPENDPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt4 - LIBS += -L$${DEST_LIBS} - - CONFIG(debug, debug|release) { - LIBS += -lQtZintd - } else { - LIBS += -lQtZint - } - + INCLUDEPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt + DEPENDPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt + LIBS += -L$${DEST_LIBS} + CONFIG(release, debug|release){ + LIBS += -lQtZint + } else { + LIBS += -lQtZintd + } } - #### Install mkspecs, headers and libs to QT_INSTALL_DIR headerFiles.path = $$[QT_INSTALL_HEADERS]/LimeReport/ @@ -114,11 +109,10 @@ INSTALLS += mkspecs target.path = $$[QT_INSTALL_LIBS] INSTALLS += target -####### ####Automatically build required translation files (*.qm) contains(CONFIG,build_translations){ - LANGUAGES = ru es_ES ar fr zh pl + LANGUAGES = ru es ar fr zh pl defineReplace(prependAll) { for(a,$$1):result += $$2$${a}$$3 @@ -128,13 +122,18 @@ contains(CONFIG,build_translations){ TRANSLATIONS = $$prependAll(LANGUAGES, $$TRANSLATIONS_PATH/limereport_,.ts) qtPrepareTool(LUPDATE, lupdate) - ts.commands = $$LUPDATE $$PWD -ts $$TRANSLATIONS +greaterThan(QT_MAJOR_VERSION, 4) { + ts.commands = $$LUPDATE $$shell_quote($$PWD) -noobsolete -ts $$TRANSLATIONS +} +lessThan(QT_MAJOR_VERSION, 5){ + ts.commands = $$LUPDATE $$quote($$PWD) -noobsolete -ts $$TRANSLATIONS +} TRANSLATIONS_FILES = qtPrepareTool(LRELEASE, lrelease) for(tsfile, TRANSLATIONS) { qmfile = $$tsfile - qmfile ~= s,.ts$,.qm, + qmfile ~= s,".ts$",".qm", qm.commands += $$LRELEASE -removeidentical $$tsfile -qm $$qmfile $$escape_expand(\\n\\t) tmp_command = $$LRELEASE -removeidentical $$tsfile -qm $$qmfile $$escape_expand(\\n\\t) TRANSLATIONS_FILES += $$qmfile diff --git a/limereport/lrbanddesignintf.cpp b/limereport/lrbanddesignintf.cpp index 1619f58..caac574 100644 --- a/limereport/lrbanddesignintf.cpp +++ b/limereport/lrbanddesignintf.cpp @@ -39,7 +39,9 @@ namespace LimeReport { BandMarker::BandMarker(BandDesignIntf *band, QGraphicsItem* parent) :QGraphicsItem(parent),m_rect(0,0,30,30),m_band(band) -{} +{ + setAcceptHoverEvents(true); +} QRectF BandMarker::boundingRect() const { @@ -52,6 +54,13 @@ void BandMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem* /**opt painter->setOpacity(Const::BAND_MARKER_OPACITY); painter->fillRect(boundingRect(),m_color); painter->setOpacity(1); + painter->setPen(QPen(QBrush(Qt::lightGray),2)); + painter->fillRect(QRectF( + boundingRect().bottomLeft().x(), + boundingRect().bottomLeft().y()-4, + boundingRect().width(),4), Qt::lightGray + ); + painter->setRenderHint(QPainter::Antialiasing); qreal size = (boundingRect().width()setBrush(LimeReport::Const::SELECTION_COLOR); painter->drawEllipse(r.adjusted(7,7,-7,-7)); } + painter->restore(); } @@ -95,6 +105,7 @@ void BandMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) if (!(event->modifiers() & Qt::ControlModifier)) m_band->scene()->clearSelection(); m_band->setSelected(true); + m_oldBandPos = m_band->pos(); update(0,0,boundingRect().width(),boundingRect().width()); } } @@ -104,6 +115,31 @@ void BandMarker::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) m_band->contextMenuEvent(event); } +void BandMarker::hoverMoveEvent(QGraphicsSceneHoverEvent* event) +{ + if (QRectF(0, height()-10, width(), 10).contains(event->pos())){ + setCursor(Qt::SizeVerCursor); + } else { + unsetCursor(); + } +} + +void BandMarker::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +{ + qreal delta = event->pos().y() - event->lastPos().y(); + if (hasCursor()){ + m_band->setHeight(m_band->height() + delta); + } else { + if (!m_band->isFixedPos()) + m_band->setItemPos(QPointF(m_band->pos().x(),m_band->pos().y()+delta)); + } +} + +void BandMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) +{ + m_band->posChanged(m_band, m_band->pos(), m_oldBandPos); +} + BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, QObject* owner, QGraphicsItem *parent) : ItemsContainerDesignInft(xmlTypeName, owner,parent), m_bandType(bandType), @@ -111,6 +147,7 @@ BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, Q m_dataSourceName(""), m_autoHeight(true), m_keepBottomSpace(false), + m_keepTopSpace(true), m_parentBand(0), m_parentBandName(""), m_bandMarker(0), @@ -128,6 +165,7 @@ BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, Q m_startFromNewPage(false), m_printAlways(false), m_repeatOnEachRow(false), + m_useAlternateBackgroundColor(false), m_bottomSpace(0) { setPossibleResizeDirectionFlags(ResizeBottom); @@ -138,6 +176,8 @@ BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, Q if (parentItem) setWidth(parentItem->width()); } + setBackgroundMode(BGMode::TransparentMode); + setFillTransparentInDesignMode(false); setHeight(100); setFixedPos(true); setFlag(QGraphicsItem::ItemClipsChildrenToShape); @@ -302,6 +342,12 @@ bool BandDesignIntf::isUnique() const return true; } +void BandDesignIntf::setItemMode(BaseDesignIntf::ItemMode mode) +{ + ItemsContainerDesignInft::setItemMode(mode); + updateBandMarkerGeometry(); +} + QString BandDesignIntf::datasourceName(){ return m_dataSourceName; } @@ -557,10 +603,24 @@ void BandDesignIntf::processPopUpAction(QAction *action) if (action->text().compare(tr("Keep bottom space")) == 0){ setProperty("keepBottomSpace",action->isChecked()); } + if (action->text().compare(tr("Print if empty")) == 0){ setProperty("printIfEmpty",action->isChecked()); } + ItemsContainerDesignInft::processPopUpAction(action); +} +void BandDesignIntf::recalcItems(DataSourceManager* dataManager) +{ + foreach(BaseDesignIntf* bi, childBaseItems()){ + ContentItemDesignIntf* ci = dynamic_cast(bi); + if (bi){ + ContentItemDesignIntf* pci = dynamic_cast(bi->patternItem()); + ci->setContent(pci->content()); + } + } + + updateItemSize(dataManager,FirstPass,height()); } BaseDesignIntf* BandDesignIntf::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) @@ -602,7 +662,6 @@ BaseDesignIntf* BandDesignIntf::cloneUpperPart(int height, QObject *owner, QGrap } } upperPart->setHeight(height); - height = maxBottom; return upperPart; } @@ -725,14 +784,18 @@ BandDesignIntf* BandDesignIntf::findParentBand() return 0; } +void BandDesignIntf::updateBandMarkerGeometry() +{ + if (parentItem() && m_bandMarker){ + m_bandMarker->setPos(pos().x()-m_bandMarker->width(),pos().y()); + m_bandMarker->setHeight(rect().height()); + } +} + void BandDesignIntf::geometryChangedEvent(QRectF, QRectF ) { if (((itemMode()&DesignMode) || (itemMode()&EditMode))&&parentItem()){ - QPointF sp = parentItem()->mapToScene(pos()); - if (m_bandMarker){ - m_bandMarker->setPos((sp.x()-m_bandMarker->boundingRect().width()),sp.y()); - m_bandMarker->setHeight(rect().height()); - } + updateBandMarkerGeometry(); } foreach (BaseDesignIntf* item, childBaseItems()) { if (item->itemAlign()!=DesignedItemAlign){ @@ -795,6 +858,21 @@ void BandDesignIntf::childBandDeleted(QObject *band) m_childBands.removeAt(m_childBands.indexOf(reinterpret_cast(band))); } +bool BandDesignIntf::useAlternateBackgroundColor() const +{ + return m_useAlternateBackgroundColor; +} + +void BandDesignIntf::setUseAlternateBackgroundColor(bool useAlternateBackgroundColor) +{ + if (m_useAlternateBackgroundColor != useAlternateBackgroundColor){ + QColor oldValue = m_useAlternateBackgroundColor; + m_useAlternateBackgroundColor=useAlternateBackgroundColor; + if (!isLoading()) + notify("useAlternateBackgroundColor",oldValue,useAlternateBackgroundColor); + } +} + QColor BandDesignIntf::alternateBackgroundColor() const { if (metaObject()->indexOfProperty("alternateBackgroundColor")!=-1) @@ -805,7 +883,12 @@ QColor BandDesignIntf::alternateBackgroundColor() const void BandDesignIntf::setAlternateBackgroundColor(const QColor &alternateBackgroundColor) { - m_alternateBackgroundColor = alternateBackgroundColor; + if (m_alternateBackgroundColor != alternateBackgroundColor){ + QColor oldValue = m_alternateBackgroundColor; + m_alternateBackgroundColor=alternateBackgroundColor; + if (!isLoading()) + notify("alternateBackgroundColor",oldValue,alternateBackgroundColor); + } } qreal BandDesignIntf::bottomSpace() const @@ -820,6 +903,20 @@ void BandDesignIntf::slotPropertyObjectNameChanged(const QString &, const QStrin m_bandNameLabel->updateLabel(newName); } +bool BandDesignIntf::keepTopSpace() const +{ + return m_keepTopSpace; +} + +void BandDesignIntf::setKeepTopSpace(bool value) +{ + if (m_keepTopSpace != value){ + m_keepTopSpace = value; + if (!isLoading()) + notify("keepTopSpace",!value,value); + } +} + int BandDesignIntf::bootomSpace() const { return m_bottomSpace; @@ -991,12 +1088,11 @@ void BandDesignIntf::setKeepFooterTogether(bool value) } } - void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) { qreal spaceBorder=0; if (keepBottomSpaceOption()) spaceBorder = bottomSpace(); - spaceBorder = spaceBorder>0 ? spaceBorder : 0; + spaceBorder = spaceBorder > 0 ? spaceBorder : 0; if (borderLines()!=0){ spaceBorder += borderLineSize(); } @@ -1004,9 +1100,16 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p spaceBorder += m_bottomSpace; restoreLinks(); snapshotItemsLayout(); - arrangeSubItems(pass, dataManager); + BandDesignIntf* patternBand = dynamic_cast(patternItem()); + if (patternBand && pass == FirstPass) emit(patternBand->preparedForRender()); + arrangeSubItems(pass, dataManager); if (autoHeight()){ - //if keepBottomSpace()&& height()setY(item->y() - minTop); + } + } setHeight(findMaxBottom()+spaceBorder); } if ((maxHeight>0)&&(height()>maxHeight)){ @@ -1016,6 +1119,17 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); } +void BandDesignIntf::restoreItems() +{ + foreach(BaseDesignIntf* bi, childBaseItems()){ + ContentItemDesignIntf* ci = dynamic_cast(bi); + if (ci){ + ContentItemDesignIntf* pci = dynamic_cast(bi->patternItem()); + ci->setContent(pci->content()); + } + } +} + void BandDesignIntf::updateBandNameLabel() { if (m_bandNameLabel) m_bandNameLabel->updateLabel(bandTitle()); diff --git a/limereport/lrbanddesignintf.h b/limereport/lrbanddesignintf.h index 68dd3dd..a6e09be 100644 --- a/limereport/lrbanddesignintf.h +++ b/limereport/lrbanddesignintf.h @@ -62,12 +62,17 @@ public: qreal width(){return m_rect.width();} qreal height(){return m_rect.height();} protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event); void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); + + void hoverMoveEvent(QGraphicsSceneHoverEvent* event); + void mouseMoveEvent(QGraphicsSceneMouseEvent* event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: QRectF m_rect; QColor m_color; BandDesignIntf* m_band; + QPointF m_oldBandPos; }; class BandNameLabel : public QGraphicsItem{ @@ -101,6 +106,7 @@ class BandDesignIntf : public ItemsContainerDesignInft Q_PROPERTY(bool autoHeight READ autoHeight WRITE setAutoHeight ) Q_PROPERTY(int bandIndex READ bandIndex WRITE setBandIndex DESIGNABLE false ) Q_PROPERTY(bool keepBottomSpace READ keepBottomSpaceOption WRITE setKeepBottomSpaceOption ) + Q_PROPERTY(bool keepTopSpace READ keepTopSpace WRITE setKeepTopSpace) Q_PROPERTY(QString parentBand READ parentBandName WRITE setParentBandName DESIGNABLE false ) Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) Q_PROPERTY(BrushStyle backgroundBrushStyle READ backgroundBrushStyle WRITE setBackgroundBrushStyle) @@ -141,7 +147,10 @@ public: virtual QString bandTitle() const; virtual QIcon bandIcon() const; virtual bool isUnique() const; + void setItemMode(BaseDesignIntf::ItemMode mode); void updateItemSize(DataSourceManager *dataManager, RenderPass pass=FirstPass, int maxHeight=0); + void restoreItems(); + void recalcItems(DataSourceManager* dataManager); void updateBandNameLabel(); virtual QColor selectionColor() const; @@ -156,6 +165,9 @@ public: void setKeepBottomSpaceOption(bool value); bool keepBottomSpaceOption() const {return m_keepBottomSpace;} + bool keepTopSpace() const; + void setKeepTopSpace(bool value); + void addChildBand(BandDesignIntf* band); bool hasChildren(){return !m_childBands.isEmpty();} void removeChildBand(BandDesignIntf* band); @@ -232,20 +244,27 @@ public: bool startFromNewPage() const; void setStartFromNewPage(bool startFromNewPage); - bool canContainChildren(){ return true;} + bool canContainChildren() const{ return true;} bool printAlways() const; void setPrintAlways(bool printAlways); bool repeatOnEachRow() const; void setRepeatOnEachRow(bool repeatOnEachRow); QColor alternateBackgroundColor() const; void setAlternateBackgroundColor(const QColor &alternateBackgroundColor); + bool useAlternateBackgroundColor() const; + void setUseAlternateBackgroundColor(bool useAlternateBackgroundColor); + void replaceGroupsFunction(BandDesignIntf *band); qreal bottomSpace() const; void setBackgroundModeProperty(BGMode value); void setBackgroundOpacity(int value); int bootomSpace() const; void setBootomSpace(int bootomSpace); + void updateBandMarkerGeometry(); + signals: void bandRendered(BandDesignIntf* band); + void preparedForRender(); + void bandRegistred(); protected: void trimToMaxHeight(int maxHeight); void setBandTypeText(const QString& value); @@ -267,6 +286,7 @@ protected: void preparePopUpMenu(QMenu &menu); void processPopUpAction(QAction *action); QString translateBandName(const BaseDesignIntf *item) const; + private slots: void childBandDeleted(QObject* band); void slotPropertyObjectNameChanged(const QString&,const QString&); @@ -277,6 +297,7 @@ private: QString m_dataSourceName; bool m_autoHeight; bool m_keepBottomSpace; + bool m_keepTopSpace; BandDesignIntf* m_parentBand; QString m_parentBandName; QList m_childBands; @@ -299,7 +320,9 @@ private: bool m_repeatOnEachRow; QMap m_slicedItems; QColor m_alternateBackgroundColor; - int m_bottomSpace; + bool m_useAlternateBackgroundColor; + int m_bottomSpace; + QMap m_bookmarks; }; class DataBandDesignIntf : public BandDesignIntf{ diff --git a/limereport/lrbasedesignintf.cpp b/limereport/lrbasedesignintf.cpp index 170102c..d76f341 100644 --- a/limereport/lrbasedesignintf.cpp +++ b/limereport/lrbasedesignintf.cpp @@ -52,7 +52,7 @@ namespace LimeReport BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, QGraphicsItem *parent) : QObject(owner), QGraphicsItem(parent), - m_resizeHandleSize(Const::RESIZE_HANDLE_SIZE), + m_resizeHandleSize(Const::RESIZE_HANDLE_SIZE*2), m_selectionPenSize(Const::SELECTION_PEN_SIZE), m_possibleResizeDirectionFlags(ResizeTop | ResizeBottom | ResizeLeft | ResizeRight), m_possibleMoveDirectionFlags(All), @@ -60,7 +60,6 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q m_width(200), m_height(50), m_fontColor(Qt::black), - m_mmFactor(Const::mmFACTOR), m_fixedPos(false), m_borderLineSize(1), m_BGMode(OpaqueMode), @@ -69,8 +68,6 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q m_storageTypeName(storageTypeName), m_itemMode(DesignMode), m_objectState(ObjectCreated), - m_selectionMarker(0), - m_joinMarker(0), m_backgroundBrushStyle(SolidPattern), m_backgroundColor(Qt::white), m_margin(4), @@ -79,7 +76,15 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q m_borderColor(Qt::black), m_reportSettings(0), m_patternName(""), - m_watermark(false) + m_patternItem(0), + m_fillInSecondPass(false), + m_watermark(false), + m_hovered(false), + m_joinMarkerOn(false), + m_selectionMarker(0), + m_fillTransparentInDesignMode(true), + m_unitType(Millimeters), + m_itemGeometryLocked(false) { setGeometry(QRectF(0, 0, m_width, m_height)); if (BaseDesignIntf *item = dynamic_cast(parent)) { @@ -92,18 +97,11 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q QRectF BaseDesignIntf::boundingRect() const { - if (m_boundingRect.isNull()) { - qreal halfpw = pen().widthF() / 2; - halfpw += 2; - m_boundingRect = rect(); - m_boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw); - }; - return m_boundingRect; + return rect(); } BaseDesignIntf::~BaseDesignIntf(void) { - delete m_selectionMarker; - delete m_joinMarker; + } void BaseDesignIntf::setParentReportItem(const QString &value) @@ -162,8 +160,10 @@ QFont BaseDesignIntf::font() const void BaseDesignIntf::setFont(QFont &font) { - m_font = font; - update(); + if (m_font != font){ + m_font = font; + if (!isLoading()) update(); + } } qreal BaseDesignIntf::width() const @@ -180,7 +180,7 @@ void BaseDesignIntf::setWidth(qreal width) QString BaseDesignIntf::setItemWidth(qreal width) { - setWidth(width * mmFactor()); + setWidth(width * unitFactor()); return QString(); } @@ -189,9 +189,9 @@ qreal BaseDesignIntf::height() const return rect().height(); } -QRectF BaseDesignIntf::geometry() const +QRect BaseDesignIntf::geometry() const { - return QRectF(pos().x(), pos().y(), width(), height()); + return QRect(pos().x(), pos().y(), width(), height()); } void BaseDesignIntf::setHeight(qreal height) @@ -201,39 +201,49 @@ void BaseDesignIntf::setHeight(qreal height) QString BaseDesignIntf::setItemHeight(qreal height) { - setHeight(height * mmFactor()); + setHeight(height * unitFactor()); return QString(); } qreal BaseDesignIntf::getItemWidth() { - return width() / mmFactor(); + return width() / unitFactor(); } qreal BaseDesignIntf::getItemHeight() { - return height() / mmFactor(); + return height() / unitFactor(); } qreal BaseDesignIntf::getItemPosX() { - return x() / mmFactor(); + return x() / unitFactor(); } qreal BaseDesignIntf::getItemPosY() { - return y() / mmFactor(); + return y() / unitFactor(); +} + +qreal BaseDesignIntf::getAbsolutePosX() +{ + return calcAbsolutePosX(0,this); +} + +qreal BaseDesignIntf::getAbsolutePosY() +{ + return calcAbsolutePosY(0,this); } QString BaseDesignIntf::setItemPosX(qreal xValue) { - setItemPos(xValue * mmFactor(),y()); + setItemPos(xValue * unitFactor(),y()); return QString(); } QString BaseDesignIntf::setItemPosY(qreal yValue) { - setItemPos(x(),yValue * mmFactor()); + setItemPos(x(),yValue * unitFactor()); return QString(); } @@ -322,32 +332,46 @@ QSizeF BaseDesignIntf::size() const QSizeF BaseDesignIntf::sizeMM() const { - return QSizeF(width() / m_mmFactor, height() / m_mmFactor); + return QSizeF(width() / Const::mmFACTOR, height() / Const::mmFACTOR); } qreal BaseDesignIntf::widthMM() const { - return width() / m_mmFactor; + return width() / Const::mmFACTOR; } qreal BaseDesignIntf::heightMM() const { - return height() / m_mmFactor; + return height() / Const::mmFACTOR; } -void BaseDesignIntf::setMMFactor(qreal mmFactor) +//void BaseDesignIntf::setUnitFactor(qreal unitFactor) +//{ +// m_unitFactor = unitFactor; +//} + +qreal BaseDesignIntf::unitFactor() const { - m_mmFactor = mmFactor; + if (m_unitType == Millimeters) + return Const::mmFACTOR; + else return Const::mmFACTOR * 2.54; } -qreal BaseDesignIntf::mmFactor() const +void BaseDesignIntf::setUnitType(BaseDesignIntf::UnitType value) { - return m_mmFactor; + foreach(BaseDesignIntf* child, childBaseItems()) + child->setUnitType(value); + m_unitType = value; +} + +BaseDesignIntf::UnitType BaseDesignIntf::unitType() +{ + return m_unitType; } QPointF BaseDesignIntf::posMM() const { - return QPointF(pos().x() / m_mmFactor, pos().y() / m_mmFactor); + return QPointF(pos().x() / Const::mmFACTOR, pos().y() / Const::mmFACTOR); } QRectF BaseDesignIntf::rect() const @@ -364,11 +388,9 @@ void BaseDesignIntf::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_resizeDirectionFlags = resizeDirectionFlags(event->pos()); - //m_startScenePos = event->scenePos(); m_startPos = pos(); m_oldGeometry = geometry(); QGraphicsItem::mousePressEvent(event); - //QApplication::processEvents(); emit(itemSelected(this)); } else QGraphicsItem::mousePressEvent(event); @@ -378,10 +400,16 @@ void BaseDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *o { Q_UNUSED(option); Q_UNUSED(widget); + ppainter->save(); setupPainter(ppainter); drawBorder(ppainter, rect()); - if (isSelected()) {drawSelection(ppainter, rect());} +// if (m_joinMarkerOn) { drawMarker(ppainter, Const::JOIN_COLOR);} +// if (isSelected() && !m_joinMarkerOn) {drawMarker(ppainter, Const::SELECTION_COLOR);} drawResizeZone(ppainter); + ppainter->restore(); +// if (m_hovered) ppainter->drawImage( +// QRectF(QPointF(rect().topRight().x()-24, rect().bottomLeft().y()-24), +// QSizeF(24, 24)),QImage(":/items/images/settings.png")); } QColor calcColor(QColor color){ @@ -412,7 +440,7 @@ void BaseDesignIntf::prepareRect(QPainter *painter, const QStyleOptionGraphicsIt qreal o = (itemMode() & DesignMode) ? 0.5 : qreal(m_opacity) / 100; painter->setOpacity(o); painter->fillRect(r, brush); - } else if (itemMode() & DesignMode){ + } else if ((itemMode() & DesignMode) && fillTransparentInDesignMode()){ painter->setOpacity(0.1); painter->fillRect(r, QBrush(QPixmap(":/report/images/empty"))); } @@ -468,6 +496,14 @@ void BaseDesignIntf::hoverLeaveEvent(QGraphicsSceneHoverEvent *) m_resizeDirectionFlags = 0; scene()->update(sceneBoundingRect()); m_resizeAreas.clear(); + m_hovered = false; + update(); +} + +void BaseDesignIntf::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + m_hovered = true; + update(); } @@ -549,6 +585,7 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) moveSelectedItems(tmpPos - pos()); if (page()->selectedItems().count()==1 && (page()->magneticMovement())) page()->itemMoved(this); + } } } @@ -624,8 +661,8 @@ QPointF BaseDesignIntf::modifyPosForAlignedItem(const QPointF& pos){ BaseDesignIntf* parent = dynamic_cast(parentItem()); PageItemDesignIntf* parentPage = dynamic_cast(parentItem()); if (parent){ - qreal leftBorder = parentPage?parentPage->leftMargin()*mmFactor():0; - qreal rightBorder = parentPage?parentPage->rightMargin()*mmFactor():0; + qreal leftBorder = parentPage ? parentPage->leftMargin() * Const::mmFACTOR : 0; + qreal rightBorder = parentPage ? parentPage->rightMargin() * Const::mmFACTOR : 0; qreal avaibleSpace = parent->width()-(leftBorder+rightBorder); switch(m_itemAlign){ @@ -649,8 +686,9 @@ QPointF BaseDesignIntf::modifyPosForAlignedItem(const QPointF& pos){ void BaseDesignIntf::turnOnJoinMarker(bool value) { + m_joinMarkerOn = value; if (value){ - m_joinMarker = new Marker(this); + m_joinMarker = new Marker(this, this); m_joinMarker->setColor(Const::JOIN_COLOR); m_joinMarker->setRect(rect()); m_joinMarker->setVisible(true); @@ -665,10 +703,9 @@ void BaseDesignIntf::updateItemAlign(){ PageItemDesignIntf* parentPage = dynamic_cast(parentItem()); m_changingItemAlign = true; if (parent){ - qreal leftBorder = parentPage?parentPage->leftMargin()*mmFactor():0; - qreal rightBorder = parentPage?parentPage->rightMargin()*mmFactor():0; + qreal leftBorder = parentPage ? parentPage->leftMargin() * Const::mmFACTOR : 0; + qreal rightBorder = parentPage ? parentPage->rightMargin() * Const::mmFACTOR : 0; qreal aviableSpace = parent->width()-(leftBorder+rightBorder); - setPos(modifyPosForAlignedItem(pos())); if (m_itemAlign == ParentWidthItemAlign) setWidth(aviableSpace); @@ -693,19 +730,65 @@ void BaseDesignIntf::updatePossibleDirectionFlags(){ } } -void BaseDesignIntf::turnOnSelectionMarker(bool value) +bool BaseDesignIntf::isGeometryLocked() const { - if (value && !m_selectionMarker){ - m_selectionMarker = new SelectionMarker(this); - m_selectionMarker->setColor(selectionMarkerColor()); - updateSelectionMarker(); - m_selectionMarker->setVisible(true); - } else { - delete m_selectionMarker; - m_selectionMarker = 0; + return m_itemGeometryLocked; +} + +void BaseDesignIntf::setGeometryLocked(bool itemLocked) +{ + if (m_itemGeometryLocked != itemLocked){ + m_itemGeometryLocked = itemLocked; + if (itemLocked){ + m_savedPossibleMoveDirectionFlags = m_possibleMoveDirectionFlags; + m_savedPossibleResizeDirectionFlags = m_possibleResizeDirectionFlags; + m_possibleMoveDirectionFlags = None; + m_possibleResizeDirectionFlags = Fixed; + m_savedFixedPos = m_fixedPos; + m_fixedPos = true; + } else { + m_possibleMoveDirectionFlags = m_savedPossibleMoveDirectionFlags; + m_possibleResizeDirectionFlags = m_savedPossibleResizeDirectionFlags; + m_fixedPos = m_savedFixedPos; + } + if (!isLoading()){ + update(); + m_selectionMarker->update(); + notify("geometryLocked", !itemLocked, itemLocked); + } } } +bool BaseDesignIntf::fillTransparentInDesignMode() const +{ + return m_fillTransparentInDesignMode; +} + +void BaseDesignIntf::setFillTransparentInDesignMode(bool fillTransparentInDesignMode) +{ + m_fillTransparentInDesignMode = fillTransparentInDesignMode; +} + +void BaseDesignIntf::emitPosChanged(QPointF oldPos, QPointF newPos) +{ + emit posChanged(this, oldPos, newPos); +} + +bool BaseDesignIntf::fillInSecondPass() const +{ + return m_fillInSecondPass; +} + +void BaseDesignIntf::setFillInSecondPass(bool fillInSecondPass) +{ + + if (m_fillInSecondPass != fillInSecondPass){ + m_fillInSecondPass = fillInSecondPass; + notify("fillInSecondPass",!fillInSecondPass,fillInSecondPass); + } + +} + bool BaseDesignIntf::isWatermark() const { return m_watermark; @@ -719,6 +802,30 @@ void BaseDesignIntf::setWatermark(bool watermark) } } +void BaseDesignIntf::updateSelectionMarker() +{ + if (m_selectionMarker && (itemMode() & DesignMode || itemMode() & EditMode)) { + if ((!m_selectionMarker->scene()) && scene()) scene()->addItem(m_selectionMarker); + if (parentItem()) { + m_selectionMarker->setRect(rect()); + m_selectionMarker->setPos(0,0); + } + } +} + +void BaseDesignIntf::turnOnSelectionMarker(bool value) +{ + if (value && !m_selectionMarker){ + m_selectionMarker = new SelectionMarker(this, this); + m_selectionMarker->setColor(selectionMarkerColor()); + updateSelectionMarker(); + m_selectionMarker->setVisible(true); + } else { + delete m_selectionMarker; + m_selectionMarker = 0; + } +} + QString BaseDesignIntf::patternName() const { return (m_patternName.isEmpty()) ? objectName() : m_patternName; @@ -729,6 +836,16 @@ void BaseDesignIntf::setPatternName(const QString &patternName) m_patternName = patternName; } +BaseDesignIntf* BaseDesignIntf::patternItem() const +{ + return m_patternItem; +} + +void BaseDesignIntf::setPatternItem(BaseDesignIntf *patternItem) +{ + m_patternItem = patternItem; +} + ReportSettings *BaseDesignIntf::reportSettings() const { return m_reportSettings; @@ -956,9 +1073,9 @@ void BaseDesignIntf::beforeDelete() } -void BaseDesignIntf::setGeometryProperty(QRectF rect) +void BaseDesignIntf::setGeometryProperty(QRect rect) { - if (rect!=geometry()){ + if ( rect != m_itemGeometry ){ QRectF oldValue = geometry(); if ((rect.x() != geometry().x()) || (rect.y() != geometry().y())) setPos(rect.x(), rect.y()); @@ -1023,8 +1140,10 @@ void BaseDesignIntf::initMode(ItemMode mode) QVariant BaseDesignIntf::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { + if (change == QGraphicsItem::ItemPositionHasChanged) { updateSelectionMarker(); + emit geometryChanged(this, geometry(), geometry()); } if (change == QGraphicsItem::ItemSelectedChange) { @@ -1068,20 +1187,32 @@ QPainterPath BaseDesignIntf::shape() const return path; } -void BaseDesignIntf::drawSelection(QPainter *painter, QRectF /*rect*/) const +void BaseDesignIntf::drawMarker(QPainter *painter, QColor color) const { painter->save(); - // painter->setPen(QPen(Qt::red,m_selectionPenSize)); - // painter->drawLine(QPointF(m_resizeHandleSize,0),QPointF(0,0)); - // painter->drawLine(QPointF(0,m_resizeHandleSize),QPointF(0,0)); - // painter->drawLine(rect.right()-m_resizeHandleSize,0,rect.right(),0); - // painter->drawLine(rect.right(),m_resizeHandleSize,rect.right(),0); - // painter->drawLine(0,rect.bottom(),0,rect.bottom()-10); - // painter->drawLine(0,rect.bottom(),m_resizeHandleSize,rect.bottom()); - // painter->drawLine(rect.right()-m_resizeHandleSize,rect.bottom(),rect.right(),rect.bottom()); - // painter->drawLine(rect.right(),rect.bottom()-m_resizeHandleSize,rect.right(),rect.bottom()); - // painter->setOpacity(Consts::SELECTION_COLOR_OPACITY); - // painter->fillRect(rect,selectionColor()); + + QPen pen(color, m_selectionPenSize); + painter->setPen(pen); + painter->setBrush(QBrush(color)); + painter->setOpacity(1); + const int markerSize = Const::RESIZE_HANDLE_SIZE; + painter->drawRect(QRectF(-markerSize,-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().right()-markerSize,rect().bottom()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().right()-markerSize,rect().top()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().left()-markerSize,rect().bottom()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().left()-markerSize, + rect().bottom()-rect().height()/2-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().right()-markerSize, + rect().bottom()-rect().height()/2-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().left()+rect().width()/2-markerSize, + rect().top()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(rect().left()+rect().width()/2-markerSize, + rect().bottom()-markerSize,markerSize*2,markerSize*2)); + + pen.setStyle(Qt::DotLine); + painter->setPen(pen); + painter->setBrush(QBrush(Qt::transparent)); + painter->drawRect(rect()); painter->restore(); } @@ -1129,15 +1260,22 @@ void BaseDesignIntf::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QRectF newGeometry = geometry(); if (newGeometry != m_oldGeometry) { geometryChangedEvent(newGeometry, m_oldGeometry); - updateSelectionMarker(); - emit(posChanged(this, newGeometry.topLeft(), m_oldGeometry.topLeft())); + emit posChanged(this, newGeometry.topLeft(), m_oldGeometry.topLeft()); } QGraphicsItem::mouseReleaseEvent(event); } +QWidget* findRootWidget(QWidget* widget){ + while (widget->parentWidget()) { + widget = widget->parentWidget(); + } + return widget; +} + void BaseDesignIntf::showEditorDialog(){ - QWidget *editor = defaultEditor(); + QWidget *editor = defaultEditor(); if (editor) { + editor->setStyleSheet(findRootWidget(scene()->views().at(0))->styleSheet()); QDialog* dialog = new QDialog(QApplication::activeWindow()); dialog->setAttribute(Qt::WA_DeleteOnClose); #ifdef Q_OS_MAC @@ -1150,6 +1288,7 @@ void BaseDesignIntf::showEditorDialog(){ dialog->layout()->setContentsMargins(2,2,2,2); dialog->layout()->addWidget(editor); connect(editor,SIGNAL(destroyed()),dialog,SLOT(close())); + dialog->setWindowTitle(editor->windowTitle()); dialog->exec(); } } @@ -1172,25 +1311,41 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) page->clearSelection(); this->setSelected(true); } - QMenu menu; - QAction* copyAction = menu.addAction(QIcon(":/report/images/copy.png"), tr("Copy")); + QMenu menu(event->widget()); + + QAction* lockGeometryAction = menu.addAction(tr("Lock item geometry")); + lockGeometryAction->setCheckable(true); + lockGeometryAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); + lockGeometryAction->setChecked(isGeometryLocked()); + menu.addSeparator(); + + QAction* copyAction = menu.addAction(QIcon(":/report/images/copy"), tr("Copy")); copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C)); - QAction* cutAction = menu.addAction(QIcon(":/report//images/cut"), tr("Cut")); + QAction* cutAction = menu.addAction(QIcon(":/report/images/cut"), tr("Cut")); cutAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X)); - QAction* pasteAction = menu.addAction(QIcon(":/report/images/paste.png"), tr("Paste")); + QAction* pasteAction = menu.addAction(QIcon(":/report/images/paste"), tr("Paste")); pasteAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V)); pasteAction->setEnabled(false); + QClipboard *clipboard = QApplication::clipboard(); ItemsReaderIntf::Ptr reader = StringXMLreader::create(clipboard->text()); if (reader->first() && reader->itemType() == "Object"){ pasteAction->setEnabled(true); } menu.addSeparator(); - QAction* brinToTopAction = menu.addAction(QIcon(":/report//images/bringToTop"), tr("Bring to top")); - QAction* sendToBackAction = menu.addAction(QIcon(":/report//images/sendToBack"), tr("Send to back")); + QAction* bringToTopAction = menu.addAction(QIcon(":/report/images/bringToTop"), tr("Bring to top")); + QAction* sendToBackAction = menu.addAction(QIcon(":/report/images/sendToBack"), tr("Send to back")); + QAction* createHLayout = 0; + if( page->selectedItems().count()>1){ + createHLayout = menu.addAction(QIcon(":/report/images/hlayout"), tr("Create Horizontal Layout")); + } + QAction* createVLayout = 0; + if( page->selectedItems().count()>1){ + createVLayout = menu.addAction(QIcon(":/report/images/vlayout"), tr("Create Vertical Layout")); + } menu.addSeparator(); - QAction* noBordersAction = menu.addAction(QIcon(":/report//images/noLines"), tr("No borders")); - QAction* allBordersAction = menu.addAction(QIcon(":/report//images/allLines"), tr("All borders")); + QAction* noBordersAction = menu.addAction(QIcon(":/report/images/noLines"), tr("No borders")); + QAction* allBordersAction = menu.addAction(QIcon(":/report/images/allLines"), tr("All borders")); preparePopUpMenu(menu); QAction* a = menu.exec(event->screenPos()); if (a){ @@ -1203,7 +1358,7 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) page->copy(); if (a == pasteAction) page->paste(); - if (a == brinToTopAction) + if (a == bringToTopAction) page->bringToFront(); if (a == sendToBackAction) page->sendToBack(); @@ -1211,6 +1366,10 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) page->setBorders(BaseDesignIntf::NoLine); if (a == allBordersAction) page->setBorders(BaseDesignIntf::AllLines); + if (a == createHLayout) + page->addHLayout(); + if (a == createVLayout) + page->addVLayout(); processPopUpAction(a); } } @@ -1237,17 +1396,6 @@ void BaseDesignIntf::setMarginSize(int value) } } -void BaseDesignIntf::updateSelectionMarker() -{ - if (m_selectionMarker && (itemMode() & DesignMode || itemMode() & EditMode)) { - if ((!m_selectionMarker->scene()) && scene()) scene()->addItem(m_selectionMarker); - if (parentItem()) { - m_selectionMarker->setRect(rect()); - m_selectionMarker->setPos(0,0); - } - } -} - void BaseDesignIntf::drawResizeZone(QPainter* /*painter*/) { @@ -1310,7 +1458,7 @@ QObject *BaseDesignIntf::createElement(const QString& /*collectionName*/, const connect(obj, SIGNAL(propertyChanged(QString,QVariant,QVariant)), page(), SLOT(slotItemPropertyChanged(QString,QVariant,QVariant))); } - } catch (ReportError error){ + } catch (ReportError &error){ qDebug()<setPatternName(this->objectName()); + clone->setPatternItem(this); #ifdef HAVE_QT5 foreach(QObject * child, children()) { #else @@ -1428,6 +1577,39 @@ QList BaseDesignIntf::childBaseItems() return resList; } + +void BaseDesignIntf::addChildItems(QList* list){ + foreach(BaseDesignIntf* item, childBaseItems()){ + list->append(item); + item->addChildItems(list); + } +} + +qreal BaseDesignIntf::calcAbsolutePosY(qreal currentOffset, BaseDesignIntf *item) +{ + BaseDesignIntf* parent = dynamic_cast(item->parent()); + if (parent) + return calcAbsolutePosY(currentOffset + item->getItemPosY(), parent); + else + return currentOffset + item->getItemPosY(); +} + +qreal BaseDesignIntf::calcAbsolutePosX(qreal currentOffset, BaseDesignIntf *item) +{ + BaseDesignIntf* parent = dynamic_cast(item->parent()); + if (parent) + return calcAbsolutePosX(currentOffset + item->getItemPosX(), parent); + else + return currentOffset + item->getItemPosX(); +} + +QList BaseDesignIntf::allChildBaseItems() +{ + QList resList; + addChildItems(&resList); + return resList; +} + BaseDesignIntf *BaseDesignIntf::childByName(const QString &name) { foreach(BaseDesignIntf* item, childBaseItems()){ @@ -1458,43 +1640,23 @@ void BaseDesignIntf::notify(const QVector& propertyNames) emit propertyesChanged(propertyNames); } -SelectionMarker::SelectionMarker(QGraphicsItem *parent)//, QGraphicsScene *scene) - : Marker(parent) -{ - setAcceptHoverEvents(true); + +QMap BaseDesignIntf::getStringForTranslation(){ + return QMap(); } -void SelectionMarker::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +QVariant BookmarkContainerDesignIntf::getBookMark(const QString& key) { - BaseDesignIntf* baseItem = dynamic_cast(parentItem()); - if(baseItem) baseItem->hoverMoveEvent(event); + if (m_bookmarks.contains(key)) + return m_bookmarks.value(key); + else return QVariant(); } -void SelectionMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +void BookmarkContainerDesignIntf::copyBookmarks(BookmarkContainerDesignIntf* source) { - parentItem()->setSelected(true); - BaseDesignIntf* baseItem = dynamic_cast(parentItem()); - if(baseItem) baseItem->mousePressEvent(event); - QGraphicsItem::mousePressEvent(event); -} - -void SelectionMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - BaseDesignIntf* baseItem = dynamic_cast(parentItem()); - if(baseItem) baseItem->mouseReleaseEvent(event); -} - -void SelectionMarker::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) -{ - BaseDesignIntf* baseItem = dynamic_cast(parentItem()); - if(baseItem) baseItem->mouseDoubleClickEvent(event); - QGraphicsItem::mouseDoubleClickEvent(event); -} - -void SelectionMarker::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - BaseDesignIntf* baseItem = dynamic_cast(parentItem()); - if(baseItem) baseItem->mouseMoveEvent(event); + foreach(QString key, source->bookmarks()){ + addBookmark(key,source->getBookMark(key)); + } } QRectF Marker::boundingRect() const @@ -1502,7 +1664,7 @@ QRectF Marker::boundingRect() const return m_rect.adjusted(-15,-15,15,15); } -void Marker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +void Marker::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) { QPen pen; const int markerSize = 5; @@ -1526,29 +1688,62 @@ void Marker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget painter->drawRect(QRectF(rect().left()+rect().width()/2-markerSize, rect().top()-markerSize,markerSize*2,markerSize*2)); painter->drawRect(QRectF(rect().left()+rect().width()/2-markerSize, - rect().bottom()-markerSize,markerSize*2,markerSize*2)); + rect().bottom()-markerSize,markerSize*2,markerSize*2)); } -QRectF Marker::rect() const -{ - return m_rect; -} - -QColor Marker::color() const -{ +QColor Marker::color() const { return m_color; } -BaseDesignIntf *Marker::object() const +SelectionMarker::SelectionMarker(QGraphicsItem* parent, BaseDesignIntf* owner) + : Marker(parent, owner) { - return m_object; + setAcceptHoverEvents(true); +} + +QColor SelectionMarker::color() const +{ + return owner()->isGeometryLocked() ? Qt::darkGray : Marker::color(); +} + +void SelectionMarker::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + if (owner()) owner()->hoverMoveEvent(event); + QGraphicsItem::hoverMoveEvent(event); +} + +void SelectionMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (owner()){ + owner()->setSelected(true); + owner()->mousePressEvent(event); + } + QGraphicsItem::mousePressEvent(event); +} + +void SelectionMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (owner()) owner()->mouseReleaseEvent(event); +} + +void SelectionMarker::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + if (owner()) owner()->mouseDoubleClickEvent(event); + QGraphicsItem::mouseDoubleClickEvent(event); +} + +void SelectionMarker::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + qDebug() << "mouse move"; + if (owner()) owner()->mouseMoveEvent(event); +} + +void BaseDesignIntf::processPopUpAction(QAction *action){ + if (page()){ + if (action->text().compare(tr("Lock item geometry")) == 0){ + page()->setPropertyToSelectedItems("geometryLocked",action->isChecked()); + } + } } } //namespace LimeReport - - - - - - - diff --git a/limereport/lrbasedesignintf.h b/limereport/lrbasedesignintf.h index cff06ca..462791f 100644 --- a/limereport/lrbasedesignintf.h +++ b/limereport/lrbasedesignintf.h @@ -51,23 +51,24 @@ class BaseDesignIntf; class Marker : public QGraphicsItem{ public: - Marker(QGraphicsItem* parent=0):QGraphicsItem(parent),m_object(NULL){} + Marker(QGraphicsItem* parent = 0, BaseDesignIntf* owner = 0): QGraphicsItem(parent), m_owner(owner){} QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); void setRect(QRectF rect){prepareGeometryChange();m_rect=rect;} void setColor(QColor color){m_color=color;} - QRectF rect() const; - QColor color() const; - BaseDesignIntf *object() const; + QRectF rect() const {return m_rect;} + virtual QColor color() const; + BaseDesignIntf* owner() const {return m_owner;} private: QRectF m_rect; QColor m_color; - BaseDesignIntf* m_object; + BaseDesignIntf* m_owner; }; class SelectionMarker : public Marker{ public: - SelectionMarker(QGraphicsItem* parent=0); + SelectionMarker(QGraphicsItem* parent=0, BaseDesignIntf* owner = 0); + QColor color() const; protected: void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event); @@ -88,7 +89,8 @@ class BaseDesignIntf : Q_ENUMS(BrushStyle) Q_ENUMS(ItemAlign) Q_FLAGS(BorderLines) - Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometryProperty NOTIFY geometryChanged) + Q_ENUMS(UnitType) + Q_PROPERTY(QRect geometry READ geometry WRITE setGeometryProperty NOTIFY geometryChanged) Q_PROPERTY(ACollectionProperty children READ fakeCollectionReader DESIGNABLE false) Q_PROPERTY(qreal zOrder READ zValue WRITE setZValueProperty DESIGNABLE false) Q_PROPERTY(BorderLines borders READ borderLines WRITE setBorderLinesFlags) @@ -96,6 +98,8 @@ class BaseDesignIntf : Q_PROPERTY(int borderLineSize READ borderLineSize WRITE setBorderLineSize) Q_PROPERTY(bool isVisible READ isVisible WRITE setItemVisible DESIGNABLE false) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) + Q_PROPERTY(bool geometryLocked READ isGeometryLocked WRITE setGeometryLocked) + friend class ReportRender; public: enum BGMode { TransparentMode, OpaqueMode}; @@ -122,7 +126,8 @@ public: ResizeBottom = 8, AllDirections = 15 }; - enum MoveFlags { LeftRight=1, + enum MoveFlags { None = 0, + LeftRight=1, TopBotom=2, All=3 }; @@ -136,6 +141,7 @@ public: }; enum ObjectState {ObjectLoading, ObjectLoaded, ObjectCreated}; enum ItemAlign {LeftItemAlign,RightItemAlign,CenterItemAlign,ParentWidthItemAlign,DesignedItemAlign}; + enum UnitType {Millimeters, Inches}; // enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols}; Q_DECLARE_FLAGS(BorderLines, BorderSide) Q_DECLARE_FLAGS(ItemMode,ItemModes) @@ -179,14 +185,16 @@ public: virtual QPainterPath shape() const; void setFixedPos(bool fixedPos); + bool isFixedPos(){return m_fixedPos;} int resizeHandleSize() const; - void setMMFactor(qreal mmFactor); - qreal mmFactor() const; - virtual QRectF geometry() const; + qreal unitFactor() const; + void setUnitType(UnitType unitType); + UnitType unitType(); + virtual QRect geometry() const; void setGeometry(QRectF rect); - QRectF rect()const; + QRectF rect() const; void setupPainter(QPainter* painter) const; virtual QRectF boundingRect() const; @@ -207,7 +215,7 @@ public: ItemMode itemMode() const {return m_itemMode;} virtual void setBorderLinesFlags(LimeReport::BaseDesignIntf::BorderLines flags); - void setGeometryProperty(QRectF rect); + void setGeometryProperty(QRect rect); PageDesignIntf* page(); BorderLines borderLines() const; @@ -237,6 +245,7 @@ public: virtual void beforeDelete(); QList childBaseItems(); + QList allChildBaseItems(); BaseDesignIntf* childByName(const QString& name); virtual QWidget *defaultEditor(); @@ -266,24 +275,39 @@ public: QColor borderColor() const; void setBorderColor(const QColor &borderColor); void setItemVisible(const bool& value); - virtual bool canContainChildren(){ return false;} + virtual bool canContainChildren() const { return false;} ReportSettings* reportSettings() const; void setReportSettings(ReportSettings *reportSettings); void setZValueProperty(qreal value); QString patternName() const; void setPatternName(const QString &patternName); + BaseDesignIntf* patternItem() const; + void setPatternItem(BaseDesignIntf* patternItem); + virtual QMap getStringForTranslation(); + bool fillInSecondPass() const; + void setFillInSecondPass(bool fillInSecondPass); bool isWatermark() const; virtual void setWatermark(bool watermark); - + void updateSelectionMarker(); + void turnOnSelectionMarker(bool value); Q_INVOKABLE QString setItemWidth(qreal width); Q_INVOKABLE QString setItemHeight(qreal height); Q_INVOKABLE qreal getItemWidth(); Q_INVOKABLE qreal getItemHeight(); Q_INVOKABLE qreal getItemPosX(); Q_INVOKABLE qreal getItemPosY(); + Q_INVOKABLE qreal getAbsolutePosX(); + Q_INVOKABLE qreal getAbsolutePosY(); Q_INVOKABLE QString setItemPosX(qreal xValue); Q_INVOKABLE QString setItemPosY(qreal yValue); + bool fillTransparentInDesignMode() const; + void setFillTransparentInDesignMode(bool fillTransparentInDesignMode); + void emitPosChanged(QPointF oldPos, QPointF newPos); + + bool isGeometryLocked() const; + void setGeometryLocked(bool itemLocked); + protected: //ICollectionContainer @@ -296,10 +320,11 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent* event); void hoverMoveEvent(QGraphicsSceneHoverEvent* event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - //void virtual hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent* event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); virtual void geometryChangedEvent(QRectF newRect, QRectF oldRect); @@ -322,7 +347,7 @@ protected: void drawDesignModeBorder(QPainter* painter, QRectF rect) const; void drawRenderModeBorder(QPainter *painter, QRectF rect) const; void drawResizeZone(QPainter*); - void drawSelection(QPainter* painter, QRectF) const; + void drawMarker(QPainter* painter, QColor color) const; void drawPinArea(QPainter* painter) const; void initResizeZones(); @@ -342,27 +367,32 @@ protected: QVariant m_varValue; virtual void preparePopUpMenu(QMenu& menu){Q_UNUSED(menu)} - virtual void processPopUpAction(QAction* action){Q_UNUSED(action)} + virtual void processPopUpAction(QAction* action); + + void addChildItems(QList* list); + qreal calcAbsolutePosY(qreal currentOffset, BaseDesignIntf* item); + qreal calcAbsolutePosX(qreal currentOffset, BaseDesignIntf* item); + private: - void updateSelectionMarker(); int resizeDirectionFlags(QPointF position); void moveSelectedItems(QPointF delta); Qt::CursorShape getPossibleCursor(int cursorFlags); void updatePossibleDirectionFlags(); - void turnOnSelectionMarker(bool value); private: QPointF m_startPos; int m_resizeHandleSize; int m_selectionPenSize; int m_possibleResizeDirectionFlags; int m_possibleMoveDirectionFlags; + int m_savedPossibleResizeDirectionFlags; + int m_savedPossibleMoveDirectionFlags; + int m_savedFixedPos; int m_resizeDirectionFlags; qreal m_width; qreal m_height; QPen m_pen; QFont m_font; QColor m_fontColor; - qreal m_mmFactor; bool m_fixedPos; int m_borderLineSize; @@ -384,8 +414,6 @@ private: ItemMode m_itemMode; ObjectState m_objectState; - SelectionMarker* m_selectionMarker; - Marker* m_joinMarker; BrushStyle m_backgroundBrushStyle; QColor m_backgroundColor; @@ -398,7 +426,17 @@ private: QColor m_borderColor; ReportSettings* m_reportSettings; QString m_patternName; - bool m_watermark; + BaseDesignIntf* m_patternItem; + bool m_fillInSecondPass; + bool m_watermark; + bool m_hovered; + bool m_joinMarkerOn; + SelectionMarker* m_selectionMarker; + Marker* m_joinMarker; + bool m_fillTransparentInDesignMode; + QRect m_itemGeometry; + UnitType m_unitType; + bool m_itemGeometryLocked; signals: void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); void posChanging(QObject* object, QPointF newPos, QPointF oldPos); @@ -418,6 +456,19 @@ signals: void afterRender(); }; +class BookmarkContainerDesignIntf: public BaseDesignIntf{ + Q_OBJECT +public: + BookmarkContainerDesignIntf(const QString& storageTypeName, QObject* owner = 0, QGraphicsItem* parent = 0) + :BaseDesignIntf(storageTypeName, owner, parent){} + void addBookmark(const QString& key, const QVariant& value){ m_bookmarks.insert(key, value);} + QList bookmarks(){ return m_bookmarks.keys();} + QVariant getBookMark(const QString& key); + void copyBookmarks(BookmarkContainerDesignIntf* source); +private: + QMap m_bookmarks; +}; + } //namespace LimeReport #endif // LRBASEDESIGNINTF_H diff --git a/limereport/lrcollection.h b/limereport/lrcollection.h index d5d5ffe..641ddff 100644 --- a/limereport/lrcollection.h +++ b/limereport/lrcollection.h @@ -45,7 +45,7 @@ Q_DECLARE_METATYPE(ACollectionProperty) namespace LimeReport{ -const int VARIABLE_IS_NOT_USED COLLECTION_TYPE_ID = qMetaTypeId(); +const int COLLECTION_TYPE_ID = qMetaTypeId(); class ICollectionContainer{ public: virtual QObject* createElement(const QString& collectionName,const QString& elementType)=0; diff --git a/limereport/lrcolorindicator.cpp b/limereport/lrcolorindicator.cpp new file mode 100644 index 0000000..4844330 --- /dev/null +++ b/limereport/lrcolorindicator.cpp @@ -0,0 +1,50 @@ +#include "lrcolorindicator.h" +#include +#include + +void ColorIndicator::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + painter.save(); + painter.setBrush(m_color); + painter.setPen(Qt::gray); + + QRect rect = event->rect().adjusted(3,3,-3,-3); + + if (rect.height() < rect.width()){ + qreal offset = (rect.width()-rect.height()) / 2; + rect.setWidth(rect.height()); + rect.adjust(offset,0,offset,0); + } else { + qreal offset = (rect.height()-rect.width()) / 2; + rect.setHeight(rect.width()); + rect.adjust(0,offset,0,offset); + } + + painter.setRenderHint(QPainter::Antialiasing); + painter.drawEllipse(rect); + painter.restore(); +} + +ColorIndicator::ColorIndicator(QWidget *parent) + :QWidget(parent), m_color(Qt::white){ + setAttribute(Qt::WA_StaticContents); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + setFocusPolicy(Qt::NoFocus); +} + +QColor ColorIndicator::color() const +{ + return m_color; +} + +void ColorIndicator::setColor(const QColor &color) +{ + m_color = color; + update(); +} + +QSize ColorIndicator::sizeHint() const +{ + return QSize(20,20); +} diff --git a/limereport/lrcolorindicator.h b/limereport/lrcolorindicator.h new file mode 100644 index 0000000..5ed1754 --- /dev/null +++ b/limereport/lrcolorindicator.h @@ -0,0 +1,20 @@ +#ifndef COLORINDICATOR_H +#define COLORINDICATOR_H + +#include +#include + +class ColorIndicator : public QWidget{ + Q_OBJECT +public: + ColorIndicator(QWidget* parent = 0); + QColor color() const; + void setColor(const QColor &color); + QSize sizeHint() const; +protected: + void paintEvent(QPaintEvent *event); +private: + QColor m_color; +}; + +#endif // COLORINDICATOR_H diff --git a/limereport/lrdatadesignintf.cpp b/limereport/lrdatadesignintf.cpp index b98c4aa..6fa78a5 100644 --- a/limereport/lrdatadesignintf.cpp +++ b/limereport/lrdatadesignintf.cpp @@ -77,10 +77,8 @@ bool QueryHolder::runQuery(IDataSource::DatasourceMode mode) return false; } - if (!m_prepared){ - extractParams(); - if (!m_prepared) return false; - } + extractParams(); + if (!m_prepared) return false; query.prepare(m_preparedSQL); fillParams(&query); @@ -152,35 +150,13 @@ void QueryHolder::fillParams(QSqlQuery *query) void QueryHolder::extractParams() { - m_preparedSQL = replaceVariables(m_queryText); + m_preparedSQL = dataManager()->replaceVariables(m_queryText, m_aliasesToParam); m_prepared = true; } QString QueryHolder::replaceVariables(QString query) { - QRegExp rx(Const::VARIABLE_RX); - int curentAliasIndex = 0; - if (query.contains(rx)){ - int pos = -1; - while ((pos=rx.indexIn(query))!=-1){ - - QString variable=rx.cap(0); - variable.remove("$V{"); - variable.remove("}"); - - if (m_aliasesToParam.contains(variable)){ - curentAliasIndex++; - m_aliasesToParam.insert(variable+"_alias"+QString::number(curentAliasIndex),variable); - variable += "_alias"+QString::number(curentAliasIndex); - } else { - m_aliasesToParam.insert(variable,variable); - } - - query.replace(pos,rx.cap(0).length(),":"+variable); - - } - } - return query; + return dataManager()->replaceVariables(query, m_aliasesToParam); } QString QueryHolder::queryText() @@ -282,6 +258,23 @@ QVariant ModelToDataSource::data(const QString &columnName) return m_model->data(m_model->index(currentRow(),columnIndexByName(columnName))); } +QVariant ModelToDataSource::dataByRowIndex(const QString &columnName, int rowIndex) +{ + if (m_model->rowCount() > rowIndex) + return m_model->data(m_model->index(rowIndex, columnIndexByName(columnName))); + return QVariant(); +} + +QVariant ModelToDataSource::dataByKeyField(const QString& columnName, const QString& keyColumnName, QVariant keyData) +{ + for( int i=0; i < m_model->rowCount(); ++i ){ + if (m_model->data(m_model->index(i, columnIndexByName(keyColumnName))) == keyData){ + return m_model->data(m_model->index(i, columnIndexByName(columnName))); + } + } + return QVariant(); +} + int ModelToDataSource::columnCount() { if (isInvalid()) return 0; @@ -440,32 +433,7 @@ QString SubQueryHolder::extractField(QString source) QString SubQueryHolder::replaceFields(QString query) { - QRegExp rx(Const::FIELD_RX); - int curentAliasIndex=0; - if (query.contains(rx)){ - int pos; - while ((pos=rx.indexIn(query))!=-1){ - QString field=rx.cap(0); - field.remove("$D{"); - field.remove("}"); - - if (!m_aliasesToParam.contains(field)){ - if (field.contains(".")) - m_aliasesToParam.insert(field,field); - else - m_aliasesToParam.insert(field,m_masterDatasource+"."+field); - } else { - curentAliasIndex++; - if (field.contains(".")) - m_aliasesToParam.insert(field+"_alias"+QString::number(curentAliasIndex),field); - else - m_aliasesToParam.insert(field+"_alias"+QString::number(curentAliasIndex),m_masterDatasource+"."+field); - field+="_alias"+QString::number(curentAliasIndex); - } - query.replace(pos,rx.cap(0).length(),":"+extractField(field)); - } - } - return query; + return dataManager()->replaceFields(query, m_aliasesToParam); } SubQueryDesc::SubQueryDesc(QString queryName, QString queryText, QString connection, QString masterDatasourceName) @@ -497,7 +465,7 @@ QObject *ProxyDesc::elementAt(const QString &collectionName, int index) ProxyHolder::ProxyHolder(ProxyDesc* desc, DataSourceManager* dataManager) :m_model(0), m_desc(desc), m_lastError(""), m_mode(IDataSource::RENDER_MODE), - m_invalid(false), m_dataManger(dataManager) + m_invalid(false), m_dataManager(dataManager) {} QString ProxyHolder::masterDatasource() @@ -707,17 +675,24 @@ void CallbackDatasource::first(){ else m_eof = !result; } +QVariant CallbackDatasource::callbackData(const QString& columnName, int row) +{ + CallbackInfo info; + QVariant result; + info.dataType = CallbackInfo::ColumnData; + info.columnName = columnName; + info.index = row; + emit getCallbackData(info, result); + return result; +} + QVariant CallbackDatasource::data(const QString& columnName) { QVariant result; if (!bof()) { if (!m_getDataFromCache){ - CallbackInfo info; - info.dataType = CallbackInfo::ColumnData; - info.columnName = columnName; - info.index = m_currentRow; - emit getCallbackData(info,result); + result = callbackData(columnName, m_currentRow); } else { result = m_valuesCache[columnName]; } @@ -725,6 +700,46 @@ QVariant CallbackDatasource::data(const QString& columnName) return result; } +QVariant CallbackDatasource::dataByRowIndex(const QString &columnName, int rowIndex) +{ + int backupCurrentRow = m_currentRow; + QVariant result = QVariant(); + first(); + for (int i = 0; i < rowIndex && !eof(); ++i, next()){} + if (!eof()) result = callbackData(columnName, rowIndex); + first(); + if (backupCurrentRow != -1){ + for (int i = 0; i < backupCurrentRow; ++i) + next(); + } + return result; +} + +QVariant CallbackDatasource::dataByKeyField(const QString& columnName, const QString& keyColumnName, QVariant keyData) +{ + int backupCurrentRow = m_currentRow; + QVariant result = QVariant(); + first(); + if (!checkIfEmpty()){ + int currentRow = 0; + do { + QVariant key = callbackData(keyColumnName, currentRow); + if (key == keyData){ + result = callbackData(columnName, currentRow); + break; + } + currentRow++; + } while (next()); + } + + first(); + if (backupCurrentRow != -1){ + for (int i = 0; i < backupCurrentRow; ++i) + next(); + } + return result; +} + int CallbackDatasource::columnCount(){ CallbackInfo info; if (m_columnCount == -1){ @@ -786,7 +801,7 @@ int CallbackDatasource::columnIndexByName(QString name) bool CallbackDatasource::checkNextRecord(int recordNum){ if (bof()) checkIfEmpty(); if (m_rowCount > 0) { - return (m_currentRow < (m_rowCount-1)); + return (recordNum < (m_rowCount-1)); } else { QVariant result = false; CallbackInfo info; @@ -816,4 +831,118 @@ bool CallbackDatasource::checkIfEmpty(){ } } +QString CSVDesc::name() const +{ + return m_csvName; +} + +void CSVDesc::setName(const QString &csvName) +{ + m_csvName = csvName; +} + +QString CSVDesc::csvText() const +{ + return m_csvText; +} + +void CSVDesc::setCsvText(const QString &csvText) +{ + m_csvText = csvText; + emit cvsTextChanged(m_csvName, m_csvText); +} + +QString CSVDesc::separator() const +{ + return m_separator; +} + +void CSVDesc::setSeparator(const QString &separator) +{ + m_separator = separator; +} + +bool CSVDesc::firstRowIsHeader() const +{ + return m_firstRowIsHeader; +} + +void CSVDesc::setFirstRowIsHeader(bool firstRowIsHeader) +{ + m_firstRowIsHeader = firstRowIsHeader; +} + +void CSVHolder::updateModel() +{ + m_model.clear(); + QString sep = (separator().compare("\\t") == 0) ? "\t" : separator(); + bool firstRow = true; + QList columns; + QStringList headers; + foreach(QString line, m_csvText.split('\n')){ + columns.clear(); + foreach(QString item, line.split(sep)){ + columns.append(new QStandardItem(item)); + if (firstRow && m_firstRowIsHeader) headers.append(item); + } + + if (firstRow){ + if (!headers.isEmpty()){ + m_model.setHorizontalHeaderLabels(headers); + firstRow = false; + } else { + m_model.appendRow(columns); + } + } else { + m_model.appendRow(columns); + } + + } + + +} + +bool CSVHolder::firsRowIsHeader() const +{ + return m_firstRowIsHeader; +} + +void CSVHolder::setFirsRowIsHeader(bool firstRowIsHeader) +{ + m_firstRowIsHeader = firstRowIsHeader; +} + +CSVHolder::CSVHolder(const CSVDesc &desc, DataSourceManager *dataManager) + : m_csvText(desc.csvText()), + m_separator(desc.separator()), + m_dataManager(dataManager), + m_firstRowIsHeader(desc.firstRowIsHeader()) +{ + m_dataSource = IDataSource::Ptr(new ModelToDataSource(&m_model, false)); + updateModel(); +} + +void CSVHolder::setCSVText(QString csvText) +{ + m_csvText = csvText; + updateModel(); +} + +QString CSVHolder::separator() const +{ + return m_separator; +} + +void CSVHolder::setSeparator(const QString &separator) +{ + m_separator = separator; + updateModel(); +} + +IDataSource *CSVHolder::dataSource(IDataSource::DatasourceMode mode) +{ + Q_UNUSED(mode); + return m_dataSource.data(); +} + } //namespace LimeReport diff --git a/limereport/lrdatadesignintf.h b/limereport/lrdatadesignintf.h index 0e77ae8..8665bc1 100644 --- a/limereport/lrdatadesignintf.h +++ b/limereport/lrdatadesignintf.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -40,46 +41,12 @@ #include #include "lrcollection.h" #include "lrcallbackdatasourceintf.h" +#include "lrdatasourceintf.h" namespace LimeReport{ class DataSourceManager; -class IDataSource { -public: - enum DatasourceMode{DESIGN_MODE,RENDER_MODE}; - typedef QSharedPointer Ptr; - virtual ~IDataSource(){} - virtual bool next() = 0; - virtual bool hasNext() = 0; - virtual bool prior() = 0; - virtual void first() = 0; - virtual void last() = 0; - virtual bool bof() = 0; - virtual bool eof() = 0; - virtual QVariant data(const QString& columnName) = 0; - virtual int columnCount() = 0; - virtual QString columnNameByIndex(int columnIndex) = 0; - virtual int columnIndexByName(QString name) = 0; - virtual bool isInvalid() const = 0; - virtual QString lastError() = 0; - virtual QAbstractItemModel* model() = 0; -}; - -class IDataSourceHolder { -public: - virtual IDataSource* dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE) = 0; - virtual QString lastError() const = 0; - virtual bool isInvalid() const = 0; - virtual bool isOwned() const = 0; - virtual bool isEditable() const = 0; - virtual bool isRemovable() const = 0; - virtual void invalidate(IDataSource::DatasourceMode mode, bool dbWillBeClosed = false) = 0; - virtual void update() = 0; - virtual void clearErrors() = 0; - virtual ~IDataSourceHolder(){} -}; - class ModelHolder: public QObject, public IDataSourceHolder{ Q_OBJECT public: @@ -165,6 +132,64 @@ public: virtual QString lastError() const = 0; }; +class CSVDesc: public QObject{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString csvText READ csvText WRITE setCsvText) + Q_PROPERTY(QString separator READ separator WRITE setSeparator) + Q_PROPERTY(bool firstRowIsHeader READ firstRowIsHeader WRITE setFirstRowIsHeader) +public: + CSVDesc(const QString name, const QString csvText, QString separator, bool firstRowIsHeader) + : m_csvName(name), m_csvText(csvText), m_separator(separator), m_firstRowIsHeader(firstRowIsHeader){} + explicit CSVDesc(QObject* parent = 0):QObject(parent) {} + QString name() const; + void setName(const QString &name); + QString csvText() const; + void setCsvText(const QString &csvText); + QString separator() const; + void setSeparator(const QString &separator); + bool firstRowIsHeader() const; + void setFirstRowIsHeader(bool firstRowIsHeader); +signals: + void cvsTextChanged(const QString& cvsName, const QString& cvsText); +private: + QString m_csvName; + QString m_csvText; + QString m_separator; + bool m_firstRowIsHeader; +}; + +class CSVHolder: public IDataSourceHolder{ +public: + CSVHolder(const CSVDesc& desc, DataSourceManager* dataManager); + void setCSVText(QString csvText); + QString csvText() { return m_csvText;} + QString separator() const; + void setSeparator(const QString &separator); + bool firsRowIsHeader() const; + void setFirsRowIsHeader(bool firstRowIsHeader); + // IDataSourceHolder interface +public: + IDataSource *dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE); + QString lastError() const {return "";} + bool isInvalid() const {return false;} + bool isOwned() const {return true;} + bool isEditable() const {return true;} + bool isRemovable() const {return true;} + void invalidate(IDataSource::DatasourceMode mode, bool dbWillBeClosed){ updateModel();} + void update(){ updateModel(); } + void clearErrors(){} +private: + void updateModel(); +private: + QString m_csvText; + QStandardItemModel m_model; + QString m_separator; + IDataSource::Ptr m_dataSource; + DataSourceManager* m_dataManager; + bool m_firstRowIsHeader; +}; + class QueryDesc : public QObject{ Q_OBJECT Q_PROPERTY(QString queryName READ queryName WRITE setQueryName) @@ -174,11 +199,11 @@ public: QueryDesc(QString queryName, QString queryText, QString connection); explicit QueryDesc(QObject* parent=0):QObject(parent){} void setQueryName(QString value){m_queryName=value;} - QString queryName(){return m_queryName;} + QString queryName() const {return m_queryName;} void setQueryText(QString value){m_queryText=value; emit queryTextChanged(m_queryName, m_queryText);} - QString queryText(){return m_queryText;} + QString queryText() const {return m_queryText;} void setConnectionName(QString value){m_connectionName=value;} - QString connectionName(){return m_connectionName;} + QString connectionName() const {return m_connectionName;} signals: void queryTextChanged(const QString& queryName, const QString& queryText); private: @@ -336,7 +361,7 @@ public: void invalidate(IDataSource::DatasourceMode mode, bool dbWillBeClosed = false); void update(){} void clearErrors(){m_lastError = "";} - DataSourceManager* dataManager() const {return m_dataManger;} + DataSourceManager* dataManager() const {return m_dataManager;} private slots: void slotChildModelDestoroyed(); private: @@ -346,7 +371,7 @@ private: QString m_lastError; IDataSource::DatasourceMode m_mode; bool m_invalid; - DataSourceManager* m_dataManger; + DataSourceManager* m_dataManager; }; class ModelToDataSource : public QObject, public IDataSource{ @@ -362,6 +387,8 @@ public: bool eof(); bool bof(); QVariant data(const QString& columnName); + QVariant dataByRowIndex(const QString &columnName, int rowIndex); + QVariant dataByKeyField(const QString& columnName, const QString& keyColumnName, QVariant keyData); int columnCount(); QString columnNameByIndex(int columnIndex); int columnIndexByName(QString name); @@ -393,6 +420,8 @@ public: bool bof(){return m_currentRow == -1;} bool eof(){return m_eof;} QVariant data(const QString &columnName); + QVariant dataByRowIndex(const QString& columnName, int rowIndex); + QVariant dataByKeyField(const QString& columnName, const QString& keyColumnName, QVariant keyData); int columnCount(); QString columnNameByIndex(int columnIndex); int columnIndexByName(QString name); @@ -410,6 +439,7 @@ private: int m_rowCount; QHash m_valuesCache; bool m_getDataFromCache; + QVariant callbackData(const QString& columnName, int row); }; class CallbackDatasourceHolder :public QObject, public IDataSourceHolder{ diff --git a/limereport/lrdatasourceintf.h b/limereport/lrdatasourceintf.h new file mode 100644 index 0000000..26f7a65 --- /dev/null +++ b/limereport/lrdatasourceintf.h @@ -0,0 +1,48 @@ +#ifndef LRDATASOURCEINTF_H +#define LRDATASOURCEINTF_H +#include +#include +namespace LimeReport { + +class IDataSource { +public: + enum DatasourceMode{DESIGN_MODE,RENDER_MODE}; + typedef QSharedPointer Ptr; + virtual ~IDataSource() {} + virtual bool next() = 0; + virtual bool hasNext() = 0; + virtual bool prior() = 0; + virtual void first() = 0; + virtual void last() = 0; + virtual bool bof() = 0; + virtual bool eof() = 0; + virtual QVariant data(const QString& columnName) = 0; + virtual QVariant dataByRowIndex(const QString& columnName, int rowIndex) = 0; + virtual QVariant dataByKeyField(const QString& columnName, const QString& keyColumnName, QVariant keyData) = 0; + virtual int columnCount() = 0; + virtual QString columnNameByIndex(int columnIndex) = 0; + virtual int columnIndexByName(QString name) = 0; + virtual bool isInvalid() const = 0; + virtual QString lastError() = 0; + virtual QAbstractItemModel* model() = 0; +}; + +class IDataSourceHolder { +public: + virtual ~IDataSourceHolder(){} + virtual IDataSource* dataSource(IDataSource::DatasourceMode mode = IDataSource::RENDER_MODE) = 0; + virtual QString lastError() const = 0; + virtual bool isInvalid() const = 0; + virtual bool isOwned() const = 0; + virtual bool isEditable() const = 0; + virtual bool isRemovable() const = 0; + virtual void invalidate(IDataSource::DatasourceMode mode, bool dbWillBeClosed = false) = 0; + virtual void update() = 0; + virtual void clearErrors() = 0; +}; + +} // namespace LimeReport + +#endif // LRDATASOURCEINTF_H + + diff --git a/limereport/lrdatasourcemanager.cpp b/limereport/lrdatasourcemanager.cpp index 20ff3fb..1fcc20d 100644 --- a/limereport/lrdatasourcemanager.cpp +++ b/limereport/lrdatasourcemanager.cpp @@ -37,6 +37,13 @@ #include #include +#ifdef BUILD_WITH_EASY_PROFILER +#include "easy/profiler.h" +#else +# define EASY_BLOCK(...) +# define EASY_END_BLOCK +#endif + namespace LimeReport{ DataNode::~DataNode() @@ -172,7 +179,7 @@ DataNode* DataSourceModel::nodeFromIndex(const QModelIndex& index) const void DataSourceModel::fillFields(DataNode* parent) { foreach(QString name, m_dataManager->fieldNames(parent->name())){ - parent->addChild(name,DataNode::Field,QIcon(":/report/images/field")); + parent->addChild(name, DataNode::Field,QIcon(":/report/images/field")); } } @@ -211,13 +218,13 @@ void DataSourceModel::updateModel() } vars = m_rootNode->addChild(tr("External variables"),DataNode::Variables,QIcon(":/report/images/folder")); - foreach (QString name, m_dataManager->namesOfUserVariables()){ + foreach (QString name, m_dataManager->userVariableNames()){ vars->addChild(name,DataNode::Variable,QIcon(":/report/images/value")); } } DataSourceManager::DataSourceManager(QObject *parent) : - QObject(parent), m_lastError(""), m_designTime(true), m_needUpdate(false), + QObject(parent), m_lastError(""), m_designTime(false), m_needUpdate(false), m_dbCredentialsProvider(0), m_hasChanges(false) { m_groupFunctionFactory.registerFunctionCreator(QLatin1String("COUNT"),new ConstructorGroupFunctionCreator); @@ -225,10 +232,11 @@ DataSourceManager::DataSourceManager(QObject *parent) : m_groupFunctionFactory.registerFunctionCreator(QLatin1String("AVG"),new ConstructorGroupFunctionCreator); m_groupFunctionFactory.registerFunctionCreator(QLatin1String("MIN"),new ConstructorGroupFunctionCreator); m_groupFunctionFactory.registerFunctionCreator(QLatin1String("MAX"),new ConstructorGroupFunctionCreator); - setSystemVariable(QLatin1String("#PAGE"),1,FirstPass); + setSystemVariable(QLatin1String("#PAGE"),1,SecondPass); setSystemVariable(QLatin1String("#PAGE_COUNT"),0,SecondPass); setSystemVariable(QLatin1String("#IS_LAST_PAGEFOOTER"),false,FirstPass); setSystemVariable(QLatin1String("#IS_FIRST_PAGEFOOTER"),false,FirstPass); + m_datasourcesModel.setDataSourceManager(this); connect(&m_reportVariables, SIGNAL(variableHasBeenAdded(QString)), this, SLOT(slotVariableHasBeenAdded(QString))); @@ -239,7 +247,7 @@ DataSourceManager::DataSourceManager(QObject *parent) : connect(&m_userVariables, SIGNAL(variableHasBeenChanged(QString)), this, SLOT(slotVariableHasBeenChanged(QString))); - m_datasourcesModel.setDataSourceManager(this); + } QString DataSourceManager::defaultDatabasePath() const @@ -300,7 +308,7 @@ void DataSourceManager::connectAllDatabases() foreach(ConnectionDesc* conn,m_connections){ try{ connectConnection(conn); - } catch (ReportError e){ + } catch (ReportError &e){ putError(e.what()); setLastError(e.what()); qDebug()<DataSourceManager::previewSQL(const QString &c void DataSourceManager::updateDatasourceModel() { m_datasourcesModel.updateModel(); + emit datasourcesChanged(); m_needUpdate = false; } @@ -442,17 +451,32 @@ QString DataSourceManager::replaceVariables(QString query, QMap QString var=rx.cap(0); var.remove("$V{"); var.remove("}"); - - if (aliasesToParam.contains(var)){ - curentAliasIndex++; - aliasesToParam.insert(var+"_v_alias"+QString::number(curentAliasIndex),var); - var += "_v_alias"+QString::number(curentAliasIndex); + if (!rx.cap(1).isEmpty()){ + if (aliasesToParam.contains(var)){ + curentAliasIndex++; + aliasesToParam.insert(var+"_v_alias"+QString::number(curentAliasIndex),var); + var += "_v_alias"+QString::number(curentAliasIndex); + } else { + aliasesToParam.insert(var,var); + } + query.replace(pos,rx.cap(0).length(),":"+var); } else { - aliasesToParam.insert(var,var); + QString varName = rx.cap(2).trimmed(); + QString varParam = rx.cap(3).trimmed(); + if (!varName.isEmpty()){ + if (!varParam.isEmpty() && varParam.compare("nobind") == 0 ){ + query.replace(pos,rx.cap(0).length(), variable(varName).toString()); + } else { + query.replace(pos,rx.cap(0).length(), + QString(tr("Unknown parameter \"%1\" for variable \"%2\" found!") + .arg(varName) + .arg(varParam)) + ); + } + } else { + query.replace(pos,rx.cap(0).length(),QString(tr("Variable \"%1\" not found!").arg(var))); + } } - - query.replace(pos,rx.cap(0).length(),":"+var); - } } return query; @@ -461,8 +485,8 @@ QString DataSourceManager::replaceVariables(QString query, QMap QString DataSourceManager::replaceFields(QString query, QMap &aliasesToParam, QString masterDatasource) { QRegExp rx(Const::FIELD_RX); - int curentAliasIndex=0; if (query.contains(rx)){ + int curentAliasIndex=0; int pos; while ((pos=rx.indexIn(query))!=-1){ QString field=rx.cap(0); @@ -513,7 +537,7 @@ void DataSourceManager::addSubQuery(const QString &name, const QString &sqlText, emit datasourcesChanged(); } -void DataSourceManager::addProxy(const QString &name, QString master, QString detail, QList fields) +void DataSourceManager::addProxy(const QString &name, const QString &master, const QString &detail, QList fields) { ProxyDesc *proxyDesc = new ProxyDesc(); proxyDesc->setName(name); @@ -528,6 +552,15 @@ void DataSourceManager::addProxy(const QString &name, QString master, QString de emit datasourcesChanged(); } +void DataSourceManager::addCSV(const QString& name, const QString& csvText, const QString &separator, bool firstRowIsHeader) +{ + CSVDesc* csvDesc = new CSVDesc(name, csvText, separator, firstRowIsHeader); + putCSVDesc(csvDesc); + putHolder(name, new CSVHolder(*csvDesc, this)); + m_hasChanges = true; + emit datasourcesChanged(); +} + QString DataSourceManager::queryText(const QString &dataSourceName) { if (isQuery(dataSourceName)) return queryByName(dataSourceName)->queryText(); @@ -535,16 +568,16 @@ QString DataSourceManager::queryText(const QString &dataSourceName) else return QString(); } -QueryDesc *DataSourceManager::queryByName(const QString &dataSourceName) +QueryDesc *DataSourceManager::queryByName(const QString &datasourceName) { - int queryIndex = queryIndexByName(dataSourceName); + int queryIndex = queryIndexByName(datasourceName); if (queryIndex!=-1) return m_queries.at(queryIndex); return 0; } -SubQueryDesc* DataSourceManager::subQueryByName(const QString &dataSourceName) +SubQueryDesc* DataSourceManager::subQueryByName(const QString &datasourceName) { - int queryIndex = subQueryIndexByName(dataSourceName); + int queryIndex = subQueryIndexByName(datasourceName); if (queryIndex!=-1) return m_subqueries.at(queryIndex); return 0; } @@ -583,6 +616,15 @@ int DataSourceManager::proxyIndexByName(const QString &dataSourceName) return -1; } +int DataSourceManager::csvIndexByName(const QString &dataSourceName) +{ + for(int i=0; i < m_csvs.count();++i){ + CSVDesc* desc=m_csvs.at(i); + if (desc->name().compare(dataSourceName,Qt::CaseInsensitive)==0) return i; + } + return -1; +} + int DataSourceManager::connectionIndexByName(const QString &connectionName) { for(int i=0;i-1) return m_proxies.at(proxyIndex); + if (proxyIndex > -1) return m_proxies.at(proxyIndex); + else return 0; +} + +CSVDesc *DataSourceManager::csvByName(const QString &datasourceName) +{ + int csvIndex = csvIndexByName(datasourceName); + if (csvIndex > -1) return m_csvs.at(csvIndex); else return 0; } @@ -647,6 +696,11 @@ void DataSourceManager::removeDatasource(const QString &name) delete m_proxies.at(proxyIndex); m_proxies.removeAt(proxyIndex); } + if (isCSV(name)){ + int csvIndex=csvIndexByName(name); + delete m_csvs.at(csvIndex); + m_csvs.removeAt(csvIndex); + } m_hasChanges = true; emit datasourcesChanged(); } @@ -665,7 +719,7 @@ void DataSourceManager::removeConnection(const QString &connectionName) delete (*cit); cit = m_connections.erase(cit); } else { - cit++; + ++cit; } } m_hasChanges = true; @@ -739,6 +793,15 @@ void DataSourceManager::putProxyDesc(ProxyDesc *proxyDesc) } else throw ReportError(tr("Datasource with name \"%1\" already exists!").arg(proxyDesc->name())); } +void DataSourceManager::putCSVDesc(CSVDesc *csvDesc) +{ + if (!containsDatasource(csvDesc->name())){ + m_csvs.append(csvDesc); + connect(csvDesc, SIGNAL(cvsTextChanged(QString, QString)), + this, SLOT(slotCSVTextChanged(QString, QString))); + } else throw ReportError(tr("Datasource with name \"%1\" already exists!").arg(csvDesc->name())); +} + bool DataSourceManager::initAndOpenDB(QSqlDatabase& db, ConnectionDesc& connectionDesc){ bool connected = false; @@ -869,7 +932,7 @@ void DataSourceManager::connectAutoConnections() if (conn->autoconnect()) { try { connectConnection(conn); - } catch(ReportError e){ + } catch(ReportError &e){ setLastError(e.what()); putError(e.what()); qDebug()<isInvalid()){ - for(int i=0;icolumnCount();i++){ + for(int i=0; i < ds->columnCount(); i++){ result.append(ds->columnNameByIndex(i)); } result.sort(); @@ -1065,6 +1133,12 @@ QObject *DataSourceManager::createElement(const QString& collectionName, const Q return var; } + if (collectionName=="csvs"){ + CSVDesc* csvDesc = new CSVDesc; + m_csvs.append(csvDesc); + return csvDesc; + } + return 0; } @@ -1083,7 +1157,10 @@ int DataSourceManager::elementsCount(const QString &collectionName) return m_proxies.count(); } if (collectionName=="variables"){ - return m_reportVariables.userVariablesCount(); + return m_reportVariables.variablesCount(); + } + if (collectionName=="csvs"){ + return m_csvs.count(); } return 0; } @@ -1103,18 +1180,21 @@ QObject* DataSourceManager::elementAt(const QString &collectionName, int index) return m_proxies.at(index); } if (collectionName=="variables"){ - return m_reportVariables.userVariableAt(index); + return m_reportVariables.variableAt(index); + } + if (collectionName=="csvs"){ + return m_csvs.at(index); } return 0; } void DataSourceManager::collectionLoadFinished(const QString &collectionName) { - + EASY_BLOCK("DataSourceManager::collectionLoadFinished"); if (collectionName.compare("connections",Qt::CaseInsensitive) == 0){ } - + EASY_BLOCK("queryes"); if (collectionName.compare("queries",Qt::CaseInsensitive) == 0){ QMutableListIterator it(m_queries); @@ -1131,7 +1211,8 @@ void DataSourceManager::collectionLoadFinished(const QString &collectionName) } } - + EASY_END_BLOCK; + EASY_BLOCK("subqueries") if (collectionName.compare("subqueries",Qt::CaseInsensitive) == 0){ QMutableListIterator it(m_subqueries); @@ -1153,7 +1234,8 @@ void DataSourceManager::collectionLoadFinished(const QString &collectionName) } } - + EASY_END_BLOCK; + EASY_BLOCK("subproxies"); if (collectionName.compare("subproxies",Qt::CaseInsensitive) == 0){ QMutableListIterator it(m_proxies); while (it.hasNext()){ @@ -1166,19 +1248,48 @@ void DataSourceManager::collectionLoadFinished(const QString &collectionName) } } } - + EASY_END_BLOCK; + EASY_BLOCK("variables"); if (collectionName.compare("variables",Qt::CaseInsensitive) == 0){ foreach (VarDesc* item, m_tempVars) { if (!m_reportVariables.containsVariable(item->name())){ m_reportVariables.addVariable(item->name(),item->value(),VarDesc::Report,FirstPass); + VarDesc* currentVar = m_reportVariables.variableByName(item->name()); + currentVar->initFrom(item); } delete item; } m_tempVars.clear(); } + EASY_END_BLOCK; - emit datasourcesChanged(); + if (collectionName.compare("csvs", Qt::CaseInsensitive) == 0){ + QMutableListIterator it(m_csvs); + while (it.hasNext()){ + it.next(); + if (!m_datasources.contains(it.value()->name().toLower())){ + connect(it.value(), SIGNAL(cvsTextChanged(QString,QString)), + this, SLOT(slotCSVTextChanged(QString,QString))); + putHolder( + it.value()->name(), + new CSVHolder(*it.value(), this) + ); + } else { + delete it.value(); + it.remove(); + } + } + } + + if (designTime()){ + EASY_BLOCK("emit datasourcesChanged()"); + emit datasourcesChanged(); + EASY_END_BLOCK; + } + EASY_BLOCK("emit loadCollectionFinished(collectionName)"); emit loadCollectionFinished(collectionName); + EASY_END_BLOCK; + EASY_END_BLOCK; } void DataSourceManager::addVariable(const QString &name, const QVariant &value, VarDesc::VarType type, RenderPass pass) @@ -1188,8 +1299,11 @@ void DataSourceManager::addVariable(const QString &name, const QVariant &value, } else { m_reportVariables.addVariable(name,value,type,pass); } - if (designTime()) - emit datasourcesChanged(); + if (designTime()){ + EASY_BLOCK("DataSourceManager::addVariable emit ds changed"); + emit datasourcesChanged(); + EASY_END_BLOCK; + } } void DataSourceManager::deleteVariable(const QString& name) @@ -1212,6 +1326,7 @@ void DataSourceManager::changeVariable(const QString& name,const QVariant& value if (m_reportVariables.containsVariable(name)){ m_reportVariables.changeVariable(name,value); } + } void DataSourceManager::setSystemVariable(const QString &name, const QVariant &value, RenderPass pass) @@ -1288,6 +1403,14 @@ void DataSourceManager::slotVariableHasBeenChanged(const QString& variableName) m_hasChanges = true; } +void DataSourceManager::slotCSVTextChanged(const QString &csvName, const QString &csvText) +{ + CSVHolder* holder = dynamic_cast(m_datasources.value(csvName)); + if (holder){ + holder->setCSVText(csvText); + } +} + void DataSourceManager::clear(ClearMethod method) { DataSourcesMap::iterator dit; @@ -1429,6 +1552,35 @@ QVariant DataSourceManager::fieldData(const QString &fieldName) return QVariant(); } +QVariant DataSourceManager::fieldDataByRowIndex(const QString &fieldName, int rowIndex) +{ + if (containsField(fieldName)){ + IDataSource* ds = dataSource(extractDataSource(fieldName)); + if (ds){ + return ds->dataByRowIndex(extractFieldName(fieldName), rowIndex); + } + } + return QVariant(); +} + +QVariant DataSourceManager::fieldDataByKey(const QString& datasourceName, const QString& valueFieldName, const QString& keyFieldName, QVariant keyValue) +{ + IDataSource* ds = dataSource(datasourceName); + if (ds){ + return ds->dataByKeyField(valueFieldName, keyFieldName, keyValue); + } + return QVariant(); +} + +void DataSourceManager::reopenDatasource(const QString& datasourceName) +{ + QueryHolder* qh = dynamic_cast(dataSourceHolder(datasourceName)); + if (qh){ + qh->invalidate(designTime()?IDataSource::DESIGN_MODE:IDataSource::RENDER_MODE); + invalidateChildren(datasourceName); + } +} + QVariant DataSourceManager::variable(const QString &variableName) { if (m_userVariables.containsVariable(variableName)) @@ -1450,12 +1602,36 @@ bool DataSourceManager::variableIsSystem(const QString &name) return false; } +bool DataSourceManager::variableIsMandatory(const QString& name) +{ + if (m_reportVariables.containsVariable(name)) + return m_reportVariables.variableByName(name)->isMandatory(); + return false; +} + +void DataSourceManager::setVarableMandatory(const QString& name, bool value) +{ + if (m_reportVariables.containsVariable(name)) + m_reportVariables.variableByName(name)->setMandatory(value); +} + QStringList DataSourceManager::variableNames() { return m_reportVariables.variableNames(); } -QStringList DataSourceManager::namesOfUserVariables(){ +QStringList DataSourceManager::variableNamesByRenderPass(RenderPass pass) +{ + QStringList result; + foreach(QString variableName, m_reportVariables.variableNames()){ + if (m_reportVariables.variablePass(variableName) == pass){ + result.append(variableName); + } + } + return result; +} + +QStringList DataSourceManager::userVariableNames(){ return m_userVariables.variableNames(); } @@ -1466,6 +1642,19 @@ VarDesc::VarType DataSourceManager::variableType(const QString &name) return VarDesc::User; } +VariableDataType DataSourceManager::variableDataType(const QString& name) +{ + if (m_reportVariables.containsVariable(name)) + return m_reportVariables.variableByName(name)->dataType(); + return Enums::Undefined; +} + +void DataSourceManager::setVariableDataType(const QString& name, VariableDataType value) +{ + if (m_reportVariables.containsVariable(name)) + m_reportVariables.variableByName(name)->setDataType(value); +} + void DataSourceManager::setAllDatasourcesToFirst() { foreach(IDataSourceHolder* ds,m_datasources.values()) { diff --git a/limereport/lrdatasourcemanager.h b/limereport/lrdatasourcemanager.h index 32e1168..de708fe 100644 --- a/limereport/lrdatasourcemanager.h +++ b/limereport/lrdatasourcemanager.h @@ -38,6 +38,7 @@ #include "lrvariablesholder.h" #include "lrgroupfunctions.h" #include "lrdatasourcemanagerintf.h" +#include "lrdatasourceintf.h" namespace LimeReport{ @@ -99,6 +100,7 @@ class DataSourceManager : public QObject, public ICollectionContainer, public IV Q_PROPERTY(ACollectionProperty subqueries READ fakeCollectionReader) Q_PROPERTY(ACollectionProperty subproxies READ fakeCollectionReader) Q_PROPERTY(ACollectionProperty variables READ fakeCollectionReader) + Q_PROPERTY(ACollectionProperty csvs READ fakeCollectionReader) friend class ReportEnginePrivate; friend class ReportRender; public: @@ -111,7 +113,8 @@ public: bool checkConnectionDesc(ConnectionDesc *connection); void addQuery(const QString& name, const QString& sqlText, const QString& connectionName=""); void addSubQuery(const QString& name, const QString& sqlText, const QString& connectionName, const QString& masterDatasource); - void addProxy(const QString& name, QString master, QString detail, QList fields); + void addProxy(const QString& name, const QString& master, const QString& detail, QList fields); + void addCSV(const QString& name, const QString& csvText, const QString& separator, bool firstRowIsHeader); bool addModel(const QString& name, QAbstractItemModel *model, bool owned); void removeModel(const QString& name); ICallbackDatasource* createCallbackDatasource(const QString &name); @@ -123,12 +126,17 @@ public: void clearUserVariables(); void addVariable(const QString& name, const QVariant& value, VarDesc::VarType type=VarDesc::User, RenderPass pass=FirstPass); void changeVariable(const QString& name,const QVariant& value); - QVariant variable(const QString& variableName); - RenderPass variablePass(const QString& name); + QVariant variable(const QString& variableName); + RenderPass variablePass(const QString& name); QStringList variableNames(); - QStringList namesOfUserVariables(); - VarDesc::VarType variableType(const QString& name); + QStringList variableNamesByRenderPass(RenderPass pass); + QStringList userVariableNames(); + VarDesc::VarType variableType(const QString& name); + VariableDataType variableDataType(const QString& name); + void setVariableDataType(const QString &name, VariableDataType value); bool variableIsSystem(const QString& name); + bool variableIsMandatory(const QString& name); + void setVarableMandatory(const QString &name, bool value); QString queryText(const QString& dataSourceName); QString connectionName(const QString& dataSourceName); void removeDatasource(const QString& name); @@ -137,18 +145,21 @@ public: bool containsDatasource(const QString& dataSourceName); bool isSubQuery(const QString& dataSourceName); bool isProxy(const QString& dataSourceName); + bool isCSV(const QString& datasourceName); bool isConnection(const QString& connectionName); bool isConnectionConnected(const QString& connectionName); bool connectConnection(const QString &connectionName); void connectAutoConnections(); void disconnectConnection(const QString &connectionName); - QueryDesc* queryByName(const QString& dataSourceName); - SubQueryDesc* subQueryByName(const QString& dataSourceName); - ProxyDesc* proxyByName(QString datasourceName); + QueryDesc* queryByName(const QString& datasourceName); + SubQueryDesc* subQueryByName(const QString& datasourceName); + ProxyDesc* proxyByName(const QString& datasourceName); + CSVDesc* csvByName(const QString& datasourceName); ConnectionDesc *connectionByName(const QString& connectionName); int queryIndexByName(const QString& dataSourceName); int subQueryIndexByName(const QString& dataSourceName); int proxyIndexByName(const QString& dataSourceName); + int csvIndexByName(const QString& dataSourceName); int connectionIndexByName(const QString& connectionName); QList &conections(); @@ -159,8 +170,16 @@ public: QStringList dataSourceNames(const QString& connectionName); QStringList connectionNames(); QStringList fieldNames(const QString& datasourceName); - bool containsField(const QString& fieldName); - QVariant fieldData(const QString& fieldName); + bool containsField(const QString& fieldName); + QVariant fieldData(const QString& fieldName); + QVariant fieldDataByRowIndex(const QString& fieldName, int rowIndex); + QVariant fieldDataByKey( + const QString& datasourceName, + const QString& valueFieldName, + const QString& keyFieldName, + QVariant keyValue + ); + void reopenDatasource(const QString& datasourceName); QString extractDataSource(const QString& fieldName); QString extractFieldName(const QString& fieldName); @@ -201,7 +220,7 @@ public: ReportSettings *reportSettings() const; void setReportSettings(ReportSettings *reportSettings); - bool isHasChanges(){ return m_hasChanges; } + bool hasChanges(){ return m_hasChanges; } void dropChanges(){ m_hasChanges = false; } signals: void loadCollectionFinished(const QString& collectionName); @@ -212,6 +231,7 @@ protected: void putQueryDesc(QueryDesc *queryDesc); void putSubQueryDesc(SubQueryDesc *subQueryDesc); void putProxyDesc(ProxyDesc *proxyDesc); + void putCSVDesc(CSVDesc* csvDesc); bool connectConnection(ConnectionDesc* connectionDesc); void clearReportVariables(); QList childDatasources(const QString& datasourceName); @@ -232,6 +252,7 @@ private slots: void slotQueryTextChanged(const QString& queryName, const QString& queryText); void slotVariableHasBeenAdded(const QString& variableName); void slotVariableHasBeenChanged(const QString& variableName); + void slotCSVTextChanged(const QString& csvName, const QString& csvText); private: explicit DataSourceManager(QObject *parent = 0); bool initAndOpenDB(QSqlDatabase &db, ConnectionDesc &connectionDesc); @@ -242,6 +263,7 @@ private: QList m_subqueries; QList m_proxies; QList m_tempVars; + QList m_csvs; QMultiMap m_groupFunctions; GroupFunctionFactory m_groupFunctionFactory; diff --git a/limereport/lrdatasourcemanagerintf.h b/limereport/lrdatasourcemanagerintf.h index e3a6ce7..040dd1d 100644 --- a/limereport/lrdatasourcemanagerintf.h +++ b/limereport/lrdatasourcemanagerintf.h @@ -31,6 +31,8 @@ #define LRDATASOURCEMANAGERINTF_H #include "lrcallbackdatasourceintf.h" +#include "lrglobal.h" +#include "lrdatasourceintf.h" class QVariant; class QString; @@ -39,12 +41,14 @@ namespace LimeReport{ class IDbCredentialsProvider{ public: + virtual ~IDbCredentialsProvider(){} virtual QString getUserName(const QString& connectionName) = 0; virtual QString getPassword(const QString& connectionName) = 0; }; class IDataSourceManager{ public: + virtual ~IDataSourceManager(){} virtual void setReportVariable(const QString& name, const QVariant& value) = 0; virtual void setDefaultDatabasePath(const QString &defaultDatabasePath) = 0; virtual void deleteVariable(const QString& name) = 0; @@ -56,8 +60,14 @@ public: virtual void clearUserVariables()=0; virtual ICallbackDatasource* createCallbackDatasource(const QString& name) = 0; virtual void registerDbCredentialsProvider(IDbCredentialsProvider* provider) = 0; - //virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; + virtual QStringList variableNames() = 0; + virtual bool variableIsMandatory(const QString& name) = 0; + virtual VariableDataType variableDataType(const QString& name) = 0; + virtual bool variableIsSystem(const QString& name) = 0; + virtual IDataSource* dataSource(const QString& name) = 0; + virtual IDataSourceHolder* dataSourceHolder(const QString& name) = 0; }; } #endif // LRDATASOURCEMANAGERINTF_H + diff --git a/limereport/lrdesignelementsfactory.h b/limereport/lrdesignelementsfactory.h index 3afc554..986c354 100644 --- a/limereport/lrdesignelementsfactory.h +++ b/limereport/lrdesignelementsfactory.h @@ -31,7 +31,6 @@ #define LRDESIGNELEMENTSFACTORY_H #include "lrbanddesignintf.h" -#include "lrpageheader.h" #include "lrattribsabstractfactory.h" #include "lrsimpleabstractfactory.h" #include "lrsingleton.h" diff --git a/limereport/lrdesignerplugininterface.h b/limereport/lrdesignerplugininterface.h new file mode 100644 index 0000000..f9cab7e --- /dev/null +++ b/limereport/lrdesignerplugininterface.h @@ -0,0 +1,28 @@ +#ifndef LRDESIGNERPLUGININTERFACE_H +#define LRDESIGNERPLUGININTERFACE_H + +#include +#include + +#include +#include "lrreportdesignwindowintrerface.h" + +QT_BEGIN_NAMESPACE +class QSettings; +class QMainWindow; +QT_END_NAMESPACE + +namespace LimeReport { + class ReportDesignWindow; + class ReportEnginePrivateInterface; +} + +class LimeReportDesignerPluginInterface { +public: + virtual ~LimeReportDesignerPluginInterface() { } + virtual LimeReport::ReportDesignWindowInterface* getDesignerWindow(LimeReport::ReportEnginePrivateInterface* report, QWidget *parent = 0, QSettings* settings=0) = 0; +}; + +Q_DECLARE_INTERFACE( LimeReportDesignerPluginInterface, "ru.limereport.LimeReport.DesignerPluginInterface/1.0" ) + +#endif // LRDESIGNERPLUGININTERFACE_H diff --git a/limereport/lrexporterintf.h b/limereport/lrexporterintf.h new file mode 100644 index 0000000..bbeb043 --- /dev/null +++ b/limereport/lrexporterintf.h @@ -0,0 +1,21 @@ +#ifndef LREXPORTERINTF_H +#define LREXPORTERINTF_H + +#include +#include +#include +#include "lrpageitemdesignintf.h" + +namespace LimeReport { + +class ReportExporterInterface { +public: + virtual ~ReportExporterInterface(){} + virtual bool exportPages(LimeReport::ReportPages pages, const QString& fileName, const QMap& params = QMap()) = 0; + virtual QString exporterName() = 0; + virtual QString exporterFileExt() = 0; + virtual QString hint() = 0; +}; + +} // namespace LimeReport +#endif // LREXPORTERINTF_H diff --git a/limereport/lrexportersfactory.h b/limereport/lrexportersfactory.h new file mode 100644 index 0000000..bbb5e56 --- /dev/null +++ b/limereport/lrexportersfactory.h @@ -0,0 +1,34 @@ +#ifndef LREXPORTERSFACTORY_H +#define LREXPORTERSFACTORY_H + +#include "lrattribsabstractfactory.h" +#include "lrexporterintf.h" + +namespace LimeReport{ + +typedef ReportExporterInterface* (*CreateExporter)(ReportEnginePrivate* parent); + +struct ExporterAttribs{ + QString m_alias; + QString m_tag; + ExporterAttribs(){} + ExporterAttribs(const QString& alias, const QString& tag):m_alias(alias),m_tag(tag){} + bool operator==( const ExporterAttribs &right) const { + return (m_alias==right.m_alias) && (m_tag==right.m_tag); + } +}; + +class ExportersFactory : public AttribsAbstractFactory +{ +private: + friend class Singleton; +private: + ExportersFactory(){} + ~ExportersFactory(){} + ExportersFactory(const ExportersFactory&){} + ExportersFactory& operator = (const ExportersFactory&){return *this;} +}; + +} // namespace LimeReport + +#endif // LREXPORTERSFACTORY_H diff --git a/limereport/lrfactoryinitializer.cpp b/limereport/lrfactoryinitializer.cpp index 5aef43a..f244d1a 100644 --- a/limereport/lrfactoryinitializer.cpp +++ b/limereport/lrfactoryinitializer.cpp @@ -15,9 +15,10 @@ #include "items/lrhorizontallayout.h" #include "items/lrimageitem.h" #include "items/lrshapeitem.h" +#include "items/lrchartitem.h" #include "lrdesignelementsfactory.h" - +#ifdef HAVE_REPORT_DESIGNER #include "objectinspector/lrobjectpropitem.h" #include "objectinspector/propertyItems/lrboolpropitem.h" #include "objectinspector/propertyItems/lrcolorpropitem.h" @@ -34,17 +35,26 @@ #include "objectinspector/propertyItems/lrstringpropitem.h" #include "items/lralignpropitem.h" #include "items/lrsubitemparentpropitem.h" +#endif #include "serializators/lrxmlbasetypesserializators.h" #include "serializators/lrxmlqrectserializator.h" #include "serializators/lrxmlserializatorsfactory.h" +#include "lrexportersfactory.h" +#include "lrexporterintf.h" +#include "exporters/lrpdfexporter.h" + void initResources(){ Q_INIT_RESOURCE(report); +#ifdef HAVE_REPORT_DESIGNER Q_INIT_RESOURCE(lobjectinspector); Q_INIT_RESOURCE(lrdatabrowser); Q_INIT_RESOURCE(items); Q_INIT_RESOURCE(lrscriptbrowser); + Q_INIT_RESOURCE(translationeditor); + Q_INIT_RESOURCE(dialogdesigner); +#endif } namespace LimeReport{ @@ -106,14 +116,18 @@ BaseDesignIntf* createHLayout(QObject *owner, LimeReport::BaseDesignIntf *paren return new HorizontalLayout(owner, parent); } -BaseDesignIntf * createImageItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ +BaseDesignIntf* createImageItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ return new ImageItem(owner,parent); } -BaseDesignIntf * createShapeItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ +BaseDesignIntf* createShapeItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ return new ShapeItem(owner,parent); } +BaseDesignIntf* createChartItem(QObject* owner, LimeReport::BaseDesignIntf* parent){ + return new ChartItem(owner,parent); +} + void initReportItems(){ initResources(); DesignElementsFactory::instance().registerCreator( @@ -139,6 +153,9 @@ void initReportItems(){ DesignElementsFactory::instance().registerCreator( "ShapeItem", LimeReport::ItemAttribs(QObject::tr("Shape Item"),"Item"), createShapeItem ); + DesignElementsFactory::instance().registerCreator( + "ChartItem", LimeReport::ItemAttribs(QObject::tr("Chart Item"),"Item"), createChartItem + ); DesignElementsFactory::instance().registerCreator( "Data", LimeReport::ItemAttribs(QObject::tr("Data"),LimeReport::Const::bandTAG), @@ -198,6 +215,8 @@ void initReportItems(){ } +#ifdef HAVE_REPORT_DESIGNER + ObjectPropItem * createBoolPropItem( QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) { @@ -275,7 +294,7 @@ ObjectPropItem * createReqtItem( ObjectPropItem * createReqtMMItem( QObject*object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly ){ - return new LimeReport::RectMMPropItem(object, objects, name, displayName, data, parent, readonly); + return new LimeReport::RectUnitPropItem(object, objects, name, displayName, data, parent, readonly); } ObjectPropItem * createStringPropItem( @@ -360,7 +379,7 @@ void initObjectInspectorProperties() ); } - +#endif SerializatorIntf * createIntSerializator(QDomDocument *doc, QDomElement *node){ return new LimeReport::XmlIntSerializator(doc,node); } @@ -427,4 +446,17 @@ void initSerializators() XMLAbstractSerializatorFactory::instance().registerCreator("QRectF", createQRectSerializator); } +LimeReport::ReportExporterInterface* createPDFExporter(ReportEnginePrivate* parent){ + return new LimeReport::PDFExporter(parent); +} + +void initExporters() +{ + ExportersFactory::instance().registerCreator( + "PDF", + LimeReport::ExporterAttribs(QObject::tr("Export to PDF"), "PDFExporter"), + createPDFExporter + ); +} + } //namespace LimeReport diff --git a/limereport/lrfactoryinitializer.h b/limereport/lrfactoryinitializer.h index 679d657..8810e55 100644 --- a/limereport/lrfactoryinitializer.h +++ b/limereport/lrfactoryinitializer.h @@ -3,4 +3,5 @@ namespace LimeReport{ void initReportItems(); void initObjectInspectorProperties(); void initSerializators(); + void initExporters(); } // namespace LimeReport diff --git a/limereport/lrglobal.cpp b/limereport/lrglobal.cpp index b4eb854..4d8da61 100644 --- a/limereport/lrglobal.cpp +++ b/limereport/lrglobal.cpp @@ -76,4 +76,17 @@ QVector normalizeCaptures(const QRegExp& reg){ return result; } +bool isColorDark(QColor color){ + qreal darkness = 1-(0.299*color.red() + 0.587*color.green() + 0.114*color.blue())/255; + if(darkness<0.5){ + return false; + } else { + return true; + } +} + +ReportError::ReportError(const QString& message):std::runtime_error(message.toStdString()){} +IExternalPainter::~IExternalPainter(){} +IPainterProxy::~IPainterProxy(){} + } //namespace LimeReport diff --git a/limereport/lrglobal.h b/limereport/lrglobal.h index ea8b279..da6ab47 100644 --- a/limereport/lrglobal.h +++ b/limereport/lrglobal.h @@ -52,8 +52,8 @@ namespace LimeReport { namespace Const{ - int const RESIZE_HANDLE_SIZE = 10; - int const SELECTION_PEN_SIZE = 4; + int const RESIZE_HANDLE_SIZE = 5; + int const SELECTION_PEN_SIZE = 1; int const MINIMUM_ITEM_WIDTH = 2*RESIZE_HANDLE_SIZE; int const MINIMUM_ITEM_HEIGHT = 2*RESIZE_HANDLE_SIZE; double const RESIZE_ZONE_OPACITY = 0.5; @@ -75,25 +75,31 @@ namespace Const{ const qreal BAND_NAME_TEXT_OPACITY = 0.6; const qreal SELECTION_OPACITY = 0.3; const QString FIELD_RX = "\\$D\\s*\\{\\s*([^{}]*)\\s*\\}"; - const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; - const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\s*\\}"; - const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; + const QString VARIABLE_RX = "\\$V\\s*\\{\\s*(?:([^\\{\\},]*)|(?:([^\\{\\}]*)\\s*,\\s*([^\\{\\}]*)))\\s*\\}"; + const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(?:(%1)|(?:(%1)\\s*,\\s*([^\\{\\}]*)))\\s*\\}"; + const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*((?:(?:\\\")|(?:))(?:(?:\\$(?:(?:D\\{\\s*\\w*..*\\})|(?:V\\{\\s*\\w*\\s*\\})|(?:S\\{.+\\})))|(?:\\w*))(?:(?:\\\")|(?:)))(?:(?:\\s*,\\s*(?:\\\"(\\w*)\\\"))|(?:))(?:(?:\\s*,\\s*(?:(\\w*)))|(?:))\\)"; - const int DATASOURCE_INDEX = 3;//4; - const int VALUE_INDEX = 2; //2; - const int EXPRESSION_ARGUMENT_INDEX = 1;//3; + const int DATASOURCE_INDEX = 3; + const int VALUE_INDEX = 2; + const int EXPRESSION_ARGUMENT_INDEX = 1; const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; const int SCENE_MARGIN = 50; + const QString FUNCTION_MANAGER_NAME = "LimeReport"; + const QString DATAFUNCTIONS_MANAGER_NAME = "DatasourceFunctions"; + const QString EOW("~!@#$%^&*()+{}|:\"<>?,/;'[]\\-="); + const int DEFAULT_TAB_INDENTION = 4; + const int DOCKWIDGET_MARGINS = 4; } QString extractClassName(QString className); QString escapeSimbols(const QString& value); QString replaceHTMLSymbols(const QString &value); QVector normalizeCaptures(const QRegExp ®); + bool isColorDark(QColor color); enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols}; - enum RenderPass {FirstPass, SecondPass}; + enum RenderPass {FirstPass = 1, SecondPass = 2}; enum ArrangeType {AsNeeded, Force}; enum ScaleType {FitWidth, FitPage, OneToOne, Percents}; enum PreviewHint{ShowAllPreviewBars = 0, @@ -108,7 +114,7 @@ namespace Const{ class ReportError : public std::runtime_error{ public: - ReportError(const QString& message):std::runtime_error(message.toStdString()){} + ReportError(const QString& message); }; class ReportSettings{ @@ -121,12 +127,38 @@ namespace Const{ bool m_suppressAbsentFieldsAndVarsWarnings; }; -#ifdef HAVE_QT4 + class IExternalPainter{ + public: + virtual void paintByExternalPainter(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem* options) = 0; + virtual ~IExternalPainter(); + }; + + class IPainterProxy{ + public: + virtual void setExternalPainter(IExternalPainter* externalPainter) = 0; + virtual ~IPainterProxy(); + }; + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) typedef QStyleOptionViewItemV4 StyleOptionViewItem; #else typedef QStyleOptionViewItem StyleOptionViewItem; #endif +#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) + Q_NAMESPACE +#endif + class Enums + { + public: + enum VariableDataType {Undefined, String, Bool, Int, Real, Date, Time, DateTime}; + Q_ENUMS(VariableDataType) + private: + Enums(){} + Q_GADGET + }; + + typedef Enums::VariableDataType VariableDataType; } // namespace LimeReport diff --git a/limereport/lrgroupfunctions.cpp b/limereport/lrgroupfunctions.cpp index c265dfc..1061ea5 100644 --- a/limereport/lrgroupfunctions.cpp +++ b/limereport/lrgroupfunctions.cpp @@ -32,6 +32,7 @@ #include "lrbanddesignintf.h" #include "lritemdesignintf.h" #include "lrscriptenginemanager.h" +#include "lrpageitemdesignintf.h" #include @@ -50,6 +51,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) QString field = rxField.cap(1); if (m_dataManager->containsField(field)){ m_values.push_back(m_dataManager->fieldData(field)); + m_valuesByBand.insert(band, m_dataManager->fieldData(field)); } else { setInvalid(tr("Field \"%1\" not found").arg(m_data)); } @@ -60,6 +62,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) QString var = rxVar.cap(1); if (m_dataManager->containsVariable(var)){ m_values.push_back(m_dataManager->variable(var)); + m_valuesByBand.insert(band, m_dataManager->variable(var)); } else { setInvalid(tr("Variable \"%1\" not found").arg(m_data)); } @@ -70,6 +73,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) QVariant value = sm.evaluateScript(m_data); if (value.isValid()){ m_values.push_back(value); + m_valuesByBand.insert(band, value); } else { setInvalid(tr("Wrong script syntax \"%1\" ").arg(m_data)); } @@ -78,10 +82,12 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) case ContentItem:{ QString itemName = m_data; ContentItemDesignIntf* item = dynamic_cast(band->childByName(itemName.remove('"'))); - if (item) + if (item){ m_values.push_back(item->content()); - else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) { + m_valuesByBand.insert(band, item->content()); + } else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) { m_values.push_back(1); + m_valuesByBand.insert(band, 1); } else setInvalid(tr("Item \"%1\" not found").arg(m_data)); break; @@ -112,9 +118,8 @@ QVariant GroupFunction::multiplication(QVariant value1, QVariant value2) } GroupFunction::GroupFunction(const QString &expression, const QString &dataBandName, DataSourceManager* dataManager) - :m_dataBandName(dataBandName), m_dataManager(dataManager),m_isValid(true), m_errorMessage("") + :m_data(expression), m_dataBandName(dataBandName), m_dataManager(dataManager), m_isValid(true), m_errorMessage("") { - m_data = expression; QRegExp rxField(Const::FIELD_RX,Qt::CaseInsensitive); QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive); QRegExp rxScript(Const::SCRIPT_RX,Qt::CaseInsensitive); @@ -153,20 +158,32 @@ GroupFunctionFactory::~GroupFunctionFactory() m_creators.clear(); } -QVariant SumGroupFunction::calculate() +QVariant SumGroupFunction::calculate(PageItemDesignIntf *page) { - QVariant res=0; - foreach(QVariant value,values()){ - res=addition(res,value); + QVariant res = 0; + if (!page){ + foreach(QVariant value,values()){ + res = addition(res,value); + } + } else { + foreach (BandDesignIntf* band, page->bands()) { + res = addition(res, m_valuesByBand.value(band)); + } } return res; } -QVariant AvgGroupFunction::calculate() +QVariant AvgGroupFunction::calculate(PageItemDesignIntf *page) { - QVariant res=QVariant(); - foreach(QVariant value,values()){ - res=addition(res,value); + QVariant res = QVariant(); + if (!page){ + foreach(QVariant value,values()){ + res=addition(res,value); + } + } else { + foreach (BandDesignIntf* band, page->bands()) { + res = addition(res, m_valuesByBand.value(band)); + } } if (!res.isNull()&&(values().count()>0)){ res=division(res,values().count()); @@ -174,29 +191,58 @@ QVariant AvgGroupFunction::calculate() return res; } -QVariant MinGroupFunction::calculate() +QVariant MinGroupFunction::calculate(PageItemDesignIntf *page) { //TODO: check variant type QVariant res = QVariant(); - if (!values().empty()) res = values().at(0); - foreach(QVariant value, values()){ - if (res.toDouble()>value.toDouble()) res = value; + if (!page){ + if (!values().empty()) res = values().at(0); + foreach(QVariant value, values()){ + if (res.toDouble() > value.toDouble()) res = value; + } + } else { + if (!page->bands().empty()) res = m_valuesByBand.value(page->bands().at(0)); + foreach (BandDesignIntf* band, page->bands()) { + if (res.toDouble() > m_valuesByBand.value(band).toDouble()) res = m_valuesByBand.value(band); + } } return res; } -QVariant MaxGroupFunction::calculate() +QVariant MaxGroupFunction::calculate(PageItemDesignIntf *page) { //TODO: check variant type QVariant res = QVariant(); - if (!values().empty()) res = values().at(0); - foreach(QVariant value, values()){ - if (res.toDouble()bands().empty()) res = m_valuesByBand.value(page->bands().at(0)); + foreach (BandDesignIntf* band, page->bands()) { + if (res.toDouble() < m_valuesByBand.value(band).toDouble()) res = m_valuesByBand.value(band); + } } return res; } +QVariant CountGroupFunction::calculate(PageItemDesignIntf *page){ + if (!page){ + return values().count(); + } else { + int res = 0; + foreach (BandDesignIntf* band, page->bands()) { + if (!m_valuesByBand.value(band).isNull()){ + res++; + } + } + return res; + } +} + } //namespace LimeReport diff --git a/limereport/lrgroupfunctions.h b/limereport/lrgroupfunctions.h index f85a0bd..28cc08b 100644 --- a/limereport/lrgroupfunctions.h +++ b/limereport/lrgroupfunctions.h @@ -38,6 +38,7 @@ namespace LimeReport{ class DataSourceManager; class BandDesignIntf; +class PageItemDesignIntf; class GroupFunction : public QObject{ Q_OBJECT @@ -50,8 +51,9 @@ public: const QString& data(){return m_data;} const QString& error(){return m_errorMessage;} QVector& values(){return m_values;} + QHash m_valuesByBand; const QString& dataBandName(){return m_dataBandName;} - virtual QVariant calculate()=0; + virtual QVariant calculate(PageItemDesignIntf* page = 0)=0; public slots: void slotBandRendered(BandDesignIntf* band); protected: @@ -95,7 +97,7 @@ public: CountGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("COUNT");} protected: - virtual QVariant calculate(){return values().count();} + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class SumGroupFunction :public GroupFunction{ @@ -104,7 +106,7 @@ public: SumGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("SUM");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class AvgGroupFunction :public GroupFunction{ @@ -113,7 +115,7 @@ public: AvgGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("AVG");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class MinGroupFunction :public GroupFunction{ @@ -122,7 +124,7 @@ public: MinGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("MIN");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class MaxGroupFunction :public GroupFunction{ @@ -131,7 +133,7 @@ public: MaxGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("MAX");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; template diff --git a/limereport/lritemdesignintf.cpp b/limereport/lritemdesignintf.cpp index 167ac27..f90a90d 100644 --- a/limereport/lritemdesignintf.cpp +++ b/limereport/lritemdesignintf.cpp @@ -66,11 +66,13 @@ void ItemDesignIntf::setItemLocation(LocationType location) } else { if (scene()){ PageItemDesignIntf* page = dynamic_cast(scene())->pageItem(); - QPointF parentPos = page->mapFromItem(parentItem(),x(),y()); - setParentItem(page); - setParent(page); - setPos(parentPos); - emit itemLocationChanged(this, page); + if (page){ + QPointF parentPos = page->mapFromItem(parentItem(),x(),y()); + setParentItem(page); + setParent(page); + setPos(parentPos); + emit itemLocationChanged(this, page); + } } } notify("locationType",oldValue,location); @@ -118,4 +120,20 @@ void ItemDesignIntf::initFlags() Spacer::Spacer(QObject *owner, QGraphicsItem *parent) :ItemDesignIntf("Spacer",owner,parent){} +QMap ContentItemDesignIntf::getStringForTranslation(){ + QMapmap; + map.insert("content",content()); + return map; +} + +bool ContentItemDesignIntf::isContentBackedUp() const +{ + return m_contentBackedUp; +} + +void ContentItemDesignIntf::setContentBackedUp(bool contentBackedUp) +{ + m_contentBackedUp = contentBackedUp; +} + }// namespace LimeReport diff --git a/limereport/lritemdesignintf.h b/limereport/lritemdesignintf.h index 808666c..a805542 100644 --- a/limereport/lritemdesignintf.h +++ b/limereport/lritemdesignintf.h @@ -63,6 +63,7 @@ private: class Spacer :public ItemDesignIntf{ public: Spacer(QObject* owner,QGraphicsItem* parent); + bool isEmpty() const {return true;} protected: BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent){ return new Spacer(owner, parent); @@ -74,9 +75,17 @@ class ContentItemDesignIntf : public ItemDesignIntf Q_OBJECT public: ContentItemDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0) - :ItemDesignIntf(xmlTypeName,owner,parent){} + :ItemDesignIntf(xmlTypeName,owner,parent), m_contentBackedUp(false){} virtual QString content() const = 0; virtual void setContent(const QString& value) = 0; + QMap getStringForTranslation(); + void backupContent(){ m_contentBackUp = content(); m_contentBackedUp = true;} + void restoreContent() {setContent(m_contentBackUp);} + bool isContentBackedUp() const; + void setContentBackedUp(bool contentBackedUp); +private: + QString m_contentBackUp; + bool m_contentBackedUp; }; class LayoutDesignIntf : public ItemDesignIntf{ diff --git a/limereport/lritemscontainerdesignitf.cpp b/limereport/lritemscontainerdesignitf.cpp index 0e31eb8..ea5eafc 100644 --- a/limereport/lritemscontainerdesignitf.cpp +++ b/limereport/lritemscontainerdesignitf.cpp @@ -93,16 +93,27 @@ void ItemsContainerDesignInft::arrangeSubItems(RenderPass pass, DataSourceManage qreal ItemsContainerDesignInft::findMaxBottom() const { - qreal maxBottom=0; + qreal maxBottom = 0; foreach(QGraphicsItem* item,childItems()){ BaseDesignIntf* subItem = dynamic_cast(item); if(subItem) if ( subItem->isVisible() && (subItem->geometry().bottom()>maxBottom) ) - maxBottom=subItem->geometry().bottom(); + maxBottom = subItem->geometry().bottom(); } return maxBottom; } +qreal ItemsContainerDesignInft::findMinTop() const{ + qreal minTop = height(); + foreach(QGraphicsItem* item,childItems()){ + BaseDesignIntf* subItem = dynamic_cast(item); + if(subItem) + if ( subItem->isVisible() && (subItem->geometry().top()geometry().top(); + } + return minTop > 0 ? minTop : 0; +} + qreal ItemsContainerDesignInft::findMaxHeight() const { qreal maxHeight=0; diff --git a/limereport/lritemscontainerdesignitf.h b/limereport/lritemscontainerdesignitf.h index 1526ac7..b9aa421 100644 --- a/limereport/lritemscontainerdesignitf.h +++ b/limereport/lritemscontainerdesignitf.h @@ -37,15 +37,17 @@ struct ItemSortContainer { typedef QSharedPointer< ItemSortContainer > PItemSortContainer; bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2); -class ItemsContainerDesignInft : public BaseDesignIntf{ +class ItemsContainerDesignInft : public BookmarkContainerDesignIntf{ + Q_OBJECT public: ItemsContainerDesignInft(const QString& xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0): - BaseDesignIntf(xmlTypeName, owner, parent){} + BookmarkContainerDesignIntf(xmlTypeName, owner, parent){} protected: void snapshotItemsLayout(); void arrangeSubItems(RenderPass pass, DataSourceManager *dataManager, ArrangeType type = AsNeeded); qreal findMaxBottom() const; qreal findMaxHeight() const; + qreal findMinTop() const; private: QVector m_containerItems; diff --git a/limereport/lrpagedesignintf.cpp b/limereport/lrpagedesignintf.cpp index 9c3ff53..720d7bb 100644 --- a/limereport/lrpagedesignintf.cpp +++ b/limereport/lrpagedesignintf.cpp @@ -31,6 +31,7 @@ #include "lrbasedesignintf.h" #include "lrtextitem.h" #include "lrhorizontallayout.h" +#include "lrverticallayout.h" //#include "lrbarcodeitem.h" #include "lrbanddesignintf.h" #include "lrbandsmanager.h" @@ -90,7 +91,8 @@ PageDesignIntf::PageDesignIntf(QObject *parent): m_movedItem(0), m_joinItem(0), m_magneticMovement(false), - m_reportSettings(0) + m_reportSettings(0), + m_currentPage(0) { m_reportEditor = dynamic_cast(parent); updatePageRect(); @@ -126,7 +128,7 @@ void PageDesignIntf::updatePageRect() } this->setSceneRect(-Const::SCENE_MARGIN, -Const::SCENE_MARGIN, pageItem()->geometry().width() + Const::SCENE_MARGIN*2, - pageItem()->geometry().height() + Const::SCENE_MARGIN*2); + pageItem()->boundingRect().height() + Const::SCENE_MARGIN*2); emit sceneRectChanged(sceneRect()); } @@ -239,7 +241,9 @@ void PageDesignIntf::startInsertMode(const QString &ItemType) m_insertItemType = ItemType; m_itemInsertRect = this->addRect(0, 0, 200, 50); m_itemInsertRect->setVisible(false); - m_itemInsertRect->setParentItem(pageItem()); + PageItemDesignIntf* page = pageItem() ? pageItem() : getCurrentPage(); + if (page) + m_itemInsertRect->setParentItem(page); } void PageDesignIntf::startEditMode() @@ -252,18 +256,22 @@ void PageDesignIntf::startEditMode() PageItemDesignIntf *PageDesignIntf::pageItem() { - return m_pageItem.data(); + return m_currentPage ? m_currentPage : m_pageItem.data(); } void PageDesignIntf::setPageItem(PageItemDesignIntf::Ptr pageItem) { + if (pageItem.isNull()) return; if (!m_pageItem.isNull()) { removeItem(m_pageItem.data()); m_pageItem->setParent(0); } m_pageItem = pageItem; m_pageItem->setItemMode(itemMode()); - setSceneRect(pageItem->rect().adjusted(-10*Const::mmFACTOR,-10*Const::mmFACTOR,10*Const::mmFACTOR,10*Const::mmFACTOR)); + setSceneRect(pageItem->rect().adjusted(-10 * Const::mmFACTOR, + -10 * Const::mmFACTOR, + 10 * Const::mmFACTOR, + 10 * Const::mmFACTOR)); addItem(m_pageItem.data()); registerItem(m_pageItem.data()); } @@ -285,7 +293,12 @@ void PageDesignIntf::setPageItems(QList pages) curHeight+=pageItem->height()+20; if (curWidthwidth()) curWidth=pageItem->width(); } - setSceneRect(QRectF(0,0,curWidth,curHeight).adjusted(-10*Const::mmFACTOR,-10*Const::mmFACTOR,10*Const::mmFACTOR,10*Const::mmFACTOR)); + setSceneRect(QRectF( 0, 0, curWidth,curHeight).adjusted( -10 * Const::mmFACTOR, + -10 * Const::mmFACTOR, + 10 * Const::mmFACTOR, + 10 * Const::mmFACTOR)); + if (m_reportPages.count()>0) + m_currentPage = m_reportPages.at(0).data(); } @@ -333,13 +346,24 @@ void PageDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) m_selectionRect->setRect(selectionRect); } - if ((m_insertMode) && (pageItem()->rect().contains(pageItem()->mapFromScene(event->scenePos())))) { + PageItemDesignIntf* page = pageItem() ? pageItem() : getCurrentPage(); + if ((m_insertMode) && (page && page->rect().contains(page->mapFromScene(event->scenePos())))) { if (!m_itemInsertRect->isVisible()) m_itemInsertRect->setVisible(true); - qreal posY = div(pageItem()->mapFromScene(event->scenePos()).y(), verticalGridStep()).quot * verticalGridStep(); - qreal posX = div(pageItem()->mapFromScene(event->scenePos()).x(), verticalGridStep()).quot * horizontalGridStep(); + qreal posY = div(page->mapFromScene(event->scenePos()).y(), verticalGridStep()).quot * verticalGridStep(); + qreal posX = div(page->mapFromScene(event->scenePos()).x(), verticalGridStep()).quot * horizontalGridStep(); m_itemInsertRect->setPos(posX,posY); + if (magneticMovement()){ + rectMoved( + QRectF(m_itemInsertRect->pos().x(), + m_itemInsertRect->pos().y(), + m_itemInsertRect->boundingRect().width(), + m_itemInsertRect->boundingRect().height() + ) + ); + } + } else { + if (m_insertMode) m_itemInsertRect->setVisible(false); } - else { if (m_insertMode) m_itemInsertRect->setVisible(false); } QGraphicsScene::mouseMoveEvent(event); } @@ -477,29 +501,25 @@ QSizeF PageDesignIntf::placeSizeOnGrid(QSizeF size){ BaseDesignIntf *PageDesignIntf::addReportItem(const QString &itemType, QPointF pos, QSizeF size) { - BandDesignIntf *band=0; - foreach(QGraphicsItem * item, items(pos)) { - band = dynamic_cast(item); - if (band) break; - } - + BandDesignIntf *band = bandAt(pos); if (band) { BaseDesignIntf *reportItem = addReportItem(itemType, band, band); -// QPointF insertPos = band->mapFromScene(pos); -// insertPos = QPointF(div(insertPos.x(), horizontalGridStep()).quot * horizontalGridStep(), -// div(insertPos.y(), verticalGridStep()).quot * verticalGridStep()); - reportItem->setPos(placePosOnGrid(band->mapFromScene(pos))); reportItem->setSize(placeSizeOnGrid(size)); + reportItem->setUnitType(pageItem()->unitType()); return reportItem; } else { - BaseDesignIntf *reportItem = addReportItem(itemType, pageItem(), pageItem()); - reportItem->setPos(placePosOnGrid(pageItem()->mapFromScene(pos))); - reportItem->setSize(placeSizeOnGrid(size)); - ItemDesignIntf* ii = dynamic_cast(reportItem); - if (ii) - ii->setItemLocation(ItemDesignIntf::Page); - return reportItem; + PageItemDesignIntf* page = pageItem() ? pageItem() : m_currentPage; + if (page){ + BaseDesignIntf *reportItem = addReportItem(itemType, page, page); + reportItem->setPos(placePosOnGrid(page->mapFromScene(pos))); + reportItem->setSize(placeSizeOnGrid(size)); + reportItem->setUnitType(pageItem()->unitType()); + ItemDesignIntf* ii = dynamic_cast(reportItem); + if (ii) + ii->setItemLocation(ItemDesignIntf::Page); + return reportItem; + } } return 0; @@ -510,6 +530,7 @@ BaseDesignIntf *PageDesignIntf::addReportItem(const QString &itemType, QObject * BaseDesignIntf *item = LimeReport::DesignElementsFactory::instance().objectCreator(itemType)((owner) ? owner : pageItem(), (parent) ? parent : pageItem()); item->setObjectName(genObjectName(*item)); item->setItemTypeName(itemType); + item->setUnitType(pageItem()->unitType()); registerItem(item); return item; } @@ -1061,6 +1082,22 @@ void PageDesignIntf::changeSelectedGroupProperty(const QString &name, const QVar } } +PageItemDesignIntf* PageDesignIntf::getCurrentPage() const +{ + return m_currentPage; +} + +void PageDesignIntf::setCurrentPage(PageItemDesignIntf* currentPage) +{ + if (m_currentPage != currentPage ){ + if (m_currentPage) m_currentPage->setItemMode(PreviewMode); + m_currentPage = currentPage; + if (m_itemMode == DesignMode){ + m_currentPage->setItemMode(DesignMode); + } + } +} + ReportSettings *PageDesignIntf::getReportSettings() const { return m_reportSettings; @@ -1106,9 +1143,61 @@ void PageDesignIntf::endUpdate() emit pageUpdateFinished(this); } + +void PageDesignIntf::activateItemToJoin(QRectF itemRect, QList& items){ + QRectF r1(itemRect.x(), itemRect.y()-50, itemRect.width(), itemRect.height()+100); + QRectF r2(itemRect.x()-50, itemRect.y(), itemRect.width()+100, itemRect.height()); + qreal maxSquare = 0; + + if (m_joinItem) { + m_joinItem->turnOnJoinMarker(false); + m_joinItem = 0; + } + + foreach(ItemProjections p, items){ + qreal tmpSquare = qMax(p.square(r1)/itemRect.width(),p.square(r2)/itemRect.height()); + if (tmpSquare>maxSquare) { + maxSquare = tmpSquare; + m_joinItem = p.item(); + if (p.square(r1)/itemRect.width() > p.square(r2) / itemRect.height()) + m_joinType = Width; + else + m_joinType = Height; + } + } + + if (m_joinItem) m_joinItem->turnOnJoinMarker(true); +} + +void PageDesignIntf::selectAllChildren(BaseDesignIntf *item) +{ + if (item) + foreach(BaseDesignIntf* child, item->childBaseItems()){ + child->setSelected(true); + } +} + +void PageDesignIntf::rectMoved(QRectF itemRect, BaseDesignIntf* container){ + if (!container){ + container = bandAt(QPointF(itemRect.topLeft())); + if (!container) container = this->pageItem(); + } + + if (container){ + m_projections.clear(); + foreach(BaseDesignIntf* bi, container->childBaseItems()){ + m_projections.append(ItemProjections(bi)); + } + } + + activateItemToJoin(itemRect, m_projections); + +} + void PageDesignIntf::itemMoved(BaseDesignIntf *item) { if (m_movedItem!=item){ + m_movedItem = item; BaseDesignIntf* curItem = dynamic_cast(item->parentItem()); ; while (curItem){ m_movedItemContainer = dynamic_cast(curItem); @@ -1126,28 +1215,29 @@ void PageDesignIntf::itemMoved(BaseDesignIntf *item) } } - QRectF r1(item->pos().x(),item->pos().y()-50,item->width(),item->height()+100); - QRectF r2(item->pos().x()-50,item->pos().y(),item->width()+100,item->height()); - qreal maxSquare = 0; + activateItemToJoin(item->geometry(), m_projections); +// QRectF r1(item->pos().x(),item->pos().y()-50,item->width(),item->height()+100); +// QRectF r2(item->pos().x()-50,item->pos().y(),item->width()+100,item->height()); +// qreal maxSquare = 0; - if (m_joinItem) { - m_joinItem->turnOnJoinMarker(false); - m_joinItem = 0; - } +// if (m_joinItem) { +// m_joinItem->turnOnJoinMarker(false); +// m_joinItem = 0; +// } - foreach(ItemProjections p, m_projections){ - qreal tmpSquare = qMax(p.square(r1)/item->width(),p.square(r2)/item->height()); - if (tmpSquare>maxSquare) { - maxSquare = tmpSquare; - m_joinItem = p.item(); - if (p.square(r1)/item->width()>p.square(r2)/item->height()) - m_joinType = Width; - else - m_joinType = Height; - } - } +// foreach(ItemProjections p, m_projections){ +// qreal tmpSquare = qMax(p.square(r1)/item->width(),p.square(r2)/item->height()); +// if (tmpSquare>maxSquare) { +// maxSquare = tmpSquare; +// m_joinItem = p.item(); +// if (p.square(r1)/item->width()>p.square(r2)/item->height()) +// m_joinType = Width; +// else +// m_joinType = Height; +// } +// } - if (m_joinItem) m_joinItem->turnOnJoinMarker(true); +// if (m_joinItem) m_joinItem->turnOnJoinMarker(true); } @@ -1252,9 +1342,9 @@ BaseDesignIntf* PageDesignIntf::findDestObject(BaseDesignIntf* item){ void PageDesignIntf::paste() { QClipboard *clipboard = QApplication::clipboard(); - BaseDesignIntf* destItem = 0; ItemsReaderIntf::Ptr reader = StringXMLreader::create(clipboard->text()); if (reader->first() && reader->itemType() == "Object"){ + BaseDesignIntf* destItem = 0; if (!selectedItems().isEmpty()) destItem = findDestObject(dynamic_cast(selectedItems().at(0))); else @@ -1374,7 +1464,7 @@ void PageDesignIntf::alignToLeft() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setPos(QPoint(m_firstSelectedItem->pos().x(), item->pos().y())); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1391,7 +1481,7 @@ void PageDesignIntf::alignToRigth() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setPos(QPoint(m_firstSelectedItem->geometry().right() - bdItem->width(), bdItem->pos().y())); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1408,7 +1498,7 @@ void PageDesignIntf::alignToVCenter() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setPos(QPoint((m_firstSelectedItem->geometry().right() - m_firstSelectedItem->width() / 2) - bdItem->width() / 2, bdItem->pos().y())); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1425,7 +1515,7 @@ void PageDesignIntf::alignToTop() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setPos(QPoint(bdItem->pos().x(), m_firstSelectedItem->pos().y())); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1442,7 +1532,7 @@ void PageDesignIntf::alignToBottom() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setPos(QPoint(bdItem->pos().x(), m_firstSelectedItem->geometry().bottom() - bdItem->height())); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1459,7 +1549,7 @@ void PageDesignIntf::alignToHCenter() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setPos(QPoint(bdItem->pos().x(), (m_firstSelectedItem->geometry().bottom() - m_firstSelectedItem->height() / 2) - bdItem->height() / 2)); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1476,7 +1566,7 @@ void PageDesignIntf::sameWidth() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setWidth(m_firstSelectedItem->width()); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1493,7 +1583,7 @@ void PageDesignIntf::sameHeight() CommandGroup::Ptr cm = CommandGroup::create(); foreach(QGraphicsItem * item, selectedItems()) { BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { + if (bdItem && !bdItem->isGeometryLocked()) { QRectF oldGeometry = bdItem->geometry(); bdItem->setHeight(m_firstSelectedItem->height()); CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "geometry", oldGeometry, bdItem->geometry()); @@ -1547,6 +1637,46 @@ void PageDesignIntf::addHLayout() } +void PageDesignIntf::addVLayout() +{ + if (selectedItems().isEmpty()) return; + + QList si = selectedItems(); + QList::iterator it = si.begin(); + + int itemsCount = 0; + for (; it != si.end();) { + if (dynamic_cast(*it)){ + itemsCount++; + break; + } + ++it; + }; + + if (itemsCount == 0) return; + + for (; it != si.end();) { + if (!dynamic_cast(*it)) { + (*it)->setSelected(false); + it = si.erase(it); + } + else ++it; + } + + if (!si.isEmpty()){ + it = si.begin(); + QGraphicsItem* elementsParent = (*it)->parentItem(); + for (; it != si.end();++it) { + if ((*it)->parentItem()!=elementsParent){ + QMessageBox::information(0,QObject::tr("Attention!"),QObject::tr("Selected elements have different parent containers")); + return; + } + } + CommandIf::Ptr cm = InsertVLayoutCommand::create(this); + saveCommand(cm,true); + } +} + bool hLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2) { return c1->pos().x() < c2->pos().x(); @@ -1591,6 +1721,50 @@ HorizontalLayout* PageDesignIntf::internalAddHLayout() return 0; } +bool vLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2) +{ + return c1->pos().y() < c2->pos().y(); +} + +VerticalLayout* PageDesignIntf::internalAddVLayout() +{ + if (m_firstSelectedItem && (selectedItems().count() > 1)) { + + QList si = selectedItems(); + QList::iterator it = si.begin(); + qSort(si.begin(), si.end(), vLayoutLessThen); + it = si.begin(); + + if (si.count() > 1) { + + it = si.begin(); + ItemDesignIntf *firstElement = dynamic_cast(*it); + + VerticalLayout *layout = new VerticalLayout(firstElement->parent(), firstElement->parentItem()); + layout->setItemLocation(firstElement->itemLocation()); + layout->setPos(firstElement->pos()); + layout->setWidth(firstElement->width()); + layout->setHeight(0); + + for (; it != si.end(); ++it) { + BaseDesignIntf *bdItem = dynamic_cast(*it); + layout->addChild(bdItem); + } + + foreach(QGraphicsItem * item, selectedItems()) { + item->setSelected(false); + } + + layout->setObjectName(genObjectName(*layout)); + layout->setItemTypeName("VerticalLayout"); + layout->setSelected(true); + registerItem(layout); + return layout; + } + } + return 0; +} + void PageDesignIntf::setFont(const QFont& font) { changeSelectedGroupProperty("font",font); @@ -1606,20 +1780,53 @@ void PageDesignIntf::setBorders(const BaseDesignIntf::BorderLines& border) changeSelectedGroupProperty("borders", (int)border); } +void PageDesignIntf::lockSelectedItems() +{ + foreach(QGraphicsItem* graphicItem, selectedItems()){ + BaseDesignIntf* item = dynamic_cast(graphicItem); + if (item) item->setProperty("geometryLocked", true); + } +} + +void PageDesignIntf::unlockSelectedItems() +{ + foreach(QGraphicsItem* graphicItem, selectedItems()){ + BaseDesignIntf* item = dynamic_cast(graphicItem); + if (item) item->setProperty("geometryLocked", false); + } +} + + +void PageDesignIntf::selectOneLevelItems() +{ + foreach(QGraphicsItem* graphicItem, selectedItems()){ + BaseDesignIntf* item = dynamic_cast(graphicItem->parentItem()); + if (item) + selectAllChildren(item); + else + selectAllChildren(dynamic_cast(graphicItem)); + } +} + void PageDesignIntf::removeAllItems() { pageItem()->clear(); m_commandsList.clear(); } -void PageDesignIntf::setItemMode(BaseDesignIntf::ItemMode state) +void PageDesignIntf::setItemMode(BaseDesignIntf::ItemMode mode) { - m_itemMode = state; - foreach(QGraphicsItem * item, items()) { - BaseDesignIntf *reportItem = dynamic_cast(item); - - if (reportItem) { - reportItem->setItemMode(itemMode()); + if (m_itemMode != mode){ + m_itemMode = mode; + if (m_currentPage) { + m_currentPage->setItemMode(mode); + } else { + foreach(QGraphicsItem * item, items()) { + BaseDesignIntf *reportItem = dynamic_cast(item); + if (reportItem) { + reportItem->setItemMode(itemMode()); + } + } } } } @@ -1644,6 +1851,16 @@ QList PageDesignIntf::reportItemsByName(const QString &name){ return result; } +BandDesignIntf *PageDesignIntf::bandAt(QPointF pos) +{ + BandDesignIntf *band=0; + foreach(QGraphicsItem * item, items(pos)) { + band = dynamic_cast(item); + if (band) break; + } + return band; +} + void CommandIf::addCommand(Ptr command, bool execute) { Q_UNUSED(command) @@ -1915,7 +2132,11 @@ bool PosChangedCommand::doIt() for (int i = 0; i < m_newPos.count(); i++) { BaseDesignIntf *reportItem = page()->reportItemByName(m_newPos[i].objectName); - if (reportItem && (reportItem->pos() != m_newPos[i].pos)) reportItem->setPos(m_newPos[i].pos); + if (reportItem && (reportItem->pos() != m_newPos[i].pos)){ + QPointF oldValue = reportItem->pos(); + reportItem->setPos(m_newPos[i].pos); + emit reportItem->posChanged(reportItem, oldValue, reportItem->pos()); + } } return true; @@ -1926,7 +2147,11 @@ void PosChangedCommand::undoIt() for (int i = 0; i < m_oldPos.count(); i++) { BaseDesignIntf *reportItem = page()->reportItemByName(m_oldPos[i].objectName); - if (reportItem && (reportItem->pos() != m_oldPos[i].pos)) reportItem->setPos(m_oldPos[i].pos); + if (reportItem && (reportItem->pos() != m_oldPos[i].pos)){ + QPointF oldValue = reportItem->pos(); + reportItem->setPos(m_oldPos[i].pos); + reportItem->emitPosChanged(oldValue, reportItem->pos()); + } } } @@ -2106,6 +2331,7 @@ void InsertHLayoutCommand::undoIt() bi->setPos(m_elements.value(bi->objectName())); bi->setFixedPos(false); bi->setPossibleResizeDirectionFlags(BaseDesignIntf::AllDirections); + bi->setVisible(true); } } page()->removeReportItem(layout,false); @@ -2244,6 +2470,59 @@ qreal ItemProjections::square(BaseDesignIntf *item) return square(QRectF(item->pos().x(),item->pos().y(),item->width(),item->height())); } +CommandIf::Ptr InsertVLayoutCommand::create(PageDesignIntf* page) +{ + InsertVLayoutCommand *command = new InsertVLayoutCommand(); + command->setPage(page); + + QList si = page->selectedItems(); + QList::iterator it = si.begin(); + + BaseDesignIntf* parentItem = dynamic_cast((*it)->parentItem()); + command->m_oldParentName = (parentItem)?(parentItem->objectName()):""; + + for(it = si.begin();it!=si.end();++it){ + BaseDesignIntf* bi = dynamic_cast(*it); + if (bi) + command->m_elements.insert(bi->objectName(),bi->pos()); + } + + return CommandIf::Ptr(command); +} + +bool InsertVLayoutCommand::doIt() +{ + foreach (QString itemName, m_elements.keys()) { + BaseDesignIntf* bi = page()->reportItemByName(itemName); + if (bi) + bi->setSelected(true); + } + LayoutDesignIntf* layout = page()->internalAddVLayout(); + if (layout) + m_layoutName = layout->objectName(); + return layout != 0; +} + +void InsertVLayoutCommand::undoIt() +{ + VerticalLayout* layout = dynamic_cast(page()->reportItemByName(m_layoutName)); + if (layout){ + foreach(QGraphicsItem* item, layout->childBaseItems()){ + BaseDesignIntf* bi = dynamic_cast(item); + BaseDesignIntf* parent = page()->reportItemByName(m_oldParentName); + if (bi && parent){ + bi->setParentItem(parent); + bi->setParent(parent); + bi->setPos(m_elements.value(bi->objectName())); + bi->setFixedPos(false); + bi->setPossibleResizeDirectionFlags(BaseDesignIntf::AllDirections); + bi->setVisible(true); + } + } + page()->removeReportItem(layout,false); + } +} + CommandIf::Ptr BandSwapCommand::create(PageDesignIntf *page, const QString &bandName, const QString &bandToSwapName) { BandSwapCommand *command = new BandSwapCommand(); @@ -2283,7 +2562,7 @@ CommandIf::Ptr BandMoveFromToCommand::create(PageDesignIntf* page, int from, int bool BandMoveFromToCommand::doIt() { - if (page() && from != to) { + if (page() && page()->pageItem() && from != to) { BandDesignIntf* fromBand = page()->pageItem()->bandByIndex(from); reverceTo = fromBand->minChildIndex(); if (fromBand){ @@ -2297,7 +2576,8 @@ bool BandMoveFromToCommand::doIt() void BandMoveFromToCommand::undoIt() { - if (page()) page()->pageItem()->moveBandFromTo(reverceFrom, reverceTo); + if (page() && page()->pageItem()) + page()->pageItem()->moveBandFromTo(reverceFrom, reverceTo); } } diff --git a/limereport/lrpagedesignintf.h b/limereport/lrpagedesignintf.h index 844e1b2..2ed583c 100644 --- a/limereport/lrpagedesignintf.h +++ b/limereport/lrpagedesignintf.h @@ -43,6 +43,7 @@ namespace LimeReport { class ReportEnginePrivate; class PropertyChangedCommand; class HorizontalLayout; + class VerticalLayout; class LayoutDesignIntf; class CommandIf { @@ -102,10 +103,10 @@ namespace LimeReport { public: friend class PropertyChangedCommand; friend class InsertHLayoutCommand; + friend class InsertVLayoutCommand; explicit PageDesignIntf(QObject* parent = 0); ~PageDesignIntf(); void updatePageRect(); - void startInsertMode(const QString& ItemType); void startEditMode(); @@ -127,6 +128,7 @@ namespace LimeReport { BaseDesignIntf::ItemMode itemMode(){return m_itemMode;} BaseDesignIntf* reportItemByName(const QString& name); QList reportItemsByName(const QString &name); + BandDesignIntf* bandAt(QPointF pos); BaseDesignIntf* addReportItem(const QString& itemType, QPointF pos, QSizeF size); BaseDesignIntf* addReportItem(const QString& itemType, QObject *owner=0, BaseDesignIntf *parent=0); BaseDesignIntf* createReportItem(const QString& itemType, QObject *owner=0, BaseDesignIntf *parent=0); @@ -164,14 +166,21 @@ namespace LimeReport { bool isUpdating(){return m_updating;} void endUpdate(); + void rectMoved(QRectF itemRect, BaseDesignIntf* container = 0); void itemMoved(BaseDesignIntf* item); bool magneticMovement() const; void setMagneticMovement(bool magneticMovement); + ReportSettings *getReportSettings() const; void setReportSettings(ReportSettings *reportSettings); + void setPropertyToSelectedItems(const char *name, const QVariant &value); + PageItemDesignIntf* getCurrentPage() const; + void setCurrentPage(PageItemDesignIntf* currentPage); + protected: + virtual void keyPressEvent(QKeyEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); @@ -193,6 +202,7 @@ namespace LimeReport { void objectLoadFinished(); HorizontalLayout* internalAddHLayout(); + VerticalLayout* internalAddVLayout(); QPointF placePosOnGrid(QPointF point); QSizeF placeSizeOnGrid(QSizeF size); signals: @@ -204,7 +214,10 @@ namespace LimeReport { void multiItemsSelected(QList* objectsList); void miltiItemsSelectionFinished(); void commandHistoryChanged(); - void itemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant& oldValue, const QVariant& newValue); + void itemPropertyChanged(const QString& objectName, + const QString& propertyName, + const QVariant& oldValue, + const QVariant& newValue); void itemAdded(LimeReport::PageDesignIntf* page, LimeReport::BaseDesignIntf* item); void itemRemoved(LimeReport::PageDesignIntf* page, LimeReport::BaseDesignIntf* item); void bandAdded(LimeReport::PageDesignIntf* page, LimeReport::BandDesignIntf* band); @@ -235,12 +248,18 @@ namespace LimeReport { void sameWidth(); void sameHeight(); void addHLayout(); + void addVLayout(); void setFont(const QFont &font); void setTextAlign(const Qt::Alignment& alignment); void setBorders(const BaseDesignIntf::BorderLines& border); + void lockSelectedItems(); + void unlockSelectedItems(); + void selectOneLevelItems(); private slots: void slotPageGeometryChanged(QObject*, QRectF, QRectF ); - void slotItemPropertyChanged(QString propertyName, const QVariant &oldValue, const QVariant &newValue); + void slotItemPropertyChanged(QString propertyName, + const QVariant &oldValue, + const QVariant &newValue); void slotItemPropertyObjectNameChanged(const QString& oldName, const QString& newName); void bandDeleted(QObject* band); void slotPageItemLoaded(QObject *); @@ -255,8 +274,13 @@ namespace LimeReport { void checkSizeOrPosChanges(); CommandIf::Ptr createChangePosCommand(); CommandIf::Ptr createChangeSizeCommand(); - void saveChangeProppertyCommand(const QString& objectName, const QString& propertyName, const QVariant& oldPropertyValue, const QVariant& newPropertyValue); + void saveChangeProppertyCommand(const QString& objectName, + const QString& propertyName, + const QVariant& oldPropertyValue, + const QVariant& newPropertyValue); void changeSelectedGroupProperty(const QString& name,const QVariant& value); + void activateItemToJoin(QRectF itemRect, QList& items); + void selectAllChildren(BaseDesignIntf* item); private: enum JoinType{Width, Height}; LimeReport::PageItemDesignIntf::Ptr m_pageItem; @@ -296,6 +320,7 @@ namespace LimeReport { JoinType m_joinType; bool m_magneticMovement; ReportSettings* m_reportSettings; + PageItemDesignIntf* m_currentPage; }; class AbstractPageCommand : public CommandIf{ @@ -319,6 +344,19 @@ namespace LimeReport { QMap m_elements; }; + class InsertVLayoutCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page); + bool doIt(); + void undoIt(); + private: + InsertVLayoutCommand(){} + private: + QString m_layoutName; + QString m_oldParentName; + QMap m_elements; + }; + class InsertItemCommand : public AbstractPageCommand{ public: static CommandIf::Ptr create(PageDesignIntf* page, const QString& itemType, QPointF pos, QSizeF size); diff --git a/limereport/lrpageitemdesignintf.cpp b/limereport/lrpageitemdesignintf.cpp index 8c11ade..47715c8 100644 --- a/limereport/lrpageitemdesignintf.cpp +++ b/limereport/lrpageitemdesignintf.cpp @@ -50,7 +50,8 @@ PageItemDesignIntf::PageItemDesignIntf(QObject *owner, QGraphicsItem *parent) : m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0), m_pageOrientaion(Portrait), m_pageSize(A4), m_sizeChainging(false), m_fullPage(false), m_oldPrintMode(false), m_resetPageNumber(false), - m_pageFooter(0) + m_isExtendedInDesignMode(false), m_extendedHeight(1000), m_isTOC(false), m_setPageSizeToPrinter(false), + m_endlessHeight(false), m_printable(true), m_pageFooter(0), m_printBehavior(Split) { setFixedPos(true); setPossibleResizeDirectionFlags(Fixed); @@ -63,7 +64,8 @@ PageItemDesignIntf::PageItemDesignIntf(const PageSize pageSize, const QRectF &re m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0), m_pageOrientaion(Portrait), m_pageSize(pageSize), m_sizeChainging(false), m_fullPage(false), m_oldPrintMode(false), m_resetPageNumber(false), - m_pageFooter(0) + m_isExtendedInDesignMode(false), m_extendedHeight(1000), m_isTOC(false), m_setPageSizeToPrinter(false), + m_endlessHeight(false), m_printable(true), m_pageFooter(0), m_printBehavior(Split) { setFixedPos(true); setPossibleResizeDirectionFlags(Fixed); @@ -82,14 +84,24 @@ void PageItemDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsIte { if (itemMode() & DesignMode){ + QRectF rect = pageRect(); + if (isExtendedInDesignMode()) rect.adjust(0,0,0,m_extendedHeight); ppainter->save(); ppainter->setOpacity(0.8); ppainter->fillRect(boundingRect(), pageBorderColor()); ppainter->setOpacity(1); - ppainter->fillRect(pageRect(), Qt::white); - paintGrid(ppainter); + ppainter->fillRect(rect, Qt::white); + paintGrid(ppainter, rect); ppainter->setPen(gridColor()); ppainter->drawRect(boundingRect()); + if (m_isExtendedInDesignMode){ + QPen pen; + pen.setColor(Qt::red); + pen.setStyle(Qt::DashLine); + pen.setWidth(2); + ppainter->setPen(pen); + ppainter->drawLine(pageRect().bottomLeft(),pageRect().bottomRight()); + } ppainter->restore(); } @@ -98,8 +110,8 @@ void PageItemDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsIte ppainter->fillRect(rect(), Qt::white); QPen pen; pen.setColor(Qt::gray); - pen.setWidth(2); - pen.setStyle(Qt::DotLine); + pen.setWidth(1); + pen.setStyle(Qt::SolidLine); ppainter->setPen(pen); QRectF tmpRect = rect(); tmpRect.adjust(-4,-4,4,4); @@ -139,6 +151,16 @@ QColor PageItemDesignIntf::gridColor() const return QColor(170,200,150); } +QRectF PageItemDesignIntf::boundingRect() const +{ + if (!isExtendedInDesignMode()) + return BaseDesignIntf::boundingRect(); + else { + QRectF result = BaseDesignIntf::boundingRect(); + return result.adjusted(0,0,0,m_extendedHeight); + } +} + void PageItemDesignIntf::setItemMode(BaseDesignIntf::ItemMode mode) { ItemsContainerDesignInft::setItemMode(mode); @@ -322,6 +344,97 @@ void PageItemDesignIntf::initColumnsPos(QVector &posByColumns, qreal pos, } } +void PageItemDesignIntf::setPrintBehavior(const PrintBehavior &printBehavior) +{ + m_printBehavior = printBehavior; +} + +PageItemDesignIntf::PrintBehavior PageItemDesignIntf::printBehavior() const +{ + return m_printBehavior; +} + +QString PageItemDesignIntf::printerName() const +{ + return m_printerName; +} + +void PageItemDesignIntf::setPrinterName(const QString& printerName) +{ + m_printerName = printerName; +} + +bool PageItemDesignIntf::isPrintable() const +{ + return m_printable; +} + +void PageItemDesignIntf::setPrintable(bool printable) +{ + m_printable = printable; +} + +bool PageItemDesignIntf::endlessHeight() const +{ + return m_endlessHeight; +} + +void PageItemDesignIntf::setEndlessHeight(bool endlessPage) +{ + m_endlessHeight = endlessPage; +} + +bool PageItemDesignIntf::getSetPageSizeToPrinter() const +{ + return m_setPageSizeToPrinter; +} + +void PageItemDesignIntf::setSetPageSizeToPrinter(bool setPageSizeToPrinter) +{ + if (m_setPageSizeToPrinter != setPageSizeToPrinter){ + m_setPageSizeToPrinter = setPageSizeToPrinter; + notify("setPageSizeToPrinter", !setPageSizeToPrinter, setPageSizeToPrinter); + } +} + +bool PageItemDesignIntf::isTOC() const +{ + return m_isTOC; +} + +void PageItemDesignIntf::setIsTOC(bool isTOC) +{ + if (m_isTOC != isTOC){ + m_isTOC = isTOC; + notify("pageIsTOC", !isTOC, isTOC); + } +} + +int PageItemDesignIntf::extendedHeight() const +{ + return m_extendedHeight; +} + +void PageItemDesignIntf::setExtendedHeight(int extendedHeight) +{ + m_extendedHeight = extendedHeight; + PageDesignIntf* page = dynamic_cast(scene()); + if (page) page->updatePageRect(); + update(); +} + +bool PageItemDesignIntf::isExtendedInDesignMode() const +{ + return m_isExtendedInDesignMode; +} + +void PageItemDesignIntf::setExtendedInDesignMode(bool pageIsExtended) +{ + m_isExtendedInDesignMode = pageIsExtended; + PageDesignIntf* page = dynamic_cast(scene()); + if (page) page->updatePageRect(); + update(); +} BandDesignIntf *PageItemDesignIntf::pageFooter() const { @@ -358,9 +471,7 @@ void PageItemDesignIntf::setResetPageNumber(bool resetPageNumber) { if (m_resetPageNumber!=resetPageNumber){ m_resetPageNumber = resetPageNumber; - if (!isLoading()){ - notify("resetPageNumber",!m_resetPageNumber,m_resetPageNumber); - } + notify("resetPageNumber",!m_resetPageNumber,m_resetPageNumber); } } @@ -400,7 +511,7 @@ void PageItemDesignIntf::relocateBands() { if (isLoading()) return; - int bandSpace = (itemMode() & DesignMode) ? 0 : 0; + int bandSpace = 0; QVector posByColumn; @@ -423,10 +534,10 @@ void PageItemDesignIntf::relocateBands() posByColumn[0]+=m_bands[bandIndex]->height()+bandSpace; } - if(m_bands.count()>0){ - for(int i=0; i<(m_bands.count()-1); i++){ - if (((m_bands[i+1]->bandType() != BandDesignIntf::PageFooter) && - (m_bands[i+1]->bandType() != BandDesignIntf::TearOffBand)) || (itemMode() & DesignMode)){ + if(m_bands.count()>1){ + for(int i=0;i<(m_bands.count()-1);i++){ + if (((m_bands[i+1]->bandType()!=BandDesignIntf::PageFooter) && + (m_bands[i+1]->bandType()!=BandDesignIntf::TearOffBand)) || (itemMode() & DesignMode)){ if (m_bands[i+1]->columnsCount()>1 && m_bands[i]->columnsCount() != m_bands[i+1]->columnsCount()) { @@ -593,6 +704,46 @@ void PageItemDesignIntf::preparePopUpMenu(QMenu &menu) if (action->text().compare(tr("Paste")) != 0) action->setVisible(false); } + + menu.addSeparator(); + + QAction* action = menu.addAction(tr("Page is TOC")); + action->setCheckable(true); + action->setChecked(isTOC()); + + action = menu.addAction(tr("Reset page number")); + action->setCheckable(true); + action->setChecked(resetPageNumber()); + + action = menu.addAction(tr("Full page")); + action->setCheckable(true); + action->setChecked(fullPage()); + + action = menu.addAction(tr("Set page size to printer")); + action->setCheckable(true); + action->setChecked(getSetPageSizeToPrinter()); + +// action = menu.addAction(tr("Transparent")); +// action->setCheckable(true); +// action->setChecked(backgroundMode() == TransparentMode); + +} + +void PageItemDesignIntf::processPopUpAction(QAction *action) +{ + if (action->text().compare(tr("Page is TOC")) == 0){ + page()->setPropertyToSelectedItems("pageIsTOC",action->isChecked()); + } + if (action->text().compare(tr("Reset page number")) == 0){ + page()->setPropertyToSelectedItems("resetPageNumber",action->isChecked()); + } + if (action->text().compare(tr("Full page")) == 0){ + page()->setPropertyToSelectedItems("fullPage",action->isChecked()); + } + if (action->text().compare(tr("Set page size to printer")) == 0){ + page()->setPropertyToSelectedItems("setPageSizeToPrinter",action->isChecked()); + } + } void PageItemDesignIntf::initPageSize(const PageItemDesignIntf::PageSize &size) { @@ -637,7 +788,6 @@ void PageItemDesignIntf::swapBands(BandDesignIntf* band, BandDesignIntf* bandToS BandDesignIntf* firstMoveBand = (bandToSwap->bandIndex() > band->bandIndex()) ? bandToSwap: band; firstMoveBand->changeBandIndex(firstIndex, true); - moveIndex = firstMoveBand->maxChildIndex() + 1; moveIndex = firstIndex; qSort(bandToMove.begin(), bandToMove.end(), bandIndexLessThen); @@ -763,6 +913,18 @@ void PageItemDesignIntf::bandGeometryChanged(QObject* object, QRectF newGeometry bandPositionChanged(object, newGeometry.topLeft(), oldGeometry.topLeft()); } +void PageItemDesignIntf::setUnitTypeProperty(BaseDesignIntf::UnitType value) +{ + if (unitType() != value){ + UnitType oldValue = unitType(); + setUnitType(value); + if (!isLoading()){ + update(); + notify("units", oldValue, value); + } + } +} + void PageItemDesignIntf::collectionLoadFinished(const QString &collectionName) { if (collectionName.compare("children",Qt::CaseInsensitive)==0){ @@ -784,8 +946,12 @@ void PageItemDesignIntf::collectionLoadFinished(const QString &collectionName) void PageItemDesignIntf::updateMarginRect() { m_pageRect = rect(); - m_pageRect.adjust(m_leftMargin*mmFactor(),m_topMargin*mmFactor(), - -m_rightMargin*mmFactor(),-m_bottomMargin*mmFactor()); + m_pageRect.adjust( leftMargin() * Const::mmFACTOR, + topMargin() * Const::mmFACTOR, + -rightMargin() * Const::mmFACTOR, + -bottomMargin() * Const::mmFACTOR + ); + foreach(BandDesignIntf* band,m_bands){ band->setWidth(pageRect().width()/band->columnsCount()); relocateBands(); @@ -798,27 +964,34 @@ void PageItemDesignIntf::updateMarginRect() update(); } -void PageItemDesignIntf::paintGrid(QPainter *ppainter) +void PageItemDesignIntf::paintGrid(QPainter *ppainter, QRectF rect) { ppainter->save(); ppainter->setPen(QPen(gridColor())); ppainter->setOpacity(0.5); - for (int i=0;i<=(pageRect().height()-50)/100;i++){ - ppainter->drawLine(pageRect().x(),(i*100)+pageRect().y()+50,pageRect().right(),i*100+pageRect().y()+50); + for (int i = 0; i <= (rect.height() - 5 * unitFactor()) / (10 * unitFactor()); ++i){ + if (i * 10 * unitFactor() + 5 * unitFactor() >= topMargin() * Const::mmFACTOR) + ppainter->drawLine(rect.x(), (i * 10 * unitFactor()) + ( (rect.y() + 5 * unitFactor()) - (topMargin() * Const::mmFACTOR)), + rect.right(), i * 10 * unitFactor() +( (rect.y() + 5 * unitFactor()) - (topMargin() * Const::mmFACTOR))); }; - for (int i=0;i<=((pageRect().width()-50)/100);i++){ - ppainter->drawLine(i*100+pageRect().x()+50,pageRect().y(),i*100+pageRect().x()+50,pageRect().bottom()); + for (int i=0; i<=((rect.width() - 5 * unitFactor()) / (10 * unitFactor())); ++i){ + if (i * 10 * unitFactor() + 5 * unitFactor() >= leftMargin() * Const::mmFACTOR) + ppainter->drawLine(i * 10 * unitFactor() + ((rect.x() + 5 * unitFactor()) - (leftMargin() * Const::mmFACTOR)), rect.y(), + i * 10 * unitFactor() + ((rect.x() + 5 * unitFactor()) - (leftMargin() * Const::mmFACTOR)), rect.bottom()); }; - ppainter->setPen(QPen(gridColor())); ppainter->setOpacity(1); - for (int i=0;i<=(pageRect().width()/100);i++){ - ppainter->drawLine(i*100+pageRect().x(),pageRect().y(),i*100+pageRect().x(),pageRect().bottom()); + for (int i = 0; i <= (rect.width() / (10 * unitFactor())); ++i){ + if (i * 10 * unitFactor() >= leftMargin() * Const::mmFACTOR) + ppainter->drawLine(i * 10 * unitFactor() + (rect.x() - (leftMargin() * Const::mmFACTOR)), rect.y(), + i * 10 * unitFactor() + (rect.x() - (leftMargin() * Const::mmFACTOR)), rect.bottom()); }; - for (int i=0;i<=pageRect().height()/100;i++){ - ppainter->drawLine(pageRect().x(),i*100+pageRect().y(),pageRect().right(),i*100+pageRect().y()); + for (int i = 0; i <= rect.height() / (10 * unitFactor()); ++i){ + if (i * 10 * unitFactor() >= topMargin() * Const::mmFACTOR) + ppainter->drawLine(rect.x(), i * 10 * unitFactor() + (rect.y() - (topMargin() * Const::mmFACTOR)), + rect.right(), i * 10 * unitFactor() + (rect.y() - (topMargin() * Const::mmFACTOR))); }; - ppainter->drawRect(pageRect()); + ppainter->drawRect(rect); ppainter->restore(); } diff --git a/limereport/lrpageitemdesignintf.h b/limereport/lrpageitemdesignintf.h index 3f728fb..f804776 100644 --- a/limereport/lrpageitemdesignintf.h +++ b/limereport/lrpageitemdesignintf.h @@ -44,6 +44,7 @@ class PageItemDesignIntf : public ItemsContainerDesignInft Q_OBJECT Q_ENUMS(Orientation) Q_ENUMS(PageSize) + Q_ENUMS(PrintBehavior) Q_PROPERTY(int topMargin READ topMargin WRITE setTopMargin) Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin) Q_PROPERTY(int rightMargin READ rightMargin WRITE setRightMargin) @@ -54,9 +55,19 @@ class PageItemDesignIntf : public ItemsContainerDesignInft Q_PROPERTY(bool fullPage READ fullPage WRITE setFullPage) Q_PROPERTY(bool oldPrintMode READ oldPrintMode WRITE setOldPrintMode) Q_PROPERTY(bool resetPageNumber READ resetPageNumber WRITE setResetPageNumber) + Q_PROPERTY(bool isExtendedInDesignMode READ isExtendedInDesignMode WRITE setExtendedInDesignMode) + Q_PROPERTY(int extendedHeight READ extendedHeight WRITE setExtendedHeight) + Q_PROPERTY(bool pageIsTOC READ isTOC WRITE setIsTOC) + Q_PROPERTY(bool setPageSizeToPrinter READ getSetPageSizeToPrinter WRITE setSetPageSizeToPrinter ) + Q_PROPERTY(bool endlessHeight READ endlessHeight WRITE setEndlessHeight) + Q_PROPERTY(bool printable READ isPrintable WRITE setPrintable) + Q_PROPERTY(QString printerName READ printerName WRITE setPrinterName) + Q_PROPERTY(UnitType units READ unitType WRITE setUnitTypeProperty) + Q_PROPERTY(PrintBehavior printBehavior READ printBehavior WRITE setPrintBehavior) friend class ReportRender; public: enum Orientation { Portrait = QPrinter::Portrait, Landscape = QPrinter::Landscape }; + enum PrintBehavior {Scale, Split}; enum PageSize { A4 = QPrinter::A4, B5 = QPrinter::B5, Letter = QPrinter::Letter, Legal = QPrinter::Legal, Executive = QPrinter::Executive, @@ -82,6 +93,7 @@ public: virtual QColor selectionColor() const; virtual QColor pageBorderColor() const; virtual QColor gridColor() const; + virtual QRectF boundingRect() const; void setItemMode(LimeReport::BaseDesignIntf::ItemMode mode); void clear(); const BandsList& childBands() const {return m_bands;} @@ -122,7 +134,7 @@ public: bool oldPrintMode() const; void setOldPrintMode(bool oldPrintMode); - bool canContainChildren(){ return true;} + bool canContainChildren() const{ return true;} bool resetPageNumber() const; void setResetPageNumber(bool resetPageNumber); void updateSubItemsSize(RenderPass pass, DataSourceManager *dataManager); @@ -130,15 +142,41 @@ public: void moveBandFromTo(int from, int to); QList createBandGroup(int beginIndex, int endIndex); + + bool isExtendedInDesignMode() const; + void setExtendedInDesignMode(bool isExtendedInDesignMode); + int extendedHeight() const; + void setExtendedHeight(int extendedHeight); + + bool isTOC() const; + void setIsTOC(bool isTOC); + bool getSetPageSizeToPrinter() const; + void setSetPageSizeToPrinter(bool setPageSizeToPrinter); + + bool endlessHeight() const; + void setEndlessHeight(bool endlessHeight); + + bool isPrintable() const; + void setPrintable(bool printable); + + QString printerName() const; + void setPrinterName(const QString& printerName); void placeTearOffBand(); BandDesignIntf *pageFooter() const; void setPageFooter(BandDesignIntf *pageFooter); + + PrintBehavior printBehavior() const; + void setPrintBehavior(const PrintBehavior &printBehavior); +signals: + void beforeFirstPageRendered(); + void afterLastPageRendered(); protected slots: void bandDeleted(QObject* band); void bandPositionChanged(QObject* object, QPointF newPos, QPointF oldPos); void bandGeometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); + void setUnitTypeProperty(BaseDesignIntf::UnitType value); protected: void collectionLoadFinished(const QString& collectionName); QRectF& pageRect(){return m_pageRect;} @@ -148,8 +186,9 @@ protected: void initPageSize(const QSizeF &size); QColor selectionMarkerColor(){return Qt::transparent;} void preparePopUpMenu(QMenu &menu); + void processPopUpAction(QAction *action); private: - void paintGrid(QPainter *ppainter); + void paintGrid(QPainter *ppainter, QRectF rect); void initColumnsPos(QVector&posByColumns, qreal pos, int columnCount); private: int m_topMargin; @@ -164,7 +203,17 @@ private: bool m_fullPage; bool m_oldPrintMode; bool m_resetPageNumber; + bool m_isExtendedInDesignMode; + int m_extendedHeight; + bool m_isTOC; + bool m_setPageSizeToPrinter; + bool m_endlessHeight; + bool m_printable; + QString m_printerName; BandDesignIntf* m_pageFooter; + PrintBehavior m_printBehavior; + + }; typedef QList ReportPages; diff --git a/limereport/lrpreviewreportwidget.cpp b/limereport/lrpreviewreportwidget.cpp index da0202e..01cc68e 100644 --- a/limereport/lrpreviewreportwidget.cpp +++ b/limereport/lrpreviewreportwidget.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -13,6 +14,9 @@ #include "serializators/lrxmlwriter.h" #include "lrpreparedpages.h" +#include "lrexportersfactory.h" + + namespace LimeReport { bool PreviewReportWidgetPrivate::pageIsVisible(){ @@ -50,6 +54,7 @@ void PreviewReportWidgetPrivate::setPages(ReportPages pages) m_changingPage = false; q_ptr->initPreview(); q_ptr->emitPageSet(); + q_ptr->activateCurrentPage(); } } @@ -60,15 +65,36 @@ PageItemDesignIntf::Ptr PreviewReportWidgetPrivate::currentPage() else return PageItemDesignIntf::Ptr(0); } -PreviewReportWidget::PreviewReportWidget(ReportEnginePrivate *report, QWidget *parent) : +QList PreviewReportWidgetPrivate::aviableExporters() +{ + return ExportersFactory::instance().map().keys(); +} + +void PreviewReportWidgetPrivate::startInsertTextItem() +{ + m_previewPage->startInsertMode("TextItem"); +} + +void PreviewReportWidgetPrivate::activateItemSelectionMode() +{ + m_previewPage->startEditMode(); +} + +void PreviewReportWidgetPrivate::deleteSelectedItems() +{ + m_previewPage->deleteSelected(); +} + +PreviewReportWidget::PreviewReportWidget(ReportEngine *report, QWidget *parent) : QWidget(parent), ui(new Ui::PreviewReportWidget), d_ptr(new PreviewReportWidgetPrivate(this)), - m_scaleType(FitWidth), m_scalePercent(0) + m_scaleType(FitWidth), m_scalePercent(0), m_previewPageBackgroundColor(Qt::white), + m_defaultPrinter(0) { ui->setupUi(this); - d_ptr->m_previewPage = report->createPreviewPage(); + d_ptr->m_report = report->d_ptr; + d_ptr->m_previewPage = d_ptr->m_report->createPreviewPage(); d_ptr->m_previewPage->setItemMode( LimeReport::PreviewMode ); - d_ptr->m_report = report; m_resizeTimer.setSingleShot(true); ui->errorsView->setVisible(false); @@ -88,13 +114,43 @@ PreviewReportWidget::~PreviewReportWidget() delete ui; } +QList PreviewReportWidget::aviableExporters() +{ + return d_ptr->aviableExporters(); +} + +bool PreviewReportWidget::exportReport(QString exporterName, const QMap ¶ms) +{ + if (ExportersFactory::instance().map().contains(exporterName)){ + + ReportExporterInterface* e = ExportersFactory::instance().objectCreator(exporterName)(d_ptr->m_report); + + QString filter = QString("%1 (*.%2)").arg(e->exporterName()).arg(e->exporterFileExt()); + QString fileName = QFileDialog::getSaveFileName(this,tr("%1 file name").arg(e->exporterName()),"",filter); + if (!fileName.isEmpty()){ + QFileInfo fi(fileName); + if (fi.suffix().isEmpty()) + fileName += QString(".%1").arg(e->exporterFileExt()); + bool result = e->exportPages(d_ptr->m_reportPages, fileName, params); + delete e; + return result; + } + } + return false; +} + void PreviewReportWidget::initPreview() { if (ui->graphicsView->scene()!=d_ptr->m_previewPage) ui->graphicsView->setScene(d_ptr->m_previewPage); ui->graphicsView->resetMatrix(); ui->graphicsView->centerOn(0, 0); + ui->graphicsView->scene()->setBackgroundBrush(QColor(m_previewPageBackgroundColor)); setScalePercent(d_ptr->m_scalePercent); + PageDesignIntf* page = dynamic_cast(ui->graphicsView->scene()); + if (page) + connect(page, SIGNAL(itemInserted(LimeReport::PageDesignIntf*, QPointF, QString)), + this, SIGNAL(itemInserted(LimeReport::PageDesignIntf*, QPointF, QString))); } void PreviewReportWidget::setErrorsMesagesVisible(bool visible) @@ -122,6 +178,7 @@ void PreviewReportWidget::firstPage() d_ptr->m_currentPage=1; ui->graphicsView->ensureVisible(d_ptr->calcPageShift(), 0, 0); emit pageChanged(d_ptr->m_currentPage); + activateCurrentPage(); } d_ptr->m_changingPage=false; } @@ -133,6 +190,7 @@ void PreviewReportWidget::priorPage() d_ptr->m_currentPage--; ui->graphicsView->ensureVisible(d_ptr->calcPageShift(), 0, 0); emit pageChanged(d_ptr->m_currentPage); + activateCurrentPage(); } d_ptr->m_changingPage=false; } @@ -144,6 +202,7 @@ void PreviewReportWidget::nextPage() d_ptr->m_currentPage++; ui->graphicsView->ensureVisible(d_ptr->calcPageShift(), 0, 0); emit pageChanged(d_ptr->m_currentPage); + activateCurrentPage(); } d_ptr->m_changingPage=false; } @@ -155,40 +214,54 @@ void PreviewReportWidget::lastPage() d_ptr->m_currentPage=d_ptr->m_reportPages.count(); ui->graphicsView->ensureVisible(d_ptr->calcPageShift(), 0, 0); emit pageChanged(d_ptr->m_currentPage); + activateCurrentPage(); } d_ptr->m_changingPage=false; } -void PreviewReportWidget::print() +void PreviewReportWidget::printPages(QPrinter* printer) { - QPrinter printer(QPrinter::HighResolution); - QPrintDialog dialog(&printer,QApplication::activeWindow()); - if (dialog.exec()==QDialog::Accepted){ - if (!d_ptr->m_reportPages.isEmpty()) - ReportEnginePrivate::printReport( - d_ptr->m_reportPages, - printer - ); - foreach(PageItemDesignIntf::Ptr pageItem, d_ptr->m_reportPages){ - d_ptr->m_previewPage->reactivatePageItem(pageItem); - } + if (!d_ptr->m_reportPages.isEmpty()) + ReportEnginePrivate::printReport( + d_ptr->m_reportPages, + *printer + ); + foreach(PageItemDesignIntf::Ptr pageItem, d_ptr->m_reportPages){ + d_ptr->m_previewPage->reactivatePageItem(pageItem); } } +void PreviewReportWidget::print() +{ + QPrinterInfo pi; + QPrinter lp(QPrinter::HighResolution); + + if (!pi.defaultPrinter().isNull()){ +#ifdef HAVE_QT4 + lp.setPrinterName(pi.defaultPrinter().printerName()); +#endif +#ifdef HAVE_QT5 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)) + lp.setPrinterName(pi.defaultPrinterName()); +#else + lp.setPrinterName(pi.defaultPrinter().printerName()); +#endif +#endif + } + + QPrinter* printer = m_defaultPrinter ? m_defaultPrinter : &lp; + + QPrintDialog dialog(printer,QApplication::activeWindow()); + if (dialog.exec()==QDialog::Accepted){ + printPages(printer); + } + +} + void PreviewReportWidget::printToPDF() { - QString filter = "PDF (*.pdf)"; - QString fileName = QFileDialog::getSaveFileName(this,tr("PDF file name"),"","PDF (*.pdf)"); - if (!fileName.isEmpty()){ - QFileInfo fi(fileName); - if (fi.suffix().isEmpty()) - fileName+=".pdf"; - QPrinter printer; - printer.setOutputFileName(fileName); - printer.setOutputFormat(QPrinter::PdfFormat); - if (!d_ptr->m_reportPages.isEmpty()){ - ReportEnginePrivate::printReport(d_ptr->m_reportPages,printer); - } + if (!d_ptr->m_reportPages.isEmpty()){ + exportReport("PDF"); foreach(PageItemDesignIntf::Ptr pageItem, d_ptr->m_reportPages){ d_ptr->m_previewPage->reactivatePageItem(pageItem); } @@ -201,6 +274,7 @@ void PreviewReportWidget::pageNavigatorChanged(int value) d_ptr->m_changingPage = true; if ((!d_ptr->m_reportPages.isEmpty())&&(d_ptr->m_reportPages.count() >= value) && value>0){ d_ptr->m_currentPage = value; + activateCurrentPage(); ui->graphicsView->ensureVisible(d_ptr->calcPageShift(), 0, 0); } d_ptr->m_changingPage=false; @@ -274,11 +348,36 @@ void PreviewReportWidget::emitPageSet() emit pagesSet(d_ptr->m_reportPages.count()); } +QPrinter *PreviewReportWidget::defaultPrinter() const +{ + return m_defaultPrinter; +} + +void PreviewReportWidget::setDefaultPrinter(QPrinter *defaultPrinter) +{ + m_defaultPrinter = defaultPrinter; +} + ScaleType PreviewReportWidget::scaleType() const { return m_scaleType; } +void PreviewReportWidget::startInsertTextItem() +{ + d_ptr->startInsertTextItem(); +} + +void PreviewReportWidget::activateItemSelectionMode() +{ + d_ptr->activateItemSelectionMode(); +} + +void PreviewReportWidget::deleteSelectedItems() +{ + d_ptr->deleteSelectedItems(); +} + int PreviewReportWidget::scalePercent() const { return m_scalePercent; @@ -290,6 +389,16 @@ void PreviewReportWidget::setScaleType(const ScaleType &scaleType, int percent) m_scalePercent = percent; } +void PreviewReportWidget::setPreviewPageBackgroundColor(QColor color) +{ + m_previewPageBackgroundColor = color; +} + +QColor PreviewReportWidget::previewPageBackgroundColor() +{ + return m_previewPageBackgroundColor; +} + void PreviewReportWidget::refreshPages() { if (d_ptr->m_report){ @@ -307,8 +416,16 @@ void PreviewReportWidget::refreshPages() } } +void PreviewReportWidget::activateCurrentPage() +{ + PageDesignIntf* page = dynamic_cast(ui->graphicsView->scene()); + if (page) + page->setCurrentPage(d_ptr->currentPage().data()); +} + void PreviewReportWidget::slotSliderMoved(int value) { + int curPage = d_ptr->m_currentPage; if (ui->graphicsView->verticalScrollBar()->minimum()==value){ d_ptr->m_currentPage = 1; } else if (ui->graphicsView->verticalScrollBar()->maximum()==value){ @@ -323,10 +440,13 @@ void PreviewReportWidget::slotSliderMoved(int value) } } - d_ptr->m_changingPage = true; - emit pageChanged(d_ptr->m_currentPage); + if (curPage != d_ptr->m_currentPage){ + d_ptr->m_changingPage = true; + emit pageChanged(d_ptr->m_currentPage); + activateCurrentPage(); + d_ptr->m_changingPage = false; + } - d_ptr->m_changingPage = false; d_ptr->m_priorScrolValue = value; } diff --git a/limereport/lrpreviewreportwidget.h b/limereport/lrpreviewreportwidget.h index 74c0be6..1e24e9b 100644 --- a/limereport/lrpreviewreportwidget.h +++ b/limereport/lrpreviewreportwidget.h @@ -3,6 +3,7 @@ #include #include +#include #include "lrglobal.h" #include "lrpreparedpagesintf.h" @@ -14,6 +15,8 @@ class PreviewReportWidget; class PreviewReportWidgetPrivate; class ReportEnginePrivate; +class ReportEngine; +class PageDesignIntf; class LIMEREPORT_EXPORT PreviewReportWidget : public QWidget { @@ -22,11 +25,22 @@ class LIMEREPORT_EXPORT PreviewReportWidget : public QWidget friend class PreviewReportWindow; friend class PreviewReportWidgetPrivate; public: - explicit PreviewReportWidget(ReportEnginePrivate *report, QWidget *parent = 0); - ~PreviewReportWidget(); + explicit PreviewReportWidget(ReportEngine *report, QWidget *parent = 0); + ~PreviewReportWidget(); + QList aviableExporters(); + bool exportReport(QString exporterName, const QMap& params = QMap()); ScaleType scaleType() const; int scalePercent() const; void setScaleType(const ScaleType &scaleType, int percent = 0); + void setPreviewPageBackgroundColor(QColor color); + QColor previewPageBackgroundColor(); + QPrinter *defaultPrinter() const; + void setDefaultPrinter(QPrinter *defaultPrinter); + void startInsertTextItem(); + void activateItemSelectionMode(); + void deleteSelectedItems(); + void activateCurrentPage(); + public slots: void refreshPages(); void zoomIn(); @@ -50,6 +64,7 @@ signals: void pageChanged(int page); void scalePercentChanged(int percent); void pagesSet(int pageCount); + void itemInserted(LimeReport::PageDesignIntf* report, QPointF pos, const QString& ItemType); void onSave(bool& saved, LimeReport::IPreparedPages* pages); private slots: void slotSliderMoved(int value); @@ -66,7 +81,10 @@ private: PreviewReportWidgetPrivate* d_ptr; ScaleType m_scaleType; int m_scalePercent; - QTimer m_resizeTimer; + QTimer m_resizeTimer; + QColor m_previewPageBackgroundColor; + QPrinter* m_defaultPrinter; + void printPages(QPrinter *printer); }; } // namespace LimeReport diff --git a/limereport/lrpreviewreportwidget_p.h b/limereport/lrpreviewreportwidget_p.h index 9557a5d..d7dc719 100644 --- a/limereport/lrpreviewreportwidget_p.h +++ b/limereport/lrpreviewreportwidget_p.h @@ -15,11 +15,15 @@ public: PreviewReportWidgetPrivate(PreviewReportWidget* previewReportWidget): m_previewPage(NULL), m_report(NULL), m_zoomer(NULL), m_currentPage(1), m_changingPage(false), m_priorScrolValue(0), m_scalePercent(50), - q_ptr(previewReportWidget) {} + q_ptr(previewReportWidget), m_previePageColor(Qt::white) {} bool pageIsVisible(); QRectF calcPageShift(); void setPages( ReportPages pages); PageItemDesignIntf::Ptr currentPage(); + QList aviableExporters(); + void startInsertTextItem(); + void activateItemSelectionMode(); + void deleteSelectedItems(); public: PageDesignIntf* m_previewPage; ReportPages m_reportPages; @@ -30,7 +34,7 @@ public: int m_priorScrolValue; int m_scalePercent; PreviewReportWidget* q_ptr; - + QColor m_previePageColor; }; } diff --git a/limereport/lrpreviewreportwindow.cpp b/limereport/lrpreviewreportwindow.cpp index f9b0981..2f6f391 100644 --- a/limereport/lrpreviewreportwindow.cpp +++ b/limereport/lrpreviewreportwindow.cpp @@ -34,6 +34,8 @@ #include "lrreportengine_p.h" #include "lrpreviewreportwidget.h" #include "lrpreviewreportwidget_p.h" +#include "items/editors/lrfonteditorwidget.h" +#include "items/editors/lrtextalignmenteditorwidget.h" #include #include @@ -43,9 +45,10 @@ namespace LimeReport{ -PreviewReportWindow::PreviewReportWindow(ReportEnginePrivate *report,QWidget *parent, QSettings *settings, Qt::WindowFlags flags) : +PreviewReportWindow::PreviewReportWindow(ReportEngine *report, QWidget *parent, QSettings *settings, Qt::WindowFlags flags) : QMainWindow(parent,flags), - ui(new Ui::PreviewReportWindow), m_settings(settings), m_ownedSettings(false), m_scalePercentChanging(false) + ui(new Ui::PreviewReportWindow), m_settings(settings), m_ownedSettings(false), + m_scalePercentChanging(false) { ui->setupUi(this); setWindowTitle("Lime Report Preview"); @@ -54,6 +57,7 @@ PreviewReportWindow::PreviewReportWindow(ReportEnginePrivate *report,QWidget *pa m_pagesNavigator->setPrefix(tr("Page: ")); m_pagesNavigator->setMinimumWidth(120); ui->toolBar->insertWidget(ui->actionNextPage,m_pagesNavigator); + ui->editModeTools->hide(); ui->actionShowMessages->setVisible(false); connect(m_pagesNavigator,SIGNAL(valueChanged(int)),this,SLOT(slotPageNavigatorChanged(int))); @@ -69,10 +73,10 @@ PreviewReportWindow::PreviewReportWindow(ReportEnginePrivate *report,QWidget *pa connect(m_previewReportWidget, SIGNAL(onSave(bool&, LimeReport::IPreparedPages*)), this, SIGNAL(onSave(bool&, LimeReport::IPreparedPages*))); - m_fontEditor = new FontEditorWidget(m_previewReportWidget->d_ptr->m_previewPage,tr("Font"),this); + m_fontEditor = new FontEditorWidgetForPage(m_previewReportWidget->d_ptr->m_previewPage,tr("Font"),this); m_fontEditor->setObjectName("fontTools"); m_fontEditor->setIconSize(ui->toolBar->iconSize()); - m_textAlignmentEditor = new TextAlignmentEditorWidget(m_previewReportWidget->d_ptr->m_previewPage,tr("Text align"),this); + m_textAlignmentEditor = new TextAlignmentEditorWidgetForPage(m_previewReportWidget->d_ptr->m_previewPage,tr("Text align"),this); m_textAlignmentEditor->setObjectName("textAlignmentTools"); m_textAlignmentEditor->setIconSize(ui->toolBar->iconSize()); addToolBar(Qt::TopToolBarArea,m_fontEditor); @@ -83,10 +87,13 @@ PreviewReportWindow::PreviewReportWindow(ReportEnginePrivate *report,QWidget *pa ui->toolBar->insertWidget(ui->actionZoomOut, m_scalePercent); initPercentCombobox(); -// connect(ui->graphicsView->verticalScrollBar(),SIGNAL(valueChanged(int)), this, SLOT(slotSliderMoved(int))); connect(ui->actionShowMessages, SIGNAL(triggered()), this, SLOT(slotShowErrors())); connect(m_previewReportWidget, SIGNAL(scalePercentChanged(int)), this, SLOT(slotScalePercentChanged(int))); connect(m_scalePercent, SIGNAL(currentIndexChanged(QString)), this, SLOT(scaleComboboxChanged(QString))); + connect(m_previewReportWidget, SIGNAL(pageChanged(int)), this, SLOT(slotCurrentPageChanged(int))); + connect(m_previewReportWidget, SIGNAL(itemInserted(LimeReport::PageDesignIntf*, QPointF, QString)), + this, SLOT(slotItemInserted(LimeReport::PageDesignIntf*, QPointF, QString))); + restoreSetting(); selectStateIcon(); } @@ -111,10 +118,13 @@ void PreviewReportWindow::restoreSetting() int screenWidth = desktop->screenGeometry().width(); int screenHeight = desktop->screenGeometry().height(); - int x = screenWidth*0.1; - int y = screenHeight*0.1; + int x = static_cast(screenWidth*0.1); + int y = static_cast(screenHeight*0.1); - resize(screenWidth*0.8, screenHeight*0.8); + resize( + static_cast(screenWidth*0.8), + static_cast(screenHeight*0.8) + ); move(x, y); } v = settings()->value("State"); @@ -206,7 +216,7 @@ QSettings*PreviewReportWindow::settings() if (m_settings){ return m_settings; } else { - m_settings = new QSettings("LimeReport",QApplication::applicationName()); + m_settings = new QSettings("LimeReport",QCoreApplication::applicationName()); m_ownedSettings = true; return m_settings; } @@ -231,6 +241,11 @@ void PreviewReportWindow::setPages(ReportPages pages) } } +void PreviewReportWindow::setDefaultPrinter(QPrinter *printer) +{ + m_previewReportWidget->setDefaultPrinter(printer); +} + void PreviewReportWindow::exec() { bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose); @@ -277,6 +292,7 @@ void PreviewReportWindow::moveEvent(QMoveEvent* e) void PreviewReportWindow::showEvent(QShowEvent *) { m_fontEditor->setVisible(ui->actionEdit_Mode->isChecked()); + ui->editModeTools->setVisible(false); m_textAlignmentEditor->setVisible(ui->actionEdit_Mode->isChecked()); switch (m_previewScaleType) { case FitWidth: @@ -343,7 +359,9 @@ void PreviewReportWindow::on_actionEdit_Mode_triggered(bool checked) m_previewReportWidget->d_ptr->m_previewPage->setItemMode((checked)?ItemModes(DesignMode):PreviewMode); m_textAlignmentEditor->setVisible(checked); m_fontEditor->setVisible(checked); - //m_reportPages.at(m_currentPage)->setItemMode((checked)?DesignMode:PreviewMode); + if (checked) + ui->editModeTools->show(); + else ui->editModeTools->hide(); } void PreviewReportWindow::slotSelectionChanged() @@ -385,6 +403,16 @@ void PreviewReportWindow::setPreviewScaleType(const ScaleType &previewScaleType, m_previewReportWidget->setScaleType(previewScaleType, percent); } +QColor PreviewReportWindow::previewPageBackgroundColor() +{ + return m_previewReportWidget->previewPageBackgroundColor(); +} + +void PreviewReportWindow::setPreviewPageBackgroundColor(QColor color) +{ + m_previewReportWidget->setPreviewPageBackgroundColor(color); +} + void PreviewReportWindow::on_actionSaveToFile_triggered() { m_previewReportWidget->saveToFile(); @@ -410,6 +438,24 @@ void PreviewReportWindow::slotPageChanged(int pageIndex) m_pagesNavigator->setValue(pageIndex); } +void PreviewReportWindow::slotInsertNewTextItem() +{ + m_previewReportWidget->startInsertTextItem(); + ui->actionSelection_Mode->setChecked(false); +} + +void PreviewReportWindow::slotActivateItemSelectionMode() +{ + m_previewReportWidget->activateItemSelectionMode(); + ui->actionSelection_Mode->setChecked(true); + ui->actionInsertTextItem->setChecked(false); +} + +void PreviewReportWindow::slotDeleteSelectedItems() +{ + m_previewReportWidget->deleteSelectedItems(); +} + void PreviewReportWindow::on_actionFit_page_width_triggered() { m_previewReportWidget->fitWidth(); @@ -454,7 +500,15 @@ void PreviewReportWindow::on_actionShow_Toolbar_triggered() writeSetting(); } +void PreviewReportWindow::slotCurrentPageChanged(int page) +{ + slotActivateItemSelectionMode(); +} + +void PreviewReportWindow::slotItemInserted(PageDesignIntf *, QPointF, const QString&) +{ + slotActivateItemSelectionMode(); +} + }// namespace LimeReport - - diff --git a/limereport/lrpreviewreportwindow.h b/limereport/lrpreviewreportwindow.h index ce9db57..4935201 100644 --- a/limereport/lrpreviewreportwindow.h +++ b/limereport/lrpreviewreportwindow.h @@ -34,31 +34,36 @@ #include #include #include +#include +#include +#include -#include "lrpagedesignintf.h" -#include "lrreportrender.h" -#include "serializators/lrstorageintf.h" #include "serializators/lrxmlreader.h" -#include "lrpreviewreportwidget.h" #include "lrpreparedpagesintf.h" -#include "items/editors/lrfonteditorwidget.h" -#include "items/editors/lrtextalignmenteditorwidget.h" - namespace LimeReport { namespace Ui { class PreviewReportWindow; } +class PreviewReportWidget; +class FontEditorWidget; +class TextAlignmentEditorWidget; +class ReportEngine; +class PageItemDesignIntf; +typedef QList< QSharedPointer > ReportPages; + + class PreviewReportWindow : public QMainWindow { Q_OBJECT public: - explicit PreviewReportWindow(ReportEnginePrivate *report, QWidget *parent = 0, QSettings* settings=0, Qt::WindowFlags flags=0); + explicit PreviewReportWindow(ReportEngine *report, QWidget *parent = 0, QSettings* settings=0, Qt::WindowFlags flags=0); ~PreviewReportWindow(); void setReportReader(ItemsReaderIntf::Ptr reader); void setPages(ReportPages pages); + void setDefaultPrinter(QPrinter* printer); void exec(); void initPreview(int pagesCount); void reloadPreview(); @@ -75,7 +80,8 @@ public: QSettings* settings(); ScaleType previewScaleType() const; void setPreviewScaleType(const ScaleType &previewScaleType, int percent = 0); - + QColor previewPageBackgroundColor(); + void setPreviewPageBackgroundColor(QColor color); protected: void writeSetting(); void restoreSetting(); @@ -99,6 +105,9 @@ public slots: void slotLastPage(); void slotPrintToPDF(); void slotPageChanged(int pageIndex); + void slotInsertNewTextItem(); + void slotActivateItemSelectionMode(); + void slotDeleteSelectedItems(); private slots: void on_actionFit_page_width_triggered(); void on_actionFit_page_triggered(); @@ -107,6 +116,8 @@ private slots: void slotScalePercentChanged(int percent); void on_actionShowMessages_toggled(bool value); void on_actionShow_Toolbar_triggered(); + void slotCurrentPageChanged(int page); + void slotItemInserted(LimeReport::PageDesignIntf* report, QPointF pos, const QString& ItemType); signals: void onSave(bool& saved, LimeReport::IPreparedPages* pages); private: @@ -128,7 +139,6 @@ private: ScaleType m_previewScaleType; int m_previewScalePercent; bool m_scalePercentChanging; - }; } //namespace LimeReport #endif // LRPREVIEWREPORTWINDOW_H diff --git a/limereport/lrpreviewreportwindow.ui b/limereport/lrpreviewreportwindow.ui index 50487cb..8ce8873 100644 --- a/limereport/lrpreviewreportwindow.ui +++ b/limereport/lrpreviewreportwindow.ui @@ -35,7 +35,7 @@ 0 0 800 - 19 + 20 @@ -93,6 +93,24 @@ + + + true + + + toolBar_2 + + + LeftToolBarArea + + + false + + + + + + @@ -279,9 +297,55 @@ Show toolbar + + + true + + + + :/items/TextItem:/items/TextItem + + + InsertTextItem + + + Add new TextItem + + + + + true + + + true + + + + :/report/images/editMode:/report/images/editMode + + + Selection Mode + + + + + + :/report/images/delete:/report/images/delete + + + Delete Item + + + Del + + + + + + @@ -429,6 +493,54 @@ + + actionInsertTextItem + triggered() + LimeReport::PreviewReportWindow + slotInsertNewTextItem() + + + -1 + -1 + + + 399 + 299 + + + + + actionSelection_Mode + triggered() + LimeReport::PreviewReportWindow + slotActivateItemSelectionMode() + + + -1 + -1 + + + 399 + 299 + + + + + actionDelete_Item + triggered() + LimeReport::PreviewReportWindow + slotDeleteSelectedItems() + + + -1 + -1 + + + 399 + 299 + + + slotNextPage() @@ -439,5 +551,8 @@ slotFirstPage() slotLastPage() slotPrintToPDF() + slotInsertNewTextItem() + slotActivateItemSelectionMode() + slotDeleteSelectedItems() diff --git a/limereport/lrreportdesignwidget.cpp b/limereport/lrreportdesignwidget.cpp index b12ae6f..12d4116 100644 --- a/limereport/lrreportdesignwidget.cpp +++ b/limereport/lrreportdesignwidget.cpp @@ -33,6 +33,9 @@ #include "lrreportengine_p.h" #include "lrbasedesignintf.h" #include "lrsettingdialog.h" +#include "dialogdesigner/lrdialogdesigner.h" +#include "translationeditor/translationeditor.h" +#include "scripteditor/lrscripteditor.h" #include #include @@ -48,14 +51,19 @@ namespace LimeReport { // ReportDesignIntf -ReportDesignWidget::ReportDesignWidget(ReportEnginePrivate *report, QMainWindow *mainWindow, QWidget *parent) : - QWidget(parent), m_mainWindow(mainWindow), m_verticalGridStep(10), m_horizontalGridStep(10), m_useGrid(false) -{ -#ifdef HAVE_QT5 - m_tabWidget = new QTabWidget(this); +ReportDesignWidget::ReportDesignWidget(ReportEnginePrivateInterface* report, QSettings* settings, QMainWindow *mainWindow, QWidget *parent) : + QWidget(parent), +#ifdef HAVE_QTDESIGNER_INTEGRATION + m_dialogDesignerManager(new DialogDesignerManager(this)), #endif + m_mainWindow(mainWindow), m_verticalGridStep(10), m_horizontalGridStep(10), m_useGrid(false), + m_dialogChanged(false), m_theme("Default"), m_settings(settings), m_defaultUnits(BaseDesignIntf::Millimeters) +{ #ifdef HAVE_QT4 m_tabWidget = new LimeReportTabWidget(this); +#endif +#ifdef HAVE_QT5 + m_tabWidget = new QTabWidget(this); #endif m_tabWidget->setTabPosition(QTabWidget::South); m_tabWidget->setMovable(true); @@ -65,30 +73,111 @@ ReportDesignWidget::ReportDesignWidget(ReportEnginePrivate *report, QMainWindow mainLayout->addWidget(m_tabWidget); setLayout(mainLayout); - if (!report) { - m_report=new ReportEnginePrivate(this); - m_report->setObjectName("report"); - m_report->appendPage("page1"); + m_report=report; + + m_settings->beginGroup("DesignerWidget"); + QVariant v = m_settings->value("DefaultUnits"); + if (v.isValid()){ + m_defaultUnits = static_cast(v.toInt()); } - else { - m_report=report; - if (!m_report->pageCount()) m_report->appendPage("page1"); + m_settings->endGroup(); + + if (!m_report->pageCount()){ + createStartPage(); } createTabs(); + connect(dynamic_cast(m_report), SIGNAL(pagesLoadFinished()),this,SLOT(slotPagesLoadFinished())); + connect(dynamic_cast(m_report), SIGNAL(cleared()), this, SIGNAL(cleared())); + connect(dynamic_cast(m_report), SIGNAL(loadFinished()), this, SLOT(slotReportLoaded())); - connect(m_report,SIGNAL(pagesLoadFinished()),this,SLOT(slotPagesLoadFinished())); - connect(m_report,SIGNAL(cleared()),this,SIGNAL(cleared())); connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentTabChanged(int))); - +#ifdef HAVE_UI_LOADER + connect(m_report->scriptContext(), SIGNAL(dialogDeleted(QString)), this, SLOT(slotDialogDeleted(QString))); +#endif //m_instance=this; m_scriptEditor->setPlainText(m_report->scriptContext()->initScript()); m_zoomer = new GraphicsViewZoomer(activeView()); + #ifdef Q_OS_WIN m_defaultFont = QFont("Arial",10); #endif + +#ifdef HAVE_QTDESIGNER_INTEGRATION + connect(m_dialogDesignerManager, SIGNAL(dialogChanged(QString)), + this, SLOT(slotDialogChanged(QString))); + connect(m_dialogDesignerManager, SIGNAL(dialogNameChanged(QString,QString)), + this, SLOT(slotDialogNameChanged(QString,QString))); +#endif + + m_themes.insert("Default",""); + m_localToEng.insert(QObject::tr("Dark"), "Dark"); + m_localToEng.insert(QObject::tr("Light"), "Light"); + initThemeIfExist("Dark", ":/qdarkstyle/style.qss"); + initThemeIfExist("Light", ":/qlightstyle/lightstyle.qss"); } +#ifdef HAVE_QTDESIGNER_INTEGRATION +DialogDesignerManager *ReportDesignWidget::dialogDesignerManager() const +{ + return m_dialogDesignerManager; +} + +QString ReportDesignWidget::activeDialogName() +{ + if (activeDialogPage()) + return activeDialogPage()->dialogName(); + return ""; +} + + +QWidget *ReportDesignWidget::toolWindow(ReportDesignWidget::ToolWindowType windowType) +{ + switch (windowType) { + case WidgetBox: + return dialogDesignerManager()->widgetBox(); + case PropertyEditor: + return dialogDesignerManager()->propertyEditor(); + case ObjectInspector: + return dialogDesignerManager()->objectInspector(); + case ActionEditor: + return dialogDesignerManager()->actionEditor(); + case ResourceEditor: + return dialogDesignerManager()->resourcesEditor(); + case SignalSlotEditor: + return dialogDesignerManager()->signalSlotEditor(); + } +} + +#endif + +ReportDesignWidget::EditorTabType ReportDesignWidget::activeTabType() +{ + QString tabType = m_tabWidget->tabWhatsThis(m_tabWidget->currentIndex()); + if ( tabType.compare("dialog") == 0) return Dialog; + if ( tabType.compare("script") == 0) return Script; + if ( tabType.compare("translations") == 0) return Translations; + return Page; +} + +#ifdef HAVE_QTDESIGNER_INTEGRATION + +void ReportDesignWidget::initDialogDesignerToolBar(QToolBar *toolBar) +{ + m_dialogDesignerManager->initToolBar(toolBar); +} + +void ReportDesignWidget::updateDialogs() +{ + for ( int i = 0; icount(); ++i ){ + if (m_tabWidget->tabWhatsThis(i).compare("dialog") == 0){ + m_report->scriptContext()->changeDialog(m_tabWidget->tabText(i), m_dialogDesignerManager->getDialogDescription(m_tabWidget->widget(i))); + } + } +} + +#endif + bool ReportDesignWidget::useMagnet() const { return m_useMagnet; @@ -102,14 +191,17 @@ void ReportDesignWidget::setUseMagnet(bool useMagnet) } } -void ReportDesignWidget::saveState(QSettings* settings) +void ReportDesignWidget::saveState() { - settings->beginGroup("DesignerWidget"); - settings->setValue("hGridStep",m_horizontalGridStep); - settings->setValue("vGridStep",m_verticalGridStep); - settings->setValue("defaultFont",m_defaultFont); - settings->setValue("useGrid",m_useGrid); - settings->endGroup(); + m_settings->beginGroup("DesignerWidget"); + m_settings->setValue("hGridStep",m_horizontalGridStep); + m_settings->setValue("vGridStep",m_verticalGridStep); + m_settings->setValue("defaultFont",m_defaultFont); + m_settings->setValue("useGrid",m_useGrid); + m_settings->setValue("theme",m_theme); + m_settings->setValue("ScriptEditorState", m_scriptEditor->saveState()); + m_settings->setValue("DefaultUnits", m_defaultUnits); + m_settings->endGroup(); } void ReportDesignWidget::applySettings() @@ -118,57 +210,144 @@ void ReportDesignWidget::applySettings() m_report->pageAt(i)->pageItem()->setFont(m_defaultFont); } applyUseGrid(); + + if (m_themes.contains(m_theme)){ + parentWidget()->setStyleSheet(m_themes.value(m_theme)); + m_report->setStyleSheet(m_themes.value(m_theme)); + } else { + m_theme = "Default"; + parentWidget()->setStyleSheet(""); + m_report->setStyleSheet(""); + } + +// if (m_theme.compare("Dark") == 0) { +// QFile theme(":/qdarkstyle/style.qss"); +// theme.open(QIODevice::ReadOnly); +// QString styleSheet = theme.readAll(); +// parentWidget()->setStyleSheet(styleSheet); +// m_report->setStyleSheet(styleSheet); +// } else { +// parentWidget()->setStyleSheet(""); +// m_report->setStyleSheet(""); +// } + + if (m_settings){ + m_settings->beginGroup("ScriptEditor"); + QVariant v = m_settings->value("DefaultFontName"); + if (v.isValid()){ + QVariant fontSize = m_settings->value("DefaultFontSize"); + m_scriptEditor->setEditorFont(QFont(v.toString(),fontSize.toInt())); + } + v = m_settings->value("TabIndention"); + if (v.isValid()){ + m_scriptEditor->setTabIndention(v.toInt()); + } + m_settings->endGroup(); + } } -void ReportDesignWidget::loadState(QSettings* settings) +void ReportDesignWidget::loadState() { - settings->beginGroup("DesignerWidget"); - QVariant v = settings->value("hGridStep"); + m_settings->beginGroup("DesignerWidget"); + QVariant v = m_settings->value("hGridStep"); if (v.isValid()){ m_horizontalGridStep = v.toInt(); } - v = settings->value("vGridStep"); + v = m_settings->value("vGridStep"); if (v.isValid()){ m_verticalGridStep = v.toInt(); } - v = settings->value("defaultFont"); + v = m_settings->value("defaultFont"); if (v.isValid()){ m_defaultFont = v.value(); } - v = settings->value("useGrid"); + v = m_settings->value("useGrid"); if (v.isValid()){ m_useGrid = v.toBool(); } - settings->endGroup(); + + v = m_settings->value("theme"); + if (v.isValid()){ + m_theme = v.toString(); + } + + v = m_settings->value("ScriptEditorState"); + if (v.isValid() && m_scriptEditor){ + m_scriptEditor->restoreState(v.toByteArray()); + } + + v = m_settings->value("DefaultUnits"); + if (v.isValid()){ + m_defaultUnits = static_cast(v.toInt()); + } + + m_settings->endGroup(); applySettings(); } void ReportDesignWidget::createTabs(){ - for (int i = 0; ipageCount();++i){ - QGraphicsView* view = new QGraphicsView(qobject_cast(this)); + m_tabWidget->clear(); + int pageIndex = -1; + for (int i = 0; i < m_report->pageCount(); ++i){ + PageView* view = new PageView(qobject_cast(this)); view->setBackgroundBrush(QBrush(Qt::gray)); view->setFrameShape(QFrame::NoFrame); view->setScene(m_report->pageAt(i)); + view->setPageItem(m_report->pageAt(i)->pageItem()); - foreach(QGraphicsItem* item, m_report->pageAt(i)->selectedItems()){ - item->setSelected(false); - } + m_report->pageAt(i)->clearSelection(); view->centerOn(0,0); view->scale(0.5,0.5); connectPage(m_report->pageAt(i)); - m_tabWidget->addTab(view,QIcon(),m_report->pageAt(i)->pageItem()->objectName()); + pageIndex = m_tabWidget->addTab(view,QIcon(),m_report->pageAt(i)->pageItem()->objectName()); + m_tabWidget->setTabWhatsThis(pageIndex, "page"); connect(m_report->pageAt(i)->pageItem(), SIGNAL(propertyObjectNameChanged(QString,QString)), this, SLOT(slotPagePropertyObjectNameChanged(QString,QString))); } - m_scriptEditor = new QTextEdit(this); - m_tabWidget->addTab(m_scriptEditor,QIcon(),tr("Script")); + + m_scriptEditor = new ScriptEditor(this); + + connect(m_scriptEditor, SIGNAL(textChanged()), this, SLOT(slotScriptTextChanged())); + m_scriptEditor->setReportEngine(m_report); + pageIndex = m_tabWidget->addTab(m_scriptEditor,QIcon(),tr("Script")); + m_tabWidget->setTabWhatsThis(pageIndex,"script"); m_tabWidget->setCurrentIndex(0); + +#ifdef HAVE_QTDESIGNER_INTEGRATION + QWidget* dialogDesigner; + foreach(DialogDescriber::Ptr dialogDesc, m_report->scriptContext()->dialogDescribers()){ + dialogDesigner = m_dialogDesignerManager->createFormEditor(dialogDesc->description()); + pageIndex = m_tabWidget->addTab(dialogDesigner,QIcon(),dialogDesc->name()); + m_tabWidget->setTabWhatsThis(pageIndex,"dialog"); + } +#endif + + m_traslationEditor = new TranslationEditor(this); + pageIndex = m_tabWidget->addTab(m_traslationEditor,QIcon(),tr("Translations")); + m_tabWidget->setTabWhatsThis(pageIndex,"translations"); + } +#ifdef HAVE_QTDESIGNER_INTEGRATION +void ReportDesignWidget::createNewDialogTab(const QString& dialogName, const QByteArray& description) +{ + QWidget* dialogDesigner = m_dialogDesignerManager->createFormEditor(description); + int pageIndex = m_tabWidget->addTab(dialogDesigner,QIcon(),dialogName); + m_tabWidget->setTabWhatsThis(pageIndex,"dialog"); + m_tabWidget->setCurrentIndex(pageIndex); + m_dialogDesignerManager->setActiveEditor(dialogDesigner); +} + +DialogDesigner*ReportDesignWidget::activeDialogPage() +{ + return dynamic_cast(m_tabWidget->currentWidget()); +} +#endif + ReportDesignWidget::~ReportDesignWidget() { delete m_zoomer; @@ -199,14 +378,15 @@ void ReportDesignWidget::connectPage(PageDesignIntf *page) connect(page, SIGNAL(pageUpdateFinished(LimeReport::PageDesignIntf*)), this, SIGNAL(activePageUpdated(LimeReport::PageDesignIntf*))); - //activeView()->centerOn(0,0); emit activePageChanged(); } -void ReportDesignWidget::createStartPage() +PageDesignIntf* ReportDesignWidget::createStartPage() { - m_report->appendPage("page1"); - createTabs(); + PageDesignIntf* page = m_report->appendPage("page1"); + page->pageItem()->setUnitType(m_defaultUnits); +// createTabs(); + return page; } void ReportDesignWidget::removeDatasource(const QString &datasourceName) @@ -242,7 +422,7 @@ void ReportDesignWidget::startEditMode() PageDesignIntf * ReportDesignWidget::activePage() { if (activeView()) - return qobject_cast(activeView()->scene()); + return dynamic_cast(activeView()->scene()); return 0; } @@ -266,43 +446,74 @@ void ReportDesignWidget::slotItemSelected(BaseDesignIntf *item){ emit itemSelected(item); } -void ReportDesignWidget::saveToFile(const QString &fileName){ +bool ReportDesignWidget::saveToFile(const QString &fileName){ + + bool result = false; prepareReport(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + updateDialogs(); +#endif + if (m_report->saveToFile(fileName)) { - m_report->emitSaveFinished(); + m_report->emitSaveFinished(); + result = true; } + +#ifdef HAVE_QTDESIGNER_INTEGRATION + if (result){ + m_dialogChanged = false; + m_dialogDesignerManager->setDirty(false); + } +#endif + return result; } bool ReportDesignWidget::save() { prepareReport(); - if (!m_report->reportFileName().isEmpty()){ +#ifdef HAVE_QTDESIGNER_INTEGRATION + updateDialogs(); +#endif + + bool result = false; + + if (emitSaveReport()) { + result = true; // saved via signal + } + else if (!m_report->reportFileName().isEmpty()){ if (m_report->saveToFile()){ m_report->emitSaveFinished(); - return true; + result = true; } - } - else { - m_report->emitSaveReport(); + } else { if (m_report->isSaved()) { m_report->emitSaveFinished(); - return true; + result = true; } - if (m_report->saveToFile(QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files (*.lrxml);; All files (*)"))){ + else if (m_report->saveToFile(QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files (*.lrxml);; All files (*)"))){ m_report->emitSaveFinished(); - return true; + result = true; }; } - return false; + +#ifdef HAVE_QTDESIGNER_INTEGRATION + if (result){ + m_dialogChanged = false; + m_dialogDesignerManager->setDirty(false); + } +#endif + return result; } bool ReportDesignWidget::loadFromFile(const QString &fileName) { if (m_report->loadFromFile(fileName,false)){ - createTabs(); - //connectPage(m_report->pageAt(0)); - m_scriptEditor->setPlainText(m_report->scriptContext()->initScript()); - emit loaded(); +// QByteArray editorState = m_scriptEditor->saveState(); +// createTabs(); +// m_scriptEditor->setPlainText(m_report->scriptContext()->initScript()); +// m_scriptEditor->restoreState(editorState); +// emit loaded(); +// m_dialogChanged = false; return true; } else { QMessageBox::critical(this,tr("Error"),tr("Wrong file format")); @@ -326,10 +537,20 @@ QString ReportDesignWidget::reportFileName() bool ReportDesignWidget::isNeedToSave() { if(m_report) - return m_report->isNeedToSave(); + return (m_report->isNeedToSave() || m_dialogChanged); return false; } +bool ReportDesignWidget::emitSaveReport() +{ + return m_report->emitSaveReport(); +} + +bool ReportDesignWidget::emitSaveReportAs() +{ + return m_report->emitSaveReportAs(); +} + bool ReportDesignWidget::emitLoadReport() { return m_report->emitLoadReport(); @@ -345,12 +566,20 @@ void ReportDesignWidget::undo() { if (activePage()) activePage()->undo(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + if (activeDialogPage()) + activeDialogPage()->undo(); +#endif } void ReportDesignWidget::redo() { if (activePage()) activePage()->redo(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + if (activeDialogPage()) + activeDialogPage()->redo(); +#endif } void ReportDesignWidget::copy() @@ -371,7 +600,7 @@ void ReportDesignWidget::cut() activePage()->cut(); } -void ReportDesignWidget::brinToFront() +void ReportDesignWidget::bringToFront() { if (activePage()) activePage()->bringToFront(); @@ -446,6 +675,12 @@ void ReportDesignWidget::addHLayout() activePage()->addHLayout(); } +void ReportDesignWidget::addVLayout() +{ + if (activePage()) + activePage()->addVLayout(); +} + void ReportDesignWidget::setFont(const QFont& font) { if (activePage()) @@ -470,15 +705,31 @@ void ReportDesignWidget::prepareReport() report()->clearSelection(); } +void ReportDesignWidget::initThemeIfExist(const QString &themeName, const QString &path) +{ + QFile theme(path); + if (theme.exists()){ + theme.open(QIODevice::ReadOnly); + QString styleSheet = theme.readAll(); + m_themes.insert(themeName, styleSheet); + } +} + void ReportDesignWidget::previewReport() { prepareReport(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + updateDialogs(); +#endif report()->previewReport(); } void ReportDesignWidget::printReport() { prepareReport(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + updateDialogs(); +#endif setCursor(Qt::WaitCursor); report()->printReport(); setCursor(Qt::ArrowCursor); @@ -524,16 +775,46 @@ void ReportDesignWidget::deleteCurrentPage() void ReportDesignWidget::editSetting() { SettingDialog setting(this); + setting.setSettings(m_settings); setting.setVerticalGridStep(m_verticalGridStep); setting.setHorizontalGridStep(m_horizontalGridStep); setting.setDefaultFont(m_defaultFont); setting.setSuppressAbsentFieldsAndVarsWarnings(m_report->suppressFieldAndVarError()); + QStringList themes; + themes.append(QObject::tr("Default")); + foreach(QString theme, m_themes.keys()) + if (!themes.contains(QObject::tr(theme.toLatin1()))) + themes.append(QObject::tr(theme.toLatin1())); + + setting.setDesignerThemes(themes, QObject::tr(m_theme.toLatin1())); + setting.setDesignerLanguages(m_report->designerLanguages(), m_report->currentDesignerLanguage()); + + QList unitTypes; + unitTypes << QObject::tr("Millimeters") << QObject::tr("Inches"); + setting.setDesignerUnites(unitTypes, + m_defaultUnits == BaseDesignIntf::Millimeters ? + QObject::tr("Millimeters") : + QObject::tr("Inches")); + if (setting.exec()){ m_horizontalGridStep = setting.horizontalGridStep(); m_verticalGridStep = setting.verticalGridStep(); m_defaultFont = setting.defaultFont(); + if (setting.reportUnits().compare(QObject::tr("Millimeters")) == 0) + m_defaultUnits = BaseDesignIntf::Millimeters; + else { + m_defaultUnits = BaseDesignIntf::Inches; + } + if (m_localToEng.contains(setting.theme())){ + m_theme = m_localToEng.value(setting.theme()); + } else { + m_theme = "Default"; + } m_report->setSuppressFieldAndVarError(setting.suppressAbsentFieldsAndVarsWarnings()); + if (m_report->currentDesignerLanguage() != setting.designerLanguage() ){ + m_report->setCurrentDesignerLanguage(setting.designerLanguage()); + } applySettings(); } } @@ -602,7 +883,35 @@ void ReportDesignWidget::slotPagesLoadFinished() { applySettings(); //setActivePage(m_report->pageAt(0)); - emit loaded(); + emit loadFinished(); +} + +void ReportDesignWidget::slotDialogDeleted(QString dialogName) +{ + for (int i = 0; icount(); ++i ){ + if (m_tabWidget->tabText(i).compare(dialogName) == 0){ + delete m_tabWidget->widget(i); + break; + } + } +} + +void ReportDesignWidget::lockSelectedItems() +{ + if (activePage()) + activePage()->lockSelectedItems(); +} + +void ReportDesignWidget::unlockSelectedItems() +{ + if (activePage()) + activePage()->unlockSelectedItems(); +} + +void ReportDesignWidget::selectOneLevelItems() +{ + if (activePage()) + activePage()->selectOneLevelItems(); } void ReportDesignWidget::slotDatasourceCollectionLoaded(const QString & /*collectionName*/) @@ -619,13 +928,75 @@ void ReportDesignWidget::slotCurrentTabChanged(int index) QGraphicsView* view = dynamic_cast(m_tabWidget->widget(index)); if (view) { if (view->scene()){ - foreach (QGraphicsItem* item, view->scene()->selectedItems()) item->setSelected(false); + //foreach (QGraphicsItem* item, view->scene()->selectedItems()) item->setSelected(false); + view->scene()->clearSelection(); } m_zoomer->setView(view); } +#ifdef HAVE_QTDESIGNER_INTEGRATION + if (activeTabType() == Dialog){ + m_dialogDesignerManager->setActiveEditor(m_tabWidget->widget(index)); + } + updateDialogs(); +#endif + if (activeTabType() == Translations){ + m_traslationEditor->setReportEngine(dynamic_cast(report())); + } + + if (activeTabType() == Script){ + m_scriptEditor->initCompleter(); + m_scriptEditor->setFocus(); + } + emit activePageChanged(); + + if (view) view->centerOn(0,0); } +void ReportDesignWidget::slotReportLoaded() +{ + QByteArray editorState = m_scriptEditor->saveState(); + createTabs(); + m_scriptEditor->setPlainText(m_report->scriptContext()->initScript()); + m_scriptEditor->restoreState(editorState); + emit loadFinished(); + m_dialogChanged = false; +} + +void ReportDesignWidget::slotScriptTextChanged() +{ + m_report->scriptContext()->setInitScript(m_scriptEditor->toPlainText()); +} + +#ifdef HAVE_QTDESIGNER_INTEGRATION + +void ReportDesignWidget::addNewDialog() +{ + QFile templateUi(":/templates/templates/Dialog.ui"); + templateUi.open(QIODevice::ReadOnly|QIODevice::Text); + QString templateStr = templateUi.readAll(); + QString dialogName = m_report->scriptContext()->getNewDialogName(); + templateStr.replace("$ClassName$", dialogName); + m_report->scriptContext()->addDialog(dialogName,templateStr.toUtf8()); + createNewDialogTab(dialogName, templateStr.toUtf8()); +} + +void ReportDesignWidget::slotDialogChanged(QString ) +{ + m_dialogChanged = true; +} + +void ReportDesignWidget::slotDialogNameChanged(QString oldName, QString newName) +{ + for (int i = 0; i < m_tabWidget->count(); ++i){ + if (m_tabWidget->tabText(i).compare(oldName) == 0) + m_tabWidget->setTabText(i, newName); + } + m_report->scriptContext()->changeDialogName(oldName, newName); +} + +#endif + void ReportDesignWidget::slotPagePropertyObjectNameChanged(const QString &oldValue, const QString &newValue) { for (int i = 0; i < m_tabWidget->count(); ++i ){ @@ -682,6 +1053,179 @@ void ReportDesignWidget::clear() m_scriptEditor->setPlainText(""); } +void PageView::setPageItem(PageItemDesignIntf *pageItem) +{ + if (!pageItem) return; + m_pageItem = pageItem; + if (!m_horizontalRuller){ + m_horizontalRuller = new Ruler(Ruler::Horizontal, this); + m_horizontalRuller->setPage(pageItem); + } + if (!m_verticalRuller){ + m_verticalRuller = new Ruler(Ruler::Vertical, this); + m_verticalRuller->setPage(pageItem); + } +} + +bool PageView::viewportEvent(QEvent *event) +{ + switch (event->type()) { + case QEvent::MouseMove: + m_horizontalRuller->setMousePos(dynamic_cast(event)->pos()); + m_verticalRuller->setMousePos(dynamic_cast(event)->pos()); + m_horizontalRuller->update(); + m_verticalRuller->update(); + break; + //case QEvent::Resize: + case QEvent::Paint: + if (m_horizontalRuller){ + int x = mapFromScene(m_pageItem->boundingRect().x(),m_pageItem->boundingRect().y()).x(); + int y = mapFromScene(m_pageItem->boundingRect().x(),m_pageItem->boundingRect().y()).y(); + int width = mapFromScene(m_pageItem->boundingRect().bottomRight().x(),m_pageItem->boundingRect().bottomRight().y()).x(); + int height = mapFromScene(m_pageItem->boundingRect().bottomRight().x(),m_pageItem->boundingRect().bottomRight().y()).y(); + + x = x < 0 ? 0 : x; + y = y < 0 ? 0 : y; + + m_horizontalRuller->setGeometry(x+20, 0, (width-x), 20); + m_verticalRuller->setGeometry(0, y+20, 20, (height - y)); + m_verticalRuller->update(); + m_horizontalRuller->update(); + } + break; + default: + break; + } + + return QGraphicsView::viewportEvent(event); +} + +void Ruler::setPage(PageItemDesignIntf *page) +{ + m_page = page; + +} + +void Ruler::paintEvent(QPaintEvent *event){ + QPainter painter(this); + painter.setBrush(palette().background()); + painter.setPen(Qt::NoPen); + painter.drawRect(event->rect()); +// painter.setPen(palette().foreground().color()); + + if (m_page){ + qreal rulerWidth = m_page->geometry().width() / m_page->unitFactor(); + qreal rulerHeight = m_page->geometry().height() / m_page->unitFactor(); + + QGraphicsView* view = qobject_cast(parent()); + + int hStartPos = view->mapFromScene(0,0).x(); + int vStartPos = view->mapFromScene(0,0).y(); + + QFont font = painter.font(); + font.setPointSize(7); + painter.setFont(font); + + switch (m_type) { + case Horizontal: + painter.setPen(Qt::NoPen); + + if (isColorDark(palette().background().color())) + painter.setBrush(QColor("#64893d")); + else + painter.setBrush(QColor("#b5da91")); + + drawItemWithChildren(&painter, m_page); + painter.setPen(palette().foreground().color()); + + for (int i = 0; i < rulerWidth / 10; ++i){ + int hs10 = view->mapFromScene(QPointF(m_page->geometry().topLeft().x() + i * 10 * m_page->unitFactor(), 0)).x(); + int hs5 = view->mapFromScene(QPointF(m_page->geometry().topLeft().x() + i * 10 * m_page->unitFactor() + 5 * m_page->unitFactor(), 0)).x(); + if (hs10 > 0){ + if (hStartPos > 0){ + hs10 -= hStartPos; + hs5 -= hStartPos; + } + painter.drawLine(hs10, 15, hs10, 20); + painter.drawLine(hs5, 10, hs5, 20); + if ( i > 0) + painter.drawText(QPoint(hs10 - (painter.fontMetrics().width(QString::number(i))/2), 12), + QString::number(i)); + } + } + painter.setPen(palette().foreground().color()); + painter.drawLine(m_mousePos.x() - (hStartPos > 0 ? hStartPos : 0) , 0, + m_mousePos.x() - (hStartPos > 0 ? hStartPos : 0) , 20); + break; + case Vertical: + painter.setPen(Qt::NoPen); + + if (isColorDark(palette().background().color())) + painter.setBrush(QColor("#64893d")); + else + painter.setBrush(QColor("#b5da91")); + + drawItemWithChildren(&painter, m_page); + painter.setPen(palette().foreground().color()); + for (int i = 0; i < rulerHeight / 10; ++i){ + int vs10 = view->mapFromScene(QPointF(0, m_page->geometry().topLeft().y()+i * 10 * m_page->unitFactor())).y(); + int vs5 = view->mapFromScene(QPointF(0, m_page->geometry().topLeft().y()+i * 10 * m_page->unitFactor() + 5 * m_page->unitFactor())).y(); + if (vs10 > 0){ + if (vStartPos > 0){ + vs10 -= vStartPos; + vs5 -= vStartPos; + } + painter.drawLine(15, vs10, 20, vs10); + if ( i > 0 ) + painter.drawText(QPoint( (15 - painter.fontMetrics().width(QString::number(i))) / 2 , + vs10 + (painter.fontMetrics().height()/2)), QString::number(i)); + painter.drawLine(10, vs5, 20, vs5); + } + } + painter.setPen(palette().foreground().color()); + painter.drawLine(0, m_mousePos.y() - (vStartPos > 0 ? vStartPos : 0), + 20, m_mousePos.y() - (vStartPos > 0 ? vStartPos : 0)); + break; + } + } +} + +void Ruler::drawItemWithChildren(QPainter* painter, BaseDesignIntf *item) +{ + foreach(BaseDesignIntf* child, item->childBaseItems()){ + if (!child->childBaseItems().isEmpty()) + drawItemWithChildren(painter, child); + else drawItem(painter, child); + + } + drawItem(painter, item); +} + +void Ruler::drawItem(QPainter* painter, BaseDesignIntf *item) +{ + if (!item->isSelected()) return; + + QGraphicsView* view = qobject_cast(parent()); + int hStartPos = view->mapFromScene(0,0).x(); + int vStartPos = view->mapFromScene(0,0).y(); + + int itemWidth = view->mapFromScene(item->mapToScene(item->geometry().width(),0).x() - item->mapToScene(0,0).x(), 0).x() - hStartPos; + int itemHeight = view->mapFromScene(0, item->mapToScene(0, item->geometry().height()).y() - item->mapToScene(0,0).y()).y() - vStartPos; + + switch (m_type) { + case Horizontal: + if (item->isSelected()) + painter->drawRect(view->mapFromScene(item->mapToScene(0,0)).x() - (hStartPos > 0 ? hStartPos : 0) , 0, + itemWidth, 20); + break; + case Vertical: + if (item->isSelected()) + painter->drawRect(0, view->mapFromScene(item->mapToScene(0, 0)).y() - (vStartPos > 0 ? vStartPos : 0), + 20, itemHeight); + break; + } +} + } diff --git a/limereport/lrreportdesignwidget.h b/limereport/lrreportdesignwidget.h index 407e2dc..f48879c 100644 --- a/limereport/lrreportdesignwidget.h +++ b/limereport/lrreportdesignwidget.h @@ -58,16 +58,75 @@ namespace LimeReport { class ReportEnginePrivate; class DataBrowser; class ReportDesignWindow; +class DialogDesignerManager; +class DialogDesigner; +class TranslationEditor; +class ScriptEditor; + + +class Ruler: public QWidget{ +public: + enum RulerType{Horizontal, Vertical}; + Ruler(RulerType type, QWidget* parent = 0): QWidget(parent), m_page(0), m_type(type){} + void setPage(PageItemDesignIntf* page); + void setMousePos(QPoint mousePos){ m_mousePos = mousePos;} +protected: + void paintEvent(QPaintEvent* event); + void drawItemWithChildren(QPainter *painter, BaseDesignIntf* item); + void drawItem(QPainter *painter, BaseDesignIntf* item); +private: + PageItemDesignIntf* m_page; + RulerType m_type; + QPoint m_mousePos; +}; + +class PageView: public QGraphicsView{ +public: + PageView(QWidget *parent = nullptr): QGraphicsView(parent), + m_horizontalRuller(0), m_verticalRuller(0) + { + setViewportMargins(20,20,0,0); + } + PageView(QGraphicsScene *scene, QWidget *parent = nullptr): + QGraphicsView(scene, parent), + m_horizontalRuller(0), m_verticalRuller(0) + { + setViewportMargins(20,20,0,0); + } + void setPageItem(PageItemDesignIntf* pageItem); +protected: + bool viewportEvent(QEvent *event); +private: + PageItemDesignIntf* m_pageItem; + Ruler* m_horizontalRuller; + Ruler* m_verticalRuller; +}; class ReportDesignWidget : public QWidget { Q_OBJECT Q_PROPERTY(QObject* datasourcesManager READ dataManager()) - friend class ReportDesignWindow; public: + enum ToolWindowType{ + WidgetBox = 1, + ObjectInspector = 2, + ActionEditor = 3, + SignalSlotEditor = 4, + PropertyEditor = 5, + ResourceEditor = 6 + }; + enum EditorTabType{ + Page, + Dialog, + Script, + Translations, + TabTypeCount + }; + ReportDesignWidget(ReportEnginePrivateInterface* report, QSettings* settings, + QMainWindow *mainWindow, QWidget *parent = 0); ~ReportDesignWidget(); -// static ReportDesignWidget* instance(){return m_instance;} - void createStartPage(); + PageDesignIntf *createStartPage(); + void createTabs(); void clear(); DataSourceManager* dataManager(); ScriptEngineManager* scriptManager(); @@ -86,21 +145,30 @@ public: QList selectedItems(); QStringList datasourcesNames(); void scale( qreal sx, qreal sy); -// void setDatabrowser(DataBrowser* databrowser); - ReportEnginePrivate* report(){return m_report;} + ReportEnginePrivateInterface* report(){return m_report;} QString reportFileName(); bool isNeedToSave(); + bool emitSaveReport(); + bool emitSaveReportAs(); bool emitLoadReport(); - void saveState(QSettings *settings); - void loadState(QSettings *settings); + void saveState(); + void loadState(); void applySettings(); void applyUseGrid(); bool useGrid(){ return m_useGrid;} bool useMagnet() const; void setUseMagnet(bool useMagnet); - + EditorTabType activeTabType(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + void initDialogDesignerToolBar(QToolBar* toolBar); + void updateDialogs(); + DialogDesignerManager *dialogDesignerManager() const; + QString activeDialogName(); + DialogDesigner* activeDialogPage(); + QWidget* toolWindow(ToolWindowType windowType); +#endif public slots: - void saveToFile(const QString&); + bool saveToFile(const QString&); bool save(); bool loadFromFile(const QString&); void deleteSelectedItems(); @@ -110,7 +178,7 @@ public slots: void copy(); void paste(); void cut(); - void brinToFront(); + void bringToFront(); void sendToBack(); void alignToLeft(); void alignToRight(); @@ -122,6 +190,7 @@ public slots: void sameWidth(); void editLayoutMode(bool value); void addHLayout(); + void addVLayout(); void setFont(const QFont &font); void setTextAlign(const bool &horizontalAlign, const Qt::AlignmentFlag &alignment); void setBorders(const BaseDesignIntf::BorderLines& borders); @@ -131,13 +200,26 @@ public slots: void printReport(); void addPage(); void deleteCurrentPage(); + void slotPagesLoadFinished(); + void slotDialogDeleted(QString dialogName); + void lockSelectedItems(); + void unlockSelectedItems(); + void selectOneLevelItems(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + void addNewDialog(); +#endif private slots: void slotItemSelected(LimeReport::BaseDesignIntf *item); void slotSelectionChanged(); - void slotPagesLoadFinished(); void slotDatasourceCollectionLoaded(const QString&); void slotSceneRectChanged(QRectF); void slotCurrentTabChanged(int index); + void slotReportLoaded(); + void slotScriptTextChanged(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + void slotDialogChanged(QString); + void slotDialogNameChanged(QString oldName, QString newName); +#endif void slotPagePropertyObjectNameChanged(const QString& oldValue, const QString& newValue); void slotTabMoved(int from, int to); signals: @@ -149,7 +231,7 @@ signals: void multiItemSelected(); void commandHistoryChanged(); void cleared(); - void loaded(); + void loadFinished(); void activePageChanged(); void activePageUpdated(LimeReport::PageDesignIntf*); void bandAdded(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*); @@ -159,20 +241,27 @@ signals: void pageAdded(PageDesignIntf* page); void pageDeleted(); protected: - void createTabs(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + void createNewDialogTab(const QString& dialogName,const QByteArray& description); +#endif private: bool eventFilter(QObject *target, QEvent *event); - ReportDesignWidget(ReportEnginePrivate* report,QMainWindow *mainWindow,QWidget *parent = 0); + void prepareReport(); + void initThemeIfExist(const QString& themeName, const QString& path); private: - ReportEnginePrivate* m_report; + ReportEnginePrivateInterface* m_report; QGraphicsView *m_view; - QTextEdit* m_scriptEditor; - QMainWindow *m_mainWindow; -#ifdef HAVE_QT5 - QTabWidget* m_tabWidget; + ScriptEditor* m_scriptEditor; + TranslationEditor* m_traslationEditor; +#ifdef HAVE_QTDESIGNER_INTEGRATION + DialogDesignerManager* m_dialogDesignerManager; #endif + QMainWindow *m_mainWindow; #ifdef HAVE_QT4 LimeReportTabWidget* m_tabWidget; +#endif +#ifdef HAVE_QT5 + QTabWidget* m_tabWidget; #endif GraphicsViewZoomer* m_zoomer; QFont m_defaultFont; @@ -180,9 +269,13 @@ private: int m_horizontalGridStep; bool m_useGrid; bool m_useMagnet; -// static ReportDesignWidget* m_instance; - void prepareReport(); + bool m_dialogChanged; + QString m_theme; + QSettings* m_settings; + QMap m_themes; + QMap m_localToEng; + BaseDesignIntf::UnitType m_defaultUnits; }; -} +} // namespace LimeReport #endif // LRREPORTDESIGNWIDGET_H diff --git a/limereport/lrreportdesignwindow.cpp b/limereport/lrreportdesignwindow.cpp index 7b4ee68..d98af07 100644 --- a/limereport/lrreportdesignwindow.cpp +++ b/limereport/lrreportdesignwindow.cpp @@ -40,6 +40,9 @@ #include #include #include +#include +#include +#include #include "lrreportdesignwindow.h" #include "lrbandsmanager.h" @@ -62,8 +65,9 @@ namespace LimeReport{ ReportDesignWindow* ReportDesignWindow::m_instance=0; -ReportDesignWindow::ReportDesignWindow(ReportEnginePrivate *report, QWidget *parent, QSettings* settings) : - QMainWindow(parent), m_textAttibutesIsChanging(false), m_settings(settings), m_ownedSettings(false), m_progressDialog(0), m_showProgressDialog(true) +ReportDesignWindow::ReportDesignWindow(ReportEnginePrivateInterface* report, QWidget *parent, QSettings* settings) : + ReportDesignWindowInterface(parent), m_textAttibutesIsChanging(false), m_settings(settings), m_ownedSettings(false), + m_progressDialog(0), m_showProgressDialog(true), m_editorTabType(ReportDesignWidget::Page), m_reportItemIsLocked(false) { initReportEditor(report); createActions(); @@ -73,18 +77,30 @@ ReportDesignWindow::ReportDesignWindow(ReportEnginePrivate *report, QWidget *par createDataWindow(); createScriptWindow(); createObjectsBrowser(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + createDialogWidgetBox(); + createDialogPropertyEditor(); + createDialogObjectInspector(); + createDialogActionEditor(); + createDialogSignalSlotEditor(); + createDialogResourceEditor(); + createDialogDesignerToolBar(); +#endif m_instance=this; m_statusBar=new QStatusBar(this); m_lblReportName = new QLabel(report->reportFileName(),this); m_statusBar->insertWidget(0,m_lblReportName); setStatusBar(m_statusBar); + QString windowTitle = "Lime Report Designer"; if (!report->reportName().isEmpty()) windowTitle = report->reportName() + " - " + windowTitle; setWindowTitle(windowTitle); + showDefaultEditors(); + showDefaultToolBars(); restoreSetting(); m_hideLeftPanel->setChecked(isDockAreaVisible(Qt::LeftDockWidgetArea)); - m_hideRightPanel->setChecked(isDockAreaVisible(Qt::RightDockWidgetArea)); + m_hideRightPanel->setChecked(isDockAreaVisible(Qt::RightDockWidgetArea)); } ReportDesignWindow::~ReportDesignWindow() @@ -114,6 +130,7 @@ void ReportDesignWindow::createActions() m_editModeAction->setIcon(QIcon(":/report/images/editMode")); m_editModeAction->setCheckable(true); m_editModeAction->setChecked(true); + m_editModeAction->setShortcut(QKeySequence(Qt::Key_Escape)); connect(m_editModeAction,SIGNAL(triggered()),this,SLOT(slotEditMode())); m_undoAction = new QAction(tr("Undo"),this); @@ -202,11 +219,6 @@ void ReportDesignWindow::createActions() m_testAction->setIcon(QIcon(":/report/images/pin")); connect(m_testAction,SIGNAL(triggered()),this,SLOT(slotTest())); -// m_printReportAction = new QAction(tr("Print Report"),this); -// m_printReportAction->setIcon(QIcon(":/report/images/print")); -// m_printReportAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P)); -// connect(m_printReportAction,SIGNAL(triggered()),this,SLOT(slotPrintReport())); - m_editLayoutMode = new QAction(tr("Edit layouts mode"),this); m_editLayoutMode->setIcon(QIcon(":/report/images/editlayout")); m_editLayoutMode->setCheckable(true); @@ -216,6 +228,10 @@ void ReportDesignWindow::createActions() m_addHLayout->setIcon(QIcon(":/report/images/hlayout")); connect(m_addHLayout,SIGNAL(triggered()),this,SLOT(slotHLayout())); + m_addVLayout = new QAction(tr("Vertical layout"),this); + m_addVLayout->setIcon(QIcon(":/report/images/vlayout")); + connect(m_addVLayout,SIGNAL(triggered()),this,SLOT(slotVLayout())); + m_aboutAction = new QAction(tr("About"),this); m_aboutAction->setIcon(QIcon(":/report/images/copyright")); connect(m_aboutAction,SIGNAL(triggered()),this,SLOT(slotShowAbout())); @@ -231,6 +247,33 @@ void ReportDesignWindow::createActions() m_hideRightPanel->setIcon(QIcon(":/report/images/hideRightPanel")); m_hideRightPanel->setShortcut(QKeySequence(Qt::ALT + Qt::Key_R)); connect(m_hideRightPanel,SIGNAL(toggled(bool)), this, SLOT(slotHideRightPanel(bool))); +#ifdef HAVE_QTDESIGNER_INTEGRATION + m_deleteDialogAction = new QAction(tr("Delete dialog"), this); + m_deleteDialogAction->setIcon(QIcon(":/report//images/deleteDialog")); + connect(m_deleteDialogAction, SIGNAL(triggered()), this, SLOT(slotDeleteDialog())); + + m_addNewDialogAction = new QAction(tr("Add new dialog"), this); + m_addNewDialogAction->setIcon(QIcon(":/report//images/addDialog")); + connect(m_addNewDialogAction, SIGNAL(triggered()), this, SLOT(slotAddNewDialog())); +#endif + + m_lockSelectedItemsAction = new QAction(tr("Lock selected items"), this); + m_lockSelectedItemsAction->setIcon(QIcon(":/report/images/lock")); + m_lockSelectedItemsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); + connect(m_lockSelectedItemsAction, SIGNAL(triggered()), + this, SLOT(slotLockSelectedItems())); + + m_unlockSelectedItemsAction = new QAction(tr("Unlock selected items"), this); + m_unlockSelectedItemsAction->setIcon(QIcon(":/report/images/unlock")); + m_unlockSelectedItemsAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_L)); + connect(m_unlockSelectedItemsAction, SIGNAL(triggered()), + this, SLOT(slotUnlockSelectedItems())); + + m_selectOneLevelItems = new QAction(tr("Select one level items"), this); + //m_unlockSelectedItemsAction->setIcon(QIcon(":/report/images/unlock")); + m_selectOneLevelItems->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_A)); + connect(m_selectOneLevelItems, SIGNAL(triggered()), + this, SLOT(slotSelectOneLevelItems())); } void ReportDesignWindow::createReportToolBar() @@ -243,8 +286,8 @@ void ReportDesignWindow::createReportToolBar() m_reportToolBar->setObjectName("reportTools"); createItemsActions(); m_reportToolBar->addSeparator(); - //m_reportToolBar->addAction(m_editLayoutMode); m_reportToolBar->addAction(m_addHLayout); + m_reportToolBar->addAction(m_addVLayout); m_reportToolBar->addSeparator(); m_reportToolBar->addAction(m_deleteItemAction); @@ -277,6 +320,9 @@ void ReportDesignWindow::createToolBars() m_mainToolBar->addAction(m_newPageAction); m_mainToolBar->addAction(m_deletePageAction); +#ifdef HAVE_QTDESIGNER_INTEGRATION + m_mainToolBar->addAction(m_addNewDialogAction); +#endif m_mainToolBar->addSeparator(); m_mainToolBar->addAction(m_copyAction); @@ -295,11 +341,11 @@ void ReportDesignWindow::createToolBars() //m_mainToolBar->addAction(m_printReportAction); - m_fontEditorBar = new FontEditorWidget(m_reportDesignWidget,tr("Font"),this); + m_fontEditorBar = new FontEditorWidgetForDesigner(m_reportDesignWidget,tr("Font"),this); m_fontEditorBar->setIconSize(m_mainToolBar->iconSize()); m_fontEditorBar->setObjectName("fontTools"); addToolBar(m_fontEditorBar); - m_textAlignmentEditorBar = new TextAlignmentEditorWidget(m_reportDesignWidget,tr("Text alignment"),this); + m_textAlignmentEditorBar = new TextAlignmentEditorWidgetForDesigner(m_reportDesignWidget,tr("Text alignment"),this); m_textAlignmentEditorBar->setIconSize(m_mainToolBar->iconSize()); m_textAlignmentEditorBar->setObjectName("textAlignmentTools"); addToolBar(m_textAlignmentEditorBar); @@ -310,12 +356,17 @@ void ReportDesignWindow::createToolBars() m_itemsAlignmentEditorBar->insertAction(m_itemsAlignmentEditorBar->actions().at(1),m_useMagnetAction); m_itemsAlignmentEditorBar->insertSeparator(m_itemsAlignmentEditorBar->actions().at(2)); addToolBar(m_itemsAlignmentEditorBar); - m_itemsBordersEditorBar = new ItemsBordersEditorWidget(m_reportDesignWidget,tr("Borders"),this); + m_itemsBordersEditorBar = new ItemsBordersEditorWidgetForDesigner(m_reportDesignWidget,tr("Borders"),this); m_itemsBordersEditorBar->setIconSize(m_mainToolBar->iconSize()); m_itemsBordersEditorBar->setObjectName("itemsBorderTools"); addToolBar(m_itemsBordersEditorBar); createReportToolBar(); + + m_pageTools << m_mainToolBar << m_reportToolBar << m_fontEditorBar + << m_textAlignmentEditorBar << m_itemsAlignmentEditorBar + << m_itemsBordersEditorBar; + } void ReportDesignWindow::createItemsActions() @@ -432,6 +483,10 @@ void ReportDesignWindow::createMainMenu() m_editMenu->addAction(m_pasteAction); m_editMenu->addAction(m_cutAction); m_editMenu->addAction(m_settingsAction); + m_editMenu->addSeparator(); + m_editMenu->addAction(m_lockSelectedItemsAction); + m_editMenu->addAction(m_unlockSelectedItemsAction); + m_editMenu->addAction(m_selectOneLevelItems); m_infoMenu = menuBar()->addMenu(tr("Info")); m_infoMenu->addAction(m_aboutAction); m_recentFilesMenu = m_fileMenu->addMenu(tr("Recent Files")); @@ -440,9 +495,9 @@ void ReportDesignWindow::createMainMenu() m_recentFilesMenu->setDisabled(m_recentFiles.isEmpty()); } -void ReportDesignWindow::initReportEditor(ReportEnginePrivate* report) +void ReportDesignWindow::initReportEditor(ReportEnginePrivateInterface* report) { - m_reportDesignWidget=new ReportDesignWidget(report,this,this); + m_reportDesignWidget=new ReportDesignWidget(report, m_settings, this,this); setCentralWidget(m_reportDesignWidget); connect(m_reportDesignWidget,SIGNAL(itemSelected(LimeReport::BaseDesignIntf*)), this,SLOT(slotItemSelected(LimeReport::BaseDesignIntf*))); @@ -453,16 +508,16 @@ void ReportDesignWindow::initReportEditor(ReportEnginePrivate* report) connect(m_reportDesignWidget,SIGNAL(itemInserted(LimeReport::PageDesignIntf*,QPointF,QString)), this,SLOT(slotItemInserted(LimeReport::PageDesignIntf*,QPointF,QString))); connect(m_reportDesignWidget,SIGNAL(itemInsertCanceled(QString)),this,SLOT(slotItemInsertCanceled(QString))); - connect(m_reportDesignWidget->report(),SIGNAL(datasourceCollectionLoadFinished(QString)),this,SLOT(slotUpdateDataBrowser(QString))); + connect(dynamic_cast(report), SIGNAL(datasourceCollectionLoadFinished(QString)),this,SLOT(slotUpdateDataBrowser(QString))); connect(m_reportDesignWidget,SIGNAL(commandHistoryChanged()),this,SLOT(slotCommandHistoryChanged())); connect(m_reportDesignWidget,SIGNAL(activePageChanged()),this,SLOT(slotActivePageChanged())); connect(m_reportDesignWidget, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), this, SLOT(slotBandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); connect(m_reportDesignWidget, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), this, SLOT(slotBandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); - connect(m_reportDesignWidget->report(), SIGNAL(renderStarted()), this, SLOT(renderStarted())); - connect(m_reportDesignWidget->report(), SIGNAL(renderPageFinished(int)), this, SLOT(renderPageFinished(int))); - connect(m_reportDesignWidget->report(), SIGNAL(renderFinished()), this, SLOT(renderFinished())); + connect(dynamic_cast(report), SIGNAL(renderStarted()), this, SLOT(renderStarted())); + connect(dynamic_cast(report), SIGNAL(renderPageFinished(int)), this, SLOT(renderPageFinished(int))); + connect(dynamic_cast(report), SIGNAL(renderFinished()), this, SLOT(renderFinished())); connect(m_reportDesignWidget, SIGNAL(pageAdded(PageDesignIntf*)), this, SLOT(slotPageAdded(PageDesignIntf*))); connect(m_reportDesignWidget, SIGNAL(pageDeleted()), this, SLOT(slotPageDeleted())); } @@ -470,24 +525,22 @@ void ReportDesignWindow::initReportEditor(ReportEnginePrivate* report) void ReportDesignWindow::createObjectInspector() { m_objectInspector = new ObjectInspectorWidget(this); - m_propertyModel = new BaseDesignPropertyModel(this); m_validator = new ObjectNameValidator(); - m_propertyModel->setValidator(m_validator); - m_propertyModel->setSubclassesAsLevel(false); -// connect(m_propertyModel,SIGNAL(objectPropetyChanged(QString,QVariant,QVariant)),this,SLOT(slotItemDataChanged(QString,QVariant,QVariant))); - m_objectInspector->setModel(m_propertyModel); + m_objectInspector->setValidator(m_validator); + m_objectInspector->setSubclassesAsLevel(false); + m_objectInspector->setTranslateProperties(true); m_objectInspector->setAlternatingRowColors(true); - m_objectInspector->setRootIsDecorated(!m_propertyModel->subclassesAsLevel()); - + m_objectInspector->setRootIsDecorated(!m_objectInspector->subclassesAsLevel()); QDockWidget *objectDoc = new QDockWidget(this); QWidget* w = new QWidget(objectDoc); QVBoxLayout* l = new QVBoxLayout(w); l->addWidget(m_objectInspector); - l->setContentsMargins(2,2,2,2); + l->setMargin(0); w->setLayout(l); objectDoc->setWindowTitle(tr("Object Inspector")); objectDoc->setWidget(w); objectDoc->setObjectName("objectInspector"); + m_pageEditors.append(objectDoc); addDockWidget(Qt::LeftDockWidgetArea,objectDoc); } @@ -500,9 +553,90 @@ void ReportDesignWindow::createObjectsBrowser() doc->setObjectName("structureDoc"); addDockWidget(Qt::RightDockWidgetArea,doc); m_objectsBrowser->setMainWindow(this); + m_pageEditors.append(doc); m_objectsBrowser->setReportEditor(m_reportDesignWidget); } +#ifdef HAVE_QTDESIGNER_INTEGRATION + +void ReportDesignWindow::createDialogWidgetBox() +{ + QDockWidget *doc = new QDockWidget(this); + doc->setWindowTitle(tr("Widget Box")); + doc->setWidget(m_reportDesignWidget->toolWindow(ReportDesignWidget::WidgetBox)); + doc->setObjectName("WidgetBox"); + addDockWidget(Qt::LeftDockWidgetArea,doc); + m_dialogEditors.append(doc); +} + +void ReportDesignWindow::createDialogPropertyEditor() +{ + QDockWidget *doc = new QDockWidget(this); + doc->setWindowTitle(tr("Property Editor")); + doc->setWidget(m_reportDesignWidget->toolWindow(ReportDesignWidget::PropertyEditor)); + doc->setObjectName("PropertyEditor"); + addDockWidget(Qt::RightDockWidgetArea,doc); + m_dialogEditors.append(doc); +} + +void ReportDesignWindow::createDialogObjectInspector() +{ + QDockWidget *dock = new QDockWidget(this); + dock->setWindowTitle(tr("Object Inspector")); + dock->setWidget(m_reportDesignWidget->toolWindow(ReportDesignWidget::ObjectInspector)); + dock->setObjectName("ObjectInspector"); + addDockWidget(Qt::RightDockWidgetArea,dock); + m_dialogEditors.append(dock); +} + +void ReportDesignWindow::createDialogActionEditor() +{ + QDockWidget *dock = new QDockWidget(this); + dock->setWindowTitle(tr("Action Editor")); + dock->setWidget(m_reportDesignWidget->toolWindow(ReportDesignWidget::ActionEditor)); + dock->setObjectName("ActionEditor"); + addDockWidget(Qt::BottomDockWidgetArea,dock); + m_dialogEditors.append(dock); + m_docksToTabify.append(dock); +} + +void ReportDesignWindow::createDialogResourceEditor() +{ + QDockWidget *dock = new QDockWidget(this); + dock->setWindowTitle(tr("Resource Editor")); + dock->setWidget(m_reportDesignWidget->toolWindow(ReportDesignWidget::ResourceEditor)); + dock->setObjectName("ResourceEditor"); + addDockWidget(Qt::BottomDockWidgetArea,dock); + m_dialogEditors.append(dock); + m_docksToTabify.append(dock); +} + +void ReportDesignWindow::createDialogSignalSlotEditor() +{ + QDockWidget *dock = new QDockWidget(this); + dock->setWindowTitle(tr("SignalSlot Editor")); + dock->setWidget(m_reportDesignWidget->toolWindow(ReportDesignWidget::SignalSlotEditor)); + dock->setObjectName("SignalSlotEditor"); + addDockWidget(Qt::BottomDockWidgetArea,dock); + m_dialogEditors.append(dock); + m_docksToTabify.append(dock); +} + +void ReportDesignWindow::createDialogDesignerToolBar() +{ + m_dialogDesignerToolBar = addToolBar(tr("Dialog Designer Tools")); + m_dialogDesignerToolBar->setObjectName("DialogDesignerTools"); + m_dialogDesignerToolBar->addAction(m_saveReportAction); + m_dialogDesignerToolBar->addAction(m_previewReportAction); + m_dialogDesignerToolBar->addSeparator(); + m_dialogDesignerToolBar->addAction(m_deleteDialogAction); + m_dialogDesignerToolBar->addSeparator(); + m_reportDesignWidget->initDialogDesignerToolBar(m_dialogDesignerToolBar); + m_dialogTools << m_dialogDesignerToolBar; +} + +#endif + void ReportDesignWindow::createDataWindow() { QDockWidget *dataDoc = new QDockWidget(this); @@ -513,6 +647,7 @@ void ReportDesignWindow::createDataWindow() addDockWidget(Qt::LeftDockWidgetArea,dataDoc); m_dataBrowser->setSettings(settings()); m_dataBrowser->setMainWindow(this); + m_pageEditors.append(dataDoc); m_dataBrowser->setReportEditor(m_reportDesignWidget); } @@ -525,6 +660,7 @@ void ReportDesignWindow::createScriptWindow() dataDoc->setObjectName("scriptDoc"); addDockWidget(Qt::LeftDockWidgetArea,dataDoc); m_scriptBrowser->setReportEditor(m_reportDesignWidget); + m_pageEditors.append(dataDoc); #ifdef HAVE_UI_LOADER m_scriptBrowser->updateDialogsTree(); #endif @@ -538,8 +674,10 @@ void ReportDesignWindow::updateRedoUndo() void ReportDesignWindow::startNewReport() { + m_reportDesignWidget->saveState(); m_reportDesignWidget->clear(); m_reportDesignWidget->createStartPage(); + m_reportDesignWidget->createTabs(); m_lblReportName->setText(""); updateRedoUndo(); m_reportDesignWidget->slotPagesLoadFinished(); @@ -547,22 +685,42 @@ void ReportDesignWindow::startNewReport() m_newPageFooter->setEnabled(true); m_newReportHeader->setEnabled(true); m_newReportFooter->setEnabled(true); + m_editorTabType = ReportDesignWidget::Page; + showDefaultToolBars(); m_reportDesignWidget->report()->dataManager()->dropChanges(); + m_reportDesignWidget->report()->scriptContext()->dropChanges(); + m_reportDesignWidget->loadState(); + } void ReportDesignWindow::writePosition() { settings()->beginGroup("DesignerWindow"); settings()->setValue("Geometry",saveGeometry()); - settings()->setValue("State",saveState()); settings()->endGroup(); } +void ReportDesignWindow::setDocWidgetsVisibility(bool visible) +{ + if (!m_hideLeftPanel->isChecked()) + hideDockWidgets(Qt::LeftDockWidgetArea,!visible); + if (!m_hideRightPanel->isChecked()) + hideDockWidgets(Qt::RightDockWidgetArea,!visible); +} + void ReportDesignWindow::writeState() { settings()->beginGroup("DesignerWindow"); - settings()->setValue("State",saveState()); - settings()->setValue("InspectorFirsColumnWidth",m_objectInspector->columnWidth(0)); + + setDocWidgetsVisibility(true); + + m_editorsStates[m_editorTabType] = saveState(); + settings()->setValue("PageEditorsState", m_editorsStates[ReportDesignWidget::Page]); + settings()->setValue("DialogEditorsState", m_editorsStates[ReportDesignWidget::Dialog]); + settings()->setValue("ScriptEditorsState", m_editorsStates[ReportDesignWidget::Script]); + settings()->setValue("TranslationEditorsState", m_editorsStates[ReportDesignWidget::Translations]); + settings()->setValue("InspectorFirsColumnWidth", m_objectInspector->columnWidth(0)); + settings()->setValue("InspectorTranslateProperties", m_objectInspector->translateProperties()); settings()->endGroup(); settings()->beginGroup("RecentFiles"); settings()->setValue("filesCount",m_recentFiles.count()); @@ -575,7 +733,7 @@ void ReportDesignWindow::writeState() ++it; } settings()->endGroup(); - m_reportDesignWidget->saveState(settings()); + m_reportDesignWidget->saveState(); } void ReportDesignWindow::createRecentFilesMenu() @@ -648,21 +806,41 @@ void ReportDesignWindow::restoreSetting() int screenWidth = desktop->screenGeometry().width(); int screenHeight = desktop->screenGeometry().height(); - int x = screenWidth*0.1; - int y = screenHeight*0.1; + int x = screenWidth * 0.1; + int y = screenHeight * 0.1; - resize(screenWidth*0.8, screenHeight*0.8); + resize(screenWidth * 0.8, screenHeight * 0.8); move(x, y); } - v = settings()->value("State"); + v = settings()->value("PageEditorsState"); if (v.isValid()){ - restoreState(v.toByteArray()); + m_editorsStates[ReportDesignWidget::Page] = v.toByteArray(); + m_editorTabType = ReportDesignWidget::Page; } + v = settings()->value("DialogEditorsState"); + if (v.isValid()){ + m_editorsStates[ReportDesignWidget::Dialog] = v.toByteArray(); + } + v = settings()->value("ScriptEditorsState"); + if (v.isValid()){ + m_editorsStates[ReportDesignWidget::Script] = v.toByteArray(); + } + + v = settings()->value("TranslationEditorsState"); + if (v.isValid()){ + m_editorsStates[ReportDesignWidget::Translations] = v.toByteArray(); + } + v = settings()->value("InspectorFirsColumnWidth"); if (v.isValid()){ m_objectInspector->setColumnWidth(0,v.toInt()); } + v = settings()->value("InspectorTranslateProperties"); + if (v.isValid()){ + m_objectInspector->setTranslateProperties(v.toBool()); + } + settings()->endGroup(); settings()->beginGroup("RecentFiles"); @@ -678,7 +856,7 @@ void ReportDesignWindow::restoreSetting() } settings()->endGroup(); - m_reportDesignWidget->loadState(settings()); + m_reportDesignWidget->loadState(); m_useGridAction->setChecked(m_reportDesignWidget->useGrid()); createRecentFilesMenu(); } @@ -767,6 +945,7 @@ void ReportDesignWindow::slotNewTextItem() { if (m_newTextItemAction->isChecked()) {m_newTextItemAction->setCheckable(false);return;} if (m_reportDesignWidget) { + m_reportItemIsLocked = QApplication::keyboardModifiers() == Qt::SHIFT; m_reportDesignWidget->startInsertMode("TextItem"); m_newTextItemAction->setCheckable(true); m_newTextItemAction->setChecked(true); @@ -785,7 +964,7 @@ void ReportDesignWindow::slotNewBand(int bandType) void ReportDesignWindow::slotItemSelected(LimeReport::BaseDesignIntf *item) { - if (m_propertyModel->currentObject()!=item){ + if (m_objectInspector->object()!=item){ m_newSubDetail->setEnabled(false); m_newSubDetailHeader->setEnabled(false); @@ -796,9 +975,9 @@ void ReportDesignWindow::slotItemSelected(LimeReport::BaseDesignIntf *item) m_newDataFooter->setEnabled(false); m_objectInspector->commitActiveEditorData(); - m_propertyModel->setObject(item); + m_objectInspector->setObject(item); - if (m_propertyModel->subclassesAsLevel()) + if (m_objectInspector->subclassesAsLevel()) m_objectInspector->expandToDepth(0); QSet bs; @@ -832,7 +1011,7 @@ void ReportDesignWindow::slotItemSelected(LimeReport::BaseDesignIntf *item) m_fontEditorBar->setItem(item); m_textAlignmentEditorBar->setItem(item); m_itemsBordersEditorBar->setItem(item); - } else {m_propertyModel->clearObjectsList();} + } else {m_objectInspector->clearObjectsList();} } void ReportDesignWindow::slotItemPropertyChanged(const QString &objectName, const QString &propertyName, const QVariant& oldValue, const QVariant& newValue ) @@ -840,8 +1019,8 @@ void ReportDesignWindow::slotItemPropertyChanged(const QString &objectName, cons Q_UNUSED(oldValue) Q_UNUSED(newValue) - if (m_propertyModel->currentObject()&&(m_propertyModel->currentObject()->objectName()==objectName)){ - m_propertyModel->updateProperty(propertyName); + if (m_objectInspector->object()&&(m_objectInspector->object()->objectName()==objectName)){ + m_objectInspector->updateProperty(propertyName); } } @@ -854,8 +1033,8 @@ void ReportDesignWindow::slotMultiItemSelected() QObject* oi = dynamic_cast(gi); if (oi) selectionList.append(oi); } - m_propertyModel->setMultiObjects(&selectionList); - if (m_propertyModel->subclassesAsLevel()) + m_objectInspector->setMultiObjects(&selectionList); + if (m_objectInspector->subclassesAsLevel()) m_objectInspector->expandToDepth(0); } @@ -866,14 +1045,19 @@ void ReportDesignWindow::slotInsertModeStarted() void ReportDesignWindow::slotItemInserted(PageDesignIntf *, QPointF, const QString &ItemType) { - m_editModeAction->setChecked(true); - if (m_actionMap.value(ItemType)) - m_actionMap.value(ItemType)->setCheckable(false); + if (!m_reportItemIsLocked){ + m_editModeAction->setChecked(true); + if (m_actionMap.value(ItemType)) + m_actionMap.value(ItemType)->setCheckable(false); + } else { + m_reportDesignWidget->startInsertMode(ItemType); + } } void ReportDesignWindow::slotItemInsertCanceled(const QString &ItemType) { m_editModeAction->setChecked(true); + m_reportItemIsLocked = false; if (m_actionMap.value(ItemType)) m_actionMap.value(ItemType)->setCheckable(false); } @@ -904,13 +1088,19 @@ void ReportDesignWindow::slotCommandHistoryChanged() void ReportDesignWindow::slotSaveReport() { + if (m_reportDesignWidget->emitSaveReport()) return; // report save as'd via signal + m_reportDesignWidget->save(); - m_lblReportName->setText(m_reportDesignWidget->reportFileName()); - if (!m_reportDesignWidget->reportFileName().isEmpty()) addRecentFile(m_reportDesignWidget->reportFileName()); + + QString filename = m_reportDesignWidget->reportFileName(); + m_lblReportName->setText(filename); + if(!filename.isEmpty()) addRecentFile(filename); } void ReportDesignWindow::slotSaveReportAs() { + if (m_reportDesignWidget->emitSaveReportAs()) return; // report save as'd via signal + QString fileName = QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files(*.lrxml);; All files(*)"); if (!fileName.isEmpty()){ m_reportDesignWidget->saveToFile(fileName); @@ -921,47 +1111,49 @@ void ReportDesignWindow::slotSaveReportAs() void ReportDesignWindow::slotLoadReport() { - if (checkNeedToSave()){ - if (!m_reportDesignWidget->emitLoadReport()){ - QString fileName = QFileDialog::getOpenFileName( - this,tr("Report file name"), - m_reportDesignWidget->report()->currentReportsDir(), - "Report files(*.lrxml);; All files(*)" - ); - if (!fileName.isEmpty()) { - QApplication::processEvents(); - setCursor(Qt::WaitCursor); - m_reportDesignWidget->clear(); - if (m_reportDesignWidget->loadFromFile(fileName)){ - m_lblReportName->setText(fileName); - m_propertyModel->setObject(0); - updateRedoUndo(); - if (!m_recentFiles.contains(fileName)){ - if (m_recentFiles.count()==10){ - QMap::const_iterator it = m_recentFiles.constBegin(); - QDateTime minDate = QDateTime::currentDateTime(); - while (it != m_recentFiles.constEnd()) { - if (minDate>it.value()) minDate = it.value(); - ++it; - } - m_recentFiles.remove(m_recentFiles.key(minDate)); - } - m_recentFiles.insert(fileName,QDateTime::currentDateTime()); - } else { - m_recentFiles[fileName] = QDateTime::currentDateTime(); - } - createRecentFilesMenu(); - m_deletePageAction->setEnabled(m_reportDesignWidget->report()->pageCount()>1); - } else { - slotNewReport(); - } - unsetCursor(); - setWindowTitle(m_reportDesignWidget->report()->reportName() + " - Lime Report Designer"); - addRecentFile(fileName); - } - } + if (!checkNeedToSave()) return; // don't need to save + if (m_reportDesignWidget->emitLoadReport()) return; // report loaded via signal + + QString fileName = QFileDialog::getOpenFileName( + this,tr("Report file name"), + m_reportDesignWidget->report()->currentReportsDir(), + "Report files(*.lrxml);; All files(*)" + ); + if (!fileName.isEmpty()) { + QApplication::processEvents(); + setCursor(Qt::WaitCursor); + m_reportDesignWidget->clear(); + if (m_reportDesignWidget->loadFromFile(fileName)){ + m_lblReportName->setText(fileName); + m_objectInspector->setObject(0); + updateRedoUndo(); + setWindowTitle(m_reportDesignWidget->report()->reportName() + " - Lime Report Designer"); + if (!m_recentFiles.contains(fileName)){ + if (m_recentFiles.count()==10){ + QMap::const_iterator it = m_recentFiles.constBegin(); + QDateTime minDate = QDateTime::currentDateTime(); + while (it != m_recentFiles.constEnd()) { + if (minDate>it.value()) minDate = it.value(); + ++it; + } + m_recentFiles.remove(m_recentFiles.key(minDate)); + } + m_recentFiles.insert(fileName,QDateTime::currentDateTime()); + } else { + m_recentFiles[fileName] = QDateTime::currentDateTime(); + } + createRecentFilesMenu(); + m_deletePageAction->setEnabled(m_reportDesignWidget->report()->pageCount()>1); + } else { + slotNewReport(); + } + unsetCursor(); + setWindowTitle(m_reportDesignWidget->report()->reportName() + " - Lime Report Designer"); + addRecentFile(fileName); + m_editorTabType = ReportDesignWidget::Page; } + } void ReportDesignWindow::slotZoomIn() @@ -1023,6 +1215,11 @@ void ReportDesignWindow::slotHLayout() m_reportDesignWidget->addHLayout(); } +void ReportDesignWindow::slotVLayout() +{ + m_reportDesignWidget->addVLayout(); +} + void ReportDesignWindow::slotTest() { } @@ -1044,6 +1241,7 @@ void ReportDesignWindow::slotItemActionCliked() QAction* action=dynamic_cast(sender()); action->setCheckable(true); action->setChecked(true); + m_reportItemIsLocked = QApplication::keyboardModifiers() == Qt::SHIFT; m_reportDesignWidget->startInsertMode(action->whatsThis()); } @@ -1126,18 +1324,62 @@ void ReportDesignWindow::updateAvaibleBands(){ } } +void ReportDesignWindow::showDefaultToolBars(){ + foreach (QToolBar* tb, m_pageTools){ + tb->setVisible(m_editorTabType != ReportDesignWidget::Dialog); + } + foreach (QToolBar* tb, m_dialogTools){ + tb->setVisible(m_editorTabType == ReportDesignWidget::Dialog); + } +} + +void ReportDesignWindow::showDefaultEditors(){ + foreach (QDockWidget* w, m_pageEditors) { + w->setVisible(m_editorTabType != ReportDesignWidget::Dialog); + } +#ifdef HAVE_QTDESIGNER_INTEGRATION + foreach (QDockWidget* w, m_dialogEditors) { + w->setVisible(m_editorTabType == ReportDesignWidget::Dialog); + } + for ( int i = 0; i < m_docksToTabify.size() - 1; ++i){ + tabifyDockWidget(m_docksToTabify.at(i),m_docksToTabify.at(i+1)); + } + m_docksToTabify.at(0)->raise(); +#endif +} + void ReportDesignWindow::slotActivePageChanged() { - m_propertyModel->setObject(0); + m_objectInspector->setObject(0); updateRedoUndo(); updateAvaibleBands(); + + if (m_editorTabType == ReportDesignWidget::Dialog){ +#ifdef HAVE_UI_LOADER + m_scriptBrowser->updateDialogsTree(); +#endif + } + + setDocWidgetsVisibility(true); + + m_editorsStates[m_editorTabType] = saveState(); + m_editorTabType = m_reportDesignWidget->activeTabType(); + + if (!m_editorsStates[m_editorTabType].isEmpty()){ + restoreState(m_editorsStates[m_editorTabType]); + } else { + showDefaultEditors(); + showDefaultToolBars(); + } + + setDocWidgetsVisibility(false); } void ReportDesignWindow::renderStarted() { if (m_showProgressDialog){ m_progressDialog = new QProgressDialog(tr("Rendering report"),tr("Abort"),0,0,this); - m_progressDialog->open(m_reportDesignWidget->report(),SLOT(cancelRender())); + m_progressDialog->open(dynamic_cast(m_reportDesignWidget->report()), SLOT(cancelRender())); QApplication::processEvents(); } } @@ -1174,20 +1416,42 @@ bool ReportDesignWindow::isDockAreaVisible(Qt::DockWidgetArea area){ void ReportDesignWindow::hideDockWidgets(Qt::DockWidgetArea area, bool value){ QList dockWidgets = findChildren(); + QMap* currentDocState = 0; + + switch (area) { + case Qt::LeftDockWidgetArea: + if (value) + m_leftDocVisibleState.clear(); + currentDocState = &m_leftDocVisibleState; + break; + case Qt::RightDockWidgetArea: + if (value) + m_rightDocVisibleState.clear(); + currentDocState = &m_rightDocVisibleState; + default: + break; + } + foreach (QDockWidget* dw, dockWidgets) { - if (dockWidgetArea(dw) == area) - value ? dw->show(): dw->hide(); + if (dockWidgetArea(dw) == area){ + if (!value){ + if (currentDocState->value(dw)) dw->show(); + } else { + currentDocState->insert(dw, dw->isVisible()); + dw->hide(); + } + } } } void ReportDesignWindow::slotHideLeftPanel(bool value) { - hideDockWidgets(Qt::LeftDockWidgetArea,value); + hideDockWidgets(Qt::LeftDockWidgetArea,!value); } void ReportDesignWindow::slotHideRightPanel(bool value) { - hideDockWidgets(Qt::RightDockWidgetArea,value); + hideDockWidgets(Qt::RightDockWidgetArea,!value); } void ReportDesignWindow::slotEditSettings() @@ -1214,7 +1478,7 @@ void ReportDesignWindow::slotLoadRecentFile(const QString fileName) m_reportDesignWidget->clear(); m_reportDesignWidget->loadFromFile(fileName); m_lblReportName->setText(fileName); - m_propertyModel->setObject(0); + m_objectInspector->setObject(0); updateRedoUndo(); unsetCursor(); setWindowTitle(m_reportDesignWidget->report()->reportName() + " - Lime Report Designer"); @@ -1237,6 +1501,41 @@ void ReportDesignWindow::slotPageDeleted() m_deletePageAction->setEnabled(m_reportDesignWidget->report()->pageCount()>1); } +void ReportDesignWindow::slotFilterTextChanged(const QString& filter) +{ + m_filterModel->setFilterRegExp(QRegExp(filter, Qt::CaseInsensitive, QRegExp::FixedString)); +} + +#ifdef HAVE_QTDESIGNER_INTEGRATION +void ReportDesignWindow::slotDeleteDialog() +{ + if ( m_editorTabType == ReportDesignWidget::Dialog ){ + m_reportDesignWidget->report()->scriptContext()->deleteDialog(m_reportDesignWidget->activeDialogName()); + } +} + +void ReportDesignWindow::slotAddNewDialog() +{ + m_reportDesignWidget->addNewDialog(); +} + +#endif + +void ReportDesignWindow::slotLockSelectedItems() +{ + m_reportDesignWidget->lockSelectedItems(); +} + +void ReportDesignWindow::slotUnlockSelectedItems() +{ + m_reportDesignWidget->unlockSelectedItems(); +} + +void ReportDesignWindow::slotSelectOneLevelItems() +{ + m_reportDesignWidget->selectOneLevelItems(); +} + void ReportDesignWindow::closeEvent(QCloseEvent * event) { if (checkNeedToSave()){ @@ -1260,6 +1559,19 @@ void ReportDesignWindow::resizeEvent(QResizeEvent*) #endif } +void ReportDesignWindow::showEvent(QShowEvent* event) +{ + QMainWindow::showEvent(event); + + if (!m_editorsStates[m_editorTabType].isEmpty()){ + restoreState(m_editorsStates[m_editorTabType]); + } else { + showDefaultEditors(); + showDefaultToolBars(); + } + +} + void ReportDesignWindow::moveEvent(QMoveEvent*) { #ifdef Q_OS_UNIX diff --git a/limereport/lrreportdesignwindow.h b/limereport/lrreportdesignwindow.h index 147f47f..5701894 100644 --- a/limereport/lrreportdesignwindow.h +++ b/limereport/lrreportdesignwindow.h @@ -43,6 +43,7 @@ #include "items/editors/lritemsaligneditorwidget.h" #include "items/editors/lritemsborderseditorwidget.h" #include "lrobjectitemmodel.h" +#include "lrreportdesignwindowintrerface.h" namespace LimeReport{ @@ -55,11 +56,11 @@ class BaseDesignIntf; class PageDesignIntf; class ObjectBrowser; -class ReportDesignWindow : public QMainWindow +class ReportDesignWindow : public ReportDesignWindowInterface { Q_OBJECT public: - explicit ReportDesignWindow(ReportEnginePrivate* report, QWidget *parent = 0, QSettings* settings=0); + explicit ReportDesignWindow(ReportEnginePrivateInterface *report, QWidget *parent = 0, QSettings* settings=0); ~ReportDesignWindow(); static ReportDesignWindow* instance(){return m_instance;} @@ -70,7 +71,6 @@ public: QSettings* settings(); void restoreSetting(); void setShowProgressDialog(bool value){m_showProgressDialog = value;} - private slots: void slotNewReport(); void slotNewPage(); @@ -92,6 +92,7 @@ private slots: void slotDelete(); void slotEditLayoutMode(); void slotHLayout(); + void slotVLayout(); void slotItemSelected(LimeReport::BaseDesignIntf *item); void slotItemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant &oldValue, const QVariant &newValue); void slotMultiItemSelected(); @@ -119,13 +120,25 @@ private slots: void slotLoadRecentFile(const QString fileName); void slotPageAdded(PageDesignIntf* ); void slotPageDeleted(); + void slotFilterTextChanged(const QString& filter); +#ifdef HAVE_QTDESIGNER_INTEGRATION + void slotDeleteDialog(); + void slotAddNewDialog(); +#endif + void slotLockSelectedItems(); + void slotUnlockSelectedItems(); + void slotSelectOneLevelItems(); protected: void closeEvent(QCloseEvent *event); void resizeEvent(QResizeEvent *); + void showEvent(QShowEvent* event); void moveEvent(QMoveEvent *); void hideDockWidgets(Qt::DockWidgetArea area, bool value); bool isDockAreaVisible(Qt::DockWidgetArea area); + void setDocWidgetsVisibility(bool visible); + private: + void initReportEditor(ReportEnginePrivate* report); void createActions(); void createBandsButton(); void createMainMenu(); @@ -134,9 +147,18 @@ private: void createItemsActions(); void createObjectInspector(); void createObjectsBrowser(); - void initReportEditor(ReportEnginePrivate* report); + void initReportEditor(ReportEnginePrivateInterface* report); void createDataWindow(); void createScriptWindow(); +#ifdef HAVE_QTDESIGNER_INTEGRATION + void createDialogWidgetBox(); + void createDialogPropertyEditor(); + void createDialogObjectInspector(); + void createDialogActionEditor(); + void createDialogResourceEditor(); + void createDialogSignalSlotEditor(); + void createDialogDesignerToolBar(); +#endif void updateRedoUndo(); void updateAvaibleBands(); void startNewReport(); @@ -146,6 +168,8 @@ private: void removeNotExistedRecentFiles(); void removeNotExistedRecentFilesFromMenu(const QString& fileName); void addRecentFile(const QString& fileName); + void showDefaultToolBars(); + void showDefaultEditors(); private: static ReportDesignWindow* m_instance; QStatusBar* m_statusBar; @@ -153,6 +177,9 @@ private: QToolBar* m_fontToolBar; QToolBar* m_reportToolBar; QToolBar* m_alignToolBar; +#ifdef HAVE_QTDESIGNER_INTEGRATION + QToolBar* m_dialogDesignerToolBar; +#endif QToolButton* m_newBandButton; QMenuBar* m_mainMenu; QMenu* m_fileMenu; @@ -201,16 +228,24 @@ private: QAction* m_aboutAction; QAction* m_editLayoutMode; QAction* m_addHLayout; + QAction* m_addVLayout; QAction* m_hideLeftPanel; QAction* m_hideRightPanel; +#ifdef HAVE_QTDESIGNER_INTEGRATION + QAction* m_deleteDialogAction; + QAction* m_addNewDialogAction; +#endif + + QAction* m_lockSelectedItemsAction; + QAction* m_unlockSelectedItemsAction; + QAction* m_selectOneLevelItems; + QMenu* m_recentFilesMenu; QSignalMapper* m_bandsAddSignalsMap; QSignalMapper* m_recentFilesSignalMap; ObjectInspectorWidget* m_objectInspector; - QObjectPropertyModel* m_propertyModel; - ReportDesignWidget* m_reportDesignWidget; DataBrowser * m_dataBrowser; ScriptBrowser* m_scriptBrowser; @@ -235,6 +270,17 @@ private: QProgressDialog* m_progressDialog; bool m_showProgressDialog; QMap m_recentFiles; + QVector m_pageEditors; + QVector m_dialogEditors; + QVector m_docksToTabify; + ReportDesignWidget::EditorTabType m_editorTabType; + QByteArray m_editorsStates[ReportDesignWidget::TabTypeCount]; + QVector m_pageTools; + QVector m_dialogTools; + bool m_reportItemIsLocked; + QMap m_leftDocVisibleState; + QMap m_rightDocVisibleState; + QSortFilterProxyModel* m_filterModel; }; class ObjectNameValidator : public ValidatorIntf{ diff --git a/limereport/lrreportdesignwindowintrerface.h b/limereport/lrreportdesignwindowintrerface.h new file mode 100644 index 0000000..858881e --- /dev/null +++ b/limereport/lrreportdesignwindowintrerface.h @@ -0,0 +1,23 @@ +#ifndef LRREPORTDESIGNWINDOWINTRERFACE_H +#define LRREPORTDESIGNWINDOWINTRERFACE_H + +#include +#include + +namespace LimeReport { + +class ReportDesignWindowInterface: public QMainWindow{ +public: + ReportDesignWindowInterface(QWidget* parent = 0): QMainWindow(parent){} + virtual bool checkNeedToSave() = 0; + virtual void showModal() = 0; + virtual void showNonModal() = 0; + virtual void setSettings(QSettings* value) = 0; + virtual QSettings* settings() = 0; + virtual void restoreSetting() = 0; + virtual void setShowProgressDialog(bool value) = 0; +}; + +} // namespace LimeReport + +#endif // LRREPORTDESIGNWINDOWINTRERFACE_H diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp index 5288a80..8006745 100644 --- a/limereport/lrreportengine.cpp +++ b/limereport/lrreportengine.cpp @@ -29,10 +29,14 @@ ****************************************************************************/ #include #include +#include #include #include #include #include +#include +#include +#include #include "time.h" @@ -41,8 +45,11 @@ #include "lrpagedesignintf.h" #include "lrdatasourcemanager.h" + +#ifdef HAVE_REPORT_DESIGNER #include "lrdatabrowser.h" #include "lrreportdesignwindow.h" +#endif #include "serializators/lrxmlwriter.h" #include "serializators/lrxmlreader.h" @@ -50,11 +57,21 @@ #include "lrpreviewreportwindow.h" #include "lrpreviewreportwidget.h" #include "lrpreviewreportwidget_p.h" +#include "lrexporterintf.h" +#include "lrexportersfactory.h" + +#ifdef BUILD_WITH_EASY_PROFILER +#include "easy/profiler.h" +#else +# define EASY_BLOCK(...) +# define EASY_END_BLOCK +#endif #include "lrpreparedpages.h" #ifdef HAVE_STATIC_BUILD #include "lrfactoryinitializer.h" #endif + namespace LimeReport{ QSettings* ReportEngine::m_settings = 0; @@ -65,23 +82,53 @@ ReportEnginePrivate::ReportEnginePrivate(QObject *parent) : m_showProgressDialog(true), m_reportName(""), m_activePreview(0), m_previewWindowIcon(":/report/images/logo32"), m_previewWindowTitle(tr("Preview")), m_reportRendering(false), m_resultIsEditable(true), m_passPhrase("HjccbzHjlbyfCkjy"), - m_fileWatcher( new QFileSystemWatcher(this) ), m_previewLayoutDirection(Qt::LayoutDirectionAuto), - m_previewScaleType(FitWidth), m_previewScalePercent(0), m_saveToFileVisible(true), m_printToPdfVisible(true), + m_fileWatcher( new QFileSystemWatcher( this ) ), m_reportLanguage(QLocale::AnyLanguage), + m_previewLayoutDirection(Qt::LayoutDirectionAuto), m_designerFactory(0), + m_previewScaleType(FitWidth), m_previewScalePercent(0), m_startTOCPage(0), + m_previewPageBackgroundColor(Qt::gray), + m_saveToFileVisible(true), m_printToPdfVisible(true), m_printVisible(true) { #ifdef HAVE_STATIC_BUILD initResources(); initReportItems(); +#ifdef HAVE_REPORT_DESIGNER initObjectInspectorProperties(); +#endif initSerializators(); #endif m_datasources = new DataSourceManager(this); m_datasources->setReportSettings(&m_reportSettings); scriptManager()->setDataManager(m_datasources); m_scriptEngineContext = new ScriptEngineContext(this); + + ICallbackDatasource* tableOfContents = m_datasources->createCallbackDatasource("tableofcontents"); + connect(tableOfContents, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), + m_scriptEngineContext->tableOfContents(), SLOT(slotOneSlotDS(LimeReport::CallbackInfo,QVariant&))); + m_datasources->setObjectName("datasources"); connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString))); connect(m_fileWatcher,SIGNAL(fileChanged(const QString &)),this,SLOT(slotLoadFromFile(const QString &))); + + QDir pluginsDir = QCoreApplication::applicationDirPath(); + pluginsDir.cd("../lib" ); + if (!pluginsDir.exists()){ + pluginsDir.cd("./lib"); + if (!pluginsDir.exists()) pluginsDir.setPath(QCoreApplication::applicationDirPath()); + } + + foreach( const QString& pluginName, pluginsDir.entryList( QDir::Files ) ) { + QPluginLoader loader( pluginsDir.absoluteFilePath( pluginName ) ); + if( loader.load() ) { +#ifndef HAVE_REPORT_DESIGNER + if( LimeReportDesignerPluginInterface* designerPlugin = qobject_cast< LimeReportDesignerPluginInterface* >( loader.instance() ) ) { + m_designerFactory = designerPlugin; + break; + } +#endif + } + } + } ReportEnginePrivate::~ReportEnginePrivate() @@ -94,6 +141,11 @@ ReportEnginePrivate::~ReportEnginePrivate() } foreach(PageDesignIntf* page,m_pages) delete page; m_pages.clear(); + + foreach(ReportTranslation* translation, m_translations) + delete translation; + m_translations.clear(); + if (m_ownedSettings&&m_settings) delete m_settings; delete m_preparedPagesManager; } @@ -108,12 +160,13 @@ QObject *ReportEnginePrivate::elementAt(const QString &, int index) return pageAt(index); } -PageDesignIntf *ReportEnginePrivate::createPage(const QString &pageName) +PageDesignIntf *ReportEnginePrivate::createPage(const QString &pageName, bool preview) { PageDesignIntf* page =new PageDesignIntf(); page->setObjectName(pageName); page->pageItem()->setObjectName("Report"+pageName); - page->setReportEditor(this); + if (!preview) + page->setReportEditor(this); page->setReportSettings(&m_reportSettings); return page; } @@ -138,7 +191,7 @@ bool ReportEnginePrivate::deletePage(PageDesignIntf *page){ PageDesignIntf *ReportEnginePrivate::createPreviewPage() { - return createPage(); + return createPage("preview",true); } int ReportEnginePrivate::elementsCount(const QString &) @@ -168,6 +221,15 @@ void ReportEnginePrivate::showError(QString message) QMessageBox::critical(0,tr("Error"),message); } +void ReportEnginePrivate::updateTranslations() +{ + foreach(ReportTranslation* translation, m_translations.values()){ + foreach(PageDesignIntf* page, m_pages){ + translation->updatePageTranslation(page); + } + } +} + void ReportEnginePrivate::slotDataSourceCollectionLoaded(const QString &collectionName) { emit datasourceCollectionLoadFinished(collectionName); @@ -180,10 +242,19 @@ void ReportEnginePrivate::slotPreviewWindowDestroyed(QObject* window) } } +void ReportEnginePrivate::slotDesignerWindowDestroyed(QObject *window) +{ + Q_UNUSED(window) + dataManager()->setDesignTime(false); +} + void ReportEnginePrivate::clearReport() { foreach(PageDesignIntf* page,m_pages) delete page; m_pages.clear(); + foreach(ReportTranslation* reportTranslation, m_translations) + delete reportTranslation; + m_translations.clear(); m_datasources->clear(DataSourceManager::Owned); m_fileName=""; m_scriptEngineContext->clear(); @@ -225,14 +296,10 @@ void ReportEnginePrivate::printReport(ItemsReaderIntf::Ptr reader, QPrinter& pri void ReportEnginePrivate::printReport(ReportPages pages, QPrinter &printer) { - LimeReport::PageDesignIntf renderPage; - renderPage.setItemMode(PrintMode); - QPainter* painter=0; - - bool isFirst = true; int currenPage = 1; + QMap> printProcessors; + printProcessors.insert("default",QSharedPointer(new PrintProcessor(&printer))); foreach(PageItemDesignIntf::Ptr page, pages){ - if ( (printer.printRange() == QPrinter::AllPages) || ( (printer.printRange()==QPrinter::PageRange) && @@ -241,54 +308,74 @@ void ReportEnginePrivate::printReport(ReportPages pages, QPrinter &printer) ) ) { + printProcessors["default"]->printPage(page); + } + currenPage++; + } +} - QPointF pagePos = page->pos(); - page->setPos(0,0); - renderPage.setPageItem(page); - renderPage.setSceneRect(renderPage.pageItem()->mapToScene(renderPage.pageItem()->rect()).boundingRect()); - if (renderPage.pageItem()->oldPrintMode()){ - printer.setPageMargins(renderPage.pageItem()->leftMargin(), - renderPage.pageItem()->topMargin(), - renderPage.pageItem()->rightMargin(), - renderPage.pageItem()->bottomMargin(), - QPrinter::Millimeter); - printer.setOrientation((QPrinter::Orientation)renderPage.pageItem()->pageOrientation()); - QSizeF pageSize = (renderPage.pageItem()->pageOrientation()==PageItemDesignIntf::Landscape)? - QSizeF(renderPage.pageItem()->sizeMM().height(),renderPage.pageItem()->sizeMM().width()): - renderPage.pageItem()->sizeMM(); - printer.setPaperSize(pageSize,QPrinter::Millimeter); - } else { - printer.setFullPage(renderPage.pageItem()->fullPage()); - printer.setOrientation((QPrinter::Orientation)renderPage.pageItem()->pageOrientation()); - if (renderPage.pageItem()->pageSize()==PageItemDesignIntf::Custom){ - QSizeF pageSize = (renderPage.pageItem()->pageOrientation()==PageItemDesignIntf::Landscape)? - QSizeF(renderPage.pageItem()->sizeMM().height(),renderPage.pageItem()->sizeMM().width()): - renderPage.pageItem()->sizeMM(); - printer.setPaperSize(pageSize,QPrinter::Millimeter); - } else { - printer.setPaperSize((QPrinter::PageSize)renderPage.pageItem()->pageSize()); - } - } +void ReportEnginePrivate::printReport(ReportPages pages, QMap printers, bool printToAllPrinters) +{ + if (printers.values().isEmpty()) return; + int currenPage = 1; + QMap> printProcessors; + for (int i = 0; i < printers.keys().count(); ++i) { + printProcessors.insert(printers.keys()[i],QSharedPointer(new PrintProcessor(printers[printers.keys()[i]]))); + } - if (!isFirst){ - printer.newPage(); - } else { - isFirst=false; - painter = new QPainter(&printer); - } - - renderPage.render(painter); - page->setPos(pagePos); + PrintProcessor* defaultProcessor = 0; + int currentPrinter = 0; + if (printProcessors.contains("default")) defaultProcessor = printProcessors["default"].data(); + else defaultProcessor = printProcessors.values().at(0).data(); + foreach(PageItemDesignIntf::Ptr page, pages){ + if (!printToAllPrinters){ + if (printProcessors.contains(page->printerName())) + printProcessors[page->printerName()]->printPage(page); + else defaultProcessor->printPage(page); + } else { + printProcessors.values().at(currentPrinter)->printPage(page); + if (currentPrinter < printers.values().count()-1) + currentPrinter++; + else currentPrinter = 0; } currenPage++; } - delete painter; +} + +QStringList ReportEnginePrivate::aviableReportTranslations() +{ + QStringList result; + foreach (QLocale::Language language, aviableLanguages()){ + result << QLocale::languageToString(language); + } + return result; +} + +void ReportEnginePrivate::setReportTranslation(const QString &languageName) +{ + foreach(QLocale::Language language, aviableLanguages()){ + if (QLocale::languageToString(language).compare(languageName) == 0){ + setReportLanguage(language); + } + } } bool ReportEnginePrivate::printReport(QPrinter* printer) { if (!printer&&!m_printerSelected){ + QPrinterInfo pi; + if (!pi.defaultPrinter().isNull()) +#ifdef HAVE_QT4 + m_printer.data()->setPrinterName(pi.defaultPrinter().printerName()); +#endif +#ifdef HAVE_QT5 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)) + m_printer.data()->setPrinterName(pi.defaultPrinterName()); +#else + m_printer.data()->setPrinterName(pi.defaultPrinter().printerName()); +#endif +#endif QPrintDialog dialog(m_printer.data(),QApplication::activeWindow()); m_printerSelected = dialog.exec()!=QDialog::Rejected; } @@ -297,9 +384,10 @@ bool ReportEnginePrivate::printReport(QPrinter* printer) printer =(printer)?printer:m_printer.data(); if (printer&&printer->isValid()){ try{ + bool designTime = dataManager()->designTime(); dataManager()->setDesignTime(false); ReportPages pages = renderToPages(); - dataManager()->setDesignTime(true); + dataManager()->setDesignTime(designTime); if (pages.count()>0){ printReport(pages,*printer); } @@ -310,10 +398,38 @@ bool ReportEnginePrivate::printReport(QPrinter* printer) } else return false; } +bool ReportEnginePrivate::printReport(QMap printers, bool printToAllPrinters) +{ + try{ + bool designTime = dataManager()->designTime(); + dataManager()->setDesignTime(false); + ReportPages pages = renderToPages(); + dataManager()->setDesignTime(designTime); + if (pages.count()>0){ + printReport(pages, printers, printToAllPrinters); + } + } catch(ReportError &exception){ + saveError(exception.what()); + return false; + } + return true; +} + bool ReportEnginePrivate::printPages(ReportPages pages, QPrinter *printer) { - if (!printer&&!m_printerSelected){ + QPrinterInfo pi; + if (!pi.defaultPrinter().isNull()) +#ifdef HAVE_QT4 + m_printer.data()->setPrinterName(pi.defaultPrinter().printerName()); +#endif +#ifdef HAVE_QT5 +#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)) + m_printer.data()->setPrinterName(pi.defaultPrinterName()); +#else + m_printer.data()->setPrinterName(pi.defaultPrinter().printerName()); +#endif +#endif QPrintDialog dialog(m_printer.data(),QApplication::activeWindow()); m_printerSelected = dialog.exec()!=QDialog::Rejected; } @@ -355,15 +471,31 @@ void ReportEnginePrivate::printToFile(const QString &fileName) bool ReportEnginePrivate::printToPDF(const QString &fileName) { - if (!fileName.isEmpty()){ - QFileInfo fi(fileName); - QString fn = fileName; - if (fi.suffix().isEmpty()) - fn+=".pdf"; - QPrinter printer; - printer.setOutputFileName(fn); - printer.setOutputFormat(QPrinter::PdfFormat); - return printReport(&printer); + return exportReport("PDF", fileName); +} + +bool ReportEnginePrivate::exportReport(QString exporterName, const QString &fileName, const QMap ¶ms) +{ + QString fn = fileName; + if (ExportersFactory::instance().map().contains(exporterName)){ + ReportExporterInterface* e = ExportersFactory::instance().objectCreator(exporterName)(this); + if (fn.isEmpty()){ + QString filter = QString("%1 (*.%2)").arg(e->exporterName()).arg(e->exporterFileExt()); + QString fn = QFileDialog::getSaveFileName(0,tr("%1 file name").arg(e->exporterName()),"",filter); + } + if (!fn.isEmpty()){ + QFileInfo fi(fn); + if (fi.suffix().isEmpty()) + fn += QString(".%1").arg(e->exporterFileExt()); + + bool designTime = dataManager()->designTime(); + dataManager()->setDesignTime(false); + ReportPages pages = renderToPages(); + dataManager()->setDesignTime(designTime); + bool result = e->exportPages(pages, fn, params); + delete e; + return result; + } } return false; } @@ -371,7 +503,8 @@ bool ReportEnginePrivate::printToPDF(const QString &fileName) bool ReportEnginePrivate::showPreviewWindow(ReportPages pages, PreviewHints hints) { if (pages.count()>0){ - PreviewReportWindow* w = new PreviewReportWindow(this,0,settings()); + Q_Q(ReportEngine); + PreviewReportWindow* w = new PreviewReportWindow(q, 0, settings()); w->setWindowFlags(Qt::Dialog|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint| Qt::WindowMinMaxButtonsHint); w->setAttribute(Qt::WA_DeleteOnClose,true); w->setWindowModality(Qt::ApplicationModal); @@ -381,6 +514,7 @@ bool ReportEnginePrivate::showPreviewWindow(ReportPages pages, PreviewHints hint w->setSettings(settings()); w->setPages(pages); w->setLayoutDirection(m_previewLayoutDirection); + w->setStyleSheet(styleSheet()); if (!dataManager()->errorsList().isEmpty()){ w->setErrorMessages(dataManager()->errorsList()); @@ -413,21 +547,50 @@ bool ReportEnginePrivate::showPreviewWindow(ReportPages pages, PreviewHints hint void ReportEnginePrivate::previewReport(PreviewHints hints) { -// QTime start = QTime::currentTime(); - try{ - dataManager()->setDesignTime(false); - ReportPages pages = renderToPages(); - dataManager()->setDesignTime(true); - showPreviewWindow(pages, hints); - } catch (ReportError &exception){ - saveError(exception.what()); - showError(exception.what()); + previewReport(0, hints); +} + +void ReportEnginePrivate::previewReport(QPrinter *printer, PreviewHints hints) +{ + // QTime start = QTime::currentTime(); + try{ + dataManager()->setDesignTime(false); + ReportPages pages = renderToPages(); + dataManager()->setDesignTime(true); + showPreviewWindow(pages, hints); + } catch (ReportError &exception){ + saveError(exception.what()); + showError(exception.what()); + } +} + +ReportDesignWindowInterface*ReportEnginePrivate::getDesignerWindow() +{ + if (!m_designerWindow) { + if (m_designerFactory){ + m_designerWindow = m_designerFactory->getDesignerWindow(this,QApplication::activeWindow(),settings()); + m_designerWindow->setAttribute(Qt::WA_DeleteOnClose,true); + m_designerWindow->setWindowIcon(QIcon(":report/images/logo32")); + m_designerWindow->setShowProgressDialog(m_showProgressDialog); + } else { +#ifdef HAVE_REPORT_DESIGNER + m_designerWindow = new LimeReport::ReportDesignWindow(this,QApplication::activeWindow(),settings()); + m_designerWindow->setAttribute(Qt::WA_DeleteOnClose,true); + m_designerWindow->setWindowIcon(QIcon(":report/images/logo32")); + m_designerWindow->setShowProgressDialog(m_showProgressDialog); +#endif + } + } + if (m_designerWindow){ + m_datasources->updateDatasourceModel(); } + return m_designerWindow; } PreviewReportWidget* ReportEnginePrivate::createPreviewWidget(QWidget* parent){ - PreviewReportWidget* widget = new PreviewReportWidget(this, parent); + Q_Q(ReportEngine); + PreviewReportWidget* widget = new PreviewReportWidget(q, parent); try{ dataManager()->setDesignTime(false); ReportPages pages = renderToPages(); @@ -447,6 +610,7 @@ PageDesignIntf* ReportEnginePrivate::createPreviewScene(QObject* parent){ ReportPages pages = renderToPages(); result = new PageDesignIntf(parent); result->setPageItems(pages); + result->setItemMode(PrintMode); } catch (ReportError &exception){ saveError(exception.what()); showError(exception.what()); @@ -454,9 +618,18 @@ PageDesignIntf* ReportEnginePrivate::createPreviewScene(QObject* parent){ return result; } -void ReportEnginePrivate::emitSaveReport() +bool ReportEnginePrivate::emitSaveReport() { - emit onSave(); + bool result = false; + emit onSave(result); + return result; +} + +bool ReportEnginePrivate::emitSaveReportAs() +{ + bool result = false; + emit onSaveAs(result); + return result; } bool ReportEnginePrivate::emitLoadReport() @@ -471,6 +644,16 @@ void ReportEnginePrivate::emitSaveFinished() emit saveFinished(); } +void ReportEnginePrivate::emitLoadFinished() +{ + emit loadFinished(); +} + +void ReportEnginePrivate::emitPrintedToPDF(QString fileName) +{ + emit printedToPDF(fileName); +} + bool ReportEnginePrivate::isSaved() { foreach (PageDesignIntf* page, m_pages) { @@ -487,6 +670,7 @@ void ReportEnginePrivate::setCurrentReportsDir(const QString &dirName) bool ReportEnginePrivate::slotLoadFromFile(const QString &fileName) { + EASY_BLOCK("ReportEnginePrivate::slotLoadFromFile") PreviewReportWindow *currentPreview = qobject_cast(m_activePreview); if (!QFile::exists(fileName)) @@ -528,17 +712,21 @@ bool ReportEnginePrivate::slotLoadFromFile(const QString &fileName) } } } - + EASY_BLOCK("Connect auto connections") dataManager()->connectAutoConnections(); - dataManager()->dropChanges(); + EASY_END_BLOCK; + dropChanges(); + if ( hasActivePreview() ) { currentPreview->reloadPreview(); } + EASY_END_BLOCK; return true; }; } m_lastError = reader->lastError(); + EASY_END_BLOCK; return false; } @@ -549,27 +737,27 @@ void ReportEnginePrivate::cancelRender() m_reportRendering = false; } -PageDesignIntf* ReportEngine::createPreviewScene(QObject* parent){ +QGraphicsScene* ReportEngine::createPreviewScene(QObject* parent){ Q_D(ReportEngine); return d->createPreviewScene(parent); } void ReportEnginePrivate::designReport() { - if (!m_designerWindow) { - m_designerWindow = new LimeReport::ReportDesignWindow(this,QApplication::activeWindow(),settings()); - m_designerWindow->setAttribute(Qt::WA_DeleteOnClose,true); - m_designerWindow->setWindowIcon(QIcon(":report/images/logo32")); - m_designerWindow->setShowProgressDialog(m_showProgressDialog); - } - + ReportDesignWindowInterface* designerWindow = getDesignerWindow(); + if (designerWindow){ + dataManager()->setDesignTime(true); + connect(designerWindow, SIGNAL(destroyed(QObject*)), this, SLOT(slotDesignerWindowDestroyed(QObject*))); #ifdef Q_OS_WIN - m_designerWindow->setWindowModality(Qt::ApplicationModal); + designerWindow->setWindowModality(Qt::ApplicationModal); #endif - if (QApplication::activeWindow()==0){ - m_designerWindow->show();; + if (QApplication::activeWindow()==0){ + designerWindow->show();; + } else { + designerWindow->showModal(); + } } else { - m_designerWindow->showModal(); + qDebug()<<(tr("Designer not found!")); } } @@ -597,6 +785,7 @@ QSettings*ReportEnginePrivate::settings() bool ReportEnginePrivate::loadFromFile(const QString &fileName, bool autoLoadPreviewOnChange) { // only watch one file at a time + if ( !m_fileWatcher->files().isEmpty() ) { m_fileWatcher->removePaths( m_fileWatcher->files() ); @@ -607,7 +796,11 @@ bool ReportEnginePrivate::loadFromFile(const QString &fileName, bool autoLoadPre m_fileWatcher->addPath( fileName ); } - return slotLoadFromFile( fileName ); + bool result = slotLoadFromFile( fileName ); + if (result) { + emit loadFinished(); + } + return result; } bool ReportEnginePrivate::loadFromByteArray(QByteArray* data, const QString &name){ @@ -619,6 +812,7 @@ bool ReportEnginePrivate::loadFromByteArray(QByteArray* data, const QString &nam if (reader->readItem(this)){ m_fileName = ""; m_reportName = name; + emit loadFinished(); return true; }; } @@ -635,6 +829,7 @@ bool ReportEnginePrivate::loadFromString(const QString &report, const QString &n if (reader->readItem(this)){ m_fileName = ""; m_reportName = name; + emit loadFinished(); return true; }; } @@ -643,9 +838,10 @@ bool ReportEnginePrivate::loadFromString(const QString &report, const QString &n bool ReportEnginePrivate::saveToFile(const QString &fileName) { - if (fileName.isEmpty()) return false; - QFileInfo fi(fileName); - QString fn = fileName; + if (fileName.isEmpty() & m_fileName.isEmpty()) return false; + QString fn = fileName.isEmpty() ? m_fileName : fileName; + QFileInfo fi(fn); + if (fi.suffix().isEmpty()) fn+=".lrxml"; @@ -683,7 +879,7 @@ bool ReportEnginePrivate::saveToFile(const QString &fileName) page->setToSaved(); } } - m_datasources->dropChanges(); + dropChanges(); return saved; } @@ -698,7 +894,7 @@ QByteArray ReportEnginePrivate::saveToByteArray() page->setToSaved(); } } - m_datasources->dropChanges(); + dropChanges(); return result; } @@ -712,7 +908,7 @@ QString ReportEnginePrivate::saveToString(){ page->setToSaved(); } } - m_datasources->dropChanges(); + dropChanges(); return result; } @@ -721,28 +917,26 @@ bool ReportEnginePrivate::isNeedToSave() foreach(PageDesignIntf* page, m_pages){ if (page->isHasChanges()) return true; } - if (dataManager()->isHasChanges()){ + if (dataManager()->hasChanges()){ return true; } + if (scriptContext()->hasChanges()) + return true; return false; } -bool ReportEnginePrivate::saveToFile() -{ - if (m_fileName.isEmpty()) return false; - return saveToFile(m_fileName); -} - QString ReportEnginePrivate::renderToString() { LimeReport::ReportRender render; + updateTranslations(); dataManager()->connectAllDatabases(); dataManager()->setDesignTime(false); if (m_pages.count()){ render.setDatasources(dataManager()); render.setScriptContext(scriptContext()); - return render.renderPageToString(m_pages.at(0)); + return render.renderPageToString(m_pages.at(0)->pageItem()); } else return QString(); + } ScaleType ReportEnginePrivate::previewScaleType() @@ -761,6 +955,25 @@ void ReportEnginePrivate::setPreviewScaleType(const ScaleType &scaleType, int pe m_previewScalePercent = percent; } +void ReportEnginePrivate::addWatermark(const WatermarkSetting &watermarkSetting) +{ + m_watermarks.append(watermarkSetting); +} + +void ReportEnginePrivate::clearWatermarks() +{ + m_watermarks.clear(); +} + +PageItemDesignIntf* ReportEnginePrivate::getPageByName(const QString& pageName) +{ + foreach(PageItemDesignIntf* page, m_renderingPages){ + if ( page->objectName().compare(pageName, Qt::CaseInsensitive) == 0) + return page; + } + return 0; +} + IPreparedPages *ReportEnginePrivate::preparedPages(){ return m_preparedPagesManager; } @@ -784,6 +997,11 @@ bool ReportEnginePrivate::prepareReportPages() return !m_preparedPages.isEmpty(); } +bool ReportEnginePrivate::printPreparedPages() +{ + return printPages(m_preparedPages, 0); +} + Qt::LayoutDirection ReportEnginePrivate::previewLayoutDirection() { return m_previewLayoutDirection; @@ -816,6 +1034,96 @@ void ReportEnginePrivate::clearSelection() } } +bool ReportEnginePrivate::addTranslationLanguage(QLocale::Language language) +{ + if (!m_translations.keys().contains(language)){ + ReportTranslation* translation = 0; + if (!m_translations.contains(QLocale::AnyLanguage)){ + translation = new ReportTranslation(QLocale::AnyLanguage,m_pages); + m_translations.insert(QLocale::AnyLanguage,translation); + } + translation = new ReportTranslation(language,m_pages); + m_translations.insert(language, translation); + return true; + } else { + m_lastError = tr("Language %1 already exists").arg(QLocale::languageToString(language)); + return false; + } +} + +bool ReportEnginePrivate::removeTranslationLanguage(QLocale::Language language) +{ + return m_translations.remove(language) != 0; +} + +void ReportEnginePrivate::activateLanguage(QLocale::Language language) +{ + if (!m_translations.keys().contains(language)) return; + ReportTranslation* translation = m_translations.value(language); + + foreach(PageTranslation* pageTranslation, translation->pagesTranslation()){ + PageItemDesignIntf* page = getPageByName(pageTranslation->pageName); + if (page){ + foreach(ItemTranslation* itemTranslation, pageTranslation->itemsTranslation){ + BaseDesignIntf* item = page->childByName(itemTranslation->itemName); + if (item) { + foreach(PropertyTranslation* propertyTranslation, itemTranslation->propertyesTranslation){ + if (propertyTranslation->checked) + item->setProperty(propertyTranslation->propertyName.toLatin1(), propertyTranslation->value); + } + } + } + } + } +} + +QList ReportEnginePrivate::designerLanguages() +{ + + QList result; + emit getAvailableDesignerLanguages(&result); + return result; +} + +QLocale::Language ReportEnginePrivate::currentDesignerLanguage() +{ + QLocale::Language result = emit getCurrentDefaultDesignerLanguage(); + return result; +} + +void ReportEnginePrivate::setCurrentDesignerLanguage(QLocale::Language language) +{ + m_currentDesignerLanguage = language; + emit currentDefaultDesignerLanguageChanged(language); +} + +QString ReportEnginePrivate::styleSheet() const +{ + return m_styleSheet; +} + +void ReportEnginePrivate::setStyleSheet(const QString &styleSheet) +{ + m_styleSheet = styleSheet; +} + +bool ReportEnginePrivate::setReportLanguage(QLocale::Language language){ + m_reportLanguage = language; + if (!m_translations.keys().contains(language)) return false; + // activateLanguage(language); + return true; +} + +QList ReportEnginePrivate::aviableLanguages() +{ + return m_translations.keys(); +} + +ReportTranslation*ReportEnginePrivate::reportTranslation(QLocale::Language language) +{ + return m_translations.value(language); +} + bool ReportEnginePrivate::resultIsEditable() const { return m_resultIsEditable; @@ -881,6 +1189,16 @@ void ReportEnginePrivate::setPreviewWindowTitle(const QString &previewWindowTitl m_previewWindowTitle = previewWindowTitle; } +QColor ReportEnginePrivate::previewWindowPageBackground() +{ + return m_previewPageBackgroundColor; +} + +void ReportEnginePrivate::setPreviewWindowPageBackground(QColor color) +{ + m_previewPageBackgroundColor = color; +} + QIcon ReportEnginePrivate::previewWindowIcon() const { return m_previewWindowIcon; @@ -891,34 +1209,157 @@ void ReportEnginePrivate::setPreviewWindowIcon(const QIcon &previewWindowIcon) m_previewWindowIcon = previewWindowIcon; } +PageItemDesignIntf* ReportEnginePrivate::createRenderingPage(PageItemDesignIntf* page){ + PageItemDesignIntf* result = dynamic_cast(page->cloneItem(page->itemMode())); + ICollectionContainer* co = dynamic_cast(result); + if (co) co->collectionLoadFinished("children"); + return result; +} + +void ReportEnginePrivate::initReport() +{ + for(int index = 0; index < pageCount(); ++index){ + PageDesignIntf* page = pageAt(index); + if (page != 0){ + foreach (BaseDesignIntf* item, page->pageItem()->childBaseItems()) { + IPainterProxy *proxyItem = dynamic_cast(item); + if (proxyItem){ + proxyItem->setExternalPainter(this); + } + } + } + } +} + +void ReportEnginePrivate::paintByExternalPainter(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem* options) +{ + emit externalPaint(objectName, painter, options); +} + +BaseDesignIntf* ReportEnginePrivate::createWatermark(PageDesignIntf* page, WatermarkSetting watermarkSetting) +{ + + WatermarkHelper watermarkHelper(watermarkSetting); + + BaseDesignIntf* watermark = page->addReportItem("TextItem", watermarkHelper.mapToPage(*page->pageItem()), watermarkHelper.sceneSize()); + if (watermark){ + watermark->setProperty("content", watermarkSetting.text()); + watermark->setProperty("font",watermarkSetting.font()); + watermark->setProperty("watermark",true); + watermark->setProperty("itemLocation",1); + watermark->setProperty("foregroundOpacity", watermarkSetting.opacity()); + watermark->setProperty("fontColor", watermarkSetting.color()); + } + return watermark; + +} + ReportPages ReportEnginePrivate::renderToPages() { + int startTOCPage = -1; + int pageAfterTOCIndex = -1; + if (m_reportRendering) return ReportPages(); + initReport(); m_reportRender = ReportRender::Ptr(new ReportRender); - - dataManager()->clearErrors(); - dataManager()->connectAllDatabases(); - dataManager()->setDesignTime(false); - dataManager()->updateDatasourceModel(); - + updateTranslations(); connect(m_reportRender.data(),SIGNAL(pageRendered(int)), this, SIGNAL(renderPageFinished(int))); + if (m_pages.count()){ + +#ifdef HAVE_UI_LOADER + m_scriptEngineContext->initDialogs(); +#endif ReportPages result; m_reportRendering = true; - emit renderStarted(); m_reportRender->setDatasources(dataManager()); m_reportRender->setScriptContext(scriptContext()); + m_renderingPages.clear(); + foreach (PageDesignIntf* page, m_pages) { - foreach(PageDesignIntf* page , m_pages){ - m_pages.at(0)->setReportSettings(&m_reportSettings); - result.append(m_reportRender->renderPageToPages(page)); + QVector watermarks; + if (!m_watermarks.isEmpty()){ + foreach(WatermarkSetting watermarkSetting, m_watermarks){ + watermarks.append(createWatermark(page, watermarkSetting)); + } + } + + PageItemDesignIntf* rp = createRenderingPage(page->pageItem()); + + + qDeleteAll(watermarks.begin(),watermarks.end()); + watermarks.clear(); + + m_renderingPages.append(rp); + scriptContext()->baseDesignIntfToScript(rp->objectName(), rp); } - m_reportRender->secondRenderPass(result); - emit renderFinished(); - m_reportRender.clear(); + scriptContext()->qobjectToScript("engine",this); +#ifdef USE_QTSCRIPTENGINE + ScriptEngineManager::instance().scriptEngine()->pushContext(); +#endif + if (m_scriptEngineContext->runInitScript()){ + + dataManager()->clearErrors(); + dataManager()->connectAllDatabases(); + dataManager()->setDesignTime(false); + dataManager()->updateDatasourceModel(); + + activateLanguage(m_reportLanguage); + emit renderStarted(); + m_scriptEngineContext->setReportPages(&result); + + for(int i = 0; i < m_renderingPages.count(); ++i){ + PageItemDesignIntf* page = m_renderingPages.at(i); + if (!page->isTOC() && page->isPrintable()){ + page->setReportSettings(&m_reportSettings); + result.append(m_reportRender->renderPageToPages(page)); + } else { + startTOCPage = result.count(); + pageAfterTOCIndex = i+1; + m_reportRender->createTOCMarker(page->resetPageNumber()); + } + } + + for (int i=0; iisTOC()){ + page->setReportSettings(&m_reportSettings); + if (i < m_renderingPages.count()){ + PageItemDesignIntf* secondPage = 0; + if ( m_renderingPages.count() > (pageAfterTOCIndex)) + secondPage = m_renderingPages.at(pageAfterTOCIndex); + ReportPages pages = m_reportRender->renderTOC( + page, + true, + secondPage && secondPage->resetPageNumber() + ); + for (int j=0; jrenderPageToPages(page)); + } + } + } + + m_reportRender->secondRenderPass(result); + + emit renderFinished(); + m_reportRender.clear(); + + //foreach(PageItemDesignIntf* page, m_renderingPages){ + // delete page; + //} + m_renderingPages.clear(); + } m_reportRendering = false; + //activateLanguage(QLocale::AnyLanguage); +#ifdef USE_QTSCRIPTENGINE + ScriptEngineManager::instance().scriptEngine()->popContext(); +#endif return result; } else { return ReportPages(); @@ -939,9 +1380,23 @@ ReportEngine::ReportEngine(QObject *parent) connect(d, SIGNAL(renderPageFinished(int)), this, SIGNAL(renderPageFinished(int))); connect(d, SIGNAL(renderFinished()), this, SIGNAL(renderFinished())); - connect(d, SIGNAL(onSave()), this, SIGNAL(onSave())); + connect(d, SIGNAL(onSave(bool&)), this, SIGNAL(onSave(bool&))); + connect(d, SIGNAL(onSaveAs(bool&)), this, SIGNAL(onSaveAs(bool&))); connect(d, SIGNAL(onLoad(bool&)), this, SIGNAL(onLoad(bool&))); connect(d, SIGNAL(saveFinished()), this, SIGNAL(saveFinished())); + connect(d, SIGNAL(loadFinished()), this, SIGNAL(loadFinished())); + connect(d, SIGNAL(cleared()), this, SIGNAL(cleared())); + connect(d, SIGNAL(printedToPDF(QString)), this, SIGNAL(printedToPDF(QString))); + + connect(d, SIGNAL(getAvailableDesignerLanguages(QList*)), + this, SIGNAL(getAvailableDesignerLanguages(QList*))); + connect(d, SIGNAL(currentDefaultDesignerLanguageChanged(QLocale::Language)), + this, SIGNAL(currentDefaultDesignerLanguageChanged(QLocale::Language))); + connect(d, SIGNAL(getCurrentDefaultDesignerLanguage()), + this, SIGNAL(getCurrentDefaultDesignerLanguage())); + + connect(d, SIGNAL(externalPaint(const QString&, QPainter*, const QStyleOptionGraphicsItem*)), + this, SIGNAL(externalPaint(const QString&, QPainter*, const QStyleOptionGraphicsItem*))); connect(d, SIGNAL(onSavePreview(bool&, LimeReport::IPreparedPages*)), this, SIGNAL(onSavePreview(bool&, LimeReport::IPreparedPages*))); } @@ -957,6 +1412,12 @@ bool ReportEngine::printReport(QPrinter *printer) return d->printReport(printer); } +bool ReportEngine::printReport(QMap printers, bool printToAllPrinters) +{ + Q_D(ReportEngine); + return d->printReport(printers, printToAllPrinters); +} + bool ReportEngine::printPages(ReportPages pages, QPrinter *printer){ Q_D(ReportEngine); return d->printPages(pages,printer); @@ -974,6 +1435,12 @@ bool ReportEngine::printToPDF(const QString &fileName) return d->printToPDF(fileName); } +bool ReportEngine::exportReport(QString exporterName, const QString &fileName, const QMap ¶ms) +{ + Q_D(ReportEngine); + return d->exportReport(exporterName, fileName, params); +} + void ReportEngine::previewReport(PreviewHints hints) { Q_D(ReportEngine); @@ -982,6 +1449,14 @@ void ReportEngine::previewReport(PreviewHints hints) d->previewReport(hints); } +void ReportEngine::previewReport(QPrinter *printer, PreviewHints hints) +{ + Q_D(ReportEngine); + if (m_settings) + d->setSettings(m_settings); + d->previewReport(printer, hints); +} + void ReportEngine::designReport() { Q_D(ReportEngine); @@ -990,6 +1465,12 @@ void ReportEngine::designReport() d->designReport(); } +ReportDesignWindowInterface* ReportEngine::getDesignerWindow() +{ + Q_D(ReportEngine); + return d->getDesignerWindow(); +} + PreviewReportWidget* ReportEngine::createPreviewWidget(QWidget *parent) { Q_D(ReportEngine); @@ -1008,6 +1489,12 @@ void ReportEngine::setPreviewWindowIcon(const QIcon &icon) d->setPreviewWindowIcon(icon); } +void ReportEngine::setPreviewPageBackgroundColor(QColor color) +{ + Q_D(ReportEngine); + d->setPreviewWindowPageBackground(color); +} + void ReportEngine::setResultEditable(bool value) { Q_D(ReportEngine); @@ -1062,10 +1549,22 @@ bool ReportEngine::isBusy() return d->isBusy(); } -void ReportEngine::setPassPharse(QString &passPharse) +void ReportEngine::setPassPhrase(QString &passPhrase) { Q_D(ReportEngine); - d->setPassPhrase(passPharse); + d->setPassPhrase(passPhrase); +} + +QList ReportEngine::availableLanguages() +{ + Q_D(ReportEngine); + return d->aviableLanguages(); +} + +bool ReportEngine::setReportLanguage(QLocale::Language language) +{ + Q_D(ReportEngine); + return d->setReportLanguage(language); } Qt::LayoutDirection ReportEngine::previewLayoutDirection() @@ -1074,10 +1573,22 @@ Qt::LayoutDirection ReportEngine::previewLayoutDirection() return d->previewLayoutDirection(); } -void ReportEngine::setPreviewLayoutDirection(const Qt::LayoutDirection& layoutDirection) +void ReportEngine::setPreviewLayoutDirection(const Qt::LayoutDirection& previewLayoutDirection) { Q_D(ReportEngine); - return d->setPreviewLayoutDirection(layoutDirection); + d->setPreviewLayoutDirection(previewLayoutDirection); +} + +QList ReportEngine::designerLanguages() +{ + Q_D(ReportEngine); + return d->designerLanguages(); +} + +QLocale::Language ReportEngine::currentDesignerLanguage() +{ + Q_D(ReportEngine); + return d->currentDesignerLanguage(); } ScaleType ReportEngine::previewScaleType() @@ -1098,6 +1609,18 @@ void ReportEngine::setPreviewScaleType(const ScaleType &previewScaleType, int pe d->setPreviewScaleType(previewScaleType, percent); } +void ReportEngine::addWatermark(const WatermarkSetting &watermarkSetting) +{ + Q_D(ReportEngine); + d->addWatermark(watermarkSetting); +} + +void ReportEngine::clearWatermarks() +{ + Q_D(ReportEngine); + d->clearWatermarks(); +} + IPreparedPages *ReportEngine::preparedPages() { Q_D(ReportEngine); @@ -1116,6 +1639,11 @@ bool ReportEngine::prepareReportPages() return d->prepareReportPages(); } +bool ReportEngine::printPreparedPages() +{ + Q_D(ReportEngine); + return d->printPreparedPages(); +} void ReportEngine::setShowProgressDialog(bool value) { @@ -1129,7 +1657,7 @@ IDataSourceManager *ReportEngine::dataManager() return d->dataManagerIntf(); } -IScriptEngineManager* ReportEngine::scriptManager() +IScriptEngineManager *ReportEngine::scriptManager() { Q_D(ReportEngine); return d->scriptManagerIntf(); @@ -1164,12 +1692,6 @@ void ReportEngine::setReportFileName(const QString &fileName) return d->setReportFileName(fileName); } -bool ReportEngine::saveToFile() -{ - Q_D(ReportEngine); - return d->saveToFile(); -} - bool ReportEngine::saveToFile(const QString &fileName) { Q_D(ReportEngine); @@ -1229,4 +1751,279 @@ ReportEngine::ReportEngine(ReportEnginePrivate &dd, QObject *parent) connect(d, SIGNAL(renderFinished()), this, SIGNAL(renderFinished())); } +ScriptEngineManager*LimeReport::ReportEnginePrivate::scriptManager(){ + ScriptEngineManager::instance().setContext(scriptContext()); + ScriptEngineManager::instance().setDataManager(dataManager()); + return &ScriptEngineManager::instance(); } + +PrintProcessor::PrintProcessor(QPrinter* printer) + : m_printer(printer), m_painter(0), m_firstPage(true) +{} + + +bool PrintProcessor::printPage(PageItemDesignIntf::Ptr page) +{ + if (!m_firstPage && !m_painter->isActive()) return false; + + LimeReport::PageDesignIntf renderPage; + renderPage.setItemMode(PrintMode); + + QPointF backupPagePos = page->pos(); + page->setPos(0,0); + renderPage.setPageItem(page); + renderPage.setSceneRect(renderPage.pageItem()->mapToScene(renderPage.pageItem()->rect()).boundingRect()); + initPrinter(renderPage.pageItem()); + + if (!m_firstPage){ + m_printer->newPage(); + } else { + m_painter = new QPainter(m_printer); + if (!m_painter->isActive()) return false; + m_firstPage = false; + } + + qreal leftMargin, topMargin, rightMargin, bottomMargin; + m_printer->getPageMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin, QPrinter::Millimeter); + + QRectF printerPageRect = m_printer->pageRect(QPrinter::Millimeter); + printerPageRect = QRectF(0,0,(printerPageRect.size().width() + rightMargin + leftMargin) * page->unitFactor(), + (printerPageRect.size().height() + bottomMargin +topMargin) * page->unitFactor()); + + if (page->printBehavior() == PageItemDesignIntf::Split && m_printer->pageSize() != static_cast(page->pageSize()) && + printerPageRect.width() < page->geometry().width()) + { + qreal pageWidth = page->geometry().width(); + qreal pageHeight = page->geometry().height(); + QRectF currentPrintingRect = printerPageRect; + qreal curHeight = 0; + qreal curWidth = 0; + bool first = true; + while (pageHeight > 0){ + while (curWidth < pageWidth){ + if (!first) m_printer->newPage(); else first = false; + renderPage.render(m_painter, m_printer->pageRect(), currentPrintingRect); + currentPrintingRect.adjust(printerPageRect.size().width(), 0, printerPageRect.size().width(), 0); + curWidth += printerPageRect.size().width(); + + } + pageHeight -= printerPageRect.size().height(); + curHeight += printerPageRect.size().height(); + currentPrintingRect = printerPageRect; + currentPrintingRect.adjust(0, curHeight, 0, curHeight); + curWidth = 0; + } + + } else { + renderPage.render(m_painter); + } + page->setPos(backupPagePos); + return true; +} + +void PrintProcessor::initPrinter(PageItemDesignIntf* page) +{ + if (page->oldPrintMode()){ + m_printer->setPageMargins(page->leftMargin(), + page->topMargin(), + page->rightMargin(), + page->bottomMargin(), + QPrinter::Millimeter); + m_printer->setOrientation(static_cast(page->pageOrientation())); + QSizeF pageSize = (page->pageOrientation()==PageItemDesignIntf::Landscape)? + QSizeF(page->sizeMM().height(),page->sizeMM().width()): + page->sizeMM(); + m_printer->setPaperSize(pageSize,QPrinter::Millimeter); + } else { + m_printer->setFullPage(page->fullPage()); + m_printer->setOrientation(static_cast(page->pageOrientation())); + if (page->pageSize()==PageItemDesignIntf::Custom){ + QSizeF pageSize = (page->pageOrientation()==PageItemDesignIntf::Landscape)? + QSizeF(page->sizeMM().height(),page->sizeMM().width()): + page->sizeMM(); + if (page->getSetPageSizeToPrinter() || m_printer->outputFormat() == QPrinter::PdfFormat) + m_printer->setPaperSize(pageSize,QPrinter::Millimeter); + } else { + if (page->getSetPageSizeToPrinter() || m_printer->outputFormat() == QPrinter::PdfFormat) + m_printer->setPaperSize(static_cast(page->pageSize())); + } + } +} + +qreal ItemGeometry::x() const +{ + return m_x; +} + +void ItemGeometry::setX(const qreal &x) +{ + m_x = x; +} + +qreal ItemGeometry::y() const +{ + return m_y; +} + +void ItemGeometry::setY(const qreal &y) +{ + m_y = y; +} + +qreal ItemGeometry::width() const +{ + return m_width; +} + +void ItemGeometry::setWidth(const qreal &width) +{ + m_width = width; +} + +qreal ItemGeometry::height() const +{ + return m_height; +} + +void ItemGeometry::setHeight(const qreal &height) +{ + m_height = height; +} + +ItemGeometry::Type ItemGeometry::type() const +{ + return m_type; +} + +void ItemGeometry::setType(const Type &type) +{ + m_type = type; +} + +Qt::Alignment ItemGeometry::anchor() const +{ + return m_anchor; +} + +void ItemGeometry::setAnchor(const Qt::Alignment &anchor) +{ + m_anchor = anchor; +} + +QString WatermarkSetting::text() const +{ + return m_text; +} + +void WatermarkSetting::setText(const QString &text) +{ + m_text = text; +} + +QFont WatermarkSetting::font() const +{ + return m_font; +} + +void WatermarkSetting::setFont(const QFont &font) +{ + m_font = font; +} + +int WatermarkSetting::opacity() const +{ + return m_opacity; +} + +void WatermarkSetting::setOpacity(const int &opacity) +{ + m_opacity = opacity; +} + +ItemGeometry WatermarkSetting::geometry() const +{ + return m_geometry; +} + +void WatermarkSetting::setGeometry(const ItemGeometry &geometry) +{ + m_geometry = geometry; +} + +QColor WatermarkSetting::color() const +{ + return m_color; +} + +void WatermarkSetting::setColor(const QColor &color) +{ + m_color = color; +} + +qreal WatermarkHelper::sceneX() +{ + return valueToPixels(m_watermark.geometry().x()); +} + +qreal WatermarkHelper::sceneY() +{ + return valueToPixels(m_watermark.geometry().y()); +} + +qreal WatermarkHelper::sceneWidth() +{ + return valueToPixels(m_watermark.geometry().width()); +} + +qreal WatermarkHelper::sceneHeight() +{ + return valueToPixels(m_watermark.geometry().height()); +} + +QPointF WatermarkHelper::scenePos() +{ + return (QPointF(sceneX(), sceneY())); +} + +QSizeF WatermarkHelper::sceneSize() +{ + return (QSizeF(sceneWidth(), sceneHeight())); +} + +QPointF WatermarkHelper::mapToPage(const PageItemDesignIntf &page) +{ + qreal startX = 0; + qreal startY = 0; + + if ( m_watermark.geometry().anchor() & Qt::AlignLeft){ + startX = 0; + } else if ( m_watermark.geometry().anchor() & Qt::AlignRight){ + startX = page.geometry().width(); + } else { + startX = page.geometry().width() / 2; + } + + if ( m_watermark.geometry().anchor() & Qt::AlignTop){ + startY = 0; + } else if (m_watermark.geometry().anchor() & Qt::AlignBottom){ + startY = page.geometry().height(); + } else { + startY = page.geometry().height() / 2; + } + + return QPointF(startX + sceneX(), startY + sceneY()); +} + +qreal WatermarkHelper::valueToPixels(qreal value) +{ + switch (m_watermark.geometry().type()) { + case LimeReport::ItemGeometry::Millimeters: + return value * Const::mmFACTOR; + case LimeReport::ItemGeometry::Pixels: + return value; + } +} + + +}// namespace LimeReport + diff --git a/limereport/lrreportengine.h b/limereport/lrreportengine.h index 8296abc..a4c314f 100644 --- a/limereport/lrreportengine.h +++ b/limereport/lrreportengine.h @@ -33,14 +33,17 @@ #include #include #include +//#include #include "lrglobal.h" #include "lrdatasourcemanagerintf.h" #include "lrscriptenginemanagerintf.h" #include "lrpreviewreportwidget.h" +#include "lrreportdesignwindowintrerface.h" #include "lrpreparedpagesintf.h" class QPrinter; +class QGraphicsScene; namespace LimeReport { @@ -59,28 +62,107 @@ private: int m_toPage; }; +class LIMEREPORT_EXPORT ItemGeometry{ +public: + enum Type{Millimeters, Pixels}; + ItemGeometry(qreal x, qreal y, qreal width, qreal height, Qt::Alignment anchor, Type type = Millimeters) + :m_x(x), m_y(y), m_width(width), m_height(height), m_type(type), m_anchor(anchor){} + ItemGeometry(): m_x(0), m_y(0), m_width(0), m_height(0), m_type(Millimeters){} + + qreal x() const; + void setX(const qreal &x); + + qreal y() const; + void setY(const qreal &y); + + qreal width() const; + void setWidth(const qreal &width); + + qreal height() const; + void setHeight(const qreal &height); + + Type type() const; + void setType(const Type &type); + + Qt::Alignment anchor() const; + void setAnchor(const Qt::Alignment &anchor); + +private: + qreal m_x; + qreal m_y; + qreal m_width; + qreal m_height; + Type m_type; + Qt::Alignment m_anchor; +}; + +class LIMEREPORT_EXPORT WatermarkSetting{ +public: + WatermarkSetting(const QString& text, const ItemGeometry& geometry, const QFont& font) + : m_text(text), m_font(font), m_opacity(50), m_geometry(geometry), m_color(QColor(Qt::black)){} + WatermarkSetting(): m_font(QFont()), m_opacity(50), m_geometry(ItemGeometry()){} + QString text() const; + void setText(const QString &text); + + QFont font() const; + void setFont(const QFont &font); + + int opacity() const; + void setOpacity(const int &opacity); + + ItemGeometry geometry() const; + void setGeometry(const ItemGeometry &geometry); + + QColor color() const; + void setColor(const QColor &color); + +private: + QString m_text; + QFont m_font; + int m_opacity; + ItemGeometry m_geometry; + QColor m_color; +}; + +class ItemBuilder{ + virtual void setProperty(QString name, QVariant value) = 0; + virtual QVariant property(QString name) = 0; + virtual void setGeometry(ItemGeometry geometry) = 0; + virtual ItemGeometry geometry() = 0; +}; + + class DataSourceManager; class ReportEnginePrivate; class PageDesignIntf; class PageItemDesignIntf; +class ReportDesignWidget; +class PreviewReportWidget; class PreparedPages; typedef QList< QSharedPointer > ReportPages; class LIMEREPORT_EXPORT ReportEngine : public QObject{ Q_OBJECT + friend class ReportDesignWidget; + friend class PreviewReportWidget; + friend class TranslationEditor; public: static void setSettings(QSettings *value){m_settings=value;} public: explicit ReportEngine(QObject *parent = 0); ~ReportEngine(); bool printReport(QPrinter *printer=0); + bool printReport(QMap printers, bool printToAllPrinters = false); bool printPages(ReportPages pages, QPrinter *printer); void printToFile(const QString& fileName); - PageDesignIntf *createPreviewScene(QObject *parent = 0); + QGraphicsScene* createPreviewScene(QObject *parent = 0); bool printToPDF(const QString& fileName); + bool exportReport(QString exporterName, const QString &fileName = "", const QMap& params = QMap()); void previewReport(PreviewHints hints = PreviewBarsUserSetting); + void previewReport(QPrinter* printer, PreviewHints hints = PreviewBarsUserSetting); void designReport(); + ReportDesignWindowInterface* getDesignerWindow(); void setShowProgressDialog(bool value); IDataSourceManager* dataManager(); IScriptEngineManager* scriptManager(); @@ -89,7 +171,6 @@ public: bool loadFromString(const QString& data); QString reportFileName(); void setReportFileName(const QString& fileName); - bool saveToFile(); bool saveToFile(const QString& fileName); QByteArray saveToByteArray(); QString saveToString(); @@ -100,6 +181,7 @@ public: PreviewReportWidget *createPreviewWidget(QWidget *parent = 0); void setPreviewWindowTitle(const QString& title); void setPreviewWindowIcon(const QIcon& icon); + void setPreviewPageBackgroundColor(QColor color); void setResultEditable(bool value); bool resultIsEditable(); void setSaveToFileVisible(bool value); @@ -109,23 +191,41 @@ public: void setPrintVisible(bool value); bool printIsVisible(); bool isBusy(); - void setPassPharse(QString& passPharse); + void setPassPhrase(QString& passPhrase); + QList availableLanguages(); + bool setReportLanguage(QLocale::Language language); Qt::LayoutDirection previewLayoutDirection(); void setPreviewLayoutDirection(const Qt::LayoutDirection& previewLayoutDirection); + QList designerLanguages(); + QLocale::Language currentDesignerLanguage(); ScaleType previewScaleType(); int previewScalePercent(); void setPreviewScaleType(const ScaleType &previewScaleType, int percent = 0); + void addWatermark(const WatermarkSetting& watermarkSetting); + void clearWatermarks(); IPreparedPages* preparedPages(); bool showPreparedPages(PreviewHints hints = PreviewBarsUserSetting); bool prepareReportPages(); + bool printPreparedPages(); signals: + void cleared(); void renderStarted(); void renderFinished(); void renderPageFinished(int renderedPageCount); + void onSave(bool& saved); + void onSaveAs(bool& saved); void onLoad(bool& loaded); - void onSave(); void onSavePreview(bool& saved, LimeReport::IPreparedPages* pages); void saveFinished(); + void loadFinished(); + void printedToPDF(QString fileName); + + void getAvailableDesignerLanguages(QList* languages); + void currentDefaultDesignerLanguageChanged(QLocale::Language); + QLocale::Language getCurrentDefaultDesignerLanguage(); + + void externalPaint(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem*); + public slots: void cancelRender(); protected: diff --git a/limereport/lrreportengine_p.h b/limereport/lrreportengine_p.h index d0d312b..3ffec70 100644 --- a/limereport/lrreportengine_p.h +++ b/limereport/lrreportengine_p.h @@ -33,6 +33,7 @@ #include #include #include +#include #include "lrreportengine.h" #include "lrcollection.h" #include "lrglobal.h" @@ -41,16 +42,94 @@ #include "lrreportrender.h" #include "serializators/lrstorageintf.h" #include "lrscriptenginemanager.h" +#include "lrreporttranslation.h" +#include "lrdesignerplugininterface.h" +#include "lrreportdesignwindowintrerface.h" class QFileSystemWatcher; + namespace LimeReport{ class PageDesignIntf; class PrintRange; class ReportDesignWindow; +class ReportExporterInterface; -class ReportEnginePrivate : public QObject, public ICollectionContainer + +class WatermarkHelper{ +public: + WatermarkHelper(const WatermarkSetting& watermark) + : m_watermark(watermark){} + qreal sceneX(); + qreal sceneY(); + qreal sceneWidth(); + qreal sceneHeight(); + QPointF scenePos(); + QSizeF sceneSize(); + QPointF mapToPage(const PageItemDesignIntf &page); +private: + qreal valueToPixels(qreal value); +private: + const WatermarkSetting& m_watermark; +}; + + +class ReportEnginePrivateInterface { +public: + virtual PageDesignIntf* appendPage(const QString& pageName="") = 0; + virtual bool deletePage(PageDesignIntf *page) = 0; + virtual void reorderPages(const QList &reorderedPages) = 0; + virtual int pageCount() = 0; + virtual PageDesignIntf* pageAt(int index) = 0; + virtual void clearReport() = 0; + virtual ScriptEngineContext* scriptContext() = 0; + virtual ScriptEngineManager* scriptManager() = 0; + virtual DataSourceManager* dataManager() = 0; + virtual QString reportFileName() = 0; + virtual void setReportFileName(const QString& reportFileName) = 0; + virtual bool isNeedToSave() = 0; + virtual bool emitSaveReport() = 0; + virtual bool emitSaveReportAs() = 0; + virtual void emitSaveFinished() = 0; + virtual bool saveToFile(const QString& fileName = "") = 0; + virtual bool isSaved() = 0; + virtual QString reportName() = 0; + virtual bool loadFromFile(const QString& fileName, bool autoLoadPreviewOnChange) = 0; + virtual bool emitLoadReport() = 0; + virtual void emitLoadFinished() = 0; + virtual void clearSelection() = 0; + virtual bool printReport(QPrinter *printer=0) = 0; + virtual void previewReport(PreviewHints hints = PreviewBarsUserSetting) = 0; + virtual void setCurrentReportsDir(const QString& dirName) = 0; + virtual QString currentReportsDir() = 0; + virtual bool suppressFieldAndVarError() const = 0; + virtual void setSuppressFieldAndVarError(bool suppressFieldAndVarError) = 0; + virtual void setStyleSheet(const QString& styleSheet) = 0; + virtual QString styleSheet() const = 0; + virtual QList designerLanguages() = 0; + virtual QLocale::Language currentDesignerLanguage() = 0; + virtual void setCurrentDesignerLanguage(QLocale::Language language) = 0; +}; + +class PrintProcessor{ +public: + explicit PrintProcessor(QPrinter* printer); + ~PrintProcessor(){ if (m_painter) delete m_painter;} + bool printPage(LimeReport::PageItemDesignIntf::Ptr page); +private: + void initPrinter(PageItemDesignIntf* page); +private: + QPrinter* m_printer; + QPainter* m_painter; + bool m_firstPage; +}; + +class ReportEnginePrivate : public QObject, + public ICollectionContainer, + public ITranslationContainer, + public IExternalPainter, + public ReportEnginePrivateInterface { Q_OBJECT Q_DECLARE_PUBLIC(ReportEngine) @@ -58,10 +137,15 @@ class ReportEnginePrivate : public QObject, public ICollectionContainer Q_PROPERTY(QObject* datasourcesManager READ dataManager) Q_PROPERTY(QObject* scriptContext READ scriptContext) Q_PROPERTY(bool suppressFieldAndVarError READ suppressFieldAndVarError WRITE setSuppressFieldAndVarError) + Q_PROPERTY(ATranslationProperty translation READ fakeTranslationReader) + friend class PreviewReportWidget; public: static void printReport(ItemsReaderIntf::Ptr reader, QPrinter &printer); static void printReport(ReportPages pages, QPrinter &printer); + static void printReport(ReportPages pages, QMapprinters, bool printToAllPrinters = false); + Q_INVOKABLE QStringList aviableReportTranslations(); + Q_INVOKABLE void setReportTranslation(const QString& languageName); public: explicit ReportEnginePrivate(QObject *parent = 0); virtual ~ReportEnginePrivate(); @@ -73,7 +157,7 @@ public: int pageCount() {return m_pages.count();} DataSourceManager* dataManager(){return m_datasources;} ScriptEngineContext* scriptContext(){return m_scriptEngineContext;} - ScriptEngineManager* scriptManager(){return &ScriptEngineManager::instance();} + ScriptEngineManager* scriptManager(); IDataSourceManager* dataManagerIntf(){return m_datasources;} IScriptEngineManager* scriptManagerIntf(){ @@ -82,11 +166,16 @@ public: } void clearReport(); - bool printReport(QPrinter *printer=0); + bool printReport(QPrinter* printer=0); + bool printReport(QMapprinters, bool printToAllPrinters); bool printPages(ReportPages pages, QPrinter *printer); void printToFile(const QString& fileName); bool printToPDF(const QString& fileName); + bool exportReport(QString exporterName, const QString &fileName = "", const QMap& params = QMap()); void previewReport(PreviewHints hints = PreviewBarsUserSetting); + void previewReport(QPrinter* printer, PreviewHints hints = PreviewBarsUserSetting); + + ReportDesignWindowInterface* getDesignerWindow(); void designReport(); void setSettings(QSettings* value); void setShowProgressDialog(bool value){m_showProgressDialog = value;} @@ -96,16 +185,18 @@ public: bool loadFromString(const QString& report, const QString& name = ""); QString reportFileName(){return m_fileName;} void setReportFileName(const QString& reportFileName){ m_fileName = reportFileName;} - bool saveToFile(); - bool saveToFile(const QString& fileName); + bool saveToFile(const QString& fileName = ""); QByteArray saveToByteArray(); QString saveToString(); bool isNeedToSave(); QString lastError(); ReportEngine * q_ptr; - void emitSaveReport(); + bool emitSaveReport(); + bool emitSaveReportAs(); bool emitLoadReport(); void emitSaveFinished(); + void emitLoadFinished(); + void emitPrintedToPDF(QString fileName); bool isSaved(); void setCurrentReportsDir(const QString& dirName); QString currentReportsDir(){ return m_reportsDir;} @@ -118,6 +209,8 @@ public: void setPreviewWindowIcon(const QIcon &previewWindowIcon); QString previewWindowTitle() const; void setPreviewWindowTitle(const QString &previewWindowTitle); + QColor previewWindowPageBackground(); + void setPreviewWindowPageBackground(QColor color); bool suppressFieldAndVarError() const; void setSuppressFieldAndVarError(bool suppressFieldAndVarError); @@ -132,16 +225,29 @@ public: void setPrintVisible(bool value); void setPassPhrase(const QString &passPhrase); + bool addTranslationLanguage(QLocale::Language language); + bool removeTranslationLanguage(QLocale::Language language); + bool setReportLanguage(QLocale::Language language); + QList aviableLanguages(); + ReportTranslation* reportTranslation(QLocale::Language language); void reorderPages(const QList &reorderedPages); void clearSelection(); Qt::LayoutDirection previewLayoutDirection(); void setPreviewLayoutDirection(const Qt::LayoutDirection& previewLayoutDirection); + QString styleSheet() const; + void setStyleSheet(const QString &styleSheet); + QList designerLanguages(); + QLocale::Language currentDesignerLanguage(); + void setCurrentDesignerLanguage(QLocale::Language language); ScaleType previewScaleType(); int previewScalePercent(); - void setPreviewScaleType(const ScaleType &previewScaleType, int percent = 0); + void setPreviewScaleType(const ScaleType &previewScaleType, int percent = 0); + void addWatermark(const WatermarkSetting& watermarkSetting); + void clearWatermarks(); IPreparedPages* preparedPages(); bool showPreparedPages(PreviewHints hints); bool prepareReportPages(); + bool printPreparedPages(); signals: void pagesLoadFinished(); void datasourceCollectionLoadFinished(const QString& collectionName); @@ -149,20 +255,30 @@ signals: void renderStarted(); void renderFinished(); void renderPageFinished(int renderedPageCount); - void onLoad(bool& loaded); - void onSave(); - void saveFinished(); + void onSave(bool& saved); + void onSaveAs(bool& saved); void onSavePreview(bool& saved, LimeReport::IPreparedPages* pages); + void onLoad(bool& loaded); + void saveFinished(); + void loadFinished(); + void printedToPDF(QString fileName); + + void getAvailableDesignerLanguages(QList* languages); + void currentDefaultDesignerLanguageChanged(QLocale::Language); + QLocale::Language getCurrentDefaultDesignerLanguage(); + void externalPaint(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem*); + public slots: bool slotLoadFromFile(const QString& fileName); void cancelRender(); protected: - PageDesignIntf* createPage(const QString& pageName=""); + PageDesignIntf* createPage(const QString& pageName="", bool preview = false); bool showPreviewWindow(ReportPages pages, PreviewHints hints); protected slots: void slotDataSourceCollectionLoaded(const QString& collectionName); private slots: - void slotPreviewWindowDestroyed(QObject *window); + void slotPreviewWindowDestroyed(QObject* window); + void slotDesignerWindowDestroyed(QObject* window); private: //ICollectionContainer virtual QObject* createElement(const QString&,const QString&); @@ -172,10 +288,21 @@ private: void saveError(QString message); void showError(QString message); //ICollectionContainer + //ITranslationContainer + Translations* translations(){ return &m_translations;} + void updateTranslations(); + //ITranslationContainer ReportPages renderToPages(); QString renderToString(); + PageItemDesignIntf *getPageByName(const QString& pageName); + ATranslationProperty fakeTranslationReader(){ return ATranslationProperty();} + PageItemDesignIntf *createRenderingPage(PageItemDesignIntf *page); + void initReport(); + void paintByExternalPainter(const QString& objectName, QPainter* painter, const QStyleOptionGraphicsItem* options); + void dropChanges(){ m_datasources->dropChanges(); m_scriptEngineContext->dropChanges();} private: QList m_pages; + QList m_renderingPages; ReportPages m_preparedPages; PreparedPages* m_preparedPagesManager; DataSourceManager* m_datasources; @@ -193,15 +320,26 @@ private: QMainWindow* m_activePreview; QIcon m_previewWindowIcon; QString m_previewWindowTitle; - QPointer m_designerWindow; + QPointer m_designerWindow; ReportSettings m_reportSettings; bool m_reportRendering; bool m_resultIsEditable; QString m_passPhrase; QFileSystemWatcher *m_fileWatcher; + Translations m_translations; + QLocale::Language m_reportLanguage; + void activateLanguage(QLocale::Language language); Qt::LayoutDirection m_previewLayoutDirection; + LimeReportDesignerPluginInterface* m_designerFactory; + QString m_styleSheet; + QLocale::Language m_currentDesignerLanguage; + QMap exporters; ScaleType m_previewScaleType; int m_previewScalePercent; + int m_startTOCPage; + QColor m_previewPageBackgroundColor; + QVector m_watermarks; + BaseDesignIntf *createWatermark(PageDesignIntf *page, WatermarkSetting watermarkSetting); bool m_saveToFileVisible; bool m_printToPdfVisible; bool m_printVisible; diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp index 9c4d628..ec608fd 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -29,7 +29,6 @@ ****************************************************************************/ #include #include -#include #include "lrglobal.h" #include "lrreportrender.h" @@ -149,7 +148,8 @@ void ReportRender::renameChildItems(BaseDesignIntf *item){ ReportRender::ReportRender(QObject *parent) :QObject(parent), m_renderPageItem(0), m_pageCount(0), - m_lastRenderedHeader(0), m_lastDataBand(0), m_lastRenderedFooter(0), m_currentColumn(0), m_newPageStarted(false) + m_lastRenderedHeader(0), m_lastDataBand(0), m_lastRenderedFooter(0), + m_currentColumn(0), m_newPageStarted(false), m_lostHeadersMoved(false) { initColumns(); } @@ -166,23 +166,6 @@ void ReportRender::setScriptContext(ScriptEngineContext* scriptContext) m_scriptEngineContext=scriptContext; } -bool ReportRender::runInitScript(){ - if (m_scriptEngineContext){ - QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine(); - engine->pushContext(); - QScriptValue res = engine->evaluate(m_scriptEngineContext->initScript()); - if (res.isBool()) return res.toBool(); - if (engine->hasUncaughtException()) { - QMessageBox::critical(0,tr("Error"), - QString("Line %1: %2 ").arg(engine->uncaughtExceptionLineNumber()) - .arg(engine->uncaughtException().toString()) - ); - return false; - } - } - return true; -} - void ReportRender::initDatasources(){ try{ datasources()->setAllDatasourcesToFirst(); @@ -206,71 +189,61 @@ void ReportRender::initDatasource(const QString& name){ } } -void ReportRender::renderPage(PageDesignIntf* patternPage) +void ReportRender::renderPage(PageItemDesignIntf* patternPage, bool isTOC, bool isFirst, bool resetPageNumbers) { m_currentNameIndex = 0; - m_patternPageItem = patternPage->pageItem(); + m_patternPageItem = patternPage; - - if (m_patternPageItem->resetPageNumber() && m_pageCount>0) { + if (m_patternPageItem->resetPageNumber() && m_pageCount>0 && !isTOC) { resetPageNumber(PageReset); } + + if (m_patternPageItem->resetPageNumber() && !isTOC && m_pageCount == 0){ + m_pagesRanges.startNewRange(); + } + m_renderCanceled = false; BandDesignIntf* reportFooter = m_patternPageItem->bandByType(BandDesignIntf::ReportFooter); m_reportFooterHeight = 0; if (reportFooter) m_reportFooterHeight = reportFooter->height(); + initGroups(); -#ifdef HAVE_UI_LOADER - initDialogs(); -#endif + clearPageMap(); - if (m_scriptEngineContext){ - baseDesignIntfToScript(patternPage->pageItem()); - foreach (BaseDesignIntf* item, patternPage->pageItem()->childBaseItems()){ - baseDesignIntfToScript(item); - } + try{ + datasources()->setAllDatasourcesToFirst(); + datasources()->clearGroupFuntionsExpressions(); + } catch(ReportError &exception){ + //TODO possible should thow exeption + QMessageBox::critical(0,tr("Error"),exception.what()); + return; } - if (runInitScript()){ + clearPageMap(); + startNewPage(true); - clearPageMap(); + renderReportHeader(m_patternPageItem, AfterPageHeader); - try{ - datasources()->setAllDatasourcesToFirst(); - datasources()->clearGroupFuntionsExpressions(); - } catch(ReportError &exception){ - //TODO possible should thow exeption - QMessageBox::critical(0,tr("Error"),exception.what()); - return; - } - - clearPageMap(); - startNewPage(); - - renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader), 0, StartNewPageAsNeeded); - - BandDesignIntf* lastRenderedBand = 0; - for (int i=0; i < m_patternPageItem->dataBandCount() && !m_renderCanceled; i++){ - lastRenderedBand = m_patternPageItem->dataBandAt(i); - initDatasource(lastRenderedBand->datasourceName()); - renderDataBand(lastRenderedBand); - if ( i < m_patternPageItem->dataBandCount()-1) closeFooterGroup(lastRenderedBand); - } - - if (reportFooter) - renderBand(reportFooter, 0, StartNewPageAsNeeded); - if (lastRenderedBand && lastRenderedBand->keepFooterTogether()) - closeFooterGroup(lastRenderedBand); - - BandDesignIntf* tearOffBand = m_patternPageItem->bandByType(BandDesignIntf::TearOffBand); - if (tearOffBand) - renderBand(tearOffBand, 0, StartNewPageAsNeeded); - - savePage(true); - - ScriptEngineManager::instance().scriptEngine()->popContext(); + BandDesignIntf* lastRenderedBand = 0; + for (int i=0;idataBandCount() && !m_renderCanceled;i++){ + lastRenderedBand = m_patternPageItem->dataBandAt(i); + initDatasource(lastRenderedBand->datasourceName()); + renderDataBand(lastRenderedBand); + if (idataBandCount()-1) closeFooterGroup(lastRenderedBand); } + + if (reportFooter) + renderBand(reportFooter, 0, StartNewPageAsNeeded); + if (lastRenderedBand && lastRenderedBand->keepFooterTogether()) + closeFooterGroup(lastRenderedBand); + + BandDesignIntf* tearOffBand = m_patternPageItem->bandByType(BandDesignIntf::TearOffBand); + if (tearOffBand) + renderBand(tearOffBand, 0, StartNewPageAsNeeded); + + savePage(true); + } int ReportRender::pageCount() @@ -284,18 +257,23 @@ PageItemDesignIntf::Ptr ReportRender::pageAt(int index) else return m_renderedPages.at(index); } -QString ReportRender::renderPageToString(PageDesignIntf *patternPage) +QString ReportRender::renderPageToString(PageItemDesignIntf *patternPage) { renderPage(patternPage); return toString(); } -ReportPages ReportRender::renderPageToPages(PageDesignIntf *patternPage) +ReportPages ReportRender::renderPageToPages(PageItemDesignIntf *patternPage) { renderPage(patternPage); return m_renderedPages; } +ReportPages ReportRender::renderTOC(PageItemDesignIntf* patternPage, bool first, bool resetPages){ + renderPage(patternPage, true, first, resetPages); + return m_renderedPages; +} + void ReportRender::initRenderPage() { if (!m_renderPageItem) { @@ -303,6 +281,25 @@ void ReportRender::initRenderPage() m_renderPageItem->initFromItem(m_patternPageItem); m_renderPageItem->setItemMode(PreviewMode); m_renderPageItem->setPatternName(m_patternPageItem->objectName()); + m_renderPageItem->setPatternItem(m_patternPageItem); + + ScriptValueType svCurrentPage; + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); + +#ifdef USE_QJSENGINE + svCurrentPage = getJSValue(*se, m_renderPageItem); + se->globalObject().setProperty("currentPage", svCurrentPage); +#else + svCurrentPage = se->globalObject().property("currentPage"); + if (svCurrentPage.isValid()){ + se->newQObject(svCurrentPage, m_renderPageItem); + } else { + svCurrentPage = se->newQObject(m_renderPageItem); + se->globalObject().setProperty("currentPage", svCurrentPage); + } +#endif + + } } @@ -314,23 +311,27 @@ void ReportRender::initVariables() m_datasources->setReportVariable("#IS_FIRST_PAGEFOOTER",false); } -#ifdef HAVE_UI_LOADER -void ReportRender::initDialogs(){ - if (m_scriptEngineContext){ - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); - foreach(DialogDescriber::Ptr dialog, m_scriptEngineContext->dialogsDescriber()){ - QScriptValue sv = se->newQObject(m_scriptEngineContext->getDialog(dialog->name())); - se->globalObject().setProperty(dialog->name(),sv); - } - } -} -#endif - void ReportRender::clearPageMap() { m_renderedPages.clear(); } +bool ReportRender::containsGroupFunctions(BandDesignIntf *band){ + foreach(BaseDesignIntf* item,band->childBaseItems()){ + ContentItemDesignIntf* contentItem = dynamic_cast(item); + if (contentItem){ + QString content = contentItem->content(); + foreach(QString functionName, m_datasources->groupFunctionNames()){ + QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); + if (rx.indexIn(content)>=0){ + return true; + } + } + } + } + return false; +} + void ReportRender::extractGroupFuntionsFromItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band){ if ( contentItem && contentItem->content().contains(QRegExp("\\$S\\s*\\{.*\\}"))){ foreach(const QString &functionName, m_datasources->groupFunctionNames()){ @@ -371,6 +372,7 @@ void ReportRender::extractGroupFunctionsFromContainer(BaseDesignIntf* baseItem, if (contentItem) extractGroupFuntionsFromItem(contentItem, band); else extractGroupFunctionsFromContainer(item, band); } + } void ReportRender::extractGroupFunctions(BandDesignIntf *band) @@ -391,7 +393,15 @@ void ReportRender::replaceGroupFunctionsInItem(ContentItemDesignIntf* contentIte QVector captures = normalizeCaptures(rx); if (captures.size() >= 3){ QString expressionIndex = datasources()->putGroupFunctionsExpressions(captures.at(Const::VALUE_INDEX)); - content.replace(captures.at(0),QString("%1(%2,%3)").arg(functionName).arg('"'+expressionIndex+'"').arg('"'+band->objectName()+'"')); + if (captures.size()<5){ + content.replace(captures.at(0),QString("%1(%2,%3)").arg(functionName).arg('"'+expressionIndex+'"').arg('"'+band->objectName()+'"')); + } else { + content.replace(captures.at(0),QString("%1(%2,%3,%4)") + .arg(functionName) + .arg('"'+expressionIndex+'"') + .arg('"'+band->objectName()+'"') + .arg(captures.at(4))); + } } pos += rx.matchedLength(); } @@ -417,7 +427,8 @@ void ReportRender::replaceGroupsFunction(BandDesignIntf *band) BandDesignIntf* ReportRender::renderBand(BandDesignIntf *patternBand, BandDesignIntf* bandData, ReportRender::DataRenderMode mode, bool isLast) { - QApplication::processEvents(); + QCoreApplication::processEvents(); + bool bandIsSliced = false; if (patternBand){ if (patternBand->isHeader()) @@ -441,14 +452,17 @@ BandDesignIntf* ReportRender::renderBand(BandDesignIntf *patternBand, BandDesign if (patternBand->isFooter()) m_lastRenderedFooter = patternBand; - bandClone->setBackgroundColor( - (datasources()->variable(QLatin1String("line_")+patternBand->objectName().toLower()).toInt() %2 !=0 ? - bandClone->backgroundColor(): - bandClone->alternateBackgroundColor() - ) - ); + if (bandClone->useAlternateBackgroundColor()){ + bandClone->setBackgroundColor( + (datasources()->variable(QLatin1String("line_")+patternBand->objectName().toLower()).toInt() %2 == 0 ? + bandClone->backgroundColor() : + bandClone->alternateBackgroundColor() + ) + ); + } patternBand->emitBandRendered(bandClone); + m_scriptEngineContext->setCurrentBand(bandClone); emit(patternBand->afterRender()); if ( isLast && bandClone->keepFooterTogether() && bandClone->sliceLastRow() ){ @@ -461,7 +475,8 @@ BandDesignIntf* ReportRender::renderBand(BandDesignIntf *patternBand, BandDesign if (patternBand && patternBand->isHeader() && patternBand->reprintOnEachPage()) m_reprintableBands.removeOne(patternBand); if (bandClone->canBeSplitted(m_maxHeightByColumn[m_currentColumn])){ - bandClone = sliceBand(bandClone,patternBand,isLast); + bandClone = sliceBand(bandClone, patternBand, isLast); + bandIsSliced = true; } else { qreal percent = (bandClone->height()-m_maxHeightByColumn[m_currentColumn])/(bandClone->height()/100); if (bandClone->maxScalePercent()>=percent){ @@ -481,12 +496,20 @@ BandDesignIntf* ReportRender::renderBand(BandDesignIntf *patternBand, BandDesign bandClone->columnsFillDirection()==BandDesignIntf::VerticalUniform)) { startNewColumn(); - if (patternBand->bandHeader() && patternBand->bandHeader()->columnsCount()>1){ + if (patternBand->bandHeader() && + patternBand->bandHeader()->columnsCount()>1 && + !m_lostHeadersMoved && + patternBand->bandNestingLevel() == 0 + ){ renderBand(patternBand->bandHeader(), 0, mode); } } else { savePage(); startNewPage(); + if (!bandIsSliced){ + delete bandClone; + bandClone = renderData(patternBand); + } } if (!registerBand(bandClone)) { BandDesignIntf* upperPart = dynamic_cast(bandClone->cloneUpperPart(m_maxHeightByColumn[m_currentColumn])); @@ -527,19 +550,19 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) BandDesignIntf* header = dataBand->bandHeader(); BandDesignIntf* footer = dataBand->bandFooter(); - if (header && header->printAlways()) renderBand(header, 0, StartNewPageAsNeeded); + if (header && header->printAlways()) renderDataHeader(header); if(bandDatasource && !bandDatasource->eof() && !m_renderCanceled){ QString varName = QLatin1String("line_")+dataBand->objectName().toLower(); datasources()->setReportVariable(varName,1); - if (header && !header->printAlways()) - renderBand(header, 0, StartNewPageAsNeeded); - - if (dataBand->bandHeader() && dataBand->bandHeader()->reprintOnEachPage()) + if (header && header->reprintOnEachPage()) m_reprintableBands.append(dataBand->bandHeader()); + if (header && !header->printAlways()) + renderDataHeader(header); + renderGroupHeader(dataBand, bandDatasource, true); bool firstTime = true; @@ -589,7 +612,8 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) } if (!dataBand->keepFooterTogether()) - m_reprintableBands.removeOne(dataBand->bandHeader()); + m_reprintableBands.removeOne(header); + if (header) recalcIfNeeded(header); if (bandDatasource->prior()){ renderGroupFooter(dataBand); @@ -626,6 +650,17 @@ void ReportRender::renderPageHeader(PageItemDesignIntf *patternPage) } } +void ReportRender::renderReportHeader(PageItemDesignIntf *patternPage, PageRenderStage stage) +{ + BandDesignIntf* band = patternPage->bandByType(BandDesignIntf::ReportHeader); + if (band){ + if (band->property("printBeforePageHeader").toBool() && stage == BeforePageHeader ) + renderBand(band, 0, StartNewPageAsNeeded); + if (!band->property("printBeforePageHeader").toBool() && stage == AfterPageHeader ) + renderBand(band, 0, StartNewPageAsNeeded); + } +} + void ReportRender::renderPageFooter(PageItemDesignIntf *patternPage) { BandDesignIntf* band = patternPage->bandByType(BandDesignIntf::PageFooter); @@ -714,11 +749,45 @@ void ReportRender::renderChildBands(BandDesignIntf *parentBand) } } +BandDesignIntf* ReportRender::findRecalcableBand(BandDesignIntf* patternBand){ + + QList::iterator it = m_recalcBands.begin(); + for (;it !=m_recalcBands.end() ;++it){ + if ((*it)->patternItem() == patternBand){ + BandDesignIntf* result = (*it); + m_recalcBands.erase(it); + return result; + } + } + return 0; +} + +void ReportRender::recalcIfNeeded(BandDesignIntf* band){ + BandDesignIntf* recalcBand = findRecalcableBand(band); + if (recalcBand){ + QString bandName = recalcBand->objectName(); + recalcBand->restoreItems(); + recalcBand->setObjectName(recalcBand->patternItem()->objectName()); + replaceGroupsFunction(recalcBand); + recalcBand->updateItemSize(datasources()); + recalcBand->setObjectName(bandName); + datasources()->clearGroupFunctionValues(recalcBand->patternItem()->objectName()); + } +} + +void ReportRender::renderDataHeader(BandDesignIntf *header) +{ + recalcIfNeeded(header); + BandDesignIntf* renderedHeader = renderBand(header, 0); + if (containsGroupFunctions(header)) + m_recalcBands.append(renderedHeader); +} + void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* dataSource, bool firstTime) { foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::GroupHeader)){ IGroupBand* gb = dynamic_cast(band); - if (gb&&gb->isNeedToClose(m_datasources)){ + if (gb&&gb->isNeedToClose(datasources())){ if (band->childBands().count()>0){ bool didGoBack = dataSource->prior(); renderGroupFooterByHeader(band); @@ -735,17 +804,20 @@ void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* da } gb->startGroup(m_datasources); openDataGroup(band); + BandDesignIntf* renderedHeader = 0; if (!firstTime && gb->startNewPage() && !m_newPageStarted){ if (gb->resetPageNumber()) resetPageNumber(BandReset); if (band->reprintOnEachPage()){ savePage(); startNewPage(); } else { - renderBand(band, 0, ForcedStartPage); + renderedHeader = renderBand(band, 0, ForcedStartPage); } } else { - renderBand(band, 0, StartNewPageAsNeeded); + renderedHeader = renderBand(band, 0, StartNewPageAsNeeded); } + if (containsGroupFunctions(band)) + m_recalcBands.append(renderedHeader); } renderGroupHeader(band, dataSource, firstTime); @@ -781,6 +853,7 @@ void ReportRender::initGroups() if (band->isHeader()){ IGroupBand* gb = dynamic_cast(band); if (gb) gb->closeGroup(); + extractGroupFunctions(band); } } } @@ -828,7 +901,7 @@ void ReportRender::closeGroup(BandDesignIntf *band) bl->clear(); delete bl; } - it++; + ++it; } m_childBands.remove(band); @@ -858,9 +931,10 @@ void ReportRender::closeDataGroup(BandDesignIntf *band) if ((*it)->bandIndex()>band->bandIndex()) it = m_reprintableBands.erase(it); else - it++; + ++it; } } + recalcIfNeeded(band); closeGroup(band); } @@ -949,8 +1023,10 @@ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) m_currentColumn = m_currentColumn == -1 ? 0: m_currentColumn; - if ( (isMultiColumnHeader(band) && band->height() <= m_maxHeightByColumn[0]) || - (band->height() <= m_maxHeightByColumn[m_currentColumn])){ + if ( (band->height() <= m_maxHeightByColumn[m_currentColumn]) || + m_patternPageItem->endlessHeight() || + (isMultiColumnHeader(band) && (band->height() <= m_maxHeightByColumn[0])) + ){ if ( (band->bandType() == BandDesignIntf::PageFooter) ){ for (int i=0; i < m_maxHeightByColumn.size(); ++i) @@ -997,6 +1073,14 @@ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) if (band->isData()) m_renderedDataBandCount++; band->setObjectName(band->objectName()+QString::number(++m_currentNameIndex)); renameChildItems(band); + if (m_lastDataBand){ +#ifdef HAVE_QT4 + m_lastDataBand->metaObject()->invokeMethod(m_lastDataBand,"bandRegistred"); +#endif +#ifdef HAVE_QT5 + emit m_lastDataBand->bandRegistred(); +#endif + } return true; } else return false; } @@ -1031,52 +1115,83 @@ BandDesignIntf* ReportRender::sliceBand(BandDesignIntf *band, BandDesignIntf* pa if (band->isEmpty()) { delete band; band = 0; - } return band; } +void ReportRender::updateTOC(BaseDesignIntf* item, int pageNumber){ + BookmarkContainerDesignIntf* bookmarkContainer = dynamic_cast(item); + if (bookmarkContainer){ + TableOfContents* toc = m_scriptEngineContext->tableOfContents(); + foreach (QString key, bookmarkContainer->bookmarks()){ + toc->setItem(key, bookmarkContainer->getBookMark(key).toString(), pageNumber); + } + } +} + void ReportRender::secondRenderPass(ReportPages renderedPages) { + if (!m_scriptEngineContext->tableOfContents()->isEmpty()){ + for(int i=0; ichildBaseItems()){ + updateTOC(item, m_pagesRanges.findPageNumber(i)); + } + } + } + for(int i=0; isetReportVariable("#PAGE_COUNT",findLastPageNumber(i)); + m_datasources->setReportVariable("#PAGE",m_pagesRanges.findPageNumber(i)); + m_datasources->setReportVariable("#PAGE_COUNT",m_pagesRanges.findLastPageNumber(i)); foreach(BaseDesignIntf* item, page->childBaseItems()){ item->updateItemSize(m_datasources, SecondPass); } -// foreach(BandDesignIntf* band, page->childBands()){ -// band->updateItemSize(m_datasources, SecondPass); -// } } } +void ReportRender::createTOCMarker(bool startNewRange) +{ + m_pagesRanges.addTOCMarker(startNewRange); +} + BandDesignIntf *ReportRender::saveUppperPartReturnBottom(BandDesignIntf *band, int height, BandDesignIntf* patternBand) { int sliceHeight = height; BandDesignIntf* upperBandPart = dynamic_cast(band->cloneUpperPart(sliceHeight)); BandDesignIntf* bottomBandPart = dynamic_cast(band->cloneBottomPart(sliceHeight)); if (!bottomBandPart->isEmpty()){ - //bottomBandPart->updateItemSize(FirstPass,height); if (patternBand->keepFooterTogether()) closeFooterGroup(patternBand); + if (upperBandPart->isEmpty()) + bottomBandPart->copyBookmarks(band); } if (!upperBandPart->isEmpty()){ upperBandPart->updateItemSize(m_datasources, FirstPass, height); registerBand(upperBandPart); + upperBandPart->copyBookmarks(band); } else delete upperBandPart; if (band->columnsCount()>1 && (band->columnsFillDirection()==BandDesignIntf::Vertical || band->columnsFillDirection()==BandDesignIntf::VerticalUniform)){ - startNewColumn(); + startNewColumn(); + if (patternBand->bandHeader() && + patternBand->bandHeader()->columnsCount()>1 && + !m_lostHeadersMoved && + patternBand->bandNestingLevel() == 0 + ){ + renderBand(patternBand->bandHeader(), 0, StartNewPageAsNeeded); + } + } else { savePage(); startNewPage(); } -// if (!bottomBandPart->isEmpty() && patternBand->keepFooterTogether()) -// openFooterGroup(patternBand); + delete band; return bottomBandPart; } @@ -1085,15 +1200,21 @@ BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand) { BandDesignIntf* bandClone = dynamic_cast(patternBand->cloneItem(PreviewMode)); - baseDesignIntfToScript(bandClone); + m_scriptEngineContext->baseDesignIntfToScript(patternBand->parent()->objectName(), bandClone); + m_scriptEngineContext->setCurrentBand(bandClone); emit(patternBand->beforeRender()); if (patternBand->isFooter()){ replaceGroupsFunction(bandClone); } + + if (patternBand->isHeader()){ + replaceGroupsFunction(bandClone); + } + bandClone->updateItemSize(m_datasources); - baseDesignIntfToScript(bandClone); + //m_scriptEngineContext->baseDesignIntfToScript(bandClone); emit(patternBand->afterData()); return bandClone; @@ -1102,32 +1223,38 @@ BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand) void ReportRender::startNewColumn(){ if (m_currentColumn < m_maxHeightByColumn.size()-1){ m_currentColumn++; + checkLostHeadersInPrevColumn(); } else { savePage(); startNewPage(); } } -void ReportRender::startNewPage() +void ReportRender::startNewPage(bool isFirst) { m_renderPageItem = 0; m_newPageStarted = true; initColumns(); initRenderPage(); - baseDesignIntfToScript(m_renderPageItem); + m_scriptEngineContext->baseDesignIntfToScript(m_renderPageItem->patternName(), m_renderPageItem); emit m_patternPageItem->beforeRender(); m_renderPageItem->setObjectName(QLatin1String("ReportPage")+QString::number(m_pageCount)); - m_maxHeightByColumn[m_currentColumn]=m_renderPageItem->pageRect().height(); - m_currentStartDataPos[m_currentColumn]=m_patternPageItem->topMargin()*Const::mmFACTOR; - m_currentIndex=0; + m_maxHeightByColumn[m_currentColumn] = m_renderPageItem->pageRect().height(); + m_currentStartDataPos[m_currentColumn] = m_patternPageItem->topMargin() * Const::mmFACTOR; + m_currentIndex = 0; + + if (isFirst) { + renderReportHeader(m_patternPageItem, BeforePageHeader); + emit m_patternPageItem->beforeFirstPageRendered(); + } renderPageHeader(m_patternPageItem); m_pageFooterHeight = calcPageFooterHeight(m_patternPageItem)+2; m_maxHeightByColumn[m_currentColumn] -= m_pageFooterHeight; - m_currentIndex=10; + m_currentIndex = 10; m_dataAreaSize = m_maxHeightByColumn[m_currentColumn]; m_renderedDataBandCount = 0; @@ -1142,28 +1269,11 @@ void ReportRender::startNewPage() void ReportRender::resetPageNumber(ResetPageNuberType resetType) { - PagesRange range; - if (!m_ranges.isEmpty()){ - m_ranges.last().lastPage = (resetType == BandReset)? m_pageCount : m_pageCount-1; - range.firstPage = m_pageCount+((resetType == BandReset)? 1 : 0); - } else { - range.firstPage = m_pageCount; - } - range.lastPage = (resetType == BandReset)? 0 : m_pageCount; - m_ranges.append(range); + m_pagesRanges.startNewRange(); if (resetType == PageReset) m_datasources->setReportVariable("#PAGE",1); } -int ReportRender::findLastPageNumber(int currentPage) -{ - foreach (PagesRange range, m_ranges) { - if ( range.firstPage<= (currentPage) && range.lastPage>= (currentPage) ) - return (range.lastPage-(range.firstPage))+1; - } - return 0; -} - void ReportRender::cutGroups() { m_popupedExpression.clear(); @@ -1243,12 +1353,51 @@ void ReportRender::checkLostHeadersOnPrevPage() } if (lostHeaders.size() > 0){ + m_lostHeadersMoved = true; qSort(lostHeaders.begin(), lostHeaders.end(), bandLessThen); foreach(BandDesignIntf* header, lostHeaders){ registerBand(header); } + } else { + m_lostHeadersMoved = false; } + +} + +void ReportRender::checkLostHeadersInPrevColumn() +{ + QVector lostHeaders; + + QMutableListIteratorit(m_renderPageItem->bands()); + + it.toBack(); + if (it.hasPrevious()){ + if (it.previous()->isFooter()){ + if (it.hasPrevious()) it.previous(); + else return; + } + } + + while (it.hasPrevious()){ + if (it.value()->isHeader()){ + if (it.value()->reprintOnEachPage()){ + delete it.value(); + } else { lostHeaders.append(it.value());} + it.remove(); + it.previous(); + } else break; + } + + if (lostHeaders.size() > 0){ + m_lostHeadersMoved = true; + qSort(lostHeaders.begin(), lostHeaders.end(), bandLessThen); + foreach(BandDesignIntf* header, lostHeaders){ + registerBand(header); + } + } else { + m_lostHeadersMoved = false; + } } BandDesignIntf* ReportRender::findEnclosingGroup() @@ -1270,6 +1419,10 @@ BandDesignIntf* ReportRender::findEnclosingGroup() void ReportRender::savePage(bool isLast) { + if (m_renderPageItem->isTOC()) + m_pagesRanges.addTOCPage(); + else + m_pagesRanges.addPage(); m_datasources->setReportVariable("#IS_LAST_PAGEFOOTER",isLast); m_datasources->setReportVariable("#IS_FIRST_PAGEFOOTER",m_datasources->variable("#PAGE").toInt()==1); @@ -1291,14 +1444,12 @@ void ReportRender::savePage(bool isLast) } } - if (m_ranges.last().lastPage==0 && m_ranges.count()>1) { + if (m_pagesRanges.currentRange(m_patternPageItem->isTOC()).firstPage == 0) { m_datasources->setReportVariable("#PAGE",1); } else { m_datasources->setReportVariable("#PAGE",m_datasources->variable("#PAGE").toInt()+1); } - m_ranges.last().lastPage = m_pageCount; - BandDesignIntf* pageFooter = m_renderPageItem->bandByType(BandDesignIntf::PageFooter); if (pageFooter) pageFooter->setBandIndex(++m_currentIndex); m_renderedPages.append(PageItemDesignIntf::Ptr(m_renderPageItem)); @@ -1313,8 +1464,18 @@ void ReportRender::savePage(bool isLast) } m_renderPageItem->placeTearOffBand(); + m_scriptEngineContext->setCurrentPage(m_renderPageItem); emit m_patternPageItem->afterRender(); - + if (isLast) + emit m_patternPageItem->afterLastPageRendered(); + if (isLast && m_patternPageItem->endlessHeight()){ + qreal pageHeight = 0; + foreach (BandDesignIntf* band, m_renderPageItem->bands()) { + pageHeight += band->height(); + } + m_renderPageItem->setHeight(pageHeight + 10 + + (m_patternPageItem->topMargin() + m_patternPageItem->bottomMargin()) * Const::mmFACTOR); + } } QString ReportRender::toString() @@ -1334,29 +1495,96 @@ void ReportRender::cancelRender(){ m_renderCanceled = true; } -void ReportRender::baseDesignIntfToScript(BaseDesignIntf *item) +int PagesRanges::findLastPageNumber(int index) { - if ( item ) { + index++; + foreach (PagesRange range, m_ranges) { + if ( range.firstPage <= (index) && range.lastPage>= (index) ) + return (range.lastPage-(range.firstPage))+1; + } + return 0; +} - if (item->metaObject()->indexOfSignal("beforeRender()")!=-1) - item->disconnect(SIGNAL(beforeRender())); - if (item->metaObject()->indexOfSignal("afterData()")!=-1) - item->disconnect(SIGNAL(afterData())); - if (item->metaObject()->indexOfSignal("afterRender()")!=-1) - item->disconnect(SIGNAL(afterRender())); +int PagesRanges::findPageNumber(int index) +{ + index++; + foreach (PagesRange range, m_ranges) { + if ( range.firstPage <= (index) && range.lastPage >= (index) ) + return (index - range.firstPage)+1; + } + return 0; +} - QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine(); - QScriptValue sItem = engine->globalObject().property(item->patternName()); - if (sItem.isValid()){ - engine->newQObject(sItem, item); +PagesRange&PagesRanges::currentRange(bool isTOC) +{ + Q_ASSERT( (isTOC && m_TOCRangeIndex!=-1) || !isTOC); + if (isTOC && m_TOCRangeIndex !=-1) return m_ranges[m_TOCRangeIndex]; + return m_ranges.last(); +} + +void PagesRanges::startNewRange(bool isTOC) +{ + PagesRange range; + if (!m_ranges.isEmpty()){ + range.firstPage = 0; + range.lastPage = m_ranges.last().lastPage + 1; + } else { + range.firstPage = 0; + range.lastPage = 0; + } + range.isTOC = isTOC; + m_ranges.append(range); + if (isTOC) m_TOCRangeIndex = m_ranges.size()-1; +} + +void PagesRanges::addTOCMarker(bool addNewRange) +{ + if ( addNewRange || m_ranges.isEmpty()){ + startNewRange(true); + } else { + m_TOCRangeIndex = m_ranges.size()-1; + m_ranges.last().isTOC = true; + } +} + +void PagesRanges::addPage() +{ + if (m_ranges.isEmpty()) startNewRange(); + if (m_ranges.last().firstPage == 0){ + m_ranges.last().firstPage = m_ranges.last().lastPage == 0 ? 1 : m_ranges.last().lastPage; + m_ranges.last().lastPage = m_ranges.last().lastPage == 0 ? 1 : m_ranges.last().lastPage; + } else { + m_ranges.last().lastPage++; + } +} + +void PagesRanges::shiftRangesNextToTOC(){ + for(int i = m_TOCRangeIndex+1; i < m_ranges.size(); ++i){ + m_ranges[i].firstPage++; + m_ranges[i].lastPage++; + } +} + +void PagesRanges::addTOCPage() +{ + Q_ASSERT(m_TOCRangeIndex != -1); + if (m_TOCRangeIndex != -1){ + PagesRange& tocRange = m_ranges[m_TOCRangeIndex]; + if (tocRange.firstPage == 0) { + tocRange.firstPage = tocRange.lastPage == 0 ? 1 : tocRange.lastPage; + tocRange.lastPage = tocRange.lastPage == 0 ? 1 : tocRange.lastPage; + if (tocRange.firstPage == 1 && tocRange.lastPage == 1) + shiftRangesNextToTOC(); } else { - sItem = engine->newQObject(item); - engine->globalObject().setProperty(item->patternName(),sItem); - } - foreach(BaseDesignIntf* child, item->childBaseItems()){ - baseDesignIntfToScript(child); + tocRange.lastPage++; + shiftRangesNextToTOC(); } } } +void PagesRanges::clear() +{ + m_ranges.clear(); } + +} // namespace LimeReport diff --git a/limereport/lrreportrender.h b/limereport/lrreportrender.h index 7f3bcef..d31efce 100644 --- a/limereport/lrreportrender.h +++ b/limereport/lrreportrender.h @@ -61,6 +61,25 @@ private: struct PagesRange{ int firstPage; int lastPage; + bool isTOC; +}; + +class PagesRanges{ +public: + PagesRanges(): m_TOCRangeIndex(-1) {} + int findLastPageNumber(int index); + int findPageNumber(int index); + PagesRange& currentRange(bool isTOC); + void startNewRange(bool isTOC = false); + void addTOCMarker(bool addNewRange); + void addPage(); + void addTOCPage(); + void clear(); +private: + void shiftRangesNextToTOC(); +private: + QVector m_ranges; + int m_TOCRangeIndex; }; class ReportRender: public QObject @@ -71,6 +90,7 @@ public: enum DataRenderMode {StartNewPageAsNeeded, NotStartNewPage, ForcedStartPage}; enum BandPrintMode {PrintAlwaysPrintable, PrintNotAlwaysPrintable }; enum ResetPageNuberType{BandReset, PageReset}; + enum PageRenderStage{BeforePageHeader, AfterPageHeader}; typedef QSharedPointer Ptr; ~ReportRender(); ReportRender(QObject *parent = 0); @@ -79,46 +99,51 @@ public: DataSourceManager* datasources(){return m_datasources;} int pageCount(); PageItemDesignIntf::Ptr pageAt(int index); - QString renderPageToString(PageDesignIntf *patternPage); - ReportPages renderPageToPages(PageDesignIntf *patternPage); + QString renderPageToString(PageItemDesignIntf *patternPage); + ReportPages renderPageToPages(PageItemDesignIntf *patternPage); + ReportPages renderTOC(PageItemDesignIntf *patternPage, bool first, bool resetPages); void secondRenderPass(ReportPages renderedPages); + void createTOCMarker(bool startNewRange); signals: void pageRendered(int renderedPageCount); public slots: void cancelRender(); private: - void baseDesignIntfToScript(BaseDesignIntf* item); - void renderPage(PageDesignIntf *patternPage); void initDatasources(); void initDatasource(const QString &name); void initRenderPage(); -#ifdef HAVE_UI_LOADER - void initDialogs(); -#endif void initVariables(); - bool runInitScript(); + void initGroups(); void clearPageMap(); + + void renderPage(PageItemDesignIntf *patternPage, bool isTOC = false, bool isFirst = false, bool resetPageNumbers = false); BandDesignIntf* renderBand(BandDesignIntf *patternBand, BandDesignIntf *bandData, DataRenderMode mode = NotStartNewPage, bool isLast = false); void renderDataBand(BandDesignIntf* dataBand); void renderPageHeader(PageItemDesignIntf* patternPage); + void renderReportHeader(PageItemDesignIntf* patternPage, PageRenderStage stage); void renderPageFooter(PageItemDesignIntf* patternPage); - void moveTearOffBand(); void renderPageItems(PageItemDesignIntf* patternPage); - qreal calcPageFooterHeight(PageItemDesignIntf* patternPage); - qreal calcSlicePercent(qreal height); void renderChildHeader(BandDesignIntf* parent, BandPrintMode printMode); void renderChildFooter(BandDesignIntf* parent, BandPrintMode printMode); void renderChildBands(BandDesignIntf* parentBand); + void recalcIfNeeded(BandDesignIntf *band); + void renderDataHeader(BandDesignIntf* header); void renderGroupHeader(BandDesignIntf* parentBand, IDataSource* dataSource, bool firstTime); void renderGroupFooter(BandDesignIntf* parentBand); - void initGroups(); - void extractGroupFuntionsFromItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band); + void moveTearOffBand(); + qreal calcPageFooterHeight(PageItemDesignIntf* patternPage); + qreal calcSlicePercent(qreal height); + + bool containsGroupFunctions(BandDesignIntf* band); + void extractGroupFuntionsFromItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band); void extractGroupFunctionsFromContainer(BaseDesignIntf* baseItem, BandDesignIntf* band); void extractGroupFunctions(BandDesignIntf* band); void replaceGroupFunctionsInItem(ContentItemDesignIntf* contentItem, BandDesignIntf* band); void replaceGroupFunctionsInContainer(BaseDesignIntf* baseItem, BandDesignIntf* band); void replaceGroupsFunction(BandDesignIntf* band); + BandDesignIntf *findRecalcableBand(BandDesignIntf *patternBand); + void popPageFooterGroupValues(BandDesignIntf* dataBand); void pushPageFooterGroupValues(BandDesignIntf* dataBand); @@ -132,6 +157,7 @@ private: void checkFooterGroup(BandDesignIntf* groupBand); void pasteGroups(); void checkLostHeadersOnPrevPage(); + void checkLostHeadersInPrevColumn(); BandDesignIntf* findEnclosingGroup(); bool registerBand(BandDesignIntf* band, bool registerInChildren=true); @@ -140,9 +166,10 @@ private: BandDesignIntf* saveUppperPartReturnBottom(BandDesignIntf *band, int height, BandDesignIntf *patternBand); BandDesignIntf* renderData(BandDesignIntf* patternBand); void startNewColumn(); - void startNewPage(); + void startNewPage(bool isFirst = false); void resetPageNumber(ResetPageNuberType resetType); - int findLastPageNumber(int currentPage); + //int findLastPageNumber(int currentPage); + //int findPageNumber(int currentPage); void savePage(bool isLast = false); QString toString(); void initColumns(); @@ -154,8 +181,9 @@ private: qreal maxColumnHeight(); void renameChildItems(BaseDesignIntf *item); void renderGroupFooterByHeader(BandDesignIntf *groupHeader); + void updateTOC(BaseDesignIntf* item, int pageNumber); + //PagesRange& currentRange(bool isTOC = false){ return (isTOC) ? m_ranges.first(): m_ranges.last();} void placeBandOnPage(BandDesignIntf *band, int columnIndex); - private: DataSourceManager* m_datasources; ScriptEngineContext* m_scriptEngineContext; @@ -164,10 +192,8 @@ private: QList m_renderedPages; QMultiMap< BandDesignIntf*, GroupBandsHolder* > m_childBands; QList m_reprintableBands; -// QList m_lastRenderedHeaders; + QList m_recalcBands; - //int m_maxHeightByColumn[0]; - //int m_currentStartDataPos; int m_currentIndex; int m_pageCount; @@ -185,10 +211,11 @@ private: QVector m_maxHeightByColumn; QVector m_currentStartDataPos; int m_currentColumn; - QList m_ranges; + PagesRanges m_pagesRanges; QVector m_columnedBandItems; unsigned long long m_currentNameIndex; - bool m_newPageStarted; + bool m_newPageStarted; + bool m_lostHeadersMoved; }; } // namespace LimeReport diff --git a/limereport/lrreporttranslation.cpp b/limereport/lrreporttranslation.cpp new file mode 100644 index 0000000..aa6cfdd --- /dev/null +++ b/limereport/lrreporttranslation.cpp @@ -0,0 +1,142 @@ +#include "lrreporttranslation.h" + +#include "lrbasedesignintf.h" +#include "lrpagedesignintf.h" + +namespace LimeReport{ + +ReportTranslation::ReportTranslation(QLocale::Language language, QList pages) + : m_language(language) +{ + foreach (PageDesignIntf* page, pages){ + m_pagesTranslation.append(createPageTranslation(page)); + } +} + +ReportTranslation::ReportTranslation(const ReportTranslation& reportTranslation) + :m_language(reportTranslation.m_language) +{ + foreach(PageTranslation* pageTranslation, reportTranslation.m_pagesTranslation){ + m_pagesTranslation.append(pageTranslation); + } +} + +ReportTranslation::~ReportTranslation() +{ + foreach(PageTranslation* page, m_pagesTranslation){ + delete page; + } + m_pagesTranslation.clear(); +} + +PageTranslation* ReportTranslation::createPageTranslation(PageDesignIntf* page) +{ + PageTranslation* pageTranslation = new PageTranslation; + pageTranslation->pageName = page->pageItem()->objectName(); + foreach(BaseDesignIntf* item, page->pageItem()->allChildBaseItems()){ + createItemTranslation(item, pageTranslation); + } + return pageTranslation; +} + +void ReportTranslation::createItemTranslation(BaseDesignIntf* item, PageTranslation* pageTranslation){ + QMap stringsForTranslation = item->getStringForTranslation(); + if (!stringsForTranslation.isEmpty()){ + ItemTranslation* itemTranslation = new ItemTranslation; + itemTranslation->itemName = item->objectName(); + foreach(QString propertyName, stringsForTranslation.keys()){ + PropertyTranslation* propertyTranslation = new PropertyTranslation; + propertyTranslation->propertyName = propertyName; + propertyTranslation->value = stringsForTranslation.value(propertyName); + propertyTranslation->sourceValue = stringsForTranslation.value(propertyName); + propertyTranslation->checked = false; + propertyTranslation->sourceHasBeenChanged = false; + itemTranslation->propertyesTranslation.append(propertyTranslation); + } + pageTranslation->itemsTranslation.insert(itemTranslation->itemName, itemTranslation); + } +} + +PageTranslation* ReportTranslation::findPageTranslation(const QString& page_name) +{ + foreach(PageTranslation* page, m_pagesTranslation){ + if (page->pageName.compare(page_name) == 0){ + return page; + } + } + return 0; +} + +void ReportTranslation::updatePageTranslation(PageDesignIntf* page) +{ + PageTranslation* pageTranslation = findPageTranslation(page->pageItem()->objectName()); + if (!pageTranslation){ + pageTranslation = createPageTranslation(page); + m_pagesTranslation.append(pageTranslation); + } + if (pageTranslation){ + foreach(BaseDesignIntf* item, page->pageItem()->allChildBaseItems()){ + QMap stringsForTranslation = item->getStringForTranslation(); + if (!stringsForTranslation.isEmpty()){ + ItemTranslation* itemTranslation = pageTranslation->itemsTranslation.value(item->objectName()); + if (itemTranslation){ + foreach(QString propertyName, stringsForTranslation.keys()){ + PropertyTranslation* propertyTranslation = itemTranslation->findProperty(propertyName); + bool translated = propertyTranslation->sourceValue != propertyTranslation->value; + if (propertyTranslation->checked) + propertyTranslation->sourceHasBeenChanged = propertyTranslation->sourceValue != stringsForTranslation.value(propertyName); + if (propertyTranslation->sourceHasBeenChanged) + propertyTranslation->checked = false; + propertyTranslation->sourceValue = stringsForTranslation.value(propertyName); + if (!translated) propertyTranslation->value = propertyTranslation->sourceValue; + } + } else { + createItemTranslation(item, pageTranslation); + } + } + } + } +} + +QList ReportTranslation::pagesTranslation() const +{ + return m_pagesTranslation; +} + +PageTranslation*ReportTranslation::createEmptyPageTranslation() +{ + PageTranslation* pageTranslation = new PageTranslation; + m_pagesTranslation.append(pageTranslation); + return pageTranslation; +} + +QLocale::Language ReportTranslation::language() const +{ + return m_language; +} + +PropertyTranslation* ItemTranslation::findProperty(const QString& propertyName) +{ + foreach(PropertyTranslation* propertyTranslation, propertyesTranslation){ + if (propertyTranslation->propertyName.compare(propertyName) == 0){ + return propertyTranslation; + } + } + return 0; +} + +ItemTranslation::~ItemTranslation() +{ + foreach(PropertyTranslation* property, propertyesTranslation){ + delete property; + } +} + +PageTranslation::~PageTranslation() +{ + foreach(ItemTranslation* item, itemsTranslation){ + delete item; + } +} + +} //namespace LimeReport diff --git a/limereport/lrreporttranslation.h b/limereport/lrreporttranslation.h new file mode 100644 index 0000000..3c7b376 --- /dev/null +++ b/limereport/lrreporttranslation.h @@ -0,0 +1,81 @@ +#ifndef REPORTTRANSLATION_H +#define REPORTTRANSLATION_H + +#include +#include +#include +#include + +#include "lrpagedesignintf.h" + + +class ATranslationProperty{ +public: + ATranslationProperty(){} + ATranslationProperty(const ACollectionProperty& ){} + virtual ~ATranslationProperty(){} +}; + +Q_DECLARE_METATYPE(ATranslationProperty) +const int TRANSLATION_TYPE_ID = qMetaTypeId(); + +namespace LimeReport{ + +struct PropertyTranslation{ + QString propertyName; + QString value; + QString sourceValue; + bool checked; + bool sourceHasBeenChanged; +}; + +struct ItemTranslation{ + QString itemName; + PropertyTranslation* findProperty(const QString& propertyName); + ~ItemTranslation(); + QList propertyesTranslation; +}; + +struct PageTranslation{ + QString pageName; + ~PageTranslation(); + QHash itemsTranslation; +}; + +class ReportTranslation{ +public: + ReportTranslation(QLocale::Language language) :m_language(language){} + ReportTranslation(QLocale::Language language, QList pages); + ReportTranslation(const ReportTranslation& reportTranslation); + ~ReportTranslation(); + QLocale::Language language() const; + QList pagesTranslation() const; + PageTranslation* createEmptyPageTranslation(); + void updatePageTranslation(PageDesignIntf* page); + PageTranslation* findPageTranslation(const QString& page_name); + void createItemTranslation(BaseDesignIntf* item, PageTranslation* pageTranslation); +private: + PageTranslation* createPageTranslation(PageDesignIntf* page); +private: + QLocale::Language m_language; + QList m_pagesTranslation; +}; + + +typedef QMap Translations; + +class ITranslationContainer{ +public: + virtual ~ITranslationContainer(){} + virtual Translations* translations() = 0; + virtual void updateTranslations() = 0; + virtual bool addTranslationLanguage(QLocale::Language language) = 0; + virtual bool removeTranslationLanguage(QLocale::Language language) = 0; + virtual QList aviableLanguages() = 0; +}; + +} // namespace LimeReport + +//Q_DECLARE_METATYPE(ReportTranslation) + +#endif // REPORTTRANSLATION_H diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp index 720df9d..cb6e219 100644 --- a/limereport/lrscriptenginemanager.cpp +++ b/limereport/lrscriptenginemanager.cpp @@ -31,23 +31,32 @@ #include #include +#include +#ifdef USE_QTSCRIPTENGINE #include +#endif +#include #ifdef HAVE_UI_LOADER #include #include #include #endif #include "lrdatasourcemanager.h" +#include "lrbasedesignintf.h" +#include "lrbanddesignintf.h" +#include "lrpageitemdesignintf.h" Q_DECLARE_METATYPE(QColor) Q_DECLARE_METATYPE(QFont) Q_DECLARE_METATYPE(LimeReport::ScriptEngineManager *) +#ifdef USE_QTSCRIPTENGINE QScriptValue constructColor(QScriptContext *context, QScriptEngine *engine) { QColor color(context->argument(0).toString()); return engine->toScriptValue(color); } +#endif namespace LimeReport{ @@ -181,7 +190,7 @@ void ScriptEngineModel::updateModel() beginResetModel(); m_rootNode->clear(); QMap categories; - foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescriber()){ + foreach(ScriptFunctionDesc funcDesc, m_scriptManager->functionsDescribers()){ ScriptEngineNode* categ; QString categoryName = (!funcDesc.category.isEmpty())?funcDesc.category:"NO CATEGORY"; if (categories.contains(categoryName)){ @@ -192,179 +201,9 @@ void ScriptEngineModel::updateModel() } categ->addChild(funcDesc.name,funcDesc.description,ScriptEngineNode::Function,QIcon(":/report/images/function")); } - //reset(); endResetModel(); } -QScriptValue line(QScriptContext* pcontext, QScriptEngine* pengine){ - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - QString band = pcontext->argument(0).toString(); - QScriptValue res; - QString varName = QLatin1String("line_")+band.toLower(); - if (dm->variable(varName).isValid()){ - res=pengine->newVariant(dm->variable(varName)); - } else res=pengine->newVariant(QString("Variable line for band %1 not found").arg(band)); - return res; -} - -QScriptValue setVariable(QScriptContext* pcontext, QScriptEngine* /*pengine*/){ - - QString name = pcontext->argument(0).toString(); - QVariant value = pcontext->argument(1).toVariant(); - - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - - if (dm->containsVariable(name)) - dm->changeVariable(name,value); - else - dm->addVariable(name, value); - - return QScriptValue(); -} - -QScriptValue getVariable(QScriptContext* pcontext, QScriptEngine* pengine){ - - QString name = pcontext->argument(0).toString(); - - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - QScriptValue res = pengine->newVariant(dm->variable(name)); - - return res; -} - -QScriptValue getField(QScriptContext* pcontext, QScriptEngine* pengine){ - - QString name = pcontext->argument(0).toString(); - - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - QScriptValue res = pengine->newVariant(dm->fieldData(name)); - - return res; -} - -QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f'; - int precision = (pcontext->argumentCount()>2)?pcontext->argument(2).toInt32():2; - QString locale = (pcontext->argumentCount()>3)?pcontext->argument(3).toString():""; - QScriptValue res = (locale.isEmpty())?pengine->newVariant(QString::number(value.toDouble(),format,precision)): - pengine->newVariant(QLocale(locale).toString(value.toDouble(),format,precision)); - return res; -} -#if QT_VERSION>0x040800 -QScriptValue currencyFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString locale = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().name(); - return pengine->newVariant(QLocale(locale).toCurrencyString(value.toDouble())); -} - -QScriptValue currencyUSBasedFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString CurrencySymbol = (pcontext->argumentCount()>1)?pcontext->argument(1).toString():QLocale::system().currencySymbol(); - // Format it using USA locale - QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble()); - // Replace currency symbol if necesarry - if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol); - return pengine->newVariant(vTempStr); -} -#endif -/* - * sectotimeFormat(int seconds, string format) - * - convert seconds to time format without day border! - * - * examples (base: 60 days 7 Minutes 2 Seconds = 5184422 seconds): - * (3600 * 24 * 60) + (7 * 60) + 2 seconds with format hh:mm:ss = 1440:07:02 - * (3600 * 24 * 60) + (7 * 60) + 2 seconds with format mm:s = 86407:2 - * (3600 * 24 * 60) + (7 * 60) + 2 seconds with format ss = 5184422 - */ -QScriptValue sectotimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - // simplify values - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm:ss"; - - // algorithm adapted from: https://stackoverflow.com/a/25697134/4954370 - int seconds = value.toInt(); - int minutes = seconds / 60; - int hours = minutes / 60; - - // replace the following formats: hh, mm, ss, h, m, s - bool hasHour = format.contains("h"); - bool hasMinute = format.contains("m"); - for(int len = 2; len; len--) { - if(hasHour) format.replace(QString('h').repeated(len), QString::number(hours).rightJustified(len, '0')); - if(hasMinute) format.replace(QString('m').repeated(len), QString::number(hasHour ? minutes % 60 : minutes).rightJustified(len, '0')); - format.replace(QString('s').repeated(len), QString::number(hasMinute ? seconds % 60 : seconds).rightJustified(len, '0')); - } - return QScriptValue(format); -} -QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy"; - QScriptValue res = pengine->newVariant(QLocale().toString(value.toDate(),format)); - return res; -} - -QScriptValue timeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm"; - QScriptValue res = pengine->newVariant(QLocale().toString(value.toTime(),format)); - return res; -} - -QScriptValue dateTimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ - QVariant value = pcontext->argument(0).toVariant(); - QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy hh:mm"; - QScriptValue res = pengine->newVariant(QLocale().toString(value.toDateTime(),format)); - return res; -} - -QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ - return pengine->newVariant(QDateTime::currentDateTime()); -} - -QScriptValue date(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ - return pengine->newVariant(QDate::currentDate()); -} - -QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcontext, QScriptEngine* pengine){ - - ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data()); - DataSourceManager* dm = sm->dataManager(); - - QString expression; - QString band; - - if (functionName.compare("COUNT",Qt::CaseInsensitive) == 0 && pcontext->argumentCount()==1){ - expression = " "; - band = pcontext->argument(0).toString(); - } else { - expression = dm->getExpression(pcontext->argument(0).toString()); - band = pcontext->argument(1).toString(); - } - - QScriptValue res; - GroupFunction* gf = dm->groupFunction(functionName,expression,band); - if (gf){ - if (gf->isValid()){ - res=pengine->newVariant(gf->calculate()); - }else{ - res=pengine->newVariant(gf->error()); - } - } - else { - res=pengine->newVariant(QString(QObject::tr("Function %1 not found or have wrong arguments").arg(functionName))); - } - return res; -} - -QScriptValue groupFunction(QScriptContext* pcontext, QScriptEngine* pengine){ - return callGroupFunction(pcontext->callee().property("functionName").toString(),pcontext,pengine); -} - ScriptEngineManager::~ScriptEngineManager() { delete m_model; @@ -392,6 +231,44 @@ void ScriptEngineManager::deleteFunction(const QString &functionsName) } } +bool ScriptEngineManager::addFunction(const JSFunctionDesc &functionDescriber) +{ + ScriptValueType functionManager = scriptEngine()->globalObject().property(functionDescriber.managerName()); +#ifdef USE_QJSENGINE + if (functionManager.isUndefined()){ +#else + if (!functionManager.isValid()){ +#endif + functionManager = scriptEngine()->newQObject(functionDescriber.manager()); + scriptEngine()->globalObject().setProperty( + functionDescriber.managerName(), + functionManager + ); + } + + if (functionManager.toQObject() == functionDescriber.manager()){ + ScriptValueType checkWrapper = scriptEngine()->evaluate(functionDescriber.scriptWrapper()); + if (!checkWrapper.isError()){ + ScriptFunctionDesc funct; + funct.name = functionDescriber.name(); + funct.description = functionDescriber.description(); + funct.category = functionDescriber.category(); + funct.type = ScriptFunctionDesc::Native; + m_functions.append(funct); + if (m_model) + m_model->updateModel(); + return true; + } else { + m_lastError = checkWrapper.toString(); + return false; + } + } else { + m_lastError = tr("Function manager with name \"%1\" already exists!"); + return false; + } + +} + bool ScriptEngineManager::containsFunction(const QString& functionName){ foreach (ScriptFunctionDesc funct, m_functions) { if (funct.name.compare(functionName)== 0){ @@ -401,6 +278,10 @@ bool ScriptEngineManager::containsFunction(const QString& functionName){ return false; } +#ifdef USE_QTSCRIPTENGINE +#if QT_VERSION > 0x050600 +Q_DECL_DEPRECATED +#endif bool ScriptEngineManager::addFunction(const QString& name, QScriptEngine::FunctionSignature function, const QString& category, @@ -424,23 +305,23 @@ bool ScriptEngineManager::addFunction(const QString& name, return false; } } +#endif bool ScriptEngineManager::addFunction(const QString& name, const QString& script, const QString& category, const QString& description) { - QScriptSyntaxCheckResult cr = m_scriptEngine->checkSyntax(script); - if (cr.state() == QScriptSyntaxCheckResult::Valid){ + ScriptValueType functionValue = m_scriptEngine->evaluate(script); + if (!functionValue.isError()){ ScriptFunctionDesc funct; - funct.scriptValue = m_scriptEngine->evaluate(script); + funct.scriptValue = functionValue; funct.name = name; funct.category = category; funct.description = description; funct.type = ScriptFunctionDesc::Script; - funct.scriptValue.setData(m_scriptEngine->toScriptValue(this)); m_functions.append(funct); m_model->updateModel(); return true; } else { - m_lastError = cr.errorMessage(); + m_lastError = functionValue.toString(); return false; } } @@ -455,22 +336,30 @@ QStringList ScriptEngineManager::functionsNames() } void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){ - if (m_dataManager != dataManager){ + if (dataManager && m_dataManager != dataManager){ m_dataManager = dataManager; if (m_dataManager){ foreach(QString func, m_dataManager->groupFunctionNames()){ - if (isFunctionExists(func)) deleteFunction(func); - addFunction(func, groupFunction,tr("GROUP FUNCTIONS"), func+"(\""+tr("Value")+"\",\""+tr("BandName")+"\")"); - } - foreach(ScriptFunctionDesc func, m_functions){ - if (func.type==ScriptFunctionDesc::Native) - m_scriptEngine->globalObject().setProperty(func.name,func.scriptValue); + JSFunctionDesc describer( + func, + tr("GROUP FUNCTIONS"), + func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")", + LimeReport::Const::FUNCTION_MANAGER_NAME, + m_functionManager, + QString("function %1(fieldName, bandName, pageitem){\ + if (typeof pageitem == 'undefined') return %2.calcGroupFunction(\"%1\", fieldName, bandName); \ + else return %2.calcGroupFunction(\"%1\", fieldName, bandName, pageitem);}" + ).arg(func) + .arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + addFunction(describer); } + moveQObjectToScript(new DatasourceFunctions(dataManager), LimeReport::Const::DATAFUNCTIONS_MANAGER_NAME); } } } -QString ScriptEngineManager::expandUserVariables(QString context, RenderPass pass, ExpandType expandType, QVariant &varValue) +QString ScriptEngineManager::expandUserVariables(QString context, RenderPass /* pass */, ExpandType expandType, QVariant &varValue) { QRegExp rx(Const::VARIABLE_RX); if (context.contains(rx)){ @@ -480,22 +369,22 @@ QString ScriptEngineManager::expandUserVariables(QString context, RenderPass pas pos += rx.matchedLength(); if (dataManager()->containsVariable(variable) ){ try { - if (pass==dataManager()->variablePass(variable)){ - varValue = dataManager()->variable(variable); - switch (expandType){ - case EscapeSymbols: - context.replace(rx.cap(0),escapeSimbols(varValue.toString())); - break; - case NoEscapeSymbols: - context.replace(rx.cap(0),varValue.toString()); - break; - case ReplaceHTMLSymbols: - context.replace(rx.cap(0),replaceHTMLSymbols(varValue.toString())); - break; - } - pos=0; + + varValue = dataManager()->variable(variable); + switch (expandType){ + case EscapeSymbols: + context.replace(rx.cap(0),escapeSimbols(varValue.toString())); + break; + case NoEscapeSymbols: + context.replace(rx.cap(0),varValue.toString()); + break; + case ReplaceHTMLSymbols: + context.replace(rx.cap(0),replaceHTMLSymbols(varValue.toString())); + break; } - } catch (ReportError e){ + pos=0; + + } catch (ReportError &e){ dataManager()->putError(e.what()); if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings()) context.replace(rx.cap(0),e.what()); @@ -528,7 +417,7 @@ QString ScriptEngineManager::expandDataFields(QString context, ExpandType expand QString fieldValue; varValue = dataManager()->fieldData(field); if (expandType == EscapeSymbols) { - if (dataManager()->fieldData(field).isNull()) { + if (varValue.isNull()) { fieldValue="\"\""; } else { fieldValue = escapeSimbols(varValue.toString()); @@ -555,7 +444,7 @@ QString ScriptEngineManager::expandDataFields(QString context, ExpandType expand } else { QString error; if (reportItem){ - error = QString("Field %1 not found in %2 !!! ").arg(field).arg(reportItem->objectName()); + error = tr("Field %1 not found in %2!").arg(field).arg(reportItem->objectName()); dataManager()->putError(error); } varValue = QVariant(); @@ -579,16 +468,24 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, if (ScriptEngineManager::instance().dataManager()!=dataManager()) ScriptEngineManager::instance().setDataManager(dataManager()); - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); if (reportItem){ - QScriptValue svThis = se->globalObject().property("THIS"); + + ScriptValueType svThis; + +#ifdef USE_QJSENGINE + svThis = getJSValue(*se, reportItem); + se->globalObject().setProperty("THIS",svThis); +#else + svThis = se->globalObject().property("THIS"); if (svThis.isValid()){ se->newQObject(svThis, reportItem); } else { svThis = se->newQObject(reportItem); se->globalObject().setProperty("THIS",svThis); } +#endif } ScriptExtractor scriptExtractor(context); @@ -596,16 +493,26 @@ QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, for(int i=0; ievaluate(scriptBody); + ScriptValueType value = se->evaluate(scriptBody); +#ifdef USE_QJSENGINE + if (!value.isError()){ + varValue = value.toVariant(); + context.replace(scriptExtractor.scriptAt(i),value.toString()); + } else { + context.replace(scriptExtractor.scriptAt(i),value.toString()); + } +#else if (!se->hasUncaughtException()) { varValue = value.toVariant(); context.replace(scriptExtractor.scriptAt(i),value.toString()); } else { context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString()); } +#endif } } } + return context; } @@ -619,14 +526,18 @@ QVariant ScriptEngineManager::evaluateScript(const QString& script){ if (ScriptEngineManager::instance().dataManager()!=dataManager()) ScriptEngineManager::instance().setDataManager(dataManager()); - QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); ScriptExtractor scriptExtractor(script); if (scriptExtractor.parse()){ QString scriptBody = expandDataFields(scriptExtractor.bodyAt(0),EscapeSymbols, varValue, 0); scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue); - QScriptValue value = se->evaluate(scriptBody); + ScriptValueType value = se->evaluate(scriptBody); +#ifdef USE_QJSENGINE + if (!value.isError()){ +#else if (!se->hasUncaughtException()) { +#endif return value.toVariant(); } } @@ -634,35 +545,417 @@ QVariant ScriptEngineManager::evaluateScript(const QString& script){ return QVariant(); } +void ScriptEngineManager::addBookMark(const QString& uniqKey, const QString& content){ + Q_ASSERT(m_context != 0); + if (m_context){ + BandDesignIntf* currentBand = m_context->getCurrentBand(); + if (currentBand) + currentBand->addBookmark(uniqKey, content); + else if (m_context->getCurrentPage()) { + m_context->getCurrentPage()->addBookmark(uniqKey, content); + } + } + +} + +int ScriptEngineManager::findPageIndexByBookmark(const QString &uniqKey) +{ + for (int i=0; i < m_context->reportPages()->size(); ++i){ + if (m_context->reportPages()->at(i)->bookmarks().contains(uniqKey)) + return i+1; + foreach(BandDesignIntf* band, m_context->reportPages()->at(i)->bands()){ + if (band->bookmarks().contains(uniqKey)) + return i+1; + } + } + return -1; +} + +void ScriptEngineManager::addTableOfContentsItem(const QString& uniqKey, const QString& content, int indent) +{ + Q_ASSERT(m_context != 0); + if (m_context){ + m_context->tableOfContents()->setItem(uniqKey, content, 0, indent); + addBookMark(uniqKey, content); + } +} + +void ScriptEngineManager::clearTableOfContents(){ + if (m_context) { + if (m_context->tableOfContents()) + m_context->tableOfContents()->clear(); + } +} + +ScriptValueType ScriptEngineManager::moveQObjectToScript(QObject* object, const QString objectName) +{ + + ScriptValueType obj = scriptEngine()->globalObject().property(objectName); + if (!obj.isNull()) delete obj.toQObject(); + ScriptValueType result = scriptEngine()->newQObject(object); + scriptEngine()->globalObject().setProperty(objectName, result); + return result; +} + void ScriptEngineManager::updateModel() { } -ScriptEngineManager::ScriptEngineManager() - :m_model(0), m_dataManager(0) +bool ScriptEngineManager::createLineFunction() { - m_scriptEngine = new QScriptEngine; + JSFunctionDesc fd; - //addFunction("dateToStr",dateToStr,"DATE", "dateToStr(\"value\",\"format\")"); - addFunction("line",line,tr("SYSTEM"), "line(\""+tr("BandName")+"\")"); - addFunction("numberFormat",numberFormat,tr("NUMBER"), "numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+ - tr("Precision")+"\",\""+ - tr("Locale")+"\")"); - addFunction("sectotimeFormat",sectotimeFormat,tr("DATE&TIME"), "sectotimeFormat(\""+tr("Seconds")+"\",\""+tr("Format")+"\")"); - addFunction("dateFormat",dateFormat,tr("DATE&TIME"), "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("timeFormat",timeFormat,tr("DATE&TIME"), "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("dateTimeFormat", dateTimeFormat, tr("DATE&TIME"), "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("date",date,tr("DATE&TIME"),"date()"); - addFunction("now",now,tr("DATE&TIME"),"now()"); -#if QT_VERSION>0x040800 - addFunction("currencyFormat",currencyFormat,tr("NUMBER"),"currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); - addFunction("currencyUSBasedFormat",currencyUSBasedFormat,tr("NUMBER"),"currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("SYSTEM")); + fd.setName("line"); + fd.setDescription("line(\""+tr("BandName")+"\")"); + fd.setScriptWrapper(QString("function line(bandName){ return %1.line(bandName);}").arg(LimeReport::Const::FUNCTION_MANAGER_NAME)); + + return addFunction(fd); + +} + +bool ScriptEngineManager::createNumberFomatFunction() +{ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("NUMBER")); + fd.setName("numberFormat"); + fd.setDescription("numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+ + tr("Precision")+"\",\""+ + tr("Locale")+"\")" + ); + fd.setScriptWrapper(QString("function numberFormat(value, format, precision, locale){" + " if(typeof(format)==='undefined') format = \"f\"; " + " if(typeof(precision)==='undefined') precision=2; " + " if(typeof(locale)==='undefined') locale=\"\"; " + "return %1.numberFormat(value,format,precision,locale);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createDateFormatFunction(){ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("DATE&TIME")); + fd.setName("dateFormat"); + fd.setDescription("dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\", \""+tr("Locale")+"\")"); + fd.setScriptWrapper(QString("function dateFormat(value, format, locale){" + " if(typeof(format)==='undefined') format = \"dd.MM.yyyy\"; " + "return %1.dateFormat(value,format, locale);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createTimeFormatFunction(){ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("DATE&TIME")); + fd.setName("timeFormat"); + fd.setDescription("timeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + fd.setScriptWrapper(QString("function timeFormat(value, format){" + " if(typeof(format)==='undefined') format = \"hh:mm\"; " + "return %1.timeFormat(value,format);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createDateTimeFormatFunction(){ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("DATE&TIME")); + fd.setName("dateTimeFormat"); + fd.setDescription("dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\", \""+tr("Locale")+"\")"); + fd.setScriptWrapper(QString("function dateTimeFormat(value, format, locale){" + " if(typeof(format)==='undefined') format = \"dd.MM.yyyy hh:mm\"; " + "return %1.dateTimeFormat(value, format, locale);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createSectotimeFormatFunction() +{ + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("DATE&TIME")); + fd.setName("sectotimeFormat"); + fd.setDescription("sectotimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + fd.setScriptWrapper(QString("function sectotimeFormat(value, format){" + " if(typeof(format)==='undefined') format = \"hh:mm:ss\"; " + "return %1.sectotimeFormat(value,format);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createDateFunction(){ +// addFunction("date",date,"DATE&TIME","date()"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("DATE&TIME")); + fd.setName("date"); + fd.setDescription("date()"); + fd.setScriptWrapper(QString("function date(){" + "return %1.date();}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + + +bool ScriptEngineManager::createNowFunction(){ +// addFunction("now",now,"DATE&TIME","now()"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("DATE&TIME")); + fd.setName("now"); + fd.setDescription("now()"); + fd.setScriptWrapper(QString("function now(){" + "return %1.now();}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createCurrencyFormatFunction(){ +// addFunction("currencyFormat",currencyFormat,"NUMBER","currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("NUMBER")); + fd.setName("currencyFormat"); + fd.setDescription("currencyFormat(\""+tr("Value")+"\",\""+tr("Locale")+"\")"); + fd.setScriptWrapper(QString("function currencyFormat(value, locale){" + " if(typeof(locale)==='undefined') locale = \"\"; " + "return %1.currencyFormat(value,locale);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createCurrencyUSBasedFormatFunction(){ +// addFunction("currencyUSBasedFormat",currencyUSBasedFormat,"NUMBER","currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("NUMBER")); + fd.setName("currencyUSBasedFormat"); + fd.setDescription("currencyUSBasedFormat(\""+tr("Value")+",\""+tr("CurrencySymbol")+"\")"); + fd.setScriptWrapper(QString("function currencyUSBasedFormat(value, currencySymbol){" + " if(typeof(currencySymbol)==='undefined') currencySymbol = \"\"; " + "return %1.currencyUSBasedFormat(value,currencySymbol);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createSetVariableFunction(){ +// addFunction("setVariable", setVariable, "GENERAL", "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); + JSFunctionDesc fd; + + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("setVariable"); + fd.setDescription("setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); + fd.setScriptWrapper(QString("function setVariable(name, value){" + "return %1.setVariable(name,value);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createGetVariableFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("getVariable"); + fd.setDescription("getVariable(\""+tr("Name")+"\")"); + fd.setScriptWrapper(QString("function getVariable(name){" + "return %1.getVariable(name);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createGetFieldFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("getField"); + fd.setDescription("getField(\""+tr("Name")+"\")"); + fd.setScriptWrapper(QString("function getField(name){" + "return %1.getField(name);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createGetFieldByKeyFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("getFieldByKeyField"); + fd.setDescription("getFieldByKeyField(\""+tr("Datasource")+"\", \""+ + tr("ValueField")+"\",\""+ + tr("KeyField")+"\", \""+ + tr("KeyFieldValue")+"\")" + ); + fd.setScriptWrapper(QString("function getFieldByKeyField(datasource, valueFieldName, keyFieldName, keyValue){" + "return %1.getFieldByKeyField(datasource, valueFieldName, keyFieldName, keyValue);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createGetFieldByRowIndex() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("getFieldByRowIndex"); + fd.setDescription("getFieldByRowIndex(\""+tr("FieldName")+"\", \""+ + tr("RowIndex")+"\")" + ); + fd.setScriptWrapper(QString("function getFieldByRowIndex(fieldName, rowIndex){" + "return %1.getFieldByRowIndex(fieldName, rowIndex);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createAddBookmarkFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("addBookmark"); + fd.setDescription("addBookmark(\""+tr("Unique identifier")+" \""+tr("Content")+"\")"); + fd.setScriptWrapper(QString("function addBookmark(uniqKey, content){" + "return %1.addBookmark(uniqKey, content);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createFindPageIndexByBookmark() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("findPageIndexByBookmark"); + fd.setDescription("findPageIndexByBookmark(\""+tr("Unique identifier")+"\")"); + fd.setScriptWrapper(QString("function findPageIndexByBookmark(uniqKey){" + "return %1.findPageIndexByBookmark(uniqKey);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createAddTableOfContentsItemFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("addTableOfContentsItem"); + fd.setDescription("addTableOfContentsItem(\""+tr("Unique identifier")+" \""+tr("Content")+"\", \""+tr("Indent")+"\")"); + fd.setScriptWrapper(QString("function addTableOfContentsItem(uniqKey, content, indent){" + "return %1.addTableOfContentsItem(uniqKey, content, indent);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createClearTableOfContentsFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("clearTableOfContents"); + fd.setDescription("clearTableOfContents()"); + fd.setScriptWrapper(QString("function clearTableOfContents(){" + "return %1.clearTableOfContents();}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createReopenDatasourceFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("reopenDatasource"); + fd.setDescription("reopenDatasource(\""+tr("datasourceName")+"\")"); + fd.setScriptWrapper(QString("function reopenDatasource(datasourceName){" + "return %1.reopenDatasource(datasourceName);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +ScriptEngineManager::ScriptEngineManager() + :m_model(0), m_context(0), m_dataManager(0) +{ + m_scriptEngine = new ScriptEngineType; + m_functionManager = new ScriptFunctionsManager(this); + m_functionManager->setScriptEngineManager(this); +#ifdef USE_QTSCRIPTENGINE + m_scriptEngine->setDefaultPrototype(qMetaTypeId(), + m_scriptEngine->newQObject(new ComboBoxPrototype())); #endif - addFunction("setVariable", setVariable, tr("GENERAL"), "setVariable(\""+tr("Name")+"\",\""+tr("Value")+"\")"); - addFunction("getVariable", getVariable, tr("GENERAL"), "getVariable(\""+tr("Name")+"\")"); - addFunction("getField", getField, tr("GENERAL"), "getField(\""+tr("Name")+"\")"); - + createLineFunction(); + createNumberFomatFunction(); + createDateFormatFunction(); + createTimeFormatFunction(); + createDateTimeFormatFunction(); + createSectotimeFormatFunction(); + createDateFunction(); + createNowFunction(); +#if QT_VERSION>0x040800 + createCurrencyFormatFunction(); + createCurrencyUSBasedFormatFunction(); +#endif + createSetVariableFunction(); + createGetFieldFunction(); + createGetFieldByRowIndex(); + createGetFieldByKeyFunction(); + createGetVariableFunction(); +#ifdef USE_QTSCRIPTENGINE QScriptValue colorCtor = m_scriptEngine->newFunction(constructColor); m_scriptEngine->globalObject().setProperty("QColor", colorCtor); @@ -670,18 +963,14 @@ ScriptEngineManager::ScriptEngineManager() m_scriptEngine->setDefaultPrototype(qMetaTypeId(), fontProto); QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto); m_scriptEngine->globalObject().setProperty("QFont", fontConstructor); - -// foreach(QString func, dataManager()->groupFunctionNames()){ -// addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")"); -// } - -// foreach(ScriptFunctionDesc func, m_functions){ -// if (func.type==ScriptFunctionDesc::Native) -// m_scriptEngine->globalObject().setProperty(func.name,func.scriptValue); -// } +#endif + createAddBookmarkFunction(); + createFindPageIndexByBookmark(); + createAddTableOfContentsItemFunction(); + createClearTableOfContentsFunction(); + createReopenDatasourceFunction(); m_model = new ScriptEngineModel(this); - } bool ScriptExtractor::parse() @@ -817,6 +1106,49 @@ void DialogDescriber::setDescription(const QByteArray &description) void ScriptEngineContext::addDialog(const QString& name, const QByteArray& description) { m_dialogs.push_back(DialogDescriber::create(name,description)); + emit dialogAdded(name); +} + +bool ScriptEngineContext::changeDialog(const QString& name, const QByteArray& description) +{ + foreach( DialogDescriber::Ptr describer, m_dialogs){ + if (describer->name().compare(name) == 0){ + describer->setDescription(description); + { + QList::Iterator it = m_createdDialogs.begin(); + while(it!=m_createdDialogs.end()){ + if ((*it)->objectName()==name){ + it = m_createdDialogs.erase(it); + } else { + ++it; + } + } + } + return true; + } + } + return false; +} + +bool ScriptEngineContext::changeDialogName(const QString& oldName, const QString& newName) +{ + foreach( DialogDescriber::Ptr describer, m_dialogs){ + if (describer->name().compare(oldName) == 0){ + describer->setName(newName); + { + QList::Iterator it = m_createdDialogs.begin(); + while(it!=m_createdDialogs.end()){ + if ((*it)->objectName()==oldName){ + it = m_createdDialogs.erase(it); + } else { + ++it; + } + } + } + return true; + } + } + return false; } bool ScriptEngineContext::previewDialog(const QString& dialogName) @@ -847,6 +1179,7 @@ void ScriptEngineContext::deleteDialog(const QString& dialogName) while(it!=m_dialogs.end()){ if ((*it)->name()==dialogName){ it = m_dialogs.erase(it); + emit dialogDeleted(dialogName); } else { ++it; } @@ -873,6 +1206,7 @@ void ScriptEngineContext::clear() m_createdDialogs.clear(); #endif m_initScript.clear(); + m_tableOfContents->clear(); m_lastError=""; } @@ -920,6 +1254,16 @@ void ScriptEngineContext::collectionLoadFinished(const QString& collectionName) Q_UNUSED(collectionName); } +ReportPages* ScriptEngineContext::reportPages() const +{ + return m_reportPages; +} + +void ScriptEngineContext::setReportPages(ReportPages *value) +{ + m_reportPages = value; +} + #ifdef HAVE_UI_LOADER QDialog* ScriptEngineContext::createDialog(DialogDescriber* cont) { @@ -929,6 +1273,10 @@ QDialog* ScriptEngineContext::createDialog(DialogDescriber* cont) buffer.open(QIODevice::ReadOnly); QDialog* dialog = dynamic_cast(loader.load(&buffer)); m_createdDialogs.push_back(QSharedPointer(dialog)); + if (cont->name().compare(dialog->objectName())){ + cont->setName(dialog->objectName()); + emit dialogNameChanged(dialog->objectName()); + } return dialog; } @@ -951,6 +1299,37 @@ DialogDescriber* ScriptEngineContext::findDialogContainer(const QString& dialogN return 0; } +TableOfContents* ScriptEngineContext::tableOfContents() const +{ + return m_tableOfContents; +} + +void ScriptEngineContext::setTableOfContents(TableOfContents* tableOfContents) +{ + m_tableOfContents = tableOfContents; +} + +PageItemDesignIntf* ScriptEngineContext::getCurrentPage() const +{ + return m_currentPage; +} + +void ScriptEngineContext::setCurrentPage(PageItemDesignIntf* currentPage) +{ + m_currentPage = currentPage; + m_currentBand = 0; +} + +BandDesignIntf* ScriptEngineContext::getCurrentBand() const +{ + return m_currentBand; +} + +void ScriptEngineContext::setCurrentBand(BandDesignIntf* currentBand) +{ + m_currentBand = currentBand; +} + QDialog* ScriptEngineContext::getDialog(const QString& dialogName) { QDialog* dialog = findDialog(dialogName); @@ -966,7 +1345,123 @@ QDialog* ScriptEngineContext::getDialog(const QString& dialogName) } return 0; } + +QString ScriptEngineContext::getNewDialogName() +{ + QString result = "Dialog"; + int index = m_dialogs.size() - 1; + while (containsDialog(result)){ + index++; + result = QString("Dialog%1").arg(index); + } + return result; +} + #endif + +void ScriptEngineContext::baseDesignIntfToScript(const QString& pageName, BaseDesignIntf* item) +{ + if ( item ) { + if (item->metaObject()->indexOfSignal("beforeRender()")!=-1) + item->disconnect(SIGNAL(beforeRender())); + if (item->metaObject()->indexOfSignal("afterData()")!=-1) + item->disconnect(SIGNAL(afterData())); + if (item->metaObject()->indexOfSignal("afterRender()")!=-1) + item->disconnect(SIGNAL(afterRender())); + + ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine(); + +#ifdef USE_QJSENGINE + ScriptValueType sItem = getJSValue(*engine, item); + QString on = item->patternName().compare(pageName) == 0 ? pageName : pageName+"_"+item->patternName(); + engine->globalObject().setProperty(on, sItem); +#else + QString on = item->patternName().compare(pageName) == 0 ? pageName : pageName+"_"+item->patternName(); + ScriptValueType sItem = engine->globalObject().property(on); + if (sItem.isValid()){ + engine->newQObject(sItem, item); + } else { + sItem = engine->newQObject(item); + engine->globalObject().setProperty(on,sItem); + } +#endif + foreach(BaseDesignIntf* child, item->childBaseItems()){ + baseDesignIntfToScript(pageName, child); + } + } +} + +void ScriptEngineContext::qobjectToScript(const QString& name, QObject *item) +{ + ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine(); +#ifdef USE_QJSENGINE + ScriptValueType sItem = getJSValue(*engine, item); + engine->globalObject().setProperty(name, sItem); +#else + ScriptValueType sItem = engine->globalObject().property(name); + if (sItem.isValid()){ + engine->newQObject(sItem, item); + } else { + sItem = engine->newQObject(item); + engine->globalObject().setProperty(name,sItem); + } +#endif +} + +#ifdef HAVE_UI_LOADER + +#ifdef USE_QJSENGINE +void registerChildObjects(ScriptEngineType* se, ScriptValueType* sv){ + foreach(QObject* obj, sv->toQObject()->children()){ + ScriptValueType child = se->newQObject(obj); + sv->setProperty(obj->objectName(),child); + registerChildObjects(se, &child); + } +} +#endif + +void ScriptEngineContext::initDialogs(){ + ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine(); + foreach(DialogDescriber::Ptr dialog, dialogDescribers()){ + ScriptValueType sv = se->newQObject(getDialog(dialog->name())); +#ifdef USE_QJSENGINE + registerChildObjects(se,&sv); +#endif + se->globalObject().setProperty(dialog->name(),sv); + } +} + +#endif + + +bool ScriptEngineContext::runInitScript(){ + + ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineManager::instance().setContext(this); + m_tableOfContents->clear(); + + ScriptValueType res = engine->evaluate(initScript()); + if (res.isBool()) return res.toBool(); +#ifdef USE_QJSENGINE + if (res.isError()){ + QMessageBox::critical(0,tr("Error"), + QString("Line %1: %2 ").arg(res.property("lineNumber").toString()) + .arg(res.toString()) + ); + return false; + } +#else + if (engine->hasUncaughtException()) { + QMessageBox::critical(0,tr("Error"), + QString("Line %1: %2 ").arg(engine->uncaughtExceptionLineNumber()) + .arg(engine->uncaughtException().toString()) + ); + return false; + } +#endif + return true; +} + QString ScriptEngineContext::initScript() const { return m_initScript; @@ -974,7 +1469,10 @@ QString ScriptEngineContext::initScript() const void ScriptEngineContext::setInitScript(const QString& initScript) { - m_initScript = initScript; + if (m_initScript != initScript){ + m_initScript = initScript; + m_hasChanges = true; + } } DialogDescriber::Ptr DialogDescriber::create(const QString& name, const QByteArray& desc) { @@ -984,5 +1482,558 @@ DialogDescriber::Ptr DialogDescriber::create(const QString& name, const QByteArr return res; } +QString JSFunctionDesc::name() const +{ + return m_name; +} + +void JSFunctionDesc::setName(const QString &name) +{ + m_name = name; +} + +QString JSFunctionDesc::category() const +{ + return m_category; +} + +void JSFunctionDesc::setCategory(const QString &category) +{ + m_category = category; +} + +QString JSFunctionDesc::description() const +{ + return m_description; +} + +void JSFunctionDesc::setDescription(const QString &description) +{ + m_description = description; +} + +QString JSFunctionDesc::managerName() const +{ + return m_managerName; +} + +void JSFunctionDesc::setManagerName(const QString &managerName) +{ + m_managerName = managerName; +} + +QObject *JSFunctionDesc::manager() const +{ + return m_manager; +} + +void JSFunctionDesc::setManager(QObject *manager) +{ + m_manager = manager; +} + +QString JSFunctionDesc::scriptWrapper() const +{ + return m_scriptWrapper; +} + +void JSFunctionDesc::setScriptWrapper(const QString &scriptWrapper) +{ + m_scriptWrapper = scriptWrapper; +} + +QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName, QObject* currentPage) +{ + if (m_scriptEngineManager->dataManager()){ + PageItemDesignIntf* pageItem = dynamic_cast(currentPage); + QString expression = m_scriptEngineManager->dataManager()->getExpression(expressionID); + GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName); + if (gf){ + if (gf->isValid()){ + return gf->calculate(pageItem); + }else{ + return gf->error(); + } + } + else { + return QString(QObject::tr("Function %1 not found or have wrong arguments").arg(name)); + } + } else { + return QString(QObject::tr("Datasource manager not found")); + } +} + +QVariant ScriptFunctionsManager::calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName) +{ + return calcGroupFunction(name, expressionID, bandName, 0); +} + +QVariant ScriptFunctionsManager::line(const QString &bandName) +{ + QString varName = QLatin1String("line_")+bandName.toLower(); + QVariant res; + if (scriptEngineManager()->dataManager()->variable(varName).isValid()){ + res=scriptEngineManager()->dataManager()->variable(varName); + } else res=QString("Variable line for band %1 not found").arg(bandName); + return res; +} + +QVariant ScriptFunctionsManager::numberFormat(QVariant value, const char &format, int precision, const QString& locale) +{ + return (locale.isEmpty()) ? QString::number(value.toDouble(),format,precision): + QLocale(locale).toString(value.toDouble(),format,precision); +} + +QVariant ScriptFunctionsManager::dateFormat(QVariant value, const QString &format, const QString& locale) +{ + return (locale.isEmpty()) ? QLocale().toString(value.toDate(),format) : + QLocale(locale).toString(value.toDate(),format); +} + +QVariant ScriptFunctionsManager::timeFormat(QVariant value, const QString &format) +{ + return QLocale().toString(value.toTime(),format); +} + +QVariant ScriptFunctionsManager::dateTimeFormat(QVariant value, const QString &format, const QString& locale) +{ + return (locale.isEmpty()) ? QLocale().toString(value.toDateTime(),format) : + QLocale(locale).toString(value.toDateTime(),format); +} + +QVariant ScriptFunctionsManager::sectotimeFormat(QVariant value, const QString &format) +{ + int seconds = value.toInt(); + int minutes = seconds / 60; + int hours = minutes / 60; + + QString result = format; + bool hasHour = format.contains("h"); + bool hasMinute = format.contains("m"); + for(int len = 2; len; len--) { + if(hasHour) result.replace(QString('h').repeated(len), QString::number(hours).rightJustified(len, '0')); + if(hasMinute) result.replace(QString('m').repeated(len), QString::number(hasHour ? minutes % 60 : minutes).rightJustified(len, '0')); + result.replace(QString('s').repeated(len), QString::number(hasMinute ? seconds % 60 : seconds).rightJustified(len, '0')); + } + return result; +} + +QVariant ScriptFunctionsManager::date() +{ + return QDate::currentDate(); +} + +QVariant ScriptFunctionsManager::now() +{ + return QDateTime::currentDateTime(); +} + +QVariant ScriptFunctionsManager::currencyFormat(QVariant value, const QString &locale) +{ + QString l = (!locale.isEmpty())?locale:QLocale::system().name(); + return QLocale(l).toCurrencyString(value.toDouble()); +} + +QVariant ScriptFunctionsManager::currencyUSBasedFormat(QVariant value, const QString ¤cySymbol) +{ + QString CurrencySymbol = (!currencySymbol.isEmpty())?currencySymbol:QLocale::system().currencySymbol(); + // Format it using USA locale + QString vTempStr=QLocale(QLocale::English, QLocale::UnitedStates).toCurrencyString(value.toDouble()); + // Replace currency symbol if necesarry + if (CurrencySymbol!="") vTempStr.replace("$", CurrencySymbol); + return vTempStr; +} + +void ScriptFunctionsManager::setVariable(const QString &name, QVariant value) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + if (dm->containsVariable(name)){ + dm->changeVariable(name,value); + } else { + dm->addVariable(name, value, VarDesc::User); + } +} + +QVariant ScriptFunctionsManager::getVariable(const QString &name) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->variable(name); +} + +QVariant ScriptFunctionsManager::getField(const QString &field) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->fieldData(field); +} + +QVariant ScriptFunctionsManager::getFieldByKeyField(const QString& datasourceName, const QString& valueFieldName, const QString& keyFieldName, QVariant keyValue) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->fieldDataByKey(datasourceName, valueFieldName, keyFieldName, keyValue); +} + +QVariant ScriptFunctionsManager::getFieldByRowIndex(const QString &fieldName, int rowIndex) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->fieldDataByRowIndex(fieldName, rowIndex); +} + +void ScriptFunctionsManager::reopenDatasource(const QString& datasourceName) +{ + DataSourceManager* dm = scriptEngineManager()->dataManager(); + return dm->reopenDatasource(datasourceName); +} + +void ScriptFunctionsManager::addBookmark(const QString &uniqKey, const QString &content) +{ + scriptEngineManager()->addBookMark(uniqKey, content); +} + +int ScriptFunctionsManager::findPageIndexByBookmark(const QString &uniqKey) +{ + return scriptEngineManager()->findPageIndexByBookmark(uniqKey); +} + +void ScriptFunctionsManager::addTableOfContentsItem(const QString& uniqKey, const QString& content, int indent) +{ + scriptEngineManager()->addTableOfContentsItem(uniqKey, content, indent); +} + +void ScriptFunctionsManager::clearTableOfContents() +{ + scriptEngineManager()->clearTableOfContents(); +} + +QFont ScriptFunctionsManager::font(const QString &family, int pointSize, bool italic, bool bold, bool underLine) +{ + QFont result (family, pointSize); + result.setBold(bold); + result.setItalic(italic); + result.setUnderline(underLine); + return result; +} + +#ifdef USE_QJSENGINE + +void ScriptFunctionsManager::addItemsToComboBox(QJSValue object, const QStringList &values) +{ + QComboBox* comboBox = dynamic_cast(object.toQObject()); + if (comboBox){ + comboBox->addItems(values); + } +} + +void ScriptFunctionsManager::addItemToComboBox(QJSValue object, const QString &value) +{ + QComboBox* comboBox = dynamic_cast(object.toQObject()); + if (comboBox){ + comboBox->addItem(value); + } +} + +QJSValue ScriptFunctionsManager::createComboBoxWrapper(QJSValue comboBox) +{ + QComboBox* item = dynamic_cast(comboBox.toQObject()); + if (item){ + ComboBoxWrapper* wrapper = new ComboBoxWrapper(item); + return m_scriptEngineManager->scriptEngine()->newQObject(wrapper); + } + return QJSValue(); +} + +QJSValue ScriptFunctionsManager::createWrapper(QJSValue item) +{ + QObject* object = item.toQObject(); + if (object){ + IWrapperCreator* wrapper = m_wrappersFactory.value(object->metaObject()->className()); + if (wrapper){ + return m_scriptEngineManager->scriptEngine()->newQObject(wrapper->createWrapper(item.toQObject())); + } + } + return QJSValue(); +} + +#else + +void ScriptFunctionsManager::addItemsToComboBox(QScriptValue object, const QStringList &values) +{ + QComboBox* comboBox = dynamic_cast(object.toQObject()); + if (comboBox){ + comboBox->addItems(values); + } +} + +void ScriptFunctionsManager::addItemToComboBox(QScriptValue object, const QString &value) +{ + QComboBox* comboBox = dynamic_cast(object.toQObject()); + if (comboBox){ + comboBox->addItem(value); + } +} + +QScriptValue ScriptFunctionsManager::createComboBoxWrapper(QScriptValue comboBox) +{ + QComboBox* item = dynamic_cast(comboBox.toQObject()); + if (item){ + ComboBoxWrapper* wrapper = new ComboBoxWrapper(item); + return m_scriptEngineManager->scriptEngine()->newQObject(wrapper); + } + return QScriptValue(); +} + +QScriptValue ScriptFunctionsManager::createWrapper(QScriptValue item) +{ + QObject* object = item.toQObject(); + if (object){ + IWrapperCreator* wrapper = m_wrappersFactory.value(object->metaObject()->className()); + if (wrapper){ + return m_scriptEngineManager->scriptEngine()->newQObject(wrapper->createWrapper(item.toQObject())); + } + } + return QScriptValue(); +} + +#endif + +QFont ScriptFunctionsManager::font(QVariantMap params){ + if (!params.contains("family")){ + return QFont(); + } else { + QFont result(params.value("family").toString()); + if (params.contains("pointSize")) + result.setPointSize(params.value("pointSize").toInt()); + if (params.contains("bold")) + result.setBold(params.value("bold").toBool()); + if (params.contains("italic")) + result.setItalic(params.value("italic").toBool()); + if (params.contains("underline")) + result.setUnderline(params.value("underline").toBool()); + return result; + } +} + +ScriptEngineManager *ScriptFunctionsManager::scriptEngineManager() const +{ + return m_scriptEngineManager; +} + +void ScriptFunctionsManager::setScriptEngineManager(ScriptEngineManager *scriptEngineManager) +{ + m_scriptEngineManager = scriptEngineManager; +} + +TableOfContents::~TableOfContents() +{ + clear(); +} + +void TableOfContents::setItem(const QString& uniqKey, const QString& content, int pageNumber, int indent) +{ + ContentItem * item = 0; + if (m_hash.contains(uniqKey)){ + item = m_hash.value(uniqKey); + item->content = content; + item->pageNumber = pageNumber; + if (indent>0) + item->indent = indent; + } else { + item = new ContentItem; + item->content = content; + item->pageNumber = pageNumber; + item->indent = indent; + item->uniqKey = uniqKey; + m_tableOfContents.append(item); + m_hash.insert(uniqKey, item); + } + +} + +void TableOfContents::slotOneSlotDS(CallbackInfo info, QVariant& data) +{ + QStringList columns; + columns << "Content" << "Page number" << "Content Key"; + + switch (info.dataType) { + case LimeReport::CallbackInfo::RowCount: + data = m_tableOfContents.count(); + break; + case LimeReport::CallbackInfo::ColumnCount: + data = columns.size(); + break; + case LimeReport::CallbackInfo::ColumnHeaderData: { + data = columns.at(info.index); + break; + } + case LimeReport::CallbackInfo::ColumnData: + if (info.index < m_tableOfContents.count()){ + ContentItem* item = m_tableOfContents.at(info.index); + if (info.columnName.compare("Content",Qt::CaseInsensitive) == 0) + data = item->content.rightJustified(item->indent+item->content.size()); + if (info.columnName.compare("Content Key",Qt::CaseInsensitive) == 0) + data = item->uniqKey; + if (info.columnName.compare("Page number",Qt::CaseInsensitive) == 0) + data = QString::number(item->pageNumber); + } + break; + default: break; + } +} + +void LimeReport::TableOfContents::clear(){ + + m_hash.clear(); + foreach(ContentItem* item, m_tableOfContents){ + delete item; + } + m_tableOfContents.clear(); + +} + +QObject* ComboBoxWrapperCreator::createWrapper(QObject *item) +{ + QComboBox* comboBox = dynamic_cast(item); + if (comboBox){ + return new ComboBoxWrapper(comboBox); + } + return 0; +} + +bool DatasourceFunctions::first(const QString& datasourceName) +{ + if (m_dataManager && m_dataManager->dataSource(datasourceName)){ + m_dataManager->dataSource(datasourceName)->first(); + return true; + } + return false; +} + +bool DatasourceFunctions::next(const QString &datasourceName){ + if (m_dataManager && m_dataManager->dataSource(datasourceName)) + return m_dataManager->dataSource(datasourceName)->next(); + return false; +} + +bool DatasourceFunctions::prior(const QString& datasourceName) +{ + if (m_dataManager && m_dataManager->dataSource(datasourceName)) + return m_dataManager->dataSource(datasourceName)->prior(); + return false; +} + +bool DatasourceFunctions::isEOF(const QString &datasourceName) +{ + if (m_dataManager && m_dataManager->dataSource(datasourceName)) + return m_dataManager->dataSource(datasourceName)->eof(); + return true; +} + +bool DatasourceFunctions::invalidate(const QString& datasourceName) +{ + if (m_dataManager && m_dataManager->dataSource(datasourceName)){ + m_dataManager->dataSourceHolder(datasourceName)->invalidate(IDataSource::DatasourceMode::RENDER_MODE); + return true; + } + return false; +} + +QObject* DatasourceFunctions::createTableBuilder(BaseDesignIntf* horizontalLayout) +{ + return new TableBuilder(dynamic_cast(horizontalLayout), dynamic_cast(m_dataManager)); +} + +TableBuilder::TableBuilder(HorizontalLayout* layout, DataSourceManager* dataManager) + : m_horizontalLayout(layout), m_baseLayout(0), m_dataManager(dataManager) +{ + if (m_horizontalLayout) + m_patternLayout = dynamic_cast(m_horizontalLayout->cloneItem(m_horizontalLayout->itemMode())); +} + +QObject* TableBuilder::addRow() +{ + checkBaseLayout(); + if (m_baseLayout && m_patternLayout){ + HorizontalLayout* newRow = new HorizontalLayout(m_baseLayout, m_baseLayout); + newRow->setLayoutSpacing(m_horizontalLayout->layoutSpacing()); + for(int i = 0; i < m_horizontalLayout->childrenCount(); ++i){ + BaseDesignIntf* item = dynamic_cast(m_patternLayout->at(i)); + BaseDesignIntf* cloneItem = item->cloneItem(item->itemMode(), newRow, newRow); + newRow->addChild(cloneItem); + } + m_baseLayout->addChild(newRow); + return newRow; + } else return 0; +} + +QObject* TableBuilder::currentRow() +{ + checkBaseLayout(); + if (m_baseLayout && m_baseLayout->childrenCount()>0) + return m_baseLayout->at(m_baseLayout->childrenCount()-1); + return 0; +} + +void TableBuilder::fillInRowData(QObject* row) +{ + HorizontalLayout* layout = dynamic_cast(row); + if (layout){ + for (int i = 0; i < layout->childrenCount(); ++i) { + BaseDesignIntf* item = dynamic_cast(layout->at(i)); + DataSourceManager* dm = dynamic_cast(m_dataManager); + if (item && dm) + item->updateItemSize(dm); + } + } +} + +void TableBuilder::buildTable(const QString& datasourceName) +{ + checkBaseLayout(); + m_dataManager->dataSourceHolder(datasourceName)->invalidate(IDataSource::RENDER_MODE); + m_dataManager->dataSource(datasourceName)->first(); + bool firstTime = true; + QObject* row = m_horizontalLayout; + while(!m_dataManager->dataSource(datasourceName)->eof()){ + if (!firstTime) row = addRow(); + else firstTime = false; + fillInRowData(row); + m_dataManager->dataSource(datasourceName)->next(); + } +} + +void TableBuilder::checkBaseLayout() +{ + if (!m_baseLayout){ + m_baseLayout = dynamic_cast(m_horizontalLayout->parentItem()); + if (!m_baseLayout){ + m_baseLayout = new VerticalLayout(m_horizontalLayout->parent(), m_horizontalLayout->parentItem()); + m_baseLayout->setItemLocation(m_horizontalLayout->itemLocation()); + m_baseLayout->setPos(m_horizontalLayout->pos()); + m_baseLayout->setWidth(m_horizontalLayout->width()); + m_baseLayout->setHeight(0); + m_baseLayout->addChild(m_horizontalLayout); + m_baseLayout->setObjectName(QUuid::createUuid().toString()); + m_baseLayout->setItemTypeName("VerticalLayout"); + } + } +} + +#ifdef USE_QTSCRIPTENGINE +void ComboBoxPrototype::addItem(const QString &text) +{ + QComboBox* comboBox = qscriptvalue_cast(thisObject()); + if (comboBox){ + comboBox->addItem(text); + } +} + +void ComboBoxPrototype::addItems(const QStringList &texts) +{ + QComboBox* comboBox = qscriptvalue_cast(thisObject()); + if (comboBox){ + comboBox->addItems(texts); + } +} +#endif + } //namespace LimeReport diff --git a/limereport/lrscriptenginemanager.h b/limereport/lrscriptenginemanager.h index 545580b..f59405c 100644 --- a/limereport/lrscriptenginemanager.h +++ b/limereport/lrscriptenginemanager.h @@ -29,31 +29,67 @@ ****************************************************************************/ #ifndef LRSCRIPTENGINEMANAGER_H #define LRSCRIPTENGINEMANAGER_H - +#ifdef USE_QTSCRIPTENGINE #include +#include +#endif #include #include #include #include #include -#include #include +#include + +//#include #ifdef HAVE_UI_LOADER #include #endif #include "base/lrsingleton.h" +#include "lrglobal.h" #include "lrscriptenginemanagerintf.h" +#include "lrcallbackdatasourceintf.h" #include "lrcollection.h" +#include "lrdatasourceintf.h" +#include "lrdatasourcemanagerintf.h" +#include "lrhorizontallayout.h" +#include "lrverticallayout.h" namespace LimeReport{ class DataSourceManager; +class BaseDesignIntf; +class PageItemDesignIntf; +class BandDesignIntf; + +struct ContentItem { + QString content; + int indent; + int pageNumber; + QString uniqKey; +}; + +class TableOfContents : public QObject{ + Q_OBJECT +public: + TableOfContents(QObject* parent = 0):QObject(parent){} + ~TableOfContents(); + void setItem(const QString& uniqKey, const QString& content, int pageNumber, int indent = 0); + void clear(); + bool isEmpty(){ return m_tableOfContents.isEmpty();} +private slots: + void slotOneSlotDS(LimeReport::CallbackInfo info, QVariant &data); +private: + QVector m_tableOfContents; + QHash m_hash; +}; + struct ScriptFunctionDesc{ enum FuncType {Native,Script}; - QScriptValue scriptValue; + ScriptValueType scriptValue; QString name; QString description; QString category; @@ -129,6 +165,8 @@ private : QByteArray m_description; }; +typedef QList< QSharedPointer > ReportPages; + class ScriptEngineContext : public QObject, public ICollectionContainer { Q_OBJECT @@ -138,23 +176,49 @@ public: #ifdef HAVE_UI_LOADER typedef QSharedPointer DialogPtr; #endif - explicit ScriptEngineContext(QObject* parent=0):QObject(parent){} + explicit ScriptEngineContext(QObject* parent=0): + QObject(parent), m_currentBand(0), m_currentPage(0), + m_tableOfContents(new TableOfContents(this)), m_hasChanges(false) {} #ifdef HAVE_UI_LOADER - void addDialog(const QString& name, const QByteArray &description); + void addDialog(const QString& name, const QByteArray& description); + bool changeDialog(const QString& name, const QByteArray &description); + bool changeDialogName(const QString& oldName, const QString& newName); bool previewDialog(const QString& dialogName); bool containsDialog(const QString& dialogName); - const QVector& dialogsDescriber(){return m_dialogs;} + const QVector& dialogDescribers(){return m_dialogs;} void deleteDialog(const QString& dialogName); QDialog *getDialog(const QString &dialogName); + QString getNewDialogName(); + void initDialogs(); #endif - void clear(); + void baseDesignIntfToScript(const QString& pageName, BaseDesignIntf *item); + void qobjectToScript(const QString &name, QObject* item); + void clear(); QString initScript() const; - void setInitScript(const QString& initScript); + void setInitScript(const QString& initScript); + bool runInitScript(); + + BandDesignIntf* getCurrentBand() const; + void setCurrentBand(BandDesignIntf* currentBand); + PageItemDesignIntf* getCurrentPage() const; + void setCurrentPage(PageItemDesignIntf* currentPage); + TableOfContents* tableOfContents() const; + void setTableOfContents(TableOfContents* tableOfContents); + void dropChanges(){ m_hasChanges = false;} + bool hasChanges(){ return m_hasChanges;} + ReportPages* reportPages() const; + void setReportPages(ReportPages* value); +#ifdef HAVE_UI_LOADER +signals: + void dialogNameChanged(QString dialogName); + void dialogDeleted(QString dialogName); + void dialogAdded(QString dialogName); +#endif protected: QObject* createElement(const QString& collectionName,const QString& elementType); - int elementsCount(const QString& collectionName); + int elementsCount(const QString& collectionName); QObject* elementAt(const QString& collectionName,int index); - void collectionLoadFinished(const QString &collectionName); + void collectionLoadFinished(const QString &collectionName); #ifdef HAVE_UI_LOADER QDialog *createDialog(DialogDescriber *cont); QDialog *findDialog(const QString &dialogName); @@ -167,24 +231,190 @@ private: #endif QString m_lastError; QString m_initScript; + BandDesignIntf* m_currentBand; + PageItemDesignIntf* m_currentPage; + TableOfContents* m_tableOfContents; + bool m_hasChanges; + ReportPages* m_reportPages; +}; + +class JSFunctionDesc{ +public: + JSFunctionDesc(){} + JSFunctionDesc(const QString& functionName, + const QString& functionCategory, + const QString& functionDescription, + const QString& functionManagerName, + QObject* functionManager, + const QString& functionScriptWrapper + ): m_name(functionName), m_category(functionCategory), m_description(functionDescription), + m_managerName(functionManagerName), m_manager(functionManager), m_scriptWrapper(functionScriptWrapper) + {} + QString name() const; + void setName(const QString &name); + + QString category() const; + void setCategory(const QString &category); + + QString description() const; + void setDescription(const QString &description); + + QString managerName() const; + void setManagerName(const QString &managerName); + + QObject *manager() const; + void setManager(QObject *manager); + + QString scriptWrapper() const; + void setScriptWrapper(const QString &scriptWrapper); + +private: + QString m_name; + QString m_category; + QString m_description; + QString m_managerName; + QObject* m_manager; + QString m_scriptWrapper; +}; + +#ifdef USE_QTSCRIPTENGINE +class ComboBoxPrototype : public QObject, public QScriptable{ + Q_OBJECT +public: + ComboBoxPrototype(QObject* parent = 0):QObject(parent){} +public slots: + void addItem( const QString& text); + void addItems(const QStringList& texts); +}; +#endif + +class IWrapperCreator{ +public: + virtual QObject* createWrapper(QObject* item) = 0; + virtual ~IWrapperCreator(){} +}; + +class ComboBoxWrapper : public QObject{ + Q_OBJECT +public: + ComboBoxWrapper(QComboBox* comboBox, QObject* parent = 0) : QObject(parent), m_comboBox(comboBox){} + Q_INVOKABLE void addItems(const QStringList& texts){ m_comboBox->addItems(texts);} + Q_INVOKABLE void addItem(const QString& text){ m_comboBox->addItem(text);} +private: + QComboBox* m_comboBox; +}; + +class ComboBoxWrapperCreator: public IWrapperCreator{ +private: + QObject* createWrapper(QObject* item); +}; + +class TableBuilder: public QObject{ + Q_OBJECT +public: + TableBuilder(LimeReport::HorizontalLayout* layout, DataSourceManager* dataManager); + ~TableBuilder(){delete m_patternLayout;} + Q_INVOKABLE QObject* addRow(); + Q_INVOKABLE QObject* currentRow(); + Q_INVOKABLE void fillInRowData(QObject* row); + Q_INVOKABLE void buildTable(const QString& datasourceName); +private: + void checkBaseLayout(); +private: + LimeReport::HorizontalLayout* m_horizontalLayout; + LimeReport::HorizontalLayout* m_patternLayout; + LimeReport::VerticalLayout* m_baseLayout; + DataSourceManager* m_dataManager; +}; + +class DatasourceFunctions : public QObject{ + Q_OBJECT +public: + explicit DatasourceFunctions(IDataSourceManager* dataManager) + : m_dataManager(dataManager){} + Q_INVOKABLE bool first(const QString& datasourceName); + Q_INVOKABLE bool next(const QString& datasourceName); + Q_INVOKABLE bool prior(const QString& datasourceName); + Q_INVOKABLE bool isEOF(const QString& datasourceName); + Q_INVOKABLE bool invalidate(const QString& datasourceName); + Q_INVOKABLE QObject *createTableBuilder(BaseDesignIntf* horizontalLayout); +private: + IDataSourceManager* m_dataManager; +}; + +class ScriptFunctionsManager : public QObject{ + Q_OBJECT +public: + explicit ScriptFunctionsManager(QObject* parent = 0):QObject(parent){ + m_wrappersFactory.insert("QComboBox",new ComboBoxWrapperCreator()); + + } + ~ScriptFunctionsManager(){ + foreach(IWrapperCreator* wrapper, m_wrappersFactory.values()){ delete wrapper;} m_wrappersFactory.clear(); + } + Q_INVOKABLE QVariant calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName, QObject* currentPage); + Q_INVOKABLE QVariant calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName); + Q_INVOKABLE QVariant line(const QString& bandName); + Q_INVOKABLE QVariant numberFormat(QVariant value, const char &format, int precision, const QString& locale); + Q_INVOKABLE QVariant dateFormat(QVariant value, const QString& format, const QString& locale); + Q_INVOKABLE QVariant timeFormat(QVariant value, const QString& format); + Q_INVOKABLE QVariant dateTimeFormat(QVariant value, const QString& format, const QString& locale); + Q_INVOKABLE QVariant sectotimeFormat(QVariant value, const QString& format); + Q_INVOKABLE QVariant date(); + Q_INVOKABLE QVariant now(); + Q_INVOKABLE QVariant currencyFormat(QVariant value, const QString& locale); + Q_INVOKABLE QVariant currencyUSBasedFormat(QVariant value, const QString& currencySymbol); + Q_INVOKABLE void setVariable(const QString& name, QVariant value); + Q_INVOKABLE QVariant getVariable(const QString& name); + Q_INVOKABLE QVariant getField(const QString& field); + Q_INVOKABLE QVariant getFieldByKeyField(const QString& datasourceName, const QString& valueFieldName, const QString& keyFieldName, QVariant keyValue); + Q_INVOKABLE QVariant getFieldByRowIndex(const QString& fieldName, int rowIndex); + Q_INVOKABLE void reopenDatasource(const QString& datasourceName); + Q_INVOKABLE QVariant color(const QString& color){ return QColor(color);} + Q_INVOKABLE void addBookmark(const QString& uniqKey, const QString& content); + Q_INVOKABLE int findPageIndexByBookmark(const QString &uniqKey); + Q_INVOKABLE void addTableOfContentsItem(const QString& uniqKey, const QString& content, int indent = 0); + Q_INVOKABLE void clearTableOfContents(); + Q_INVOKABLE QFont font(const QString& family, int pointSize = -1, bool bold = false, bool italic = false, bool underLine = false); +#ifdef USE_QJSENGINE + Q_INVOKABLE void addItemsToComboBox(QJSValue object, const QStringList& values); + Q_INVOKABLE void addItemToComboBox(QJSValue object, const QString& value); + Q_INVOKABLE QJSValue createComboBoxWrapper(QJSValue comboBox); + Q_INVOKABLE QJSValue createWrapper(QJSValue item); +#else + Q_INVOKABLE void addItemsToComboBox(QScriptValue object, const QStringList& values); + Q_INVOKABLE void addItemToComboBox(QScriptValue object, const QString& value); + Q_INVOKABLE QScriptValue createComboBoxWrapper(QScriptValue comboBox); + Q_INVOKABLE QScriptValue createWrapper(QScriptValue item); +#endif + Q_INVOKABLE QFont font(QVariantMap params); + ScriptEngineManager *scriptEngineManager() const; + void setScriptEngineManager(ScriptEngineManager *scriptEngineManager); + static QColor createQColor(const QString& color){ return QColor(color);} +private: + ScriptEngineManager* m_scriptEngineManager; + QMap m_wrappersFactory; }; class ScriptEngineManager : public QObject, public Singleton, public IScriptEngineManager { Q_OBJECT public: - QScriptEngine* scriptEngine(){return m_scriptEngine;} - ~ScriptEngineManager(); friend class Singleton; + ScriptEngineType* scriptEngine(){return m_scriptEngine;} + ~ScriptEngineManager(); bool isFunctionExists(const QString& functionName) const; void deleteFunction(const QString& functionsName); - bool addFunction(const QString& name, QScriptEngine::FunctionSignature function, - const QString& category="", const QString& description=""); + + bool addFunction(const JSFunctionDesc& functionsDescriber); +#ifdef USE_QTSCRIPTENGINE + bool addFunction(const QString &name, QScriptEngine::FunctionSignature function, const QString &category, const QString &description); +#endif bool addFunction(const QString &name, const QString& script, const QString &category="", const QString &description=""); const QString& lastError() const {return m_lastError;} QStringList functionsNames(); - const QList& functionsDescriber(){return m_functions;} + const QList& functionsDescribers(){return m_functions;} ScriptEngineModel* model(){return m_model;} void setContext(ScriptEngineContext* context){m_context=context;} DataSourceManager* dataManager() const {return m_dataManager;} @@ -194,20 +424,46 @@ public: QString expandDataFields(QString context, ExpandType expandType, QVariant &varValue, QObject* reportItem); QString expandScripts(QString context, QVariant &varValue, QObject* reportItem); QVariant evaluateScript(const QString &script); + void addBookMark(const QString &uniqKey, const QString &content); + int findPageIndexByBookmark(const QString& uniqKey); + void addTableOfContentsItem(const QString& uniqKey, const QString& content, int indent); + void clearTableOfContents(); + ScriptValueType moveQObjectToScript(QObject* object, const QString objectName); protected: void updateModel(); bool containsFunction(const QString &functionName); private: Q_DISABLE_COPY(ScriptEngineManager) + bool createLineFunction(); + bool createNumberFomatFunction(); + bool createDateFormatFunction(); + bool createTimeFormatFunction(); + bool createDateTimeFormatFunction(); + bool createSectotimeFormatFunction(); + bool createDateFunction(); + bool createNowFunction(); + bool createCurrencyFormatFunction(); + bool createCurrencyUSBasedFormatFunction(); + bool createSetVariableFunction(); + bool createGetVariableFunction(); + bool createGetFieldFunction(); + bool createGetFieldByKeyFunction(); + bool createGetFieldByRowIndex(); + bool createAddBookmarkFunction(); + bool createFindPageIndexByBookmark(); + bool createAddTableOfContentsItemFunction(); + bool createClearTableOfContentsFunction(); + bool createReopenDatasourceFunction(); private: ScriptEngineManager(); - QScriptEngine* m_scriptEngine; + ScriptEngineType* m_scriptEngine; QString m_lastError; QList m_functions; ScriptEngineModel* m_model; ScriptEngineContext* m_context; DataSourceManager* m_dataManager; + ScriptFunctionsManager* m_functionManager; }; class ScriptExtractor @@ -241,6 +497,7 @@ private: }; +#ifdef USE_QTSCRIPTENGINE class QFontPrototype : public QObject, public QScriptable { Q_OBJECT Q_PROPERTY(QString family READ family) @@ -287,6 +544,12 @@ public: return qScriptValueFromValue(engine, font); } }; +#endif } +#ifdef USE_QTSCRIPTENGINE +Q_DECLARE_METATYPE(LimeReport::ComboBoxPrototype*) +Q_DECLARE_METATYPE(QComboBox*) +#endif + #endif // LRSCRIPTENGINEMANAGER_H diff --git a/limereport/lrscriptenginemanagerintf.h b/limereport/lrscriptenginemanagerintf.h index d7662ff..a8a7c63 100644 --- a/limereport/lrscriptenginemanagerintf.h +++ b/limereport/lrscriptenginemanagerintf.h @@ -29,21 +29,58 @@ ****************************************************************************/ #ifndef LRSCRIPTENGINEMANAGERINTF_H #define LRSCRIPTENGINEMANAGERINTF_H +#include "qglobal.h" +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) + #ifndef USE_QTSCRIPTENGINE + #ifndef USE_QJSENGINE + #define USE_QJSENGINE + #endif + #endif +#else + #ifndef USE_QTSCRIPTENGINE + #define USE_QTSCRIPTENGINE + #endif +#endif + +#ifdef USE_QJSENGINE +#include +#else #include +#endif namespace LimeReport{ +#ifdef USE_QJSENGINE + typedef QJSEngine ScriptEngineType; + typedef QJSValue ScriptValueType; + template + static inline QJSValue getJSValue(QJSEngine &e, T *p) + { + QJSValue res = e.newQObject(p); + QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership); + return res; + } +#else + typedef QScriptEngine ScriptEngineType; + typedef QScriptValue ScriptValueType; +#endif + class IScriptEngineManager{ public: - virtual QScriptEngine* scriptEngine() = 0; - virtual bool addFunction(const QString& name, QScriptEngine::FunctionSignature function, + virtual ScriptEngineType* scriptEngine() = 0; +#ifdef USE_QTSCRIPTENGINE + virtual bool addFunction(const QString& name, ScriptEngineType::FunctionSignature function, const QString& category="", const QString& description="") = 0; +#endif virtual bool addFunction(const QString &name, const QString& script, const QString &category="", const QString &description="") = 0; virtual const QString& lastError() const = 0; + virtual ScriptValueType moveQObjectToScript(QObject* object, const QString objectName) = 0; virtual ~IScriptEngineManager(){} + }; } //namespace LimeReport + #endif // LRSCRIPTENGINEMANAGERINTF_H diff --git a/limereport/lrsettingdialog.cpp b/limereport/lrsettingdialog.cpp index 0b929be..bff304c 100644 --- a/limereport/lrsettingdialog.cpp +++ b/limereport/lrsettingdialog.cpp @@ -1,13 +1,25 @@ #include "lrsettingdialog.h" #include "ui_lrsettingdialog.h" +#include "lrglobal.h" +#include +#include namespace LimeReport{ SettingDialog::SettingDialog(QWidget *parent) : - QDialog(parent), + QDialog(parent), m_settings(0), ui(new Ui::SettingDialog) { ui->setupUi(this); + ui->toolBox->setCurrentIndex(0); +// ui->cbTheme->addItem(QObject::tr("Default")); +// if (isFileExists(":/qdarkstyle/style.qss")){ +// ui->cbTheme->addItem(QObject::tr("Dark")); +// } +// if (isFileExists(":/qlightstyle/lightstyle.qss")){ +// ui->cbTheme->addItem(QObject::tr("Light")); +// } + ui->indentSize->setRange(0,10); } SettingDialog::~SettingDialog() @@ -32,11 +44,42 @@ QFont SettingDialog::defaultFont() return result; } +QFont SettingDialog::scriptFont() +{ + QFont result = ui->scriptFont->currentFont(); + result.setPointSize(ui->scriptFontSize->value()); + return result; +} + +int SettingDialog::tabIndention() +{ + return ui->indentSize->value(); +} + +QString SettingDialog::theme() +{ + return ui->cbTheme->currentText(); +} + bool SettingDialog::suppressAbsentFieldsAndVarsWarnings() { return ui->cbSuppressWarnings->isChecked(); } +QLocale::Language SettingDialog::designerLanguage() +{ + foreach (QLocale::Language language, m_aviableLanguages) { + if (ui->designerLanguage->currentText().compare(QLocale::languageToString(language)) == 0) + return language; + } + return QLocale().language(); +} + +QString SettingDialog::reportUnits() +{ + return ui->reportUnits->currentText(); +} + void SettingDialog::setSuppressAbsentFieldsAndVarsWarnings(bool value){ ui->cbSuppressWarnings->setChecked(value); } @@ -57,4 +100,107 @@ void SettingDialog::setDefaultFont(const QFont &value) ui->defaultFontSize->setValue(value.pointSize()); } +void SettingDialog::setScriptFont(const QFont& value) +{ + ui->scriptFont->setCurrentFont(value); + ui->scriptFontSize->setValue(value.pointSize()); +} + +void SettingDialog::setScritpTabIndention(int size) +{ + ui->indentSize->setValue(size); +} + +void SettingDialog::setTheme(const QString &theme) +{ +#ifdef HAVE_QT4 + ui->cbTheme->setCurrentIndex(ui->cbTheme->findText(theme)); +#else + ui->cbTheme->setCurrentText(theme); +#endif +} + +void SettingDialog::setDesignerLanguages(QList languages, QLocale::Language currentLanguage) +{ + m_aviableLanguages = languages; + m_currentLanguage = currentLanguage; + + if (languages.isEmpty()) { + ui->designerLanguage->setVisible(false); + ui->lblLanguage->setVisible(false); + return; + } + ui->designerLanguage->addItem(QLocale::languageToString(currentLanguage)); + foreach (QLocale::Language language, languages) { + if (language != currentLanguage) + ui->designerLanguage->addItem(QLocale::languageToString(language)); + } +#ifdef HAVE_QT4 + ui->designerLanguage->setCurrentIndex(ui->designerLanguage->findText(QLocale::languageToString(currentLanguage))); +#else + ui->designerLanguage->setCurrentText(QLocale::languageToString(currentLanguage)); +#endif +} + +void SettingDialog::setDesignerThemes(QList themes, const QString ¤tTheme) +{ + ui->cbTheme->clear(); + ui->cbTheme->addItems(themes); +#ifdef HAVE_QT4 + ui->cbTheme->setCurrentIndex(ui->cbTheme->findText(currentTheme)); +#else + ui->cbTheme->setCurrentText(currentTheme); +#endif +} + +void SettingDialog::setDesignerUnites(QList unitTypes, const QString currentUnitType) +{ + ui->reportUnits->clear(); + ui->reportUnits->addItems(unitTypes); +#ifdef HAVE_QT4 + ui->cbTheme->setCurrentIndex(ui->cbTheme->findText(currentUnitType)); +#else + ui->reportUnits->setCurrentText(currentUnitType); +#endif +} + +void SettingDialog::setSettings(QSettings* settings){ + m_settings = settings; + if (m_settings){ + m_settings->beginGroup("ScriptEditor"); + QVariant fontName = m_settings->value("DefaultFontName"); + if (fontName.isValid()){ + QVariant fontSize = m_settings->value("DefaultFontSize"); + ui->scriptFont->setCurrentFont(QFont(fontName.toString(),fontSize.toInt())); + ui->scriptFontSize->setValue(fontSize.toInt()); + } + QVariant indentSize = m_settings->value("TabIndention"); + if (indentSize.isValid()){ + ui->indentSize->setValue(indentSize.toInt()); + } else { + ui->indentSize->setValue(LimeReport::Const::DEFAULT_TAB_INDENTION); + } + m_settings->endGroup(); + } +} + +void SettingDialog::on_bbOkCancel_accepted() +{ + if (m_settings){ + m_settings->beginGroup("ScriptEditor"); + m_settings->setValue("DefaultFontName", ui->scriptFont->currentFont().family()); + m_settings->setValue("DefaultFontSize", ui->scriptFontSize->value()); + m_settings->setValue("TabIndention", ui->indentSize->value()); + m_settings->endGroup(); + } +} + +bool SettingDialog::isFileExists(const QString &path) +{ + QFileInfo check_file(path); + return check_file.exists() && check_file.isFile(); +} + } // namespace LimeReport + + diff --git a/limereport/lrsettingdialog.h b/limereport/lrsettingdialog.h index e9a740d..b10139f 100644 --- a/limereport/lrsettingdialog.h +++ b/limereport/lrsettingdialog.h @@ -2,6 +2,8 @@ #define LRSETTINGDIALOG_H #include +#include +#include namespace LimeReport{ @@ -19,13 +21,32 @@ public: int verticalGridStep(); int horizontalGridStep(); QFont defaultFont(); + QFont scriptFont(); + int tabIndention(); + QString theme(); bool suppressAbsentFieldsAndVarsWarnings(); + QLocale::Language designerLanguage(); + QString reportUnits(); void setSuppressAbsentFieldsAndVarsWarnings(bool value); void setHorizontalGridStep(int value); void setVerticalGridStep(int value); void setDefaultFont(const QFont& value); + void setScriptFont(const QFont& value); + void setScritpTabIndention(int size); + void setTheme(const QString& theme); + void setDesignerLanguages(QList languages, QLocale::Language currentLanguage); + void setDesignerThemes(QList themes, const QString& currentTheme); + void setDesignerUnites(QList unitTypes, const QString currentUnitType); + void setSettings(QSettings* settings); +private slots: + void on_bbOkCancel_accepted(); +private: + bool isFileExists(const QString& path); private: Ui::SettingDialog *ui; + QList m_aviableLanguages; + QLocale::Language m_currentLanguage; + QSettings* m_settings; }; } // namespace LimeReport diff --git a/limereport/lrsettingdialog.ui b/limereport/lrsettingdialog.ui index d3a143a..3c197bf 100644 --- a/limereport/lrsettingdialog.ui +++ b/limereport/lrsettingdialog.ui @@ -6,140 +6,336 @@ 0 0 - 351 - 318 + 419 + 378 + + + 0 + 0 + + Designer setting - + - - - Designer Setting + + + 0 - - - - - - - Default font - - - - - - - - - - 10 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Grid - - + + + + 0 + 0 + 401 + 250 + + + + Designer settings + + + + - - - - - Vertical grid step - - - - - - - 10 - - - - - - - Horizontal grid step - - - - - - - 10 - - - - + + + Default font + + - + + + + + + 10 + + + + + Qt::Horizontal - 73 + 40 20 - - - + + + + + Grid + + + + + + + + Vertical grid step + + + + + + + 10 + + + + + + + Horizontal grid step + + + + + + + 10 + + + + + + + + + Qt::Horizontal + + + + 73 + 20 + + + + + + + + + + + + + Language + + + + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + Theme + + + + + + + + 0 + 0 + + + + + + + + + + + + Report units + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 401 + 250 + + + + Script editor settings + + + + + + + + Font + + + + + + + + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Indent size + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 123 + + + + + + + + + + 0 + 0 + 401 + 250 + + + + Report settings + + + + + + Suppress absent fields and variables warning + + + + + + + Qt::Vertical + + + + 20 + 204 + + + + + + - - - - Report Setting - - - - - - Suppress absent fields and variables warning - - - - - - - - - - Qt::Vertical - - - - 20 - 4 - - - - diff --git a/limereport/lrsimplecrypt.cpp b/limereport/lrsimplecrypt.cpp index d79273e..f54cbb2 100644 --- a/limereport/lrsimplecrypt.cpp +++ b/limereport/lrsimplecrypt.cpp @@ -73,7 +73,7 @@ private: void RC5_SETUP(const char *K); void RC5_ENCRYPT(WORD *pt, WORD *ct); void RC5_DECRYPT(WORD *ct, WORD *pt); - WORD S[26]; + WORD S[26] = {0}; bool m_prepared; }; diff --git a/limereport/lrvariablesholder.cpp b/limereport/lrvariablesholder.cpp index 9cdf630..4e79084 100644 --- a/limereport/lrvariablesholder.cpp +++ b/limereport/lrvariablesholder.cpp @@ -44,7 +44,7 @@ VariablesHolder::~VariablesHolder() QMap::iterator it = m_varNames.begin(); while(it!=m_varNames.end()){ delete *it; - it++; + ++it; } m_varNames.clear(); m_userVariables.clear(); @@ -122,16 +122,50 @@ bool VariablesHolder::containsVariable(const QString &name) return m_varNames.contains(name); } -int VariablesHolder::userVariablesCount() +int VariablesHolder::variablesCount() { return m_userVariables.count(); } -VarDesc *VariablesHolder::userVariableAt(int index) +VarDesc* VariablesHolder::variableByName(const QString& name) +{ + if (m_varNames.contains(name)) + return m_varNames.value(name); + else return 0; +} + +VarDesc *VariablesHolder::variableAt(int index) { return m_userVariables.at(index); } +bool VariablesHolder::variableIsMandatory(const QString& name) +{ + if (m_varNames.contains(name)) + return m_varNames.value(name)->isMandatory(); + else return false; +} + +void VariablesHolder::setVarableMandatory(const QString& name, bool value) +{ + if (m_varNames.contains(name)) + m_varNames.value(name)->setMandatory(value); + +} + +VariableDataType VariablesHolder::variableDataType(const QString& name) +{ + if (m_varNames.contains(name)) + return m_varNames.value(name)->dataType(); + else return Enums::Undefined; +} + +void VariablesHolder::setVariableDataType(const QString& name, VariableDataType value) +{ + if (m_varNames.contains(name)) + m_varNames.value(name)->setDataType(value); +} + QStringList VariablesHolder::variableNames() { QStringList result; @@ -148,4 +182,40 @@ RenderPass VariablesHolder::variablePass(const QString &name) else throw ReportError(tr("variable with name ")+name+tr(" does not exists!")); } +bool VarDesc::isMandatory() const +{ + return m_mandatory; +} + +void VarDesc::setMandatory(bool mandatory) +{ + m_mandatory = mandatory; +} + +void VarDesc::initFrom(VarDesc* value) +{ + m_mandatory = value->isMandatory(); + m_dataType = value->dataType(); +} + +VariableDataType VarDesc::dataType() const +{ + return m_dataType; +} + +void VarDesc::setDataType(const VariableDataType& dataType) +{ + m_dataType = dataType; +} + +int VarDesc::readDataTypeProperty() const +{ + return static_cast(m_dataType); +} + +void VarDesc::setDataTypeProperty(int value) +{ + m_dataType = static_cast(value); +} + }// namespace LimeReport diff --git a/limereport/lrvariablesholder.h b/limereport/lrvariablesholder.h index 5c97bbe..76446b5 100644 --- a/limereport/lrvariablesholder.h +++ b/limereport/lrvariablesholder.h @@ -42,7 +42,10 @@ class VarDesc : public QObject{ Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QVariant value READ value WRITE setValue) + Q_PROPERTY(bool isMandatory READ isMandatory WRITE setMandatory) + Q_PROPERTY(int dataType READ readDataTypeProperty WRITE setDataTypeProperty) public: + VarDesc() : m_dataType(Enums::Undefined), m_mandatory(false){} enum VarType {System, User, Report}; void setVarType(VarType value){m_varType=value;} VarType varType(){return m_varType;} @@ -52,26 +55,39 @@ public: QString name(){return m_name;} void setValue(QVariant value){m_value=value;} QVariant value(){return m_value;} + VariableDataType dataType() const; + void setDataType(const VariableDataType& dataType); + int readDataTypeProperty() const; + void setDataTypeProperty(int value); + bool isMandatory() const; + void setMandatory(bool isMandatory); + void initFrom(VarDesc* value); private: VarType m_varType; RenderPass m_varPass; QString m_name; QVariant m_value; + VariableDataType m_dataType; + bool m_mandatory; }; class IVariablesContainer { public: virtual ~IVariablesContainer(){} - virtual void addVariable(const QString &name, const QVariant &value, VarDesc::VarType type=VarDesc::User, RenderPass pass=FirstPass)=0; - virtual void deleteVariable(const QString &name)=0; - virtual void changeVariable(const QString &name, const QVariant &value)=0; - virtual void clearUserVariables()=0; - virtual QVariant variable(const QString &name)=0; - virtual VarDesc::VarType variableType(const QString &name)=0; - virtual RenderPass variablePass(const QString &name)=0; - virtual bool containsVariable(const QString &name)=0; - virtual QStringList variableNames()=0; + virtual void addVariable(const QString& name, const QVariant &value, VarDesc::VarType type=VarDesc::User, RenderPass pass=FirstPass) = 0; + virtual void deleteVariable(const QString& name) = 0; + virtual void changeVariable(const QString& name, const QVariant &value) = 0; + virtual void clearUserVariables() = 0; + virtual QVariant variable(const QString& name) = 0; + virtual VarDesc::VarType variableType(const QString& name) = 0; + virtual RenderPass variablePass(const QString& name) = 0; + virtual bool containsVariable(const QString& name) = 0; + virtual QStringList variableNames() = 0; + virtual bool variableIsMandatory(const QString& name) = 0; + virtual void setVarableMandatory(const QString& name, bool value) = 0; + virtual VariableDataType variableDataType(const QString& name) = 0; + virtual void setVariableDataType(const QString& name, VariableDataType value) = 0; }; class VariablesHolder : public QObject, public IVariablesContainer @@ -85,12 +101,17 @@ public: void changeVariable(const QString &name, const QVariant &value); void clearUserVariables(); QVariant variable(const QString &name); - VarDesc::VarType variableType(const QString &name); - RenderPass variablePass(const QString &name); - bool containsVariable(const QString &name); - QStringList variableNames(); - int userVariablesCount(); - VarDesc* userVariableAt(int index); + VarDesc::VarType variableType(const QString& name); + RenderPass variablePass(const QString &name); + bool containsVariable(const QString &name); + QStringList variableNames(); + int variablesCount(); + VarDesc* variableByName(const QString& name); + VarDesc* variableAt(int index); + bool variableIsMandatory(const QString& name); + void setVarableMandatory(const QString &name, bool value); + VariableDataType variableDataType(const QString& name); + void setVariableDataType(const QString &name, VariableDataType value); signals: void variableHasBeenAdded(const QString& variableName); void variableHasBeenChanged(const QString& variableName); diff --git a/limereport/objectinspector/editors/lrbuttonlineeditor.cpp b/limereport/objectinspector/editors/lrbuttonlineeditor.cpp index 4f1bc64..8459594 100644 --- a/limereport/objectinspector/editors/lrbuttonlineeditor.cpp +++ b/limereport/objectinspector/editors/lrbuttonlineeditor.cpp @@ -131,6 +131,7 @@ void ButtonLineEditor::editingByEditorFinished() { setText(qobject_cast(sender())->text()); m_lineEdit->setFocus(); + emit editingFinished(); } } //namespace LimeReport diff --git a/limereport/objectinspector/editors/lrcoloreditor.cpp b/limereport/objectinspector/editors/lrcoloreditor.cpp index e845d76..09c22d6 100644 --- a/limereport/objectinspector/editors/lrcoloreditor.cpp +++ b/limereport/objectinspector/editors/lrcoloreditor.cpp @@ -28,11 +28,14 @@ * GNU General Public License for more details. * ****************************************************************************/ #include "lrcoloreditor.h" +#include "lrglobal.h" #include #include #include #include +#include +#include namespace LimeReport{ @@ -94,17 +97,23 @@ void ColorEditor::slotClicked() emit(editingFinished()); } - void ColorIndicator::paintEvent(QPaintEvent* event) { QPainter painter(this); + + QStyle* style = QApplication::style(); painter.save(); painter.setBrush(m_color); - painter.setPen(Qt::gray); - QRect rect = event->rect().adjusted(3,3,-4,-4); - rect.setWidth(rect.height()); - painter.setRenderHint(QPainter::Antialiasing); - painter.drawEllipse(rect); + QColor penColor = isColorDark(m_color) ? Qt::transparent : Qt::darkGray; + + painter.setPen(penColor); + int border = (event->rect().height() - style->pixelMetric(QStyle::PM_IndicatorWidth))/2; + + QRect rect(event->rect().x()+border, event->rect().y()+border, + style->pixelMetric(QStyle::PM_IndicatorWidth), + style->pixelMetric(QStyle::PM_IndicatorWidth));// = option.rect.adjusted(4,4,-4,-6); + + painter.drawRect(rect); painter.restore(); } diff --git a/limereport/objectinspector/images/clear.png b/limereport/objectinspector/images/clear.png index d6c0c31..b72a5a5 100644 Binary files a/limereport/objectinspector/images/clear.png and b/limereport/objectinspector/images/clear.png differ diff --git a/limereport/objectinspector/images/settings.png b/limereport/objectinspector/images/settings.png new file mode 100644 index 0000000..226e2f0 Binary files /dev/null and b/limereport/objectinspector/images/settings.png differ diff --git a/limereport/objectinspector/lobjectinspector.qrc b/limereport/objectinspector/lobjectinspector.qrc index 7dd5e48..6b6f10f 100644 --- a/limereport/objectinspector/lobjectinspector.qrc +++ b/limereport/objectinspector/lobjectinspector.qrc @@ -6,5 +6,6 @@ images/uncheck.png images/check_w.png images/uncheck_w.png + images/settings.png diff --git a/limereport/objectinspector/lrobjectinspectorwidget.cpp b/limereport/objectinspector/lrobjectinspectorwidget.cpp index 325ec1e..3997e16 100644 --- a/limereport/objectinspector/lrobjectinspectorwidget.cpp +++ b/limereport/objectinspector/lrobjectinspectorwidget.cpp @@ -30,6 +30,11 @@ #include #include #include +#include +#include +#include +#include +#include #include "lrglobal.h" #include "lrobjectinspectorwidget.h" @@ -37,7 +42,7 @@ namespace LimeReport{ -ObjectInspectorWidget::ObjectInspectorWidget(QWidget *parent) +ObjectInspectorTreeView::ObjectInspectorTreeView(QWidget *parent) :QTreeView(parent), m_propertyDelegate(0) { setRootIsDecorated(false); @@ -54,9 +59,9 @@ ObjectInspectorWidget::ObjectInspectorWidget(QWidget *parent) setPalette(p); } -ObjectInspectorWidget::~ObjectInspectorWidget(){} +ObjectInspectorTreeView::~ObjectInspectorTreeView(){} -void ObjectInspectorWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const +void ObjectInspectorTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { ObjectPropItem *node = nodeFromIndex(index); StyleOptionViewItem so = options; @@ -84,7 +89,7 @@ void ObjectInspectorWidget::drawRow(QPainter *painter, const QStyleOptionViewIte painter->restore(); } -void ObjectInspectorWidget::mousePressEvent(QMouseEvent *event) +void ObjectInspectorTreeView::mousePressEvent(QMouseEvent *event) { if ((event->button()==Qt::LeftButton)){ @@ -106,7 +111,7 @@ void ObjectInspectorWidget::mousePressEvent(QMouseEvent *event) QTreeView::mousePressEvent(event); } -void ObjectInspectorWidget::initColorMap() +void ObjectInspectorTreeView::initColorMap() { m_colors.reserve(6); m_colors.push_back(QColor(255,230,191)); @@ -117,12 +122,12 @@ void ObjectInspectorWidget::initColorMap() m_colors.push_back(QColor(255,191,239)); } -QColor ObjectInspectorWidget::getColor(const int index) const +QColor ObjectInspectorTreeView::getColor(const int index) const { return m_colors[index]; } -void ObjectInspectorWidget::reset() +void ObjectInspectorTreeView::reset() { QTreeView::reset(); for (int i=0;irowCount();i++){ @@ -132,12 +137,12 @@ void ObjectInspectorWidget::reset() } } -ObjectPropItem * ObjectInspectorWidget::nodeFromIndex(QModelIndex index) const +ObjectPropItem * ObjectInspectorTreeView::nodeFromIndex(QModelIndex index) const { - return static_cast(index.internalPointer()); + return qvariant_cast(index.data(Qt::UserRole)); } -void ObjectInspectorWidget::keyPressEvent(QKeyEvent *event) +void ObjectInspectorTreeView::keyPressEvent(QKeyEvent *event) { if (event->key()==Qt::Key_Return){ if(!m_propertyDelegate->isEditing()){ @@ -149,10 +154,159 @@ void ObjectInspectorWidget::keyPressEvent(QKeyEvent *event) } else QTreeView::keyPressEvent(event); } -void ObjectInspectorWidget::commitActiveEditorData(){ +void ObjectInspectorTreeView::commitActiveEditorData(){ if (state()==QAbstractItemView::EditingState){ commitData(indexWidget(currentIndex())); } } +bool PropertyFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + if (sourceParent.isValid()) return true; + return sourceModel()->data(index).toString().contains(filterRegExp()); +} + +ObjectInspectorWidget::ObjectInspectorWidget(QWidget *parent) + :QWidget(parent), m_filterModel(0) +{ + m_objectInspectorView = new ObjectInspectorTreeView(this); + m_propertyModel = new BaseDesignPropertyModel(this); + m_filterModel = new PropertyFilterModel(this); + m_filterModel->setSourceModel(m_propertyModel); + m_filterModel->setFilterRegExp(QRegExp("", Qt::CaseInsensitive, QRegExp::FixedString)); + m_objectInspectorView->setModel(m_filterModel); + QVBoxLayout* l = new QVBoxLayout(); + QLineEdit* le = new QLineEdit(this); + QToolButton * pbClear = new QToolButton(this); + pbClear->setToolTip(tr("Clear")); + pbClear->setIcon(QIcon(":/items/clear.png")); + connect(pbClear, SIGNAL(clicked()), le, SLOT(clear())); + le->setPlaceholderText(tr("Filter")); + connect(le, SIGNAL(textChanged(const QString&)), this, SLOT(slotFilterTextChanged(const QString&))); + + QToolButton* settingButton = new QToolButton(this); + settingButton->setIcon(QIcon(":/items/images/settings.png")); + QMenu* settingMenu = new QMenu(settingButton); + m_translateProperties = settingMenu->addAction(tr("Translate properties")); + m_translateProperties->setCheckable(true); + m_translateProperties->setChecked(translateProperties()); + + connect(m_translateProperties, SIGNAL(toggled(bool)), + this, SLOT(slotTranslatePropertiesChecked(bool))); + + settingButton->setMenu(settingMenu); + settingButton->setPopupMode(QToolButton::InstantPopup); + + QHBoxLayout* h = new QHBoxLayout(); + h->setSpacing(2); + h->addWidget(le); + h->addWidget(pbClear); + h->addWidget(settingButton); + l->addLayout(h); + l->addWidget(m_objectInspectorView); + l->setMargin(Const::DOCKWIDGET_MARGINS); + l->setSpacing(2); + this->setLayout(l); +} + +void ObjectInspectorWidget::setModel(QAbstractItemModel *model) +{ + + m_filterModel->setSourceModel(model); + +} + +void ObjectInspectorWidget::setAlternatingRowColors(bool value) +{ + m_objectInspectorView->setAlternatingRowColors(value); +} + +void ObjectInspectorWidget::setRootIsDecorated(bool value) +{ + m_objectInspectorView->setRootIsDecorated(value); +} + +void ObjectInspectorWidget::setColumnWidth(int column, int width) +{ + m_objectInspectorView->setColumnWidth(column, width); +} + +int ObjectInspectorWidget::columnWidth(int column) +{ + return m_objectInspectorView->columnWidth(column); +} + +void ObjectInspectorWidget::expandToDepth(int depth) +{ + m_objectInspectorView->expandToDepth(depth); +} + +void ObjectInspectorWidget::commitActiveEditorData() +{ + m_objectInspectorView->commitActiveEditorData(); +} + +void ObjectInspectorWidget::setValidator(ValidatorIntf *validator) +{ + m_propertyModel->setValidator(validator); +} + +bool ObjectInspectorWidget::subclassesAsLevel() +{ + return m_propertyModel->subclassesAsLevel(); +} + +void ObjectInspectorWidget::setSubclassesAsLevel(bool value) +{ + m_propertyModel->setSubclassesAsLevel(value); +} + +bool ObjectInspectorWidget::translateProperties() +{ + return m_propertyModel->isTranslateProperties(); +} + +void ObjectInspectorWidget::setTranslateProperties(bool value) +{ + m_propertyModel->setTranslateProperties(value); + m_translateProperties->setChecked(value); + update(); +} + +const QObject *ObjectInspectorWidget::object(){ + return m_propertyModel->currentObject(); +} + +void ObjectInspectorWidget::setObject(QObject *object) +{ + m_propertyModel->setObject(object); +} + +void ObjectInspectorWidget::setMultiObjects(QList *list) +{ + m_propertyModel->setMultiObjects(list); +} + +void ObjectInspectorWidget::clearObjectsList() +{ + m_propertyModel->clearObjectsList(); +} + +void ObjectInspectorWidget::updateProperty(const QString &propertyName) +{ + m_propertyModel->updateProperty(propertyName); +} + +void ObjectInspectorWidget::slotFilterTextChanged(const QString &filter) +{ + if (m_filterModel) + m_filterModel->setFilterRegExp(QRegExp(filter, Qt::CaseInsensitive, QRegExp::FixedString)); +} + +void ObjectInspectorWidget::slotTranslatePropertiesChecked(bool value) +{ + setTranslateProperties(value); +} + } //namespace LimeReport diff --git a/limereport/objectinspector/lrobjectinspectorwidget.h b/limereport/objectinspector/lrobjectinspectorwidget.h index d6e4495..fb1d0a6 100644 --- a/limereport/objectinspector/lrobjectinspectorwidget.h +++ b/limereport/objectinspector/lrobjectinspectorwidget.h @@ -32,17 +32,20 @@ #include #include +#include + #include "lrobjectitemmodel.h" +#include "lrbasedesignobjectmodel.h" #include "lrpropertydelegate.h" namespace LimeReport{ -class ObjectInspectorWidget : public QTreeView +class ObjectInspectorTreeView : public QTreeView { Q_OBJECT public: - ObjectInspectorWidget(QWidget * parent=0); - ~ObjectInspectorWidget(); + ObjectInspectorTreeView(QWidget * parent=0); + ~ObjectInspectorTreeView(); QColor getColor(const int index) const; virtual void reset(); virtual void commitActiveEditorData(); @@ -59,6 +62,45 @@ private: PropertyDelegate *m_propertyDelegate; }; +class PropertyFilterModel: public QSortFilterProxyModel{ +public: + PropertyFilterModel(QObject* parent = 0): QSortFilterProxyModel(parent){} +protected: + bool filterAcceptsRow(int sourceRow,const QModelIndex &sourceParent) const; +}; + +class ObjectInspectorWidget: public QWidget{ + Q_OBJECT +public: + ObjectInspectorWidget(QWidget* parent = 0); + void setModel(QAbstractItemModel* model); + void setAlternatingRowColors(bool value); + void setRootIsDecorated(bool value); + void setColumnWidth(int column, int width); + int columnWidth(int column); + void expandToDepth(int depth); + void commitActiveEditorData(); + void setValidator(ValidatorIntf *validator); + bool subclassesAsLevel(); + void setSubclassesAsLevel(bool value); + bool translateProperties(); + void setTranslateProperties(bool value); + void setObject(QObject* setObject); + const QObject* object(); + void setMultiObjects(QList* list); + void clearObjectsList(); + void updateProperty(const QString &propertyName); +private slots: + void slotFilterTextChanged(const QString& filter); + void slotTranslatePropertiesChecked(bool value); +private: + ObjectInspectorTreeView* m_objectInspectorView; + QSortFilterProxyModel* m_filterModel; + BaseDesignPropertyModel* m_propertyModel; + QAction* m_translateProperties; + +}; + } //namespace LimeReport #endif // LROBJECTINSPECTORWIDGET_H diff --git a/limereport/objectinspector/lrobjectitemmodel.cpp b/limereport/objectinspector/lrobjectitemmodel.cpp index 26088d0..ea92de3 100644 --- a/limereport/objectinspector/lrobjectitemmodel.cpp +++ b/limereport/objectinspector/lrobjectitemmodel.cpp @@ -134,10 +134,35 @@ void QObjectPropertyModel::translatePropertyName() tr("condition"); tr("groupFieldName"); tr("keepGroupTogether"); + tr("endlessHeight"); + tr("extendedHeight"); + tr("isExtendedInDesignMode"); + tr("pageIsTOC"); + tr("setPageSizeToPrinter"); + tr("fillInSecondPass"); + tr("chartTitle"); + tr("chartType"); + tr("drawLegendBorder"); + tr("labelsField"); + tr("legendAlign"); + tr("series"); + tr("titleAlign"); tr("watermark"); + tr("keepTopSpace"); + tr("printable"); + tr("variable"); tr("replaceCRwithBR"); + tr("hideIfEmpty"); + tr("hideEmptyItems"); + tr("useExternalPainter"); + tr("layoutSpacing"); + tr("printerName"); + tr("fontLetterSpacing"); tr("hideText"); tr("option3"); + tr("units"); + tr("geometryLocked"); + tr("printBehavior"); } void QObjectPropertyModel::clearObjectsList() @@ -146,7 +171,8 @@ void QObjectPropertyModel::clearObjectsList() } QObjectPropertyModel::QObjectPropertyModel(QObject *parent/*=0*/) - :QAbstractItemModel(parent),m_rootNode(0),m_object(0),m_dataChanging(false), m_subclassesAsLevel(true), m_validator(0) + :QAbstractItemModel(parent),m_rootNode(0), m_object(0), m_dataChanging(false), + m_subclassesAsLevel(true), m_validator(0), m_translateProperties(true) {} QObjectPropertyModel::~QObjectPropertyModel() @@ -274,16 +300,19 @@ QVariant QObjectPropertyModel::data(const QModelIndex &index, int role) const switch (role) { case Qt::DisplayRole: if (!node) return QVariant(); + node->setTranslateProperty(isTranslateProperties()); if (index.column()==0){ return node->displayName(); - } else return node->displayValue(); - break; + } else { + return node->displayValue(); + } case Qt::DecorationRole : if (!node) return QIcon(); if (index.column()==1){ return node->iconValue(); - }else return QIcon(); - break; + } else return QIcon(); + case Qt::UserRole: + return QVariant::fromValue(node); default: return QVariant(); } @@ -386,13 +415,23 @@ ObjectPropItem * QObjectPropertyModel::createPropertyItem(QMetaProperty prop, QO 0, 0, QString(prop.name()), - QString(prop.name()), + QString(tr(prop.name())), object->property(prop.name()), parent ); } return propertyItem; } + +bool QObjectPropertyModel::isTranslateProperties() const +{ + return m_translateProperties; +} + +void QObjectPropertyModel::setTranslateProperties(bool translateProperties) +{ + m_translateProperties = translateProperties; +} ValidatorIntf *QObjectPropertyModel::validator() const { return m_validator; diff --git a/limereport/objectinspector/lrobjectitemmodel.h b/limereport/objectinspector/lrobjectitemmodel.h index bf01cb2..2aa1f8b 100644 --- a/limereport/objectinspector/lrobjectitemmodel.h +++ b/limereport/objectinspector/lrobjectitemmodel.h @@ -72,6 +72,9 @@ public: void setValidator(ValidatorIntf* validator); void translatePropertyName(); void clearObjectsList(); + bool isTranslateProperties() const; + void setTranslateProperties(bool isTranslateProperties); + signals: void objectPropetyChanged(const QString& , const QVariant&, const QVariant&); private slots: @@ -83,12 +86,13 @@ private: LimeReport::CreatePropItem propertyItemCreator(QMetaProperty prop); LimeReport::ObjectPropItem* createPropertyItem(QMetaProperty prop, QObject *object, ObjectPropItem::ObjectsList* objects, ObjectPropItem* parent); private: - LimeReport::ObjectPropItem* m_rootNode; - QObject* m_object; - QList m_objects; - bool m_dataChanging; - bool m_subclassesAsLevel; - ValidatorIntf* m_validator; + LimeReport::ObjectPropItem* m_rootNode; + QObject* m_object; + QList m_objects; + bool m_dataChanging; + bool m_subclassesAsLevel; + ValidatorIntf* m_validator; + bool m_translateProperties; }; } diff --git a/limereport/objectinspector/lrobjectpropitem.cpp b/limereport/objectinspector/lrobjectpropitem.cpp index 3fc212c..6ef6613 100644 --- a/limereport/objectinspector/lrobjectpropitem.cpp +++ b/limereport/objectinspector/lrobjectpropitem.cpp @@ -42,7 +42,8 @@ bool lesThen(ObjectPropItem* v1, ObjectPropItem* v2){ ObjectPropItem::ObjectPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, ObjectPropItem *parent, bool isClass) :m_object(object), m_name(name), m_displayName(displayName), m_haveValue(false), m_parent(parent), m_colorIndex(-1), - m_readonly(true), m_model(0), m_isClass(isClass), m_changingValue(false) + m_readonly(true), m_model(0), m_isClass(isClass), m_changingValue(false), + m_translatePropperty(true) { if (parent) setModel(parent->model()); m_index=QModelIndex(); @@ -60,7 +61,8 @@ ObjectPropItem::ObjectPropItem(QObject *object, ObjectsList* objects, const QStr ObjectPropItem::ObjectPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly) :m_object(object), m_name(name), m_displayName(displayName), m_value(value), m_haveValue(true), m_parent(parent), m_colorIndex(-1), - m_readonly(readonly), m_model(0), m_isClass(false), m_changingValue(false) + m_readonly(readonly), m_model(0), m_isClass(false), m_changingValue(false), + m_translatePropperty(true) { if (parent) setModel(parent->model()); m_index=QModelIndex(); @@ -109,6 +111,10 @@ void ObjectPropItem::setPropertyValue(QVariant value){ } } +QString ObjectPropItem::displayName() const { + return isTranslateProperty() ? m_displayName : propertyName(); +} + int ObjectPropItem::row(){ if (m_parent) return m_parent->m_childItems.indexOf(const_cast(this)); @@ -155,6 +161,16 @@ void ObjectPropItem::setValueToObject(const QString &propertyName, QVariant prop } } +bool ObjectPropItem::isTranslateProperty() const +{ + return m_translatePropperty; +} + +void ObjectPropItem::setTranslateProperty(bool translatePropperty) +{ + m_translatePropperty = translatePropperty; +} + ObjectPropItem * ObjectPropItem::findChild(const QString &name) { foreach(ObjectPropItem* item,m_childItems){ diff --git a/limereport/objectinspector/lrobjectpropitem.h b/limereport/objectinspector/lrobjectpropitem.h index c5403cd..46392fc 100644 --- a/limereport/objectinspector/lrobjectpropitem.h +++ b/limereport/objectinspector/lrobjectpropitem.h @@ -56,7 +56,7 @@ namespace LimeReport{ virtual QVariant propertyValue() const; virtual void setPropertyValue(QVariant value); virtual QString propertyName() const {return m_name;} - virtual QString displayName() const {return m_displayName;} + virtual QString displayName() const; virtual QString displayValue() const; virtual QIcon iconValue() const{return QIcon();} virtual bool isHaveChildren() const {return m_childItems.count()>0;} @@ -90,6 +90,8 @@ namespace LimeReport{ void setModelIndex(const QModelIndex& index){m_index=index;} QModelIndex modelIndex(){return m_index;} bool isClass(){return m_isClass;} + bool isTranslateProperty() const; + void setTranslateProperty(bool translatePropperty); #ifdef INSPECT_BASEDESIGN private slots: void slotPropertyChanged(const QString& name, QVariant, QVariant newValue); @@ -120,6 +122,7 @@ namespace LimeReport{ QModelIndex m_index; bool m_isClass; bool m_changingValue; + bool m_translatePropperty; }; typedef QPair APropIdent; diff --git a/limereport/objectinspector/lrpropertydelegate.cpp b/limereport/objectinspector/lrpropertydelegate.cpp index 170ccd3..3a67cdc 100644 --- a/limereport/objectinspector/lrpropertydelegate.cpp +++ b/limereport/objectinspector/lrpropertydelegate.cpp @@ -36,14 +36,22 @@ #include "lrglobal.h" LimeReport::PropertyDelegate::PropertyDelegate(QObject *parent) - :QItemDelegate(parent), m_objectInspector(NULL), m_editingItem(0), m_isEditing(false) + :QStyledItemDelegate(parent), m_objectInspector(NULL), m_editingItem(0), m_isEditing(false) {} void LimeReport::PropertyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid()) return; - LimeReport::ObjectPropItem *node = static_cast(index.internalPointer()); +#if QT_VERSION >= 0x050000 + QStyleOptionViewItem opt = option; +#else + QStyleOptionViewItemV4 opt = option; +#endif + + QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); + + LimeReport::ObjectPropItem *node = qvariant_cast(index.data(Qt::UserRole)); if (node){ if (!node->isHaveValue()){ if (index.column()==0) { @@ -54,31 +62,15 @@ void LimeReport::PropertyDelegate::paint(QPainter *painter, const QStyleOptionVi painter->save(); painter->setPen(option.palette.color(QPalette::HighlightedText)); painter->setBackground(QBrush(option.palette.color(QPalette::Highlight))); - drawBackground(painter,option,index); cellOpt.widget->style()->drawPrimitive(QStyle::PE_IndicatorBranch,&primitiveOpt,painter); cellOpt.rect.adjust(primitiveOpt.rect.width(),0,0,0); cellOpt.font.setBold(true); cellOpt.palette.setColor(QPalette::Text,cellOpt.palette.color(QPalette::BrightText)); - drawDisplay(painter,cellOpt,cellOpt.rect,LimeReport::extractClassName(node->propertyName())); + cellOpt.text = LimeReport::extractClassName(node->propertyName()); + style->drawControl(QStyle::CE_ItemViewItem, &cellOpt, painter, cellOpt.widget); painter->restore(); } - } else - { - if (index.column()==0){ - QPointF start( - option.rect.x()+option.rect.width()-1, - option.rect.y() - ); - QPointF end( - option.rect.x()+option.rect.width()-1, - option.rect.y()+option.rect.height() - ); - painter->save(); - QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option)); - painter->setPen(color); - painter->drawLine(start,end); - painter->restore(); - } + } else { StyleOptionViewItem so = option; if ((node->isValueReadonly())&&(!node->isHaveChildren())) { @@ -98,14 +90,38 @@ void LimeReport::PropertyDelegate::paint(QPainter *painter, const QStyleOptionVi else so.palette.setColor(QPalette::Text,Qt::black); - drawBackground(painter,option,index); - if (!node->paint(painter,so,index)) - QItemDelegate::paint(painter, so, index); + opt.text = ""; + opt.rect.setHeight(opt.rect.height()-1); + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); + + if (!node->paint(painter,so,index)){ + so.state &= ~QStyle::State_HasFocus; + so.rect.adjust(0,0,0,-1); + QStyledItemDelegate::paint(painter, so, index); + } + + if (index.column()==0){ + QPointF start( + option.rect.x()+option.rect.width()-1, + option.rect.y() + ); + QPointF end( + option.rect.x()+option.rect.width()-1, + option.rect.y()+option.rect.height() + ); + painter->save(); + QColor color = static_cast(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option)); + painter->setPen(color); + painter->drawLine(start,end); + painter->restore(); + } + + } } } -QSize LimeReport::PropertyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const +QSize LimeReport::PropertyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize size=option.rect.size(); size.setHeight(option.fontMetrics.height()+ @@ -113,13 +129,15 @@ QSize LimeReport::PropertyDelegate::sizeHint(const QStyleOptionViewItem &option, #ifdef Q_OS_MAC +QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin) #endif - +2); - return size; + +4); + //return size; + QSize defaultSize = QStyledItemDelegate::sizeHint(option, index); + return size.height() > defaultSize.height() ? size : defaultSize; } QWidget * LimeReport::PropertyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { - m_editingItem=static_cast(index.internalPointer()); + m_editingItem = qvariant_cast(index.data(Qt::UserRole)); connect(m_editingItem,SIGNAL(destroyed(QObject*)), this, SLOT(slotItemDeleted(QObject*))); QWidget *editor=m_editingItem->createProperyEditor(parent); if (editor){ @@ -155,7 +173,7 @@ void LimeReport::PropertyDelegate::updateEditorGeometry(QWidget *editor, const Q if (m_editingItem) m_editingItem->updateEditorGeometry(editor,option,index); } -void LimeReport::PropertyDelegate::setObjectInspector(ObjectInspectorWidget* objectInspector) +void LimeReport::PropertyDelegate::setObjectInspector(ObjectInspectorTreeView* objectInspector) { m_objectInspector=objectInspector; } diff --git a/limereport/objectinspector/lrpropertydelegate.h b/limereport/objectinspector/lrpropertydelegate.h index f7e2414..b64cdae 100644 --- a/limereport/objectinspector/lrpropertydelegate.h +++ b/limereport/objectinspector/lrpropertydelegate.h @@ -39,14 +39,14 @@ namespace LimeReport{ -class ObjectInspectorWidget; -class PropertyDelegate : public QItemDelegate -//class PropertyDelegate : public QStyledItemDelegate +class ObjectInspectorTreeView; +//class PropertyDelegate : public QItemDelegate +class PropertyDelegate : public QStyledItemDelegate { Q_OBJECT public: PropertyDelegate(QObject *parent=0); - void setObjectInspector(ObjectInspectorWidget* objectInspector); + void setObjectInspector(ObjectInspectorTreeView* objectInspector); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; @@ -60,7 +60,7 @@ private slots: void slotEditorDeleted(); void slotItemDeleted(QObject* item); private: - LimeReport::ObjectInspectorWidget* m_objectInspector; + LimeReport::ObjectInspectorTreeView* m_objectInspector; mutable LimeReport::ObjectPropItem* m_editingItem; mutable bool m_isEditing; }; diff --git a/limereport/objectinspector/propertyItems/lrcolorpropitem.cpp b/limereport/objectinspector/propertyItems/lrcolorpropitem.cpp index 8201e22..a47f77c 100644 --- a/limereport/objectinspector/propertyItems/lrcolorpropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrcolorpropitem.cpp @@ -28,8 +28,10 @@ * GNU General Public License for more details. * ****************************************************************************/ #include "lrcolorpropitem.h" +#include "lrglobal.h" #include "editors/lrcoloreditor.h" #include +#include namespace{ LimeReport::ObjectPropItem * createColorPropItem( @@ -58,22 +60,20 @@ bool ColorPropItem::paint(QPainter *painter, const StyleOptionViewItem &option, { if (index.column()==1){ painter->save(); + + QStyle* style = option.widget ? option.widget->style() : QApplication::style(); QPen pen; - - if (option.state & QStyle::State_Selected){ - pen.setWidth(2); - pen.setColor(option.palette.brightText().color()); - }else { - pen.setColor(Qt::gray); - } - + QColor penColor = isColorDark(propertyValue().value()) ? Qt::transparent : Qt::darkGray; + pen.setColor(penColor); painter->setPen(pen); - painter->setBrush(propertyValue().value()); - QRect rect = option.rect.adjusted(4,4,-4,-6); - rect.setWidth(rect.height()); - painter->setRenderHint(QPainter::Antialiasing); - painter->drawEllipse(rect); + int border = (option.rect.height() - style->pixelMetric(QStyle::PM_IndicatorWidth))/2; + + QRect rect(option.rect.x()+border,option.rect.y()+border, + style->pixelMetric(QStyle::PM_IndicatorWidth), + style->pixelMetric(QStyle::PM_IndicatorWidth)); + painter->drawRect(rect); + painter->restore(); return true; } else return false; diff --git a/limereport/objectinspector/propertyItems/lrcontentpropitem.cpp b/limereport/objectinspector/propertyItems/lrcontentpropitem.cpp index 53c9806..cc50ced 100644 --- a/limereport/objectinspector/propertyItems/lrcontentpropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrcontentpropitem.cpp @@ -26,7 +26,6 @@ void ContentEditor::editButtonClicked() dialog->setLayout(new QVBoxLayout()); dialog->layout()->setContentsMargins(1,1,1,1); dialog->setAttribute(Qt::WA_DeleteOnClose); - //dialog->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, dialog->size(), QApplication::desktop()->availableGeometry())); dialog->setWindowTitle(propertyName()); QWidget* editor = dynamic_cast(m_object)->defaultEditor(); dialog->layout()->addWidget(editor); diff --git a/limereport/objectinspector/propertyItems/lrdatasourcepropitem.cpp b/limereport/objectinspector/propertyItems/lrdatasourcepropitem.cpp index 4f0dd11..08fc0a3 100644 --- a/limereport/objectinspector/propertyItems/lrdatasourcepropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrdatasourcepropitem.cpp @@ -48,15 +48,23 @@ namespace{ bool VARIABLE_IS_NOT_USED registredDatasouceProp = LimeReport::ObjectPropFactory::instance().registerCreator( LimeReport::APropIdent("datasource","LimeReport::DataBandDesignIntf"),QObject::tr("datasource"),createDatasourcePropItem ); + bool VARIABLE_IS_NOT_USED registredImageDatasouceProp = LimeReport::ObjectPropFactory::instance().registerCreator( LimeReport::APropIdent("datasource","LimeReport::ImageItem"),QObject::tr("datasource"),createDatasourcePropItem ); + bool VARIABLE_IS_NOT_USED registredImageFieldProp = LimeReport::ObjectPropFactory::instance().registerCreator( LimeReport::APropIdent("field","LimeReport::ImageItem"),QObject::tr("field"),createFieldPropItem ); + + bool VARIABLE_IS_NOT_USED registredChartDatasouceProp = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("datasource","LimeReport::ChartItem"),QObject::tr("datasource"),createDatasourcePropItem + ); + bool VARIABLE_IS_NOT_USED registredBarcodeDatasouceProp = LimeReport::ObjectPropFactory::instance().registerCreator( LimeReport::APropIdent("datasource","LimeReport::BarcodeItem"),QObject::tr("datasource"),createDatasourcePropItem ); + bool VARIABLE_IS_NOT_USED registredBarcodeFieldProp = LimeReport::ObjectPropFactory::instance().registerCreator( LimeReport::APropIdent("field","LimeReport::BarcodeItem"),QObject::tr("field"),createFieldPropItem ); diff --git a/limereport/objectinspector/propertyItems/lrenumpropitem.cpp b/limereport/objectinspector/propertyItems/lrenumpropitem.cpp index 36ebe26..385b2d6 100644 --- a/limereport/objectinspector/propertyItems/lrenumpropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrenumpropitem.cpp @@ -132,6 +132,21 @@ void EnumPropItem::translateEnumItemName() tr("Horizontal"); tr("Vertical"); tr("VerticalUniform"); + tr("Pie"); + tr("VerticalBar"); + tr("HorizontalBar"); + tr("LegendAlignTop"); + tr("LegendAlignCenter"); + tr("LegendAlignBottom"); + tr("TitleAlignLeft"); + tr("TitleAlignRight"); + tr("TitleAlignCenter"); + tr("Layout"); + tr("Table"); + tr("Millimeters"); + tr("Inches"); + tr("Scale"); + tr("Split"); } void EnumPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const @@ -149,7 +164,7 @@ void EnumPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *mod QString EnumPropItem::nameByType(int value) const { QMetaEnum propEnum = object()->metaObject()->property(object()->metaObject()->indexOfProperty(propertyName().toLatin1())).enumerator(); - return tr(propEnum.valueToKey(value)); + return isTranslateProperty() ? tr(propEnum.valueToKey(value)) : propEnum.valueToKey(value); } int EnumPropItem::typeByName(const QString &value) const diff --git a/limereport/objectinspector/propertyItems/lrflagspropitem.cpp b/limereport/objectinspector/propertyItems/lrflagspropitem.cpp index 987ec94..91d142e 100644 --- a/limereport/objectinspector/propertyItems/lrflagspropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrflagspropitem.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -98,8 +97,8 @@ QString FlagsPropItem::displayValue() const { if ((propEnum.keyToValue(propEnum.key(i)) == 0) ? propertyValue().toInt() == 0 : (propertyValue().toInt() & propEnum.keyToValue(propEnum.key(i))) == propEnum.keyToValue(propEnum.key(i))) { - if (result.isEmpty()) result+= tr(propEnum.key(i)); - else result=result+" | "+tr(propEnum.key(i)); + if (result.isEmpty()) result+= isTranslateProperty() ? tr(propEnum.key(i)) : propEnum.key(i); + else result=result+" | "+ (isTranslateProperty() ? tr(propEnum.key(i)) : propEnum.key(i)); } } @@ -123,6 +122,7 @@ void FlagsPropItem::translateFlagsItem() tr("BottomLine"); tr("LeftLine"); tr("RightLine"); + tr("AllLines"); } FlagPropItem::FlagPropItem(QObject* object, ObjectsList* objects, const QString &propName, const QString &displayName, const QVariant &value, ObjectPropItem* parent, bool readonly) diff --git a/limereport/objectinspector/propertyItems/lrmarginpropitem.cpp b/limereport/objectinspector/propertyItems/lrmarginpropitem.cpp new file mode 100644 index 0000000..66bbc25 --- /dev/null +++ b/limereport/objectinspector/propertyItems/lrmarginpropitem.cpp @@ -0,0 +1,102 @@ +#include "lrmarginpropitem.h" +#include +#include +#include "lrbasedesignintf.h" + +namespace { + LimeReport::ObjectPropItem * createMarginPropItem( + QObject *object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly) + { + return new LimeReport::MarginPropItem(object, objects, name, displayName, data, parent, readonly); + } + bool VARIABLE_IS_NOT_USED registredTopMargin = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("topMargin","LimeReport::PageItemDesignIntf"), + QObject::tr("margin"),createMarginPropItem + ); + bool VARIABLE_IS_NOT_USED registredRightMargin = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("rightMargin","LimeReport::PageItemDesignIntf"), + QObject::tr("margin"),createMarginPropItem + ); + bool VARIABLE_IS_NOT_USED registredBottomMargin = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("bottomMargin","LimeReport::PageItemDesignIntf"), + QObject::tr("margin"),createMarginPropItem + ); + bool VARIABLE_IS_NOT_USED registredLeftMargin = LimeReport::ObjectPropFactory::instance().registerCreator( + LimeReport::APropIdent("leftMargin","LimeReport::PageItemDesignIntf"), + QObject::tr("margin"),createMarginPropItem + ); +} + +namespace LimeReport{ + + +QString MarginPropItem::displayValue() const +{ + LimeReport::BaseDesignIntf * item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + + return QString("%1 %2").arg(propertyValue().toDouble(), 0, 'f', 2) + .arg(QObject::tr("mm")); + case LimeReport::BaseDesignIntf::Inches: + return QString("%1 %2").arg((propertyValue().toDouble() * Const::mmFACTOR) / (item->unitFactor() * 10), 0, 'f', 2) + .arg(QObject::tr("''")); + } +} + +QWidget *MarginPropItem::createProperyEditor(QWidget *parent) const +{ + QDoubleSpinBox *editor= new QDoubleSpinBox(parent); + editor->setMaximum(std::numeric_limits::max()); + editor->setMinimum(std::numeric_limits::max()*-1); + editor->setSuffix(" "+unitShortName()); + return editor; +} + +void MarginPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +{ + QDoubleSpinBox *editor =qobject_cast(propertyEditor); + editor->setValue(valueInUnits(propertyValue().toReal())); +} + +void MarginPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +{ + model->setData(index, valueInReportUnits(qobject_cast(propertyEditor)->value())); + setValueToObject(propertyName(), propertyValue()); +} + +qreal MarginPropItem::valueInUnits(qreal value) const +{ + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return value; + case LimeReport::BaseDesignIntf::Inches: + return (value * Const::mmFACTOR) / (item->unitFactor() * 10); + } +} + +qreal MarginPropItem::valueInReportUnits(qreal value) const +{ + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return value; + case LimeReport::BaseDesignIntf::Inches: + return (value * (item->unitFactor() * 10)) / Const::mmFACTOR; + + } +} + +QString MarginPropItem::unitShortName() const +{ + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return QObject::tr("mm"); + case LimeReport::BaseDesignIntf::Inches: + return QObject::tr("''"); + } +} + +} // namespace LimeReport diff --git a/limereport/objectinspector/propertyItems/lrmarginpropitem.h b/limereport/objectinspector/propertyItems/lrmarginpropitem.h new file mode 100644 index 0000000..f511ce1 --- /dev/null +++ b/limereport/objectinspector/propertyItems/lrmarginpropitem.h @@ -0,0 +1,28 @@ +#ifndef LRMARGINPROPITEM_H +#define LRMARGINPROPITEM_H + +#include "lrobjectpropitem.h" + +namespace LimeReport { + +class MarginPropItem : public ObjectPropItem +{ + Q_OBJECT +public: + MarginPropItem():ObjectPropItem(){} + MarginPropItem(QObject* object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value,ObjectPropItem* parent, bool readonly) + :ObjectPropItem(object, objects, name, displayName, value, parent, readonly){} + QString displayValue() const; + QWidget* createProperyEditor(QWidget *parent) const; + void setPropertyEditorData(QWidget * propertyEditor, const QModelIndex &) const; + void setModelData(QWidget * propertyEditor, QAbstractItemModel * model, const QModelIndex & index); +private: + qreal valueInUnits(qreal value) const; + qreal valueInReportUnits(qreal value) const; + QString unitShortName() const; +}; + +} // namespace LimeReport + + +#endif // LRMARGINPROPITEM_H diff --git a/limereport/objectinspector/propertyItems/lrqrealpropitem.cpp b/limereport/objectinspector/propertyItems/lrqrealpropitem.cpp index 096c91d..2d27868 100644 --- a/limereport/objectinspector/propertyItems/lrqrealpropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrqrealpropitem.cpp @@ -38,8 +38,9 @@ namespace{ { return new LimeReport::QRealPropItem(object, objects, name, displayName, data, parent, readonly); } + bool VARIABLE_IS_NOT_USED registred = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("qreal",""),QObject::tr("qreal"),createQRealPropItem); - bool VARIABLE_IS_NOT_USED registredDouble = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("double",""),QObject::tr("qreal"),createQRealPropItem); + bool VARIABLE_IS_NOT_USED registredDouble = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("double",""),QObject::tr("qreal"),createQRealPropItem); } namespace LimeReport{ @@ -61,7 +62,6 @@ void QRealPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelI void QRealPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) { model->setData(index,qobject_cast(propertyEditor)->value()); - //object()->setProperty(propertyName().toLatin1(),propertyValue()); setValueToObject(propertyName(),propertyValue()); } diff --git a/limereport/objectinspector/propertyItems/lrqrealpropitem.h b/limereport/objectinspector/propertyItems/lrqrealpropitem.h index d06872f..c8a2616 100644 --- a/limereport/objectinspector/propertyItems/lrqrealpropitem.h +++ b/limereport/objectinspector/propertyItems/lrqrealpropitem.h @@ -47,6 +47,4 @@ public: }; } - - #endif // LRQREALPROPITEM_H diff --git a/limereport/objectinspector/propertyItems/lrrectproptem.cpp b/limereport/objectinspector/propertyItems/lrrectproptem.cpp index 638dcab..a5503f7 100644 --- a/limereport/objectinspector/propertyItems/lrrectproptem.cpp +++ b/limereport/objectinspector/propertyItems/lrrectproptem.cpp @@ -45,14 +45,14 @@ namespace{ ){ return new LimeReport::RectPropItem(object, objects, name, displayName, data, parent, readonly); } - LimeReport::ObjectPropItem * createReqtMMItem( + LimeReport::ObjectPropItem * createReqtUnitItem( QObject*object, LimeReport::ObjectPropItem::ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& data, LimeReport::ObjectPropItem* parent, bool readonly ){ - return new LimeReport::RectMMPropItem(object, objects, name, displayName, data, parent, readonly); + return new LimeReport::RectUnitPropItem(object, objects, name, displayName, data, parent, readonly); } bool VARIABLE_IS_NOT_USED registredRectProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QRect",""),QObject::tr("QRect"),createReqtItem); bool VARIABLE_IS_NOT_USED registredRectFProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("QRectF",""),QObject::tr("QRectF"),createReqtItem); - bool VARIABLE_IS_NOT_USED registredRectMMProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("geometry","LimeReport::BaseDesignIntf"),QObject::tr("geometry"),createReqtMMItem); + bool VARIABLE_IS_NOT_USED registredRectMMProp = LimeReport::ObjectPropFactory::instance().registerCreator(LimeReport::APropIdent("geometry","LimeReport::BaseDesignIntf"),QObject::tr("geometry"),createReqtUnitItem); } namespace LimeReport{ @@ -63,9 +63,8 @@ template QString rectToString(T rect) } QRectF modifyRect(QRectF rect, const QString& name, qreal itemValue){ - - if (name=="x"){qreal width=rect.width(); rect.setX(itemValue);rect.setWidth(width);} - if (name=="y"){qreal heigh=rect.height(); rect.setY(itemValue);rect.setHeight(heigh);} + if (name=="x"){qreal width=rect.width(); rect.setX(itemValue); rect.setWidth(width);} + if (name=="y"){qreal heigh=rect.height(); rect.setY(itemValue); rect.setHeight(heigh);} if (name=="height"){rect.setHeight(itemValue);} if (name=="width"){rect.setWidth(itemValue);} @@ -89,118 +88,152 @@ QString LimeReport::RectPropItem::displayValue() const switch(propertyValue().type()){ case QVariant::Rect: return rectToString(propertyValue().toRect()); - break; case QVariant::RectF: return rectToString(propertyValue().toRect()); - break; default : return ObjectPropItem::displayValue(); - } } -LimeReport::RectMMPropItem::RectMMPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool /*readonly*/): +LimeReport::RectUnitPropItem::RectUnitPropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool /*readonly*/): ObjectPropItem(object, objects, name, displayName, value,parent) { - QRectF rect=value.toRect(); + QRectF rect= value.toRect(); LimeReport::BandDesignIntf* band = dynamic_cast(object); - LimeReport::PageItemDesignIntf *page = dynamic_cast(object); - if(band){ - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "x","x",rect.x()/10,this,true)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "y","y",rect.y()/10,this,true)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "width",tr("width"), rect.width()/10,this,true)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "height",tr("height"), rect.height()/10,this,false)); - } else if(page){ - this->appendItem(new LimeReport::RectMMValuePropItem(object, 0, "x","x",rect.x()/10,this,true)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, 0, "y","y",rect.y()/10,this,true)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, 0,"width", tr("width"), rect.width()/10,this,false)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, 0, "height", tr("height"), rect.height()/10,this,false)); + LimeReport::PageItemDesignIntf* page = dynamic_cast(object); + LimeReport::BaseDesignIntf* item = dynamic_cast(object); + + if (band){ + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "x", "x", rect.x(), this, true)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "y", "y", rect.y(), this, true)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "width", tr("width"), rect.width(), this, true)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "height", tr("height"), rect.height(), this, false)); + } else if (page){ + this->appendItem(new LimeReport::RectUnitValuePropItem(object, 0, "x", "x", rect.x(), this, true)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, 0, "y", "y",rect.y(), this, true)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, 0,"width", tr("width"), rect.width(), this, false)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, 0, "height", tr("height"), rect.height(), this, false)); } else { - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "x","x",rect.x()/10,this,false)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "y","y",rect.y()/10,this,false)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "width", tr("width"), rect.width()/10,this,false)); - this->appendItem(new LimeReport::RectMMValuePropItem(object, objects, "height", tr("height"), rect.height()/10,this,false)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "x", "x", rect.x(), this, false)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "y", "y", rect.y(), this, false)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "width", tr("width"), rect.width(), this, false)); + this->appendItem(new LimeReport::RectUnitValuePropItem(object, objects, "height", tr("height"), rect.height(), this, false)); } - LimeReport::BaseDesignIntf * item = dynamic_cast(object); + if (item){ connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),this,SLOT(itemGeometryChanged(QObject*,QRectF,QRectF))); connect(item,SIGNAL(posChanged(QObject*,QPointF,QPointF)),this,SLOT(itemPosChanged(QObject*,QPointF,QPointF))); + connect(item,SIGNAL(posChanging(QObject*,QPointF,QPointF)),this,SLOT(itemPosChanged(QObject*,QPointF,QPointF))); } } -QString LimeReport::RectMMPropItem::displayValue() const +QString LimeReport::RectUnitPropItem::displayValue() const { - QRectF rect = propertyValue().toRectF(); - return QString("[%1,%2] %3x%4 mm") - .arg(rect.x()/10,0,'f',2) - .arg(rect.y()/10,0,'f',2) - .arg(rect.width()/10,0,'f',2) - .arg(rect.height()/10,0,'f',2); + QRectF rect = rectInUnits(propertyValue().toRectF()); + return QString("[%1,%2] %3x%4 %5") + .arg(rect.x(), 0, 'f', 2) + .arg(rect.y(), 0,'f', 2) + .arg(rect.width(), 0, 'f', 2) + .arg(rect.height(), 0, 'f', 2) + .arg(unitShortName()); } -LimeReport::RectMMValuePropItem::RectMMValuePropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly +LimeReport::RectUnitValuePropItem::RectUnitValuePropItem(QObject *object, ObjectsList* objects, const QString &name, const QString &displayName, const QVariant &value, ObjectPropItem *parent, bool readonly ):ObjectPropItem(object, objects, name, displayName, value,parent,readonly){} -QWidget * LimeReport::RectMMValuePropItem::createProperyEditor(QWidget *parent) const +QWidget * LimeReport::RectUnitValuePropItem::createProperyEditor(QWidget *parent) const { QDoubleSpinBox *editor= new QDoubleSpinBox(parent); editor->setMaximum(100000); - editor->setSuffix(" mm"); + editor->setSuffix(" "+unitShortName()); return editor; } -void LimeReport::RectMMValuePropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const +void LimeReport::RectUnitValuePropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const { QDoubleSpinBox *editor = qobject_cast(propertyEditor); - editor->setValue(propertyValue().toDouble()); + editor->setValue(valueInUnits(propertyValue().toReal())); } -void LimeReport::RectMMValuePropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) +void LimeReport::RectUnitValuePropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *model, const QModelIndex &index) { - model->setData(index,qobject_cast(propertyEditor)->value()); + model->setData(index,valueInReportUnits(qobject_cast(propertyEditor)->value())); QRectF rect=object()->property(parent()->propertyName().toLatin1()).toRectF(); - object()->setProperty(parent()->propertyName().toLatin1(),modifyRect(rect,propertyName(),propertyValue().toReal()*10)); + object()->setProperty(parent()->propertyName().toLatin1(), modifyRect(rect, propertyName(), propertyValue().toReal())); } -QString LimeReport::RectMMValuePropItem::displayValue() const +qreal LimeReport::RectUnitValuePropItem::valueInUnits(qreal value) const { - return QString::number(propertyValue().toReal())+" "+QObject::tr("mm"); -} - -void LimeReport::RectMMPropItem::itemPosChanged(QObject* /*object*/, QPointF newPos, QPointF oldPos) -{ - if (newPos.x()!=oldPos.x()){ - setValue("x",newPos.x()); - } - if (newPos.y()!=oldPos.y()){ - setValue("y",newPos.y()); + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return value / item->unitFactor(); + case LimeReport::BaseDesignIntf::Inches: + return value / (item->unitFactor() * 10); } } -void LimeReport::RectMMPropItem::itemGeometryChanged(QObject * /*object*/, QRectF newGeometry, QRectF oldGeometry) +qreal LimeReport::RectUnitValuePropItem::valueInReportUnits(qreal value) const { - if (newGeometry.x()!=oldGeometry.x()){ - setValue("x",newGeometry.x()); - } - if (newGeometry.y()!=oldGeometry.y()){ - setValue("y",newGeometry.y()); - } - if (newGeometry.width()!=oldGeometry.width()){ - setValue("width",newGeometry.width()); - } - if (newGeometry.height()!=oldGeometry.height()){ - setValue("height",newGeometry.height()); + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return value * item->unitFactor(); + case LimeReport::BaseDesignIntf::Inches: + return value * (item->unitFactor() * 10); } } -void LimeReport::RectMMPropItem::setValue(const QString &name, qreal value) +QString LimeReport::RectUnitValuePropItem::unitShortName() const { - if (name!=""){ + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return QObject::tr("mm"); + case LimeReport::BaseDesignIntf::Inches: + return QObject::tr("''"); + } +} + +QString LimeReport::RectUnitValuePropItem::displayValue() const +{ + return QString("%1 %2").arg(valueInUnits(propertyValue().toReal()), 0, 'f', 2).arg(unitShortName()); +} + +void LimeReport::RectUnitPropItem::itemPosChanged(QObject* /*object*/, QPointF newPos, QPointF oldPos) +{ + if (newPos.x() != oldPos.x()){ + setValue("x", newPos.x()); + } + if (newPos.y() != oldPos.y()){ + setValue("y", newPos.y()); + } +} + +void LimeReport::RectUnitPropItem::itemGeometryChanged(QObject * /*object*/, QRectF newGeometry, QRectF oldGeometry) +{ + if (newGeometry.x() != oldGeometry.x()){ + setValue("x", newGeometry.x()); + } + if (newGeometry.y() != oldGeometry.y()){ + setValue("y", newGeometry.y()); + } + if (newGeometry.width() != oldGeometry.width()){ + setValue("width", newGeometry.width()); + } + if (newGeometry.height() != oldGeometry.height()){ + setValue("height", newGeometry.height()); + } +} + +void LimeReport::RectUnitPropItem::setValue(const QString &name, qreal value) +{ + if (name != ""){ LimeReport::ObjectPropItem* propItem = findChild(name); if (propItem) { - propItem->setPropertyValue(value/10); - setPropertyValue(LimeReport::modifyRect(propertyValue().toRectF(),name,value)); - LimeReport::QObjectPropertyModel *itemModel=dynamic_cast(model()); + propItem->setPropertyValue(value); + setPropertyValue(LimeReport::modifyRect(propertyValue().toRectF(), name, value)); + LimeReport::QObjectPropertyModel *itemModel = dynamic_cast(model()); if (itemModel) { itemModel->itemDataChanged(modelIndex()); if (propItem->modelIndex().isValid()) @@ -209,3 +242,31 @@ void LimeReport::RectMMPropItem::setValue(const QString &name, qreal value) } } } + +QRectF LimeReport::RectUnitPropItem::rectInUnits(QRectF rect) const +{ + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return QRectF(rect.x() / item->unitFactor(), + rect.y() / item->unitFactor(), + rect.width() / item->unitFactor(), + rect.height() / item->unitFactor()); + case LimeReport::BaseDesignIntf::Inches: + return QRectF(rect.x() / (item->unitFactor() * 10), + rect.y() / (item->unitFactor() * 10), + rect.width() / (item->unitFactor() * 10), + rect.height() / (item->unitFactor() * 10)); + } +} + +QString LimeReport::RectUnitPropItem::unitShortName() const +{ + BaseDesignIntf* item = dynamic_cast(object()); + switch (item->unitType()) { + case LimeReport::BaseDesignIntf::Millimeters: + return QObject::tr("mm"); + case LimeReport::BaseDesignIntf::Inches: + return QObject::tr("''"); + } +} diff --git a/limereport/objectinspector/propertyItems/lrrectproptem.h b/limereport/objectinspector/propertyItems/lrrectproptem.h index 64d8d78..bd6915c 100644 --- a/limereport/objectinspector/propertyItems/lrrectproptem.h +++ b/limereport/objectinspector/propertyItems/lrrectproptem.h @@ -43,28 +43,35 @@ public: QString displayValue() const; }; -class RectMMPropItem : public ObjectPropItem{ +class RectUnitPropItem : public ObjectPropItem{ Q_OBJECT public: - RectMMPropItem():ObjectPropItem(){} - RectMMPropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly=true); + RectUnitPropItem():ObjectPropItem(){} + RectUnitPropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly=true); QString displayValue() const; public slots: void itemPosChanged(QObject* /*object*/, QPointF newPos, QPointF oldPos); void itemGeometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); private: - void setValue(const QString& propertyName, qreal propertyValue); + void setValue(const QString& propertyName, qreal propertyValue); + QRectF rectInUnits(QRectF rect) const; + QString unitShortName() const; }; -class RectMMValuePropItem : public ObjectPropItem{ +class RectUnitValuePropItem : public ObjectPropItem{ Q_OBJECT public: - RectMMValuePropItem():ObjectPropItem(){} - RectMMValuePropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly ); + RectUnitValuePropItem():ObjectPropItem(){} + RectUnitValuePropItem(QObject *object, ObjectsList* objects, const QString& name, const QString& displayName, const QVariant& value, ObjectPropItem* parent, bool readonly ); QString displayValue() const; QWidget* createProperyEditor(QWidget *) const; void setPropertyEditorData(QWidget *, const QModelIndex &) const; void setModelData(QWidget *, QAbstractItemModel *, const QModelIndex &); +private: + qreal valueInUnits(qreal value) const; + qreal valueInReportUnits(qreal value) const; + QString unitShortName() const; + }; } diff --git a/limereport/objectsbrowser/lrobjectbrowser.cpp b/limereport/objectsbrowser/lrobjectbrowser.cpp index a5ee464..a86fac3 100644 --- a/limereport/objectsbrowser/lrobjectbrowser.cpp +++ b/limereport/objectsbrowser/lrobjectbrowser.cpp @@ -35,40 +35,40 @@ namespace LimeReport{ ObjectBrowser::ObjectBrowser(QWidget *parent) - :QWidget(parent), m_report(NULL), m_mainWindow(NULL), + :QWidget(parent), m_designerWidget(NULL), m_mainWindow(NULL), m_changingItemSelection(false), m_movingItem(false) { QVBoxLayout *layout = new QVBoxLayout(this); setLayout(layout); - layout->setMargin(2); + layout->setMargin(Const::DOCKWIDGET_MARGINS); m_treeView = new QTreeWidget(this); layout->addWidget(m_treeView); m_treeView->headerItem()->setText(0,tr("Objects")); m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); } -void ObjectBrowser::setReportEditor(ReportDesignWidget *report) +void ObjectBrowser::setReportEditor(ReportDesignWidget *designerWidget) { - m_report=report; - connect(m_report,SIGNAL(cleared()),this,SLOT(slotClear())); - connect(m_report, SIGNAL(loaded()), this, SLOT(slotReportLoaded())); - connect(m_report, SIGNAL(activePageChanged()), this, SLOT(slotActivePageChanged())); + m_designerWidget=designerWidget; + connect(m_designerWidget,SIGNAL(cleared()),this,SLOT(slotClear())); + connect(m_designerWidget, SIGNAL(loadFinished()), this, SLOT(slotReportLoaded())); + connect(m_designerWidget, SIGNAL(activePageChanged()), this, SLOT(slotActivePageChanged())); - connect(m_report,SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), + connect(m_designerWidget,SIGNAL(itemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), this, SLOT(slotItemAdded(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); - connect(m_report, SIGNAL(itemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), + connect(m_designerWidget, SIGNAL(itemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*)), this, SLOT(slotItemDeleted(LimeReport::PageDesignIntf*,LimeReport::BaseDesignIntf*))); - connect(m_report, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + connect(m_designerWidget, SIGNAL(bandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), this, SLOT(slotBandAdded(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); - connect(m_report, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), + connect(m_designerWidget, SIGNAL(bandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*)), this, SLOT(slotBandDeleted(LimeReport::PageDesignIntf*,LimeReport::BandDesignIntf*))); connect(m_treeView, SIGNAL(itemSelectionChanged()), this, SLOT(slotObjectTreeItemSelectionChanged()) ); - connect(m_report, SIGNAL(itemSelected(LimeReport::BaseDesignIntf*)), + connect(m_designerWidget, SIGNAL(itemSelected(LimeReport::BaseDesignIntf*)), this, SLOT(slotItemSelected(LimeReport::BaseDesignIntf*))); - connect(m_report, SIGNAL(multiItemSelected()), + connect(m_designerWidget, SIGNAL(multiItemSelected()), this, SLOT(slotMultiItemSelected()) ); - connect(m_report, SIGNAL(activePageUpdated(LimeReport::PageDesignIntf*)), + connect(m_designerWidget, SIGNAL(activePageUpdated(LimeReport::PageDesignIntf*)), this, SLOT(slotActivePageUpdated(LimeReport::PageDesignIntf*))); connect(m_treeView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemDoubleClicked(QTreeWidgetItem*,int))); @@ -90,7 +90,7 @@ void ObjectBrowser::fillNode(QTreeWidgetItem* parentNode, BaseDesignIntf* report foreach (BaseDesignIntf* item, reportItem->childBaseItems()) { if (item != ignoredItem){ - ObjectBrowserNode* treeItem = new ObjectBrowserNode(parentNode); + ObjectBrowserNode* treeItem = new ObjectBrowserNode(/*parentNode*/); treeItem->setText(0,item->objectName()); treeItem->setObject(item); treeItem->setIcon(0,QIcon(":/items/"+extractClassName(item->metaObject()->className()))); @@ -102,7 +102,26 @@ void ObjectBrowser::fillNode(QTreeWidgetItem* parentNode, BaseDesignIntf* report this, SLOT(slotItemParentChanged(BaseDesignIntf*,BaseDesignIntf*)), Qt::UniqueConnection); } m_itemsMap.insert(item,treeItem); - parentNode->addChild(treeItem); + + BandDesignIntf* band = dynamic_cast(item); + + QSet subBands; + subBands << BandDesignIntf::SubDetailBand << + BandDesignIntf::SubDetailHeader << + BandDesignIntf::SubDetailFooter; + + if (band && subBands.contains(band->bandType())){ + ObjectBrowserNode* parentBandNode = 0; + if (band->bandType() == BandDesignIntf::SubDetailBand){ + parentBandNode = m_itemsMap.value(band->parentBand()); + } else { + parentBandNode = m_itemsMap.value(band->parentBand()->parentBand()); + } + if(parentBandNode) + parentBandNode->addChild(treeItem); + } else { + parentNode->addChild(treeItem); + } if (!item->childBaseItems().isEmpty()) fillNode(treeItem,item, ignoredItem); } @@ -113,15 +132,15 @@ void ObjectBrowser::buildTree(BaseDesignIntf* ignoredItem){ m_treeView->clear(); m_itemsMap.clear(); - if (!m_report->activePage()) return; + if (!m_designerWidget->activePage()) return; ObjectBrowserNode *topLevelItem=new ObjectBrowserNode(m_treeView); - topLevelItem->setText(0,m_report->activePage()->objectName()); - topLevelItem->setObject(m_report->activePage()); - m_itemsMap.insert(m_report->activePage(),topLevelItem); + topLevelItem->setText(0,m_designerWidget->activePage()->objectName()); + topLevelItem->setObject(m_designerWidget->activePage()); + m_itemsMap.insert(m_designerWidget->activePage(),topLevelItem); m_treeView->addTopLevelItem(topLevelItem); - QList itemsList = m_report->activePage()->items(); + QList itemsList = m_designerWidget->activePage()->items(); foreach (QGraphicsItem* item, itemsList) { if (item != ignoredItem){ BaseDesignIntf* reportItem = dynamic_cast(item); @@ -212,20 +231,20 @@ void ObjectBrowser::slotItemDeleted(PageDesignIntf *, BaseDesignIntf *item) void ObjectBrowser::slotObjectTreeItemSelectionChanged() { - if (!m_changingItemSelection && m_report->activePage()){ + if (!m_changingItemSelection && m_designerWidget->activePage()){ m_changingItemSelection = true; - m_report->activePage()->clearSelection(); + m_designerWidget->activePage()->clearSelection(); foreach(QTreeWidgetItem* item, m_treeView->selectedItems()){ ObjectBrowserNode* tn = dynamic_cast(item); if (tn){ BaseDesignIntf* si = dynamic_cast(tn->object()); if (si) { - m_report->activePage()->animateItem(si); + m_designerWidget->activePage()->animateItem(si); si->setSelected(true); QPointF p = si->mapToScene(si->pos()); if (si->parentItem()) p = si->parentItem()->mapToScene(si->pos()); - m_report->activeView()->centerOn(p); + m_designerWidget->activeView()->centerOn(p); } } } @@ -256,7 +275,7 @@ void ObjectBrowser::slotMultiItemSelected() m_treeView->selectionModel()->clear(); - foreach(QGraphicsItem* item, m_report->activePage()->selectedItems()){ + foreach(QGraphicsItem* item, m_designerWidget->activePage()->selectedItems()){ BaseDesignIntf* bg = dynamic_cast(item); if (bg){ ObjectBrowserNode* node = m_itemsMap.value(bg); diff --git a/limereport/objectsbrowser/lrobjectbrowser.h b/limereport/objectsbrowser/lrobjectbrowser.h index 9d9482b..3616c41 100644 --- a/limereport/objectsbrowser/lrobjectbrowser.h +++ b/limereport/objectsbrowser/lrobjectbrowser.h @@ -42,7 +42,7 @@ public: void setObject(QObject* value); QObject* object() const; explicit ObjectBrowserNode(QTreeWidget *view); - explicit ObjectBrowserNode(QTreeWidgetItem *parent); + explicit ObjectBrowserNode(QTreeWidgetItem *parent = 0); bool operator <(const QTreeWidgetItem& other) const; private: QObject* m_object; @@ -53,7 +53,7 @@ class ObjectBrowser :public QWidget Q_OBJECT public: ObjectBrowser(QWidget *parent=0); - void setReportEditor(LimeReport::ReportDesignWidget* report); + void setReportEditor(LimeReport::ReportDesignWidget* designerWidget); void setMainWindow(QMainWindow* mainWindow); protected: void fillNode(QTreeWidgetItem *parentNode, BaseDesignIntf *reportItem, BaseDesignIntf* ignoredItem = 0); @@ -78,7 +78,7 @@ private slots: void slotActivePageUpdated(LimeReport::PageDesignIntf*); void slotItemParentChanged(BaseDesignIntf* item, BaseDesignIntf* parent); private: - ReportDesignWidget* m_report; + ReportDesignWidget* m_designerWidget; QMainWindow* m_mainWindow; QTreeWidget* m_treeView; QMap m_itemsMap; diff --git a/limereport/report.qrc b/limereport/report.qrc index 6548420..89999d9 100644 --- a/limereport/report.qrc +++ b/limereport/report.qrc @@ -126,9 +126,9 @@ images/hlayuot_3_24.png images/addBand1.png images/delete1.png - images/copy2.png + images/copy2.png images/new_leaf1.png - images/paste1.png + images/paste1.png images/zoom_in1.png images/zoom_out1.png images/folder3.png @@ -174,6 +174,17 @@ images/delete2.png images/addBand2.png images/edit_control_4_24.png - images/logo_32x32_1.png + images/logo_32x32_1.png + images/addDialog.png + images/deleteDialog.png + images/copy3.png + images/paste2.png + images/property.png + images/signal.png + images/object.png + images/vlayuot_4_24.png + images/designer.png + images/lock.png + images/unlock.png diff --git a/limereport/scriptbrowser/lrscriptbrowser.cpp b/limereport/scriptbrowser/lrscriptbrowser.cpp index 5f90bf3..4407170 100644 --- a/limereport/scriptbrowser/lrscriptbrowser.cpp +++ b/limereport/scriptbrowser/lrscriptbrowser.cpp @@ -43,6 +43,7 @@ ScriptBrowser::ScriptBrowser(QWidget *parent) : ui(new Ui::ScriptBrowser) { ui->setupUi(this); + ui->verticalLayout->setMargin(Const::DOCKWIDGET_MARGINS); #ifndef HAVE_UI_LOADER ui->tpDialogs->setVisible(false); ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tpDialogs)); @@ -54,11 +55,14 @@ ScriptBrowser::~ScriptBrowser() delete ui; } -void ScriptBrowser::setReportEditor(ReportDesignWidget* report) +void ScriptBrowser::setReportEditor(ReportDesignWidget* designerWidget) { - m_report=report; - connect(m_report,SIGNAL(cleared()),this,SLOT(slotClear())); - connect(m_report,SIGNAL(loaded()),this,SLOT(slotUpdate())); + m_designerWidget=designerWidget; + connect(m_designerWidget,SIGNAL(cleared()),this,SLOT(slotClear())); + connect(m_designerWidget,SIGNAL(loadFinished()),this,SLOT(slotUpdate())); +#ifdef HAVE_UI_LOADER + connect(m_designerWidget->scriptContext(), SIGNAL(dialogAdded(QString)), this, SLOT(slotDialogAdded(QString))); +#endif updateFunctionTree(); } @@ -67,7 +71,7 @@ void ScriptBrowser::updateFunctionTree() ui->twFunctions->clear(); ScriptEngineManager* sm = reportEditor()->scriptManager(); QMap categ; - foreach(ScriptFunctionDesc fd, sm->functionsDescriber()){ + foreach(ScriptFunctionDesc fd, sm->functionsDescribers()){ QString functionCategory = (fd.category!="") ? fd.category : tr("NO CATEGORY"); if (categ.contains(functionCategory)){ QTreeWidgetItem* item = new QTreeWidgetItem(categ.value(fd.category),QStringList(fd.name)); @@ -117,7 +121,7 @@ void ScriptBrowser::updateDialogsTree() { ui->twDialogs->clear(); ScriptEngineContext* sc = reportEditor()->scriptContext(); - foreach(DialogDescriber::Ptr dc, sc->dialogsDescriber()){ + foreach(DialogDescriber::Ptr dc, sc->dialogDescribers()){ QTreeWidgetItem* dialogItem = new QTreeWidgetItem(ui->twDialogs,QStringList(dc->name())); dialogItem->setIcon(0,QIcon(":/scriptbrowser/images/dialog")); fillDialog(dialogItem,dc->description()); @@ -139,6 +143,12 @@ void ScriptBrowser::slotUpdate() } #ifdef HAVE_UI_LOADER + +void ScriptBrowser::slotDialogAdded(QString) +{ + updateDialogsTree(); +} + void ScriptBrowser::on_tbAddDialog_clicked() { QFileDialog fileDialog(this); @@ -154,10 +164,10 @@ void ScriptBrowser::on_tbAddDialog_clicked() QWidget* widget = loader.load(&file); QDialog* dialog = dynamic_cast(widget); if (dialog){ - if (!m_report->scriptContext()->containsDialog(dialog->objectName())){ + if (!m_designerWidget->scriptContext()->containsDialog(dialog->objectName())){ file.seek(0); - m_report->scriptContext()->addDialog(dialog->objectName(),file.readAll()); - updateDialogsTree(); + m_designerWidget->scriptContext()->addDialog(dialog->objectName(),file.readAll()); + //updateDialogsTree(); } else { QMessageBox::critical(this,tr("Error"),tr("Dialog with name: %1 already exists").arg(dialog->objectName())); } @@ -177,14 +187,14 @@ void ScriptBrowser::on_tbAddDialog_clicked() void ScriptBrowser::on_tbRunDialog_clicked() { if (ui->twDialogs->currentItem()&& ui->twDialogs->currentItem()->parent()==0){ - m_report->scriptContext()->previewDialog(ui->twDialogs->currentItem()->text(0)); + m_designerWidget->scriptContext()->previewDialog(ui->twDialogs->currentItem()->text(0)); } } void ScriptBrowser::on_tbDeleteDialog_clicked() { if (ui->twDialogs->currentItem()&& ui->twDialogs->currentItem()->parent()==0){ - m_report->scriptContext()->deleteDialog(ui->twDialogs->currentItem()->text(0)); + m_designerWidget->scriptContext()->deleteDialog(ui->twDialogs->currentItem()->text(0)); updateDialogsTree(); } } diff --git a/limereport/scriptbrowser/lrscriptbrowser.h b/limereport/scriptbrowser/lrscriptbrowser.h index 3214617..a004eef 100644 --- a/limereport/scriptbrowser/lrscriptbrowser.h +++ b/limereport/scriptbrowser/lrscriptbrowser.h @@ -48,8 +48,8 @@ class ScriptBrowser : public QWidget public: explicit ScriptBrowser(QWidget *parent = 0); ~ScriptBrowser(); - void setReportEditor(LimeReport::ReportDesignWidget* report); - inline ReportDesignWidget* reportEditor(){return m_report;} + void setReportEditor(LimeReport::ReportDesignWidget* designerWidget); + inline ReportDesignWidget* reportEditor(){return m_designerWidget;} void updateFunctionTree(); #ifdef HAVE_UI_LOADER void updateDialogsTree(); @@ -63,6 +63,7 @@ private slots: void slotClear(); void slotUpdate(); #ifdef HAVE_UI_LOADER + void slotDialogAdded(QString); void on_tbAddDialog_clicked(); void on_tbRunDialog_clicked(); void on_tbDeleteDialog_clicked(); @@ -70,7 +71,7 @@ private slots: private: Ui::ScriptBrowser *ui; - ReportDesignWidget* m_report; + ReportDesignWidget* m_designerWidget; }; } // namespace LimeReport diff --git a/limereport/scripteditor/lrcodeeditor.cpp b/limereport/scripteditor/lrcodeeditor.cpp new file mode 100644 index 0000000..308f376 --- /dev/null +++ b/limereport/scripteditor/lrcodeeditor.cpp @@ -0,0 +1,354 @@ +#include "lrcodeeditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lrscripthighlighter.h" +#include "lrglobal.h" + +namespace LimeReport{ + +CodeEditor::CodeEditor(QWidget *parent) + : QPlainTextEdit(parent), m_compleater(0) +{ + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); + + updateLineNumberAreaWidth(0); + highlightCurrentLine(); + new ScriptHighlighter(document()); + connect(this, SIGNAL(cursorPositionChanged()), + this, SLOT(matchParentheses())); +} + +void CodeEditor::setCompleter(QCompleter *value) +{ + if (value) disconnect(value,0,this,0); + m_compleater = value; + if (!m_compleater) return; + m_compleater->setWidget(this); + m_compleater->setCompletionMode(QCompleter::PopupCompletion); + m_compleater->setCaseSensitivity(Qt::CaseInsensitive); + connect(m_compleater,SIGNAL(activated(QString)),this,SLOT(insertCompletion(QString))); +} + +void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent* event) +{ + QPainter painter(lineNumberArea); + QStyleOption option; + option.initFrom(this); + //painter.fillRect(event->rect(), QPalette().background().color()); + QColor bg = option.palette.background().color().darker(150); + painter.fillRect(event->rect(), bg); + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + painter.setPen(option.palette.text().color()); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignCenter, number); + } + + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } +} + +int CodeEditor::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + int space = fontMetrics().width(QLatin1Char('9'))*2 + fontMetrics().width(QLatin1Char('9')) * digits; + + return space; +} + +void CodeEditor::keyPressEvent(QKeyEvent *e) +{ + if (m_compleater && m_compleater->popup()->isVisible()) { + switch (e->key()) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + case Qt::Key_Tab: + case Qt::Key_Backtab: + case Qt::Key_Right: + case Qt::Key_Left: + case Qt::Key_Up: + case Qt::Key_Down: + e->ignore(); + return; + default: + break; + } + } + + bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_Space); + if (!m_compleater || !isShortcut) QPlainTextEdit::keyPressEvent(e); + + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (!m_compleater || (ctrlOrShift && e->text().isEmpty())) + return; + + bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift; + + QString completionPrefix = textUnderCursor(); + + if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3 + || Const::EOW.contains(e->text().right(1))) + ) + { + m_compleater->popup()->hide(); + return; + } + + if (completionPrefix != m_compleater->completionPrefix()) { + m_compleater->setCompletionPrefix(completionPrefix); + m_compleater->popup()->setCurrentIndex(m_compleater->completionModel()->index(0, 0)); + } + + QModelIndex ci = m_compleater->completionModel()->index(0,0); + if (ci.isValid() && m_compleater->completionModel()->data(ci).toString().compare(completionPrefix) == 0){ + m_compleater->popup()->hide(); + return; + } + + QRect cr = cursorRect(); + cr.setWidth(m_compleater->popup()->sizeHintForColumn(0) + + m_compleater->popup()->verticalScrollBar()->sizeHint().width()); + m_compleater->complete(cr); + + if (!completionPrefix.isEmpty() && + completionPrefix.at(completionPrefix.length()-1) == '.') + { + m_compleater->popup(); + } +} + +void CodeEditor::focusInEvent(QFocusEvent *e) +{ + if (m_compleater) m_compleater->setWidget(this); + QPlainTextEdit::focusInEvent(e); +} + +void CodeEditor::resizeEvent(QResizeEvent* event) +{ + QPlainTextEdit::resizeEvent(event); + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); +} + +QString CodeEditor::textUnderCursor() const +{ + QTextCursor tc = textCursor(); + QString currentText; + tc.movePosition(QTextCursor::StartOfBlock,QTextCursor::KeepAnchor); + QString blockText = tc.selectedText(); + for(int i = blockText.length(); i>0; --i){ + if (!Const::EOW.contains(blockText.at(i-1))) + currentText = blockText.at(i-1) + currentText; + else break; + } + return currentText.trimmed(); +} + +bool CodeEditor::matchLeftParenthesis(QTextBlock currentBlock, QChar parenthesisType, int i, int numLeftParentheses) +{ + TextBlockData *data = static_cast(currentBlock.userData()); + if (data){ + QVector infos = data->parentheses(); + + int docPos = currentBlock.position(); + for (; i < infos.size(); ++i) { + ParenthesisInfo *info = infos.at(i); + + if (info->character == parenthesisType) { + ++numLeftParentheses; + continue; + } + + if (info->character == getParenthesisReverceChar(parenthesisType)){ + if (numLeftParentheses == 0) { + createParenthesisSelection(docPos + info->position); + return true; + } else + --numLeftParentheses; + } + + } + + currentBlock = currentBlock.next(); + if (currentBlock.isValid()) + return matchLeftParenthesis(currentBlock, parenthesisType, 0, numLeftParentheses); + } + + return false; +} + +bool CodeEditor::matchRightParenthesis(QTextBlock currentBlock, QChar parenthesisType, int i, int numRightParentheses) +{ + TextBlockData *data = static_cast(currentBlock.userData()); + if (data){ + QVector parentheses = data->parentheses(); + int docPos = currentBlock.position(); + if (i == -2) i = parentheses.size()-1; + for (; i > -1 && parentheses.size() > 0; --i) { + ParenthesisInfo *info = parentheses.at(i); + if (info->character == parenthesisType) { + ++numRightParentheses; + continue; + } + if (info->character == getParenthesisReverceChar(parenthesisType)){ + if (numRightParentheses == 0) { + createParenthesisSelection(docPos + info->position); + return true; + } else + --numRightParentheses; + } + } + + currentBlock = currentBlock.previous(); + if (currentBlock.isValid()) + return matchRightParenthesis(currentBlock, parenthesisType, -2, numRightParentheses); + + } + return false; +} + +void CodeEditor::createParenthesisSelection(int pos) +{ + QList selections = extraSelections(); + + QTextEdit::ExtraSelection selection; + QTextCharFormat format = selection.format; + format.setBackground(QColor("#619934")); + format.setForeground(QColor("#ffffff")); + selection.format = format; + + QTextCursor cursor = textCursor(); + cursor.setPosition(pos); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + selection.cursor = cursor; + + selections.append(selection); + + setExtraSelections(selections); +} + +bool CodeEditor::charIsParenthesis(QChar character, ParenthesisType type) +{ + for (int i = 0; i < PARENHEIS_COUNT; ++i){ + if (character == parenthesisCharacters[type][i]) + return true; + } + return false; +} + +QChar CodeEditor::getParenthesisReverceChar(QChar parenthesisChar) +{ + for (int i = 0; i < PARENHEIS_COUNT; ++i){ + if ( parenthesisCharacters[RightParenthesis][i] == parenthesisChar) + return parenthesisCharacters[LeftParenthesis][i]; + if ( parenthesisCharacters[LeftParenthesis][i] == parenthesisChar) + return parenthesisCharacters[RightParenthesis][i]; + } + return ' '; +} + +void CodeEditor::insertCompletion(const QString &completion) +{ + if (m_compleater->widget() != this) + return; + QTextCursor tc = textCursor(); + int extra = completion.length() - m_compleater->completionPrefix().length(); + //tc.movePosition(QTextCursor::Left); + //tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + setTextCursor(tc); +} + +void CodeEditor::updateLineNumberAreaWidth(int /*newBlockCount*/) +{ + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); +} + +void CodeEditor::highlightCurrentLine() +{ + QList extraSelections; + + if (!isReadOnly()) { + QTextEdit::ExtraSelection selection; + + QColor lineColor = QColor(QPalette().background().color()).darker(100); + + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); +} + +void CodeEditor::updateLineNumberArea(const QRect& rect, int dy) +{ + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); +} + +void CodeEditor::matchParentheses() +{ + QList selections; + setExtraSelections(selections); + + TextBlockData *data = static_cast(textCursor().block().userData()); + + if (data) { + QVector infos = data->parentheses(); + + int pos = textCursor().block().position(); + for (int i = 0; i < infos.size(); ++i) { + ParenthesisInfo *info = infos.at(i); + + int curPos = textCursor().position() - textCursor().block().position(); + + if ( (info->position == (curPos - 1)) && charIsParenthesis(info->character, LeftParenthesis)) + { + if (matchLeftParenthesis(textCursor().block(), info->character, i + 1, 0)) + createParenthesisSelection(pos + info->position); + } else if ( (info->position == (curPos - 1)) && charIsParenthesis(info->character, RightParenthesis)) { + if (matchRightParenthesis(textCursor().block(), info->character, i - 1, 0)) + createParenthesisSelection(pos + info->position); + } + } + } +} + +} //namespace LimeReport diff --git a/limereport/scripteditor/lrcodeeditor.h b/limereport/scripteditor/lrcodeeditor.h new file mode 100644 index 0000000..851583f --- /dev/null +++ b/limereport/scripteditor/lrcodeeditor.h @@ -0,0 +1,71 @@ +#ifndef LRCODEEDITOR_H +#define LRCODEEDITOR_H + +#include +#include +#include "lrscripthighlighter.h" + +QT_BEGIN_NAMESPACE +class QWidget; +class QCompleter; +class QKeyEvent; +class QScrollBar; +QT_END_NAMESPACE + +namespace LimeReport{ + +class CodeEditor :public QPlainTextEdit +{ + Q_OBJECT +public: + CodeEditor(QWidget* parent=0); + void setCompleter(QCompleter* value); + QCompleter* compleater() const{ return m_compleater;} + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); +protected: + void keyPressEvent(QKeyEvent *e); + void focusInEvent(QFocusEvent *e); + void resizeEvent(QResizeEvent *event); +private: + QString textUnderCursor() const; + bool matchLeftParenthesis(QTextBlock currentBlock, QChar parenthesisType, int i, int numLeftParentheses); + bool matchRightParenthesis(QTextBlock currentBlock, QChar parenthesisType, int i, int numRightParentheses); + void createParenthesisSelection(int pos); + bool charIsParenthesis(QChar character, ParenthesisType type); + QChar getParenthesisReverceChar(QChar parenthesisChar); +private slots: + void insertCompletion(const QString& completion); + void updateLineNumberAreaWidth(int newBlockCount); + void highlightCurrentLine(); + void updateLineNumberArea(const QRect &rect, int dy); + void matchParentheses(); +private: + QCompleter* m_compleater; + QWidget *lineNumberArea; +}; + + +class LineNumberArea : public QWidget +{ +public: + LineNumberArea(CodeEditor *editor) : QWidget(editor) { + codeEditor = editor; + } + + QSize sizeHint() const { + return QSize(codeEditor->lineNumberAreaWidth(), 0); + } + +protected: + void paintEvent(QPaintEvent *event) { + codeEditor->lineNumberAreaPaintEvent(event); + } + +private: + CodeEditor *codeEditor; +}; + +} // namespace LimeReport + +#endif // LRCODEEDITOR_H diff --git a/limereport/scripteditor/lrscripteditor.cpp b/limereport/scripteditor/lrscripteditor.cpp new file mode 100644 index 0000000..7c9656d --- /dev/null +++ b/limereport/scripteditor/lrscripteditor.cpp @@ -0,0 +1,372 @@ +#include "lrscripteditor.h" +#include "ui_lrscripteditor.h" + +#ifdef USE_QJSENGINE +#include +#endif + +#include "lrdatasourcemanager.h" +#include "lrscriptenginemanager.h" +#include "lrdatadesignintf.h" +#include "lrreportengine_p.h" + +namespace LimeReport{ + +ScriptEditor::ScriptEditor(QWidget *parent) : + QWidget(parent), + ui(new Ui::ScriptEditor), m_reportEngine(0), m_page(0), m_tabIndention(4) +{ + ui->setupUi(this); + setFocusProxy(ui->textEdit); + m_completer = new ReportStructureCompleater(this); + ui->textEdit->setCompleter(m_completer); + ui->textEdit->setTabStopWidth(ui->textEdit->fontMetrics().width("0")*m_tabIndention); + connect(ui->splitter, SIGNAL(splitterMoved(int,int)), this, SIGNAL(splitterMoved(int,int))); + connect(ui->textEdit, SIGNAL(textChanged()), this, SIGNAL(textChanged())); +} + +ScriptEditor::~ScriptEditor() +{ + delete ui; +} + +void ScriptEditor::initEditor(DataSourceManager* dm) +{ + ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance(); + se.setDataManager(dm); + + initCompleter(); + + if (dm){ + if (dm->isNeedUpdateDatasourceModel()) + dm->updateDatasourceModel(); + ui->twData->setModel(dm->datasourcesModel()); + ui->twScriptEngine->setModel(se.model()); + } + + if (ui->twScriptEngine->selectionModel()){ + connect(ui->twScriptEngine->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + this, SLOT(slotOnCurrentChanged(QModelIndex,QModelIndex))); + } +} + +void ScriptEditor::setReportEngine(ReportEnginePrivateInterface* reportEngine) +{ + m_reportEngine = reportEngine; + DataSourceManager* dm = m_reportEngine->dataManager(); + if (dm) initEditor(dm); + else ui->tabWidget->setVisible(false); +} + +void ScriptEditor::setReportPage(PageDesignIntf* page) +{ + m_page = page; + DataSourceManager* dm = page->datasourceManager(); + if (dm) initEditor(dm); + else ui->tabWidget->setVisible(false); +} + +void ScriptEditor::setPageBand(BandDesignIntf* band) +{ + if (band && ui->twData->model() && !band->datasourceName().isEmpty()){ + QModelIndexList nodes = ui->twData->model()->match( + ui->twData->model()->index(0,0), + Qt::DisplayRole, + band->datasourceName(), + 2, + Qt::MatchRecursive + ); + if (!nodes.isEmpty()){ + ui->twData->expand(nodes.at(0).parent()); + ui->twData->expand(nodes.at(0)); + } + } +} + +void ScriptEditor::setTabIndention(int charCount) +{ + if (m_tabIndention != charCount){ + ui->textEdit->setTabStopWidth(ui->textEdit->fontMetrics().width("W")*charCount); + m_tabIndention = charCount; + } +} + +void ScriptEditor::initCompleter() +{ + if (m_reportEngine) + m_completer->updateCompleaterModel(m_reportEngine); + else + m_completer->updateCompleaterModel(m_page->datasourceManager()); +} + +QByteArray ScriptEditor::saveState() +{ + return ui->splitter->saveState(); +} + +void ScriptEditor::restoreState(QByteArray state) +{ + ui->splitter->restoreState(state); +} + +void ScriptEditor::setPlainText(const QString& text) +{ + ui->textEdit->setPlainText(text); +} + +void ScriptEditor::setEditorFont(QFont font) +{ + ui->textEdit->setFont(font); +} + +QFont ScriptEditor::editorFont() +{ + return ui->textEdit->font(); +} + +QString ScriptEditor::toPlainText() +{ + return ui->textEdit->toPlainText(); +} + +void ScriptEditor::on_twData_doubleClicked(const QModelIndex &index) +{ + if (!index.isValid()) return; + LimeReport::DataNode* node = static_cast(index.internalPointer()); + if (node->type()==LimeReport::DataNode::Field){ + ui->textEdit->insertPlainText(QString("$D{%1.%2}").arg(node->parent()->name()).arg(node->name())); + } + if (node->type()==LimeReport::DataNode::Variable){ + ui->textEdit->insertPlainText(QString("$V{%1}").arg(node->name())); + } + ui->textEdit->setFocus(); +} + +void ScriptEditor::on_twScriptEngine_doubleClicked(const QModelIndex &index) +{ + if (!index.isValid()) return; + LimeReport::ScriptEngineNode* node = static_cast(index.internalPointer()); + if (node->type()==LimeReport::ScriptEngineNode::Function){ + ui->textEdit->insertPlainText(node->name()+"()"); + } + ui->textEdit->setFocus(); +} + +void ScriptEditor::slotOnCurrentChanged(const QModelIndex &to, const QModelIndex &) +{ + LimeReport::ScriptEngineNode* node = static_cast(to.internalPointer()); + if (node->type()==LimeReport::ScriptEngineNode::Function){ + ui->lblDescription->setText(node->description()); + } +} + +QString ReportStructureCompleater::pathFromIndex(const QModelIndex &index) const +{ + QStringList dataList; + for (QModelIndex i = index; i.isValid(); i = i.parent()) { + dataList.prepend(model()->data(i, Qt::DisplayRole).toString()); + } + return dataList.join("."); +} + +QStringList ReportStructureCompleater::splitPath(const QString &path) const +{ + return path.split("."); +} + +void ReportStructureCompleater::addAdditionalDatawords(QStandardItemModel* model, DataSourceManager* dataManager){ + + foreach(const QString &dsName,dataManager->dataSourceNames()){ + QStandardItem* dsNode = new QStandardItem; + dsNode->setText(dsName); + foreach(const QString &field, dataManager->fieldNames(dsName)){ + QStandardItem* fieldNode = new QStandardItem; + fieldNode->setText(field); + dsNode->appendRow(fieldNode); + } + model->invisibleRootItem()->appendRow(dsNode); + } + + foreach (QString varName, dataManager->variableNames()) { + QStandardItem* varNode = new QStandardItem; + varNode->setText(varName.remove("#")); + model->invisibleRootItem()->appendRow(varNode); + } + +#ifdef USE_QJSENGINE + ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance(); + QJSValue globalObject = se.scriptEngine()->globalObject(); + QJSValueIterator it(globalObject); + while (it.hasNext()){ + it.next(); + if (it.value().isCallable() ){ + QStandardItem* itemNode = new QStandardItem; + itemNode->setText(it.name()+"()"); + model->invisibleRootItem()->appendRow(itemNode); + } + if (it.value().isQObject()){ + if (it.value().toQObject()){ + if (model->findItems(it.name()).isEmpty()){ + QStandardItem* objectNode = new QStandardItem; + objectNode->setText(it.name()); + objectNode->setIcon(QIcon(":/report/images/object")); + for (int i = 0; i< it.value().toQObject()->metaObject()->methodCount();++i){ + if (it.value().toQObject()->metaObject()->method(i).methodType() == QMetaMethod::Method){ + QStandardItem* methodNode = new QStandardItem; + QMetaMethod m = it.value().toQObject()->metaObject()->method(i); + QString methodSignature = m.name() + "("; + bool isFirst = true; + for (int j = 0; j < m.parameterCount(); ++j){ + methodSignature += (isFirst ? "" : ",") + m.parameterTypes()[j]+" "+m.parameterNames()[j]; + if (isFirst) isFirst = false; + } + methodSignature += ")"; + methodNode->setText(methodSignature); + objectNode->appendRow(methodNode); + } + } + model->invisibleRootItem()->appendRow(objectNode); + } + } + } + } +#endif + +} + +void ReportStructureCompleater::updateCompleaterModel(ReportEnginePrivateInterface* report) +{ + if (report){ + m_model.clear(); + QIcon signalIcon(":/report/images/signal"); + QIcon propertyIcon(":/report/images/property"); + + for ( int i = 0; i < report->pageCount(); ++i){ + PageDesignIntf* page = report->pageAt(i); + + QStandardItem* itemNode = new QStandardItem; + itemNode->setText(page->pageItem()->objectName()); + itemNode->setIcon(QIcon(":/report/images/object")); + m_model.invisibleRootItem()->appendRow(itemNode); + + QStringList items = extractSignalNames(page->pageItem()); + foreach(QString slotName, items){ + QStandardItem* slotItem = new QStandardItem; + slotItem->setText(slotName); + slotItem->setIcon(signalIcon); + itemNode->appendRow(slotItem); + } + items = extractProperties(page->pageItem()); + foreach(QString propertyName, items){ + QStandardItem* properyItem = new QStandardItem; + properyItem->setText(propertyName); + properyItem->setIcon(propertyIcon); + itemNode->appendRow(properyItem); + } + foreach (BaseDesignIntf* item, page->pageItem()->childBaseItems()){ + addChildItem(item, itemNode->text(), m_model.invisibleRootItem()); + } + } + + addAdditionalDatawords(&m_model, report->dataManager()); + m_model.sort(0); + } +} + +void ReportStructureCompleater::updateCompleaterModel(DataSourceManager *dataManager) +{ + m_model.clear(); + addAdditionalDatawords(&m_model, dataManager); +} + +QStringList ReportStructureCompleater::extractSignalNames(BaseDesignIntf *item) +{ + QStringList result; + if (!item) return result; + QMetaObject const * mo = item->metaObject(); + while (mo){ + for(int i = mo->methodOffset(); i < mo->methodCount(); ++i) + { + if (mo->method(i).methodType() == QMetaMethod::Signal) { +#ifndef HAVE_QT4 + result.append(QString::fromLatin1(mo->method(i).name())); +#else + result.append(QString::fromLatin1(mo->method(i).signature())); +#endif + } + } + mo = mo->superClass(); + } + result.sort(); + return result; +} + +QStringList ReportStructureCompleater::extractProperties(BaseDesignIntf *item) +{ + QStringList result; + if (!item) return result; + QMetaObject const * mo = item->metaObject(); + while (mo){ + for(int i = mo->propertyOffset(); i < mo->propertyCount(); ++i) + { + result.append(QString::fromLatin1(mo->property(i).name())); + } + mo = mo->superClass(); + } + result.sort(); + return result; +} + +void ReportStructureCompleater::addChildItem(BaseDesignIntf *item, const QString &pageName, QStandardItem *parent) +{ + if (!item) return; + + QIcon signalIcon(":/report/images/signal"); + QIcon propertyIcon(":/report/images/property"); + + QStandardItem* itemNode = new QStandardItem; + itemNode->setText(pageName+"_"+item->objectName()); + itemNode->setIcon(QIcon(":/report/images/object")); + parent->appendRow(itemNode); + QStringList items; + + if (!m_signals.contains(item->metaObject()->className())){ + items = extractSignalNames(item); + m_signals.insert(item->metaObject()->className(),items); + } else { + items = m_signals.value(item->metaObject()->className()); + } + + foreach(QString slotName, items){ + QStandardItem* slotItem = new QStandardItem; + slotItem->setText(slotName); + slotItem->setIcon(signalIcon); + itemNode->appendRow(slotItem); + } + + if (!m_properties.contains(item->metaObject()->className())){ + items = extractProperties(item); + m_properties.insert(item->metaObject()->className(),items); + } else { + items = m_properties.value(item->metaObject()->className()); + } + + foreach(QString propertyName, items){ + QStandardItem* properyItem = new QStandardItem; + properyItem->setText(propertyName); + properyItem->setIcon(propertyIcon); + itemNode->appendRow(properyItem); + } + + foreach (BaseDesignIntf* child, item->childBaseItems()){ + addChildItem(child, pageName, parent); + } +} + +} // namespace LimeReport + + + + + + diff --git a/limereport/scripteditor/lrscripteditor.h b/limereport/scripteditor/lrscripteditor.h new file mode 100644 index 0000000..10dcd5a --- /dev/null +++ b/limereport/scripteditor/lrscripteditor.h @@ -0,0 +1,86 @@ +#ifndef LRSCRIPTEDITOR_H +#define LRSCRIPTEDITOR_H + +#include +#include +#include +#include +#include +#include + +namespace LimeReport{ + +class ReportEnginePrivateInterface; +class BaseDesignIntf; +class PageDesignIntf; +class BandDesignIntf; +class DataSourceManager; + +namespace Ui { +class ScriptEditor; +} + +class ReportStructureCompleater : public QCompleter{ + Q_OBJECT +public: + explicit ReportStructureCompleater(QObject* parent = 0): QCompleter(parent){ setModel(&m_model);} + explicit ReportStructureCompleater(QAbstractItemModel* model, QObject* parent = 0) + :QCompleter(model, parent){ setModel(&m_model);} +public: + // QCompleter interface + QString pathFromIndex(const QModelIndex& index) const; + QStringList splitPath(const QString& path) const; + void updateCompleaterModel(ReportEnginePrivateInterface* report); + void updateCompleaterModel(DataSourceManager* dataManager); +protected: + QStringList extractSignalNames(BaseDesignIntf* item); + QStringList extractProperties(BaseDesignIntf* item); + void addChildItem(BaseDesignIntf *item, const QString &pageName, QStandardItem *parent); + void addAdditionalDatawords(QStandardItemModel* model, DataSourceManager *dataManager); +private: + QStandardItemModel m_model; + QMap m_properties; + QMap m_signals; +}; + +class ScriptEditor : public QWidget +{ + Q_OBJECT +public: + explicit ScriptEditor(QWidget *parent = 0); + ~ScriptEditor(); + void setReportEngine(LimeReport::ReportEnginePrivateInterface* reportEngine); + void setReportPage(PageDesignIntf* page); + void setPageBand(BandDesignIntf* band); + void setTabIndention(int charCount); + void initCompleter(); + QByteArray saveState(); + void restoreState(QByteArray state); + void setPlainText(const QString &text); + void setEditorFont(QFont font); + QFont editorFont(); + QString toPlainText(); + bool hasChanges() const; + void setHasChanges(bool hasChanges); +signals: + void splitterMoved(int, int); + void textChanged(); +protected: + void initEditor(DataSourceManager* dm); + +private slots: + void on_twData_doubleClicked(const QModelIndex &index); + void on_twScriptEngine_doubleClicked(const QModelIndex &index); + void slotOnCurrentChanged(const QModelIndex& to, const QModelIndex&); + +private: + Ui::ScriptEditor *ui; + ReportEnginePrivateInterface* m_reportEngine; + PageDesignIntf* m_page; + ReportStructureCompleater* m_completer; + int m_tabIndention; +}; + +} // namespace LimeReport + +#endif // LRSCRIPTEDITOR_H diff --git a/limereport/scripteditor/lrscripteditor.ui b/limereport/scripteditor/lrscripteditor.ui new file mode 100644 index 0000000..27f8e7f --- /dev/null +++ b/limereport/scripteditor/lrscripteditor.ui @@ -0,0 +1,115 @@ + + + LimeReport::ScriptEditor + + + + 0 + 0 + 706 + 541 + + + + Form + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 0 + 0 + + + + + 12 + + + + + + QTabWidget::South + + + 0 + + + + Data + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + false + + + + + + + + Functions + + + + + + Qt::Vertical + + + + false + + + + + + + + + + + + + + + + + + + LimeReport::CodeEditor + QTextEdit +
lrcodeeditor.h
+
+
+ + +
diff --git a/limereport/scripteditor/lrscripthighlighter.cpp b/limereport/scripteditor/lrscripthighlighter.cpp new file mode 100644 index 0000000..0af09ba --- /dev/null +++ b/limereport/scripteditor/lrscripthighlighter.cpp @@ -0,0 +1,225 @@ +#include "lrscripthighlighter.h" +#include "lrglobal.h" +#include +#include + +namespace LimeReport{ + +#define KEYWORDS_COUNT 59 + +static const char *const keywords[KEYWORDS_COUNT] = { + "do","if","in","for","int","new","try","var","byte","case","char","else","enum", + "goto","long","null","this","true","void","with","break","catch","class","const", + "false","final","float","short","super","throw","while","delete","double","export", + "import","native","public","return","static","switch","throws","typeof","boolean", + "default","extends","finally","package","private","abstract","continue","debugger", + "function","volatile","interface","protected","transient","implements","instanceof", + "synchronized" +}; + +enum LiteralsType{SpaceFound, AlpahabetFound, NumberFound, HashFound, SlashFound, AsterixFound, + BracketFound, QuotationFound, ApostropheFound, SeparatorFound, BackSlashFound, LiteralsCount}; +enum States {Start, MayBeKeyWord, Code, MayBeComment, Comment, Comment2, MayBeComment2End, String, String2, MayBeNumber, Separator, StatesCount}; + +void ScriptHighlighter::createParentheisisInfo(const char& literal, TextBlockData *data, const QString& text) +{ + int pos = text.indexOf(literal); + while (pos != -1) { + ParenthesisInfo *info = new ParenthesisInfo; + info->character = literal; + info->position = pos; + data->insert(info); + pos = text.indexOf(literal, pos + 1); + } +} + +void ScriptHighlighter::highlightBlock(const QString& text) +{ + int literal = -1; + bool lastWasBackSlash = false; + int state = previousBlockState() != -1 ? previousBlockState() : Start ; + int oldState = -1; + int stateMaschine[StatesCount][LiteralsCount] = { + {Separator, MayBeKeyWord, MayBeNumber, Separator, MayBeComment, Separator, Separator, String, String2, Separator, Separator}, + {Separator, MayBeKeyWord, Code, Separator, MayBeComment, Separator, Separator, String, String2, Separator, Separator}, + {Separator, Code, Code, Separator, Separator, Separator, Separator, String, String2, Separator, Separator}, + {Separator, Code, MayBeNumber, Code, Comment, Comment2, Code, String, String2, Separator, Code}, + {Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment}, + {Comment2, Comment2, Comment2, Comment2, Comment2, MayBeComment2End, Comment2, Comment2, Comment2, Comment2, Comment2}, + {Comment2, Comment2, Comment2, Comment2, Separator, Comment2, Comment2, Comment2, Comment2, Comment2, Comment2}, + {String, String, String, String, String, String, String, Separator, String, String, String}, + {String2, String2, String2, String2, String2, String2, String2, String2, Separator, String2, String2}, + {Separator, Code, MayBeNumber, Separator, MayBeComment, Separator, Separator, String, String2, Separator, Code}, + {Separator, MayBeKeyWord, MayBeNumber, Separator, MayBeComment, Separator, Separator, String, String2, Separator, Separator } + }; + + QString buffer; + + if (text.isEmpty()) return; + int i = 0; + for (;;){ + QChar currentChar = text.at(i); + switch(currentChar.toLatin1()){ + case ' ': + literal = SpaceFound; + break; + case '/': + literal = SlashFound; + break; + case '*': + literal = AsterixFound; + break; + case '#': + literal = HashFound; + break; + case '\'': + literal = ApostropheFound; + break; + case '\\': + literal = BackSlashFound; + break; + case '"': + literal = QuotationFound; + break; + case '{': case '[': case '(': + case '}': case ']': case ')': + literal = BracketFound; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + literal = NumberFound; + break; + default: + if (currentChar.isLetter()) + literal = AlpahabetFound; + else + literal = SeparatorFound; + }; + + lastWasBackSlash = !lastWasBackSlash && currentChar == QLatin1Char('\\'); + + oldState = state; + state = stateMaschine[state][literal]; + + buffer += currentChar; + + if (oldState != state){ + switch( state ){ + case MayBeComment: + if (oldState == MayBeNumber){ + setFormat(i-(buffer.length()-1), buffer.length()-1, m_formats[NumberFormat]); + } + buffer.clear(); + buffer += currentChar; + break; + case String: + case String2: + buffer.clear(); + buffer += currentChar; + break; + case MayBeKeyWord: + case MayBeNumber: + buffer.clear(); + buffer += currentChar; + break; + case Comment2: + setCurrentBlockState(Comment2); + case Separator: + switch(oldState){ + case MayBeComment2End: + setFormat(i-(buffer.length()-1), buffer.length(), m_formats[CommentFormat]); + setCurrentBlockState(-1); + buffer.clear(); + break; + case MayBeKeyWord: + if (isKeyWord(buffer.left(buffer.length()-1))){ + setFormat(i-(buffer.length()-1), buffer.length()-1, m_formats[KeywordFormat]); + } + buffer.clear(); + break; + case MayBeNumber: + setFormat(i-(buffer.length()-1), buffer.length()-1, m_formats[NumberFormat]); + buffer.clear(); + case String: + case String2: + setFormat(i-(buffer.length()-1), buffer.length(), m_formats[StringFormat]); + buffer.clear(); + break; + } + default: + break; + } + } + + if ( state == Comment || state == Comment2 ){ + setFormat(i-(buffer.length()-1), buffer.length(), m_formats[CommentFormat]); + } + + if ( state == String || state == String2 ){ + setFormat(i-(buffer.length()-1), buffer.length(), m_formats[StringFormat]); + } + + i++; + if ( i>= text.length()) break; + } + + TextBlockData *data = new TextBlockData; + + for (int i = 0; i < PARENHEIS_COUNT; ++i){ + createParentheisisInfo(parenthesisCharacters[LeftParenthesis][i].toLatin1(), data, text); + createParentheisisInfo(parenthesisCharacters[RightParenthesis][i].toLatin1(), data, text); + } + + setCurrentBlockUserData(data); +} + +bool ScriptHighlighter::isKeyWord(const QString& word) +{ + for (int i = 0; i < KEYWORDS_COUNT-1; ++i){ + if (QLatin1String(keywords[i]) == word) return true; + } + return false; +} + +ScriptHighlighter::ScriptHighlighter(QTextDocument* parent): + QSyntaxHighlighter(parent) +{ + + if ( isColorDark(QPalette().background().color())){ + m_formats[NumberFormat].setForeground(Qt::darkBlue); + m_formats[StringFormat].setForeground(Qt::darkGreen); + m_formats[KeywordFormat].setForeground(Qt::darkYellow); + m_formats[CommentFormat].setForeground(Qt::darkGreen); + m_formats[CommentFormat].setFontItalic(true); + } else { + m_formats[NumberFormat].setForeground(QColor("#ff6aad")); + m_formats[StringFormat].setForeground(QColor("#b27f40")); + m_formats[KeywordFormat].setForeground(QColor("#45c5d5")); + m_formats[CommentFormat].setForeground(QColor("#a1a4a9")); + m_formats[CommentFormat].setFontItalic(true); + } +} + +TextBlockData::~TextBlockData() +{ + foreach(ParenthesisInfo* info, m_parentheses){ + delete info; + } +} + +QVector TextBlockData::parentheses() +{ + return m_parentheses; +} + +void TextBlockData::insert(ParenthesisInfo* info) +{ + int i = 0; + while (i < m_parentheses.size() && + info->position > m_parentheses.at(i)->position) + ++i; + + m_parentheses.insert(i, info); +} + +} // namespace LimeReport diff --git a/limereport/scripteditor/lrscripthighlighter.h b/limereport/scripteditor/lrscripthighlighter.h new file mode 100644 index 0000000..46c4d24 --- /dev/null +++ b/limereport/scripteditor/lrscripthighlighter.h @@ -0,0 +1,50 @@ +#ifndef LRSCRIPTHIGHLIGHTER_H +#define LRSCRIPTHIGHLIGHTER_H + +#include + +namespace LimeReport{ + +enum ParenthesisType {LeftParenthesis, RightParenthesis, ParenthesisTypeCount}; + +#define PARENHEIS_COUNT 3 +const QChar parenthesisCharacters[ParenthesisTypeCount][PARENHEIS_COUNT] = { + {'(', '{', '['}, + {')', '}', ']'} +}; + +struct ParenthesisInfo +{ + char character; + int position; +}; + +class TextBlockData : public QTextBlockUserData +{ +public: + TextBlockData(){} + ~TextBlockData(); + QVector parentheses(); + void insert(ParenthesisInfo *info); + +private: + QVector m_parentheses; +}; + +class ScriptHighlighter : QSyntaxHighlighter{ +public: + ScriptHighlighter(QTextDocument* parent); +protected: + void highlightBlock(const QString& text); + enum ScriptFormats { + NumberFormat, StringFormat, KeywordFormat, + CommentFormat, FormatsCount + }; + QTextCharFormat m_formats[FormatsCount]; + bool isKeyWord(const QString& word); + void createParentheisisInfo(const char& literal, TextBlockData *data, const QString& text); +}; + + +} +#endif // LRSCRIPTHIGHLIGHTER_H diff --git a/limereport/serializators/lrxmlreader.cpp b/limereport/serializators/lrxmlreader.cpp index 2e791cd..7439fc4 100644 --- a/limereport/serializators/lrxmlreader.cpp +++ b/limereport/serializators/lrxmlreader.cpp @@ -33,9 +33,17 @@ #include "lrbasedesignintf.h" #include "lrdesignelementsfactory.h" #include "lrcollection.h" +#include "lrreporttranslation.h" #include +#ifdef BUILD_WITH_EASY_PROFILER +#include "easy/profiler.h" +#else +# define EASY_BLOCK(...) +# define EASY_END_BLOCK +#endif + namespace LimeReport{ XMLReader::XMLReader() @@ -106,17 +114,19 @@ bool XMLReader::readItem(QObject *item) void XMLReader::readItemFromNode(QObject* item,QDomElement *node) { + EASY_BLOCK("readItemFromNode"); ObjectLoadingStateIntf* lf = dynamic_cast(item); if(lf) lf->objectLoadStarted(); for (int i=0;ichildNodes().count();i++){ QDomElement currentNode =node->childNodes().at(i).toElement(); if (currentNode.attribute("Type")=="Object"){ readQObject(item,¤tNode); - }else if (currentNode.attribute("Type")=="Collection") + } else if (currentNode.attribute("Type")=="Collection") { readCollection(item,¤tNode); - } - else readProperty(item,¤tNode); + } else if (currentNode.attribute("Type")=="Translation"){ + readTranslation(item,¤tNode); + } else readProperty(item,¤tNode); } if (lf) lf->objectLoadFinished(); @@ -127,6 +137,7 @@ void XMLReader::readItemFromNode(QObject* item,QDomElement *node) if (baseItem) baseItem->parentObjectLoadFinished(); } } + EASY_END_BLOCK; } QString XMLReader::lastError() @@ -181,17 +192,20 @@ QVariant XMLReader::getValue(QDomElement *node) void XMLReader::readQObject(QObject* item, QDomElement* node) { + EASY_BLOCK("readQObject"); QObject* childItem = qvariant_cast(item->property(node->nodeName().toLatin1())); if (childItem) readItemFromNode(childItem,node); + EASY_END_BLOCK; } void XMLReader::readCollection(QObject *item, QDomElement *node) { + EASY_BLOCK("readCollection") ICollectionContainer* collection = dynamic_cast(item); if (collection){ QString collectionName = node->nodeName(); - for(int i=0;ichildNodes().count();i++){ + for(int i = 0; i < node->childNodes().count(); ++i){ QDomElement currentNode =node->childNodes().at(i).toElement(); QObject* obj = collection->createElement(collectionName,currentNode.attribute("ClassName")); if (obj) @@ -199,6 +213,40 @@ void XMLReader::readCollection(QObject *item, QDomElement *node) } collection->collectionLoadFinished(collectionName); } + EASY_END_BLOCK; +} + +void XMLReader::readTranslation(QObject* item, QDomElement* node) +{ + ITranslationContainer* tranclationContainer = dynamic_cast(item); + if (tranclationContainer){ + Translations* translations = tranclationContainer->translations(); + for (int langIndex = 0; langIndexchildNodes().count(); ++langIndex){ + QDomElement languageNode = node->childNodes().at(langIndex).toElement(); + ReportTranslation* curTranslation = new ReportTranslation((QLocale::Language)(languageNode.attributeNode("Value").value().toInt())); + for (int pageIndex = 0; pageIndex < languageNode.childNodes().count(); ++pageIndex){ + QDomElement pageNode = languageNode.childNodes().at(pageIndex).toElement(); + PageTranslation* pageTranslation = curTranslation->createEmptyPageTranslation(); + pageTranslation->pageName = pageNode.nodeName(); + for (int itemIndex = 0; itemIndex < pageNode.childNodes().count(); ++itemIndex){ + QDomElement itemNode = pageNode.childNodes().at(itemIndex).toElement(); + ItemTranslation* itemTranslation = new ItemTranslation(); + itemTranslation->itemName = itemNode.nodeName(); + for (int propertyIndex = 0; propertyIndex < itemNode.childNodes().count(); ++propertyIndex){ + QDomElement propertyNode = itemNode.childNodes().at(propertyIndex).toElement(); + PropertyTranslation* propertyTranslation = new PropertyTranslation; + propertyTranslation->propertyName = propertyNode.nodeName(); + propertyTranslation->value = propertyNode.attribute("Value"); + propertyTranslation->sourceValue = propertyNode.attribute("SourceValue"); + propertyTranslation->checked = propertyNode.attribute("Checked").compare("Y") == 0; + itemTranslation->propertyesTranslation.append(propertyTranslation); + } + pageTranslation->itemsTranslation.insert(itemTranslation->itemName, itemTranslation); + } + } + translations->insert(curTranslation->language(),curTranslation); + } + } } FileXMLReader::FileXMLReader(QString fileName) diff --git a/limereport/serializators/lrxmlreader.h b/limereport/serializators/lrxmlreader.h index c0f3508..3dbbc5c 100644 --- a/limereport/serializators/lrxmlreader.h +++ b/limereport/serializators/lrxmlreader.h @@ -61,6 +61,7 @@ protected: void readProperty(QObject *item, QDomElement *node); void readQObject(QObject *item, QDomElement *node); void readCollection(QObject *item, QDomElement *node); + void readTranslation(QObject *item, QDomElement *node); QVariant getValue(QDomElement *node); protected: diff --git a/limereport/serializators/lrxmlwriter.cpp b/limereport/serializators/lrxmlwriter.cpp index 3038373..84062da 100644 --- a/limereport/serializators/lrxmlwriter.cpp +++ b/limereport/serializators/lrxmlwriter.cpp @@ -31,6 +31,7 @@ #include "lrbasedesignintf.h" #include "serializators/lrxmlserializatorsfactory.h" #include "lrcollection.h" +#include "lrreporttranslation.h" #include namespace LimeReport{ @@ -137,7 +138,9 @@ void XMLWriter::saveProperty(QString name, QObject* item, QDomElement *node) typeName = item->property(name.toLatin1()).typeName(); CreateSerializator creator=0; - if (isCollection(name,item)) { saveCollection(name,item,node); return;} + if (isCollection(name, item)) { saveCollection(name,item,node); return; } + if (isTranslation(name, item)) { saveTranslation(name, item, node); return; } + if (isQObject(name,item)) { if (qvariant_cast(item->property(name.toLatin1()))) putQObjectProperty(name,qvariant_cast(item->property(name.toLatin1())),node); @@ -193,9 +196,15 @@ bool XMLWriter::isCollection(QString propertyName, QObject* item) return QMetaType::type(prop.typeName())==COLLECTION_TYPE_ID; } +bool XMLWriter::isTranslation(QString propertyName, QObject* item) +{ + QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1())); + return QMetaType::type(prop.typeName())==TRANSLATION_TYPE_ID; +} + void XMLWriter::saveCollection(QString propertyName, QObject *item, QDomElement *node) { - ICollectionContainer * collection=dynamic_cast(item); + ICollectionContainer * collection = dynamic_cast(item); QDomElement collectionNode=m_doc->createElement(propertyName); collectionNode.setAttribute("Type","Collection"); @@ -206,6 +215,42 @@ void XMLWriter::saveCollection(QString propertyName, QObject *item, QDomElement node->appendChild(collectionNode); } +void XMLWriter::saveTranslation(QString propertyName, QObject* item, QDomElement* node) +{ + ITranslationContainer* translationsContainer = dynamic_cast(item); + if (translationsContainer){ + QDomElement translationsNode=m_doc->createElement(propertyName); + translationsNode.setAttribute("Type","Translation"); + Translations* translations = translationsContainer->translations(); + foreach(QLocale::Language language, translations->keys()){ + QDomElement languageNode = m_doc->createElement(QLocale::languageToString(language)); + languageNode.setAttribute("Value",QString::number(language)); + translationsNode.appendChild(languageNode); + ReportTranslation* curTranslation = translations->value(language); + foreach(PageTranslation* page, curTranslation->pagesTranslation()){ + QDomElement pageNode = m_doc->createElement(page->pageName); + languageNode.appendChild(pageNode); + foreach(ItemTranslation* item, page->itemsTranslation){ + QDomElement itemNode = m_doc->createElement(item->itemName); + foreach(PropertyTranslation* property, item->propertyesTranslation){ + if (property->sourceValue.compare(property->value) != 0){ + QDomElement propertyNode = m_doc->createElement(property->propertyName); + propertyNode.setAttribute("Value",property->value); + propertyNode.setAttribute("SourceValue", property->sourceValue); + propertyNode.setAttribute("Checked", property->checked ? "Y":"N"); + itemNode.appendChild(propertyNode); + } + } + if (!itemNode.childNodes().isEmpty()) + pageNode.appendChild(itemNode); + } + } + } + node->appendChild(translationsNode); + } + +} + bool XMLWriter::isQObject(QString propertyName, QObject *item) { QMetaProperty prop=item->metaObject()->property(item->metaObject()->indexOfProperty(propertyName.toLatin1())); diff --git a/limereport/serializators/lrxmlwriter.h b/limereport/serializators/lrxmlwriter.h index 0259a75..05d47a7 100644 --- a/limereport/serializators/lrxmlwriter.h +++ b/limereport/serializators/lrxmlwriter.h @@ -62,7 +62,9 @@ private: bool enumOrFlag(QString name, QObject* item); QString extractClassName(QObject* item); bool isCollection(QString propertyName, QObject *item); + bool isTranslation(QString propertyName, QObject *item); void saveCollection(QString propertyName, QObject *item, QDomElement *node); + void saveTranslation(QString propertyName, QObject *item, QDomElement *node); bool isQObject(QString propertyName, QObject *item); bool replaceNode(QDomElement node, QObject *item); private: diff --git a/limereport/translationeditor/images/add.png b/limereport/translationeditor/images/add.png new file mode 100644 index 0000000..b567125 Binary files /dev/null and b/limereport/translationeditor/images/add.png differ diff --git a/limereport/translationeditor/images/checked.png b/limereport/translationeditor/images/checked.png new file mode 100644 index 0000000..8149629 Binary files /dev/null and b/limereport/translationeditor/images/checked.png differ diff --git a/limereport/translationeditor/images/green_check.png b/limereport/translationeditor/images/green_check.png new file mode 100644 index 0000000..ada2461 Binary files /dev/null and b/limereport/translationeditor/images/green_check.png differ diff --git a/limereport/translationeditor/images/question.png b/limereport/translationeditor/images/question.png new file mode 100644 index 0000000..1b358c8 Binary files /dev/null and b/limereport/translationeditor/images/question.png differ diff --git a/limereport/translationeditor/images/remove.png b/limereport/translationeditor/images/remove.png new file mode 100644 index 0000000..8a974cf Binary files /dev/null and b/limereport/translationeditor/images/remove.png differ diff --git a/limereport/translationeditor/languageselectdialog.cpp b/limereport/translationeditor/languageselectdialog.cpp new file mode 100644 index 0000000..64265c8 --- /dev/null +++ b/limereport/translationeditor/languageselectdialog.cpp @@ -0,0 +1,31 @@ +#include "languageselectdialog.h" +#include "ui_languageselectdialog.h" +#include +#include +#include + +LanguageSelectDialog::LanguageSelectDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::LanguageSelectDialog) +{ + ui->setupUi(this); + for (int i = 2; icomboBox->addItem(QLocale::languageToString(static_cast(i)),static_cast(i)); + } +#ifdef HAVE_QT5 + ui->comboBox->setCurrentText(""); +#endif +#ifdef HAVE_QT4 + ui->comboBox->setEditText(""); +#endif +} + +LanguageSelectDialog::~LanguageSelectDialog() +{ + delete ui; +} + +QLocale::Language LanguageSelectDialog::getSelectedLanguage() +{ + return ui->comboBox->itemData(ui->comboBox->currentIndex()).value(); +} diff --git a/limereport/translationeditor/languageselectdialog.h b/limereport/translationeditor/languageselectdialog.h new file mode 100644 index 0000000..0402327 --- /dev/null +++ b/limereport/translationeditor/languageselectdialog.h @@ -0,0 +1,25 @@ +#ifndef LANGUAGESELECTDIALOG_H +#define LANGUAGESELECTDIALOG_H + +#include +#include + +namespace Ui { +class LanguageSelectDialog; +} + +class LanguageSelectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LanguageSelectDialog(QWidget *parent = 0); + ~LanguageSelectDialog(); + QLocale::Language getSelectedLanguage(); +private: + Ui::LanguageSelectDialog *ui; +}; + +Q_DECLARE_METATYPE(QLocale::Language) + +#endif // LANGUAGESELECTDIALOG_H diff --git a/limereport/translationeditor/languageselectdialog.ui b/limereport/translationeditor/languageselectdialog.ui new file mode 100644 index 0000000..1575429 --- /dev/null +++ b/limereport/translationeditor/languageselectdialog.ui @@ -0,0 +1,88 @@ + + + LanguageSelectDialog + + + + 0 + 0 + 336 + 109 + + + + Dialog + + + + + + + + + 0 + 0 + + + + Language + + + + + + + true + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + LanguageSelectDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LanguageSelectDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/limereport/translationeditor/translationeditor.cpp b/limereport/translationeditor/translationeditor.cpp new file mode 100644 index 0000000..d792d67 --- /dev/null +++ b/limereport/translationeditor/translationeditor.cpp @@ -0,0 +1,237 @@ +#include "translationeditor.h" +#include "ui_translationeditor.h" +#include "lrreportengine.h" +#include "lrreportengine_p.h" +#include "lrreporttranslation.h" +#include "languageselectdialog.h" +#include + +namespace LimeReport { + +TranslationEditor::TranslationEditor(QWidget *parent) : + QWidget(parent), + ui(new Ui::TranslationEditor), m_translationContainer(0), + m_currentReportTranslation(0), m_currentPageTranslation(0), m_currentPropertyTranslation(0) +{ + ui->setupUi(this); + ui->splitter_3->setStretchFactor(1,10); + ui->splitter_3->setStretchFactor(0,2); + ui->splitter_2->setStretchFactor(1,2); + ui->splitter->setStretchFactor(0,2); + QTableWidgetItem* item = new QTableWidgetItem(); + item->setIcon(QIcon(":/translationeditor/checked")); + ui->tbStrings->setColumnCount(4); + ui->tbStrings->setColumnWidth(0,30); + ui->tbStrings->setColumnWidth(1,100); + ui->tbStrings->setColumnWidth(2,100); + ui->tbStrings->setHorizontalHeaderItem(0,item); + ui->tbStrings->setHorizontalHeaderItem(1,new QTableWidgetItem(tr("Report Item"))); + ui->tbStrings->setHorizontalHeaderItem(2,new QTableWidgetItem(tr("Property"))); + ui->tbStrings->setHorizontalHeaderItem(3,new QTableWidgetItem(tr("Source text"))); + new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this, SLOT(slotItemChecked())); + //ui->tbStrings->setSortingEnabled(true); + +} + +void TranslationEditor::setReportEngine(ITranslationContainer* translationContainer) +{ + m_translationContainer = translationContainer; + m_currentReportTranslation = 0; + m_currentPageTranslation = 0; + m_currentPropertyTranslation = 0; + + if (m_translationContainer){ + m_translationContainer->updateTranslations(); + updateUi(); + } +} + +TranslationEditor::~TranslationEditor() +{ + delete ui; +} + +QLocale::Language TranslationEditor::getLanguageByName(const QString& languageName){ + foreach(QLocale::Language language, m_translationContainer->translations()->keys()){ + if (QLocale::languageToString(language).compare(languageName) == 0){ + return language; + } + } + return QLocale::AnyLanguage; +} + +void TranslationEditor::updateUi() +{ + ui->lvLanguages->clear(); + ui->twPages->clear(); + ui->tbStrings->clearContents(); + ui->teTranslation->setPlainText(""); + ui->cbChecked->setEnabled(false); + + Q_ASSERT(m_translationContainer != 0); + if (m_translationContainer){ + Translations* translations = m_translationContainer->translations(); + Q_ASSERT(translations != 0); + if (translations){ + foreach(QLocale::Language language, translations->keys()){ + if (language != QLocale::AnyLanguage) + ui->lvLanguages->addItem(QLocale::languageToString(language)); + } + if (!translations->keys().isEmpty()){ + if (ui->lvLanguages->count()!=0){ + ui->lvLanguages->item(0)->setSelected(true); + activateLanguage(getLanguageByName(ui->lvLanguages->item(0)->text())); + } else { + //activateLanguage(QLocale::AnyLanguage); + ui->twPages->clear(); + ui->tbStrings->setRowCount(0); + } + } + } + } +} + +void TranslationEditor::activateLanguage(QLocale::Language language) +{ + ui->teTranslation->setEnabled(false); + ui->cbChecked->setEnabled(false); + ui->twPages->clear(); + Translations* translations = m_translationContainer->translations(); + Q_ASSERT(translations != 0); + if (translations){ + m_currentReportTranslation = translations->value(language); + Q_ASSERT(m_currentReportTranslation != 0); + if (m_currentReportTranslation){ + foreach(PageTranslation* pageTranslation, m_currentReportTranslation->pagesTranslation()){ + QTreeWidgetItem* pageItem = new QTreeWidgetItem(); + pageItem->setText(0,pageTranslation->pageName); + ui->twPages->addTopLevelItem(pageItem); + } + } + if (ui->twPages->topLevelItem(0)){ + ui->twPages->topLevelItem(0)->setSelected(true); + activatePage(m_currentReportTranslation->findPageTranslation(ui->twPages->topLevelItem(0)->text(0))); + } + } +} + +void TranslationEditor::activatePage(PageTranslation* pageTranslation) +{ + ui->teTranslation->setEnabled(false); + ui->cbChecked->setEnabled(false); + Q_ASSERT(pageTranslation != 0); + if(pageTranslation){ + ui->tbStrings->clearContents(); + ui->tbStrings->setRowCount(0); + m_currentPageTranslation = pageTranslation; + QStringList items = pageTranslation->itemsTranslation.keys(); + items.sort(); + foreach(QString itemName, items){ + ItemTranslation* itemTranslation = pageTranslation->itemsTranslation.value(itemName); + int rowIndex = ui->tbStrings->rowCount(); + ui->tbStrings->setRowCount(rowIndex+1); + foreach(PropertyTranslation* propertyTranslation, itemTranslation->propertyesTranslation){ + QTableWidgetItem* checkItem = new QTableWidgetItem(); + + if (propertyTranslation->sourceHasBeenChanged){ + checkItem->setIcon(QIcon(":/translationeditor/question")); + } + if (propertyTranslation->checked){ + checkItem->setIcon(QIcon(":/translationeditor/checked")); + } + + ui->tbStrings->setItem(rowIndex,0,checkItem); + ui->tbStrings->setItem(rowIndex,1,new QTableWidgetItem(itemTranslation->itemName)); + ui->tbStrings->setItem(rowIndex,2,new QTableWidgetItem(propertyTranslation->propertyName)); + ui->tbStrings->setItem(rowIndex,3,new QTableWidgetItem(propertyTranslation->sourceValue)); + } + } + } + +} + +void TranslationEditor::activateTranslation(const QString& itemName, const QString& propertyName) +{ + Q_ASSERT(m_currentPageTranslation != 0); + if (m_currentPageTranslation){ + ItemTranslation* itemTranslation = m_currentPageTranslation->itemsTranslation.value(itemName); + Q_ASSERT(itemTranslation !=0 ); + if (itemTranslation){ + m_currentPropertyTranslation = m_currentPageTranslation->itemsTranslation.value(itemName)->findProperty(propertyName); + Q_ASSERT(m_currentPropertyTranslation != 0); + if (m_currentPropertyTranslation){ + ui->teTranslation->setEnabled(true); + ui->cbChecked->setEnabled(true); + ui->teTranslation->setText(m_currentPropertyTranslation->value); + ui->cbChecked->setChecked(m_currentPropertyTranslation->checked); + } + } + } +} + +void TranslationEditor::on_tbStrings_itemSelectionChanged() +{ + if (m_currentPageTranslation) + activateTranslation(ui->tbStrings->item(ui->tbStrings->currentRow(),1)->text(), ui->tbStrings->item(ui->tbStrings->currentRow(),2)->text()); +} + +void TranslationEditor::on_teTranslation_textChanged() +{ + if (m_currentPropertyTranslation) + m_currentPropertyTranslation->value = ui->teTranslation->toPlainText(); +} + +void TranslationEditor::on_cbChecked_toggled(bool checked) +{ + if (m_currentPropertyTranslation){ + m_currentPropertyTranslation->checked = checked; + ui->tbStrings->item(ui->tbStrings->currentRow(),0)->setIcon(checked ? QIcon(":/translationeditor/checked"):QIcon()); + } +} + +void TranslationEditor::on_twPages_itemSelectionChanged() +{ + if (!ui->twPages->selectedItems().isEmpty()){ + activatePage(m_currentReportTranslation->findPageTranslation(ui->twPages->selectedItems().at(0)->text(0))); + } +} + +void TranslationEditor::on_tbAddLanguage_clicked() +{ + LanguageSelectDialog dialog; + if (dialog.exec()){ + m_translationContainer->addTranslationLanguage(dialog.getSelectedLanguage()); + updateUi(); + activateLanguage(dialog.getSelectedLanguage()); + } +} + +void TranslationEditor::on_tbDeleteLanguage_clicked() +{ + m_translationContainer->removeTranslationLanguage(m_currentReportTranslation->language()); + updateUi(); +} + +void TranslationEditor::slotItemChecked() +{ + if (ui->tbStrings->currentRow()tbStrings->rowCount()){ + ui->cbChecked->setChecked(true); + ui->tbStrings->selectRow(ui->tbStrings->currentRow()+1); + ui->teTranslation->setFocus(); + } +} + +void TranslationEditor::on_lvLanguages_itemSelectionChanged() +{ + if (ui->lvLanguages->currentItem() && m_currentReportTranslation){ + activateLanguage(getLanguageByName(ui->lvLanguages->currentItem()->text())); + } +} + +} //namespace LimeReport + + + + + + diff --git a/limereport/translationeditor/translationeditor.h b/limereport/translationeditor/translationeditor.h new file mode 100644 index 0000000..a270eb4 --- /dev/null +++ b/limereport/translationeditor/translationeditor.h @@ -0,0 +1,52 @@ +#ifndef TRANSLATIONEDITOR_H +#define TRANSLATIONEDITOR_H + +#include +#include +#include +#include "lrreporttranslation.h" + +namespace LimeReport { + +namespace Ui { +class TranslationEditor; +} + + +class TranslationEditor : public QWidget +{ + Q_OBJECT + +public: + explicit TranslationEditor(QWidget *parent = 0); + void setReportEngine(ITranslationContainer* translationContainer); + ~TranslationEditor(); + void updateUi(); + void activateLanguage(QLocale::Language language); + void activatePage(PageTranslation* pageTranslation); + void activateTranslation(const QString& itemName, const QString& propertyName); +private slots: + void on_tbStrings_itemSelectionChanged(); + void on_teTranslation_textChanged(); + void on_cbChecked_toggled(bool checked); + void on_twPages_itemSelectionChanged(); + void on_tbAddLanguage_clicked(); + void on_tbDeleteLanguage_clicked(); + void slotItemChecked(); + void on_lvLanguages_itemSelectionChanged(); + +private: + QLocale::Language getLanguageByName(const QString& languageName); +private: + Ui::TranslationEditor *ui; + ITranslationContainer* m_translationContainer; + QMap m_reportTranslations; + QMap m_pageTranslations; + ReportTranslation* m_currentReportTranslation; + PageTranslation* m_currentPageTranslation; + PropertyTranslation* m_currentPropertyTranslation; +}; + +} //namespace LimeReport + +#endif // TRANSLATIONEDITOR_H diff --git a/limereport/translationeditor/translationeditor.qrc b/limereport/translationeditor/translationeditor.qrc new file mode 100644 index 0000000..af0f804 --- /dev/null +++ b/limereport/translationeditor/translationeditor.qrc @@ -0,0 +1,9 @@ + + + images/add.png + images/remove.png + images/checked.png + images/question.png + images/green_check.png + + diff --git a/limereport/translationeditor/translationeditor.ui b/limereport/translationeditor/translationeditor.ui new file mode 100644 index 0000000..944fec4 --- /dev/null +++ b/limereport/translationeditor/translationeditor.ui @@ -0,0 +1,225 @@ + + + LimeReport::TranslationEditor + + + + 0 + 0 + 873 + 525 + + + + Form + + + + + + Qt::Horizontal + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + Qt::Vertical + + + + Languages + + + true + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + ... + + + + :/translationeditor/add:/translationeditor/add + + + true + + + + + + + ... + + + + :/translationeditor/remove:/translationeditor/remove + + + true + + + + + + + + + + + + + Pages + + + true + + + + + + false + + + false + + + + 1 + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + Qt::Vertical + + + + Strings + + + true + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + 2 + + + true + + + + + + + + :/translationeditor/checked:/translationeditor/checked + + + + + Source Text + + + + + + + + + Translation + + + true + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Checked + + + + + + + + + + + + + + + + + + + + + diff --git a/qzint.pri b/qzint.pri index 51a6a50..6dc3a08 100644 --- a/qzint.pri +++ b/qzint.pri @@ -6,33 +6,35 @@ DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$ INCLUDEPATH += \ $$ZINT_PATH/backend \ - $$ZINT_PATH/backend_qt4 + $$ZINT_PATH/backend_qt HEADERS += $$ZINT_PATH/backend/aztec.h \ - $$ZINT_PATH/backend/code1.h \ + $$ZINT_PATH/backend/bmp.h \ $$ZINT_PATH/backend/code49.h \ $$ZINT_PATH/backend/common.h \ $$ZINT_PATH/backend/composite.h \ $$ZINT_PATH/backend/dmatrix.h \ + $$ZINT_PATH/backend/eci.h \ $$ZINT_PATH/backend/font.h \ - $$ZINT_PATH/backend/gb2312.h \ $$ZINT_PATH/backend/gridmtx.h \ $$ZINT_PATH/backend/gs1.h \ + $$ZINT_PATH/backend/hanxin.h \ $$ZINT_PATH/backend/large.h \ $$ZINT_PATH/backend/maxicode.h \ - $$ZINT_PATH/backend/maxipng.h \ - $$ZINT_PATH/backend/ms_stdint.h \ + $$ZINT_PATH/backend/pcx.h \ $$ZINT_PATH/backend/pdf417.h \ - $$ZINT_PATH/backend/qr.h \ $$ZINT_PATH/backend/reedsol.h \ $$ZINT_PATH/backend/rss.h \ $$ZINT_PATH/backend/sjis.h \ + $$ZINT_PATH/backend/stdint_msvc.h \ $$ZINT_PATH/backend/zint.h \ - $$ZINT_PATH/backend_qt4/qzint.h + $$ZINT_PATH/backend_qt/qzint.h SOURCES += $$ZINT_PATH/backend/2of5.c \ $$ZINT_PATH/backend/auspost.c \ $$ZINT_PATH/backend/aztec.c \ + $$ZINT_PATH/backend/bmp.c \ + $$ZINT_PATH/backend/codablock.c \ $$ZINT_PATH/backend/code.c \ $$ZINT_PATH/backend/code1.c \ $$ZINT_PATH/backend/code128.c \ @@ -40,25 +42,33 @@ SOURCES += $$ZINT_PATH/backend/2of5.c \ $$ZINT_PATH/backend/code49.c \ $$ZINT_PATH/backend/common.c \ $$ZINT_PATH/backend/composite.c \ + $$ZINT_PATH/backend/dllversion.c \ $$ZINT_PATH/backend/dmatrix.c \ + $$ZINT_PATH/backend/dotcode.c \ + $$ZINT_PATH/backend/eci.c \ + $$ZINT_PATH/backend/emf.c \ + $$ZINT_PATH/backend/gif.c \ $$ZINT_PATH/backend/gridmtx.c \ $$ZINT_PATH/backend/gs1.c \ + $$ZINT_PATH/backend/hanxin.c \ $$ZINT_PATH/backend/imail.c \ $$ZINT_PATH/backend/large.c \ $$ZINT_PATH/backend/library.c \ $$ZINT_PATH/backend/maxicode.c \ $$ZINT_PATH/backend/medical.c \ + $$ZINT_PATH/backend/pcx.c \ $$ZINT_PATH/backend/pdf417.c \ $$ZINT_PATH/backend/plessey.c \ + $$ZINT_PATH/backend/png.c \ $$ZINT_PATH/backend/postal.c \ $$ZINT_PATH/backend/ps.c \ $$ZINT_PATH/backend/qr.c \ + $$ZINT_PATH/backend/raster.c \ $$ZINT_PATH/backend/reedsol.c \ $$ZINT_PATH/backend/render.c \ $$ZINT_PATH/backend/rss.c \ $$ZINT_PATH/backend/svg.c \ $$ZINT_PATH/backend/telepen.c \ + $$ZINT_PATH/backend/tif.c \ $$ZINT_PATH/backend/upcean.c \ - $$ZINT_PATH/backend/dllversion.c \ - $$ZINT_PATH/backend/png.c \ - $$ZINT_PATH/backend_qt4/qzint.cpp + $$ZINT_PATH/backend_qt/qzint.cpp diff --git a/tests/tests.pro b/tests/tests.pro new file mode 100644 index 0000000..e5d5838 --- /dev/null +++ b/tests/tests.pro @@ -0,0 +1,37 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-06-20T01:13:06 +# +#------------------------------------------------- + +QT += testlib gui widgets + +TARGET = tst_callbackdstest +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 +include(../common.pri) +include(../limereport/limereport.pri) + +INCLUDEPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt4 +DEPENDPATH += $$ZINT_PATH/backend $$ZINT_PATH/backend_qt4 +LIBS += -L$${DEST_LIBS} -lQtZint + +#LIBS += -L$${DEST_LIBS} -llimereport + +SOURCES += \ + tst_callbackdstest.cpp + +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/tst_callbackdstest.cpp b/tests/tst_callbackdstest.cpp new file mode 100644 index 0000000..a7e0aa6 --- /dev/null +++ b/tests/tst_callbackdstest.cpp @@ -0,0 +1,260 @@ +#include +#include +#include "../limereport/lrdatadesignintf.h" + +class CallbackDSTest : public QObject +{ + Q_OBJECT + +public: + CallbackDSTest(); +private: + LimeReport::CallbackDatasource* m_testDS; + LimeReport::CallbackDatasource* m_test1DS; + int m_currentRow; +protected Q_SLOTS: + void slotTestOneSlotDS(LimeReport::CallbackInfo info, QVariant& data); + void slotGetCallbackData(LimeReport::CallbackInfo info, QVariant& data); + void slotChangePos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result); +private Q_SLOTS: + void testOneSlotDS(); + void testTwoSlotDS(); + +}; + +CallbackDSTest::CallbackDSTest() +{ + m_testDS = new LimeReport::CallbackDatasource(); + connect(m_testDS, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), + this, SLOT(slotTestOneSlotDS(LimeReport::CallbackInfo,QVariant&))); + + m_test1DS = new LimeReport::CallbackDatasource(); + m_currentRow = -1; + connect(m_test1DS, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), + this, SLOT(slotGetCallbackData(LimeReport::CallbackInfo,QVariant&))); + connect(m_test1DS, SIGNAL(changePos(LimeReport::CallbackInfo::ChangePosType,bool&)), + this, SLOT(slotChangePos(LimeReport::CallbackInfo::ChangePosType,bool&))); +} + + + +void CallbackDSTest::slotTestOneSlotDS(LimeReport::CallbackInfo info, QVariant& data) +{ + QStringList columns; + columns << "Name" << "Value"; + QVector values; + values<<"Mazda"<<"Nissan"; + int dataIndex = 0; + switch (info.dataType) { + case LimeReport::CallbackInfo::RowCount: + data = 10; + break; + case LimeReport::CallbackInfo::ColumnCount: + data = columns.size(); + break; + case LimeReport::CallbackInfo::ColumnHeaderData: { + data = columns.at(info.index); + break; + } + case LimeReport::CallbackInfo::ColumnData: + if (info.index > 5){ + dataIndex = 1; + } + if (info.columnName == "Name") + data = values[dataIndex]; + else { + data = info.index; + } + break; + default: break; + } +} + +void CallbackDSTest::slotGetCallbackData(LimeReport::CallbackInfo info, QVariant& data) +{ + QStringList columns; + columns << "Name" << "Value"; + QVector values; + values<<"Mazda"<<"Nissan"; + int dataIndex = 0; + switch (info.dataType) { + case LimeReport::CallbackInfo::ColumnCount: + data = columns.size(); + break; + case LimeReport::CallbackInfo::ColumnHeaderData: { + data = columns.at(info.index); + break; + } + case LimeReport::CallbackInfo::HasNext:{ + data = (info.index < 9); + break; + } + case LimeReport::CallbackInfo::ColumnData: + if (info.index > 5){ + dataIndex = 1; + } + if (info.columnName == "Name") + data = values[dataIndex]; + else { + data = m_currentRow; + } + break; + default: break; + } +} + +void CallbackDSTest::slotChangePos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result) +{ + if (type == LimeReport::CallbackInfo::First) {m_currentRow = 0; result = true;} + else {if (m_currentRow<9) m_currentRow++; result = (m_currentRow <= 9);} +} + +void CallbackDSTest::testOneSlotDS() +{ + QVERIFY2(m_testDS->bof(), "Failure test bof"); + QVERIFY2(!m_testDS->eof(), "Failure test eof"); + QVERIFY2(m_testDS->hasNext(), "Failure hasNext"); + QVERIFY2(m_testDS->columnCount() == 2, "Failure test column count"); + QVERIFY2(m_testDS->columnNameByIndex(0).compare("Name") == 0, "Failure test column name"); + QVERIFY2(m_testDS->columnNameByIndex(1).compare("Value") == 0, "Failure test column name"); + QVERIFY2(m_testDS->columnIndexByName("Name") == 0, "Failure test column index"); + QVERIFY2(m_testDS->columnIndexByName("Value") == 1, "Failure test column index"); + QVERIFY2(!m_testDS->data("Name").isValid(),"Failure test data on bof"); + QVERIFY2(!m_testDS->data("Value").isValid(),"Failure test data on bof"); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),0); + QVERIFY2(!m_testDS->prior(), "Failure test prior"); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),1); + QVERIFY2(m_testDS->prior(), "Failure test prior"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),0); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),1); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),2); + QVERIFY2(m_testDS->prior(), "Failure test prior"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),1); + QVERIFY2(!m_testDS->prior(), "Failure test prior"); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),2); + for(int i = 3; i < 6; ++i) m_testDS->next(); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),5); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),6); + QVERIFY2(m_testDS->prior(), "Failure test prior"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_testDS->data("Value").toInt(),5); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),6); + for(int i = 7; i < 9; ++i) m_testDS->next(); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),8); + QVERIFY2(m_testDS->next(), "Failure next"); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),9); + QCOMPARE(m_testDS->hasNext(), false); + QCOMPARE(m_testDS->next(), false); + QCOMPARE(m_testDS->bof(), false); + QCOMPARE(m_testDS->eof(), true); + QCOMPARE(m_testDS->prior(), true); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),8); + QCOMPARE(m_testDS->hasNext(), true); + QCOMPARE(m_testDS->next(), true); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),9); + QCOMPARE(m_testDS->hasNext(), false); + QCOMPARE(m_testDS->next(), false); + QCOMPARE(m_testDS->bof(), false); + QCOMPARE(m_testDS->eof(), true); + QCOMPARE(m_testDS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_testDS->data("Value").toInt(),9); +} + + +void CallbackDSTest::testTwoSlotDS() +{ + + QVERIFY2(m_test1DS->bof(), "Failure test bof"); + QVERIFY2(!m_test1DS->eof(), "Failure test eof"); + QVERIFY2(m_test1DS->hasNext(), "Failure hasNext"); + QVERIFY2(m_test1DS->columnCount() == 2, "Failure test column count"); + QVERIFY2(m_test1DS->columnNameByIndex(0).compare("Name") == 0, "Failure test column name"); + QVERIFY2(m_test1DS->columnNameByIndex(1).compare("Value") == 0, "Failure test column name"); + QVERIFY2(m_test1DS->columnIndexByName("Name") == 0, "Failure test column index"); + QVERIFY2(m_test1DS->columnIndexByName("Value") == 1, "Failure test column index"); + QVERIFY2(!m_test1DS->data("Name").isValid(),"Failure test data on bof"); + QVERIFY2(!m_test1DS->data("Value").isValid(),"Failure test data on bof"); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),0); + QVERIFY2(!m_test1DS->prior(), "Failure test prior"); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),1); + QVERIFY2(m_test1DS->prior(), "Failure test prior"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),0); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),1); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),2); + QVERIFY2(m_test1DS->prior(), "Failure test prior"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),1); + QVERIFY2(!m_test1DS->prior(), "Failure test prior"); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),2); + for(int i = 3; i < 6; ++i) m_test1DS->next(); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),5); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),6); + QVERIFY2(m_test1DS->prior(), "Failure test prior"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Mazda")); + QCOMPARE(m_test1DS->data("Value").toInt(),5); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),6); + for(int i = 7; i < 9; ++i) m_test1DS->next(); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),8); + QVERIFY2(m_test1DS->next(), "Failure next"); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),9); + QCOMPARE(m_test1DS->hasNext(), false); + QCOMPARE(m_test1DS->next(), false); + QCOMPARE(m_test1DS->bof(), false); + QCOMPARE(m_test1DS->eof(), true); + QCOMPARE(m_test1DS->prior(), true); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),8); + QCOMPARE(m_test1DS->hasNext(), true); + QCOMPARE(m_test1DS->next(), true); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),9); + QCOMPARE(m_test1DS->hasNext(), false); + QCOMPARE(m_test1DS->next(), false); + QCOMPARE(m_test1DS->bof(), false); + QCOMPARE(m_test1DS->eof(), true); + QCOMPARE(m_test1DS->data("Name").toString(),QString("Nissan")); + QCOMPARE(m_test1DS->data("Value").toInt(),9); +} + +QTEST_APPLESS_MAIN(CallbackDSTest) + +#include "tst_callbackdstest.moc" diff --git a/translations/limereport_ar.ts b/translations/limereport_ar.ts index add2edf..0240adc 100644 --- a/translations/limereport_ar.ts +++ b/translations/limereport_ar.ts @@ -2,136 +2,57 @@ - AboutDialog + $ClassName$ - About - حول البرنامج - - - Author - المؤلف - - - License - إتفاقية الترخيص - - - Close - إغلاق - - - Version 1.1.1 - الإصدار 1.1.1 + $ClassName$ + - ConnectionDialog + ChartItemEditor - Connection - إتصال بقاعدة بيانات + Series + - Connection Name - أسم الإتصال + Add + - Driver - المشغل + Delete + - Server - الخادم + Name + الأسم - User - المستخدم + Values field + - Password - كلمة المرور + Color + - Database - قاعدة البيانات + Type + النوع - Auto connect - إتصال تلقائي + Labels field + - Check connection - فحص الإتصال + Ok + موافق - Cancel - إلغاء الأمر + Series editor + - Error - خطأ - - - Connection succsesfully established! - تم الإتصال بنجاح!! - - - Connection Name is empty - أسم الإتصال فارغ - - - Connection with name - إتصال بأسم - - - already exists - موجود مسبقاً - - - - DataBrowser - - Datasources - مصدر البيانات - - - Add database connection - إضافة إتصال قاعدة بيانات - - - Add new datasource - إضافة مصدر بيانات جديد - - - View data - عرض البيانات - - - Change datasource - تغيير مصدر البيانات - - - Delete datasource - حذف مصدر البيانات - - - Show error - عرض الأخطاء - - - Variables - المتغيرات - - - Add new variable - إضافة متغير - - - Edit variable - تعديل متغير - - - Delete variable - حذف متغير + Series name + @@ -156,20 +77,20 @@ Attention Attention + + Mandatory + + - LimeReport::AVariablesHolder + LanguageSelectDialog - variable with name - متغير بأسم + Dialog + - already exists !! - موجود مسبقاً !! - - - does not exists !! - غير موجود !! + Language + @@ -462,6 +383,10 @@ p, li { white-space: pre-wrap; } Start new page + + Keep top space + + LimeReport::BaseDesignIntf @@ -493,6 +418,10 @@ p, li { white-space: pre-wrap; } All borders محاط بإطار + + Create Horizontal Layout + + LimeReport::ConnectionDesc @@ -559,10 +488,6 @@ p, li { white-space: pre-wrap; } Connection with name إتصال بأسم - - already exists - موجود مسبقاً - ... @@ -592,19 +517,16 @@ p, li { white-space: pre-wrap; } - - LimeReport::ContentItemDesignIntf - - Variable %1 not found - المتغير %1 غير موجود - - LimeReport::DataBand Data بيانات + + Use alternate background color + + LimeReport::DataBrowser @@ -656,28 +578,10 @@ p, li { white-space: pre-wrap; } Attention Attention - - Do you really want to delete "%1" connection ? - Do you really want delete "%1" connection ? - هل ترغب في حذف الإتصال "%1" ? - - - User variables - متغيرات المستخدم - System variables متغيرات النظام - - Do you really want to delete "%1" datasource ? - Do you really want delete "%1" datasource ? - هل ترغب في حذف مصدر البيانات "%1" ? - - - Do you really want delete variable "%1" ? - هل ترغب في حذف المتغير "%1" ? - Error خطأ @@ -686,10 +590,6 @@ p, li { white-space: pre-wrap; } ... - - Do you really want to delete variable "%1" ? - هل ترغب في حذف المتغير "%1" ? - Grab variable @@ -735,19 +635,6 @@ p, li { white-space: pre-wrap; } Connection "%1" is not open الإتصال "%1" غير مفتوح - - Datasource "%1" not found ! - الإتصال "%1" غير موجود ! - - - connection with name "%1" already exists ! - الإتصال بأسم "%1" موجود مسبقاً ! - - - datasource with name "%1" already exists ! - data source with name "%1" already exists !! - مصدر البيانات بأسم "%1" موجود مسبقاً ! - invalid connection خطأ بالإتصال @@ -788,6 +675,37 @@ p, li { white-space: pre-wrap; } + + LimeReport::DialogDesignerManager + + Edit Widgets + + + + Widget Box + + + + Object Inspector + فاحص الكائن + + + Property Editor + + + + Signals && Slots Editor + + + + Resource Editor + + + + Action Editor + + + LimeReport::EnumPropItem @@ -978,6 +896,42 @@ p, li { white-space: pre-wrap; } VerticalUniform + + Pie + + + + VerticalBar + + + + HorizontalBar + + + + LegendAlignTop + + + + LegendAlignCenter + + + + LegendAlignBottom + + + + TitleAlignLeft + + + + TitleAlignRight + + + + TitleAlignCenter + + LimeReport::FlagsPropItem @@ -1001,6 +955,10 @@ p, li { white-space: pre-wrap; } RightLine خط أيمن + + AllLines + + LimeReport::FontEditorWidget @@ -1087,6 +1045,10 @@ p, li { white-space: pre-wrap; } Image صورة + + Watermark + + LimeReport::ItemLocationPropItem @@ -1194,23 +1156,20 @@ p, li { white-space: pre-wrap; } الكائن - - LimeReport::PageDesignIntf - - Warning - تحذير - - - Multi band deletion not allowed - لا يمكن حذف فقرات متعددة - - LimeReport::PageFooter Page Footer ذيل الصفحة + + Print on first page + + + + Print on last page + + LimeReport::PageHeader @@ -1225,6 +1184,22 @@ p, li { white-space: pre-wrap; } Paste لصق + + Page is TOC + + + + Reset page number + + + + Full page + + + + Set page size to printer + + LimeReport::PreviewReportWidget @@ -1315,14 +1290,6 @@ p, li { white-space: pre-wrap; } of %1 من %1 - - Report file name - أسم التقرير - - - PDF file name - أسم ملف PDF - Preview معاينة @@ -1393,10 +1360,6 @@ p, li { white-space: pre-wrap; } topMargin الهامش العلوي - - الهامش السفلي - Отступ нижний - objectName أسم الكائن @@ -1769,6 +1732,74 @@ p, li { white-space: pre-wrap; } keepGroupTogether + + endlessHeight + + + + extendedHeight + + + + isExtendedInDesignMode + + + + pageIsTOC + + + + setPageSizeToPrinter + + + + fillInSecondPass + + + + chartTitle + + + + chartType + + + + drawLegendBorder + + + + labelsField + + + + legendAlign + + + + series + + + + titleAlign + + + + watermark + + + + keepTopSpace + + + + printable + + + + variable + + LimeReport::RectMMPropItem @@ -1810,6 +1841,10 @@ p, li { white-space: pre-wrap; } Wrong file format + + Translations + + LimeReport::ReportDesignWindow @@ -1881,26 +1916,6 @@ p, li { white-space: pre-wrap; } Render Report إنشاء التقرير - - نمط تعديل النسق - Режим редактирования группировок - - - نسق أفقي - Горизонтальная группировка - - - حول البرنامج - О программе - - - Hide left panel - إخفاء المقطع الأيسر - - - Hide right panel - إخفاء المقطع الأيمن - Report Tools أدوات التقرير @@ -2001,10 +2016,6 @@ p, li { white-space: pre-wrap; } Data Browser إستعراض البيانات - - Report has been modified ! Do you want save the report ? - تم تعديل التقرير ! هل تريد حفظ التعديلات ? - Report file name أسم التقرير @@ -2065,6 +2076,38 @@ p, li { white-space: pre-wrap; } Script Browser + + Delete dialog + + + + Add new dialog + + + + Widget Box + + + + Property Editor + + + + Action Editor + + + + Resource Editor + + + + SignalSlot Editor + + + + Dialog Designer Tools + + Report has been modified! Do you want save the report? @@ -2098,6 +2141,14 @@ p, li { white-space: pre-wrap; } This preview is no longer valid. + + Language %1 already exists + + + + Designer not found! + + LimeReport::ReportFooter @@ -2190,18 +2241,6 @@ This preview is no longer valid. Error خطأ - - Datasource Name is empty ! - أسم مصدر البيانات فارغ ! - - - SQL is empty ! - SQL فارغة ! - - - Datasource with name: "%1" already exists ! - مصدر البيانات بأسم: "%1" موجود مسبقاً ! - Datasource with name %1 already exist مصدر البيانات بأسم: "%1" موجود مسبقاً @@ -2294,18 +2333,37 @@ This preview is no longer valid. + + LimeReport::ScriptEditor + + Form + نموذج + + + Data + + + + Functions + الدوال + + LimeReport::ScriptEngineContext Dialog with name: %1 can`t be created + + Error + + LimeReport::ScriptEngineManager FieldName - Имя поля + Имя поля BandName @@ -2343,6 +2401,10 @@ This preview is no longer valid. GROUP FUNCTIONS + + Field %1 not found in %2! + + SYSTEM @@ -2360,7 +2422,39 @@ This preview is no longer valid. - Seconds + Datasource + مصدر البيانات + + + ValueField + + + + KeyField + + + + KeyFieldValue + + + + Unique identifier + + + + Content + المحتوى + + + Indent + + + + datasourceName + + + + Function manager with name "%1" already exists! @@ -2398,6 +2492,14 @@ This preview is no longer valid. Suppress absent fields and variables warning + + Use dark theme + + + + Language + + LimeReport::SubDetailBand @@ -2477,10 +2579,18 @@ This preview is no longer valid. TextItem " %1 " already has folower " %2 " + + Transparent + + TextItem " %1 " not found! + + Watermark + + LimeReport::TextItemEditor @@ -2492,10 +2602,6 @@ This preview is no longer valid. Content المحتوى - - Functions - الدوال - Editor settings إعدادات المحرر @@ -2508,10 +2614,6 @@ This preview is no longer valid. Cancel إلغاء الأمر - - Data - - ... @@ -2529,20 +2631,59 @@ This preview is no longer valid. + + LimeReport::TranslationEditor + + Form + نموذج + + + Languages + + + + ... + + + + Pages + + + + Strings + + + + Source Text + + + + Translation + + + + Checked + + + + Report Item + + + + Property + + + + Source text + + + LimeReport::VariablesHolder variable with name متغير بأسم - - already exists !! - موجود مسبقاً !! - - - does not exists !! - غير موجود !! - already exists! @@ -2552,93 +2693,6 @@ This preview is no longer valid. - - PreviewReportWindow - - Preview - معاينة - - - View - عرض - - - Report - تقرير - - - toolBar - شريط الأدوات - - - Print - طباعة - - - Zoom In - تكبير - - - Zoom Out - تصغير - - - Prior Page - الصفحة السابقة - - - Next Page - الصفحة التالية - - - Close Preview - أغلاق - - - Edit Mode - وضع التعديل - - - Save to file - حفظ إلى ملف - - - Show errors - عرض الأخطاء - - - First Page - الصفحة الأولى - - - First page - الصفحة الأولى - - - Last Page - الصفحة الأخيرة - - - Print To PDF - تحويل إلى PDF - - - Page: - صفحة: - - - of %1 - من %1 - - - Report file name - أسم التقرير - - - PDF file name - أسم ملف PDF - - QObject @@ -2745,10 +2799,6 @@ This preview is no longer valid. Selected elements have different parent containers العناصر المحددة مختلفة البنية - - Object with name %1 already exists - أسم الكائن %1 уже موجود مسبقاً - Function %1 not found or have wrong arguments الدالة %1 غير موجودة او الباريميترات خاطئة @@ -2781,22 +2831,6 @@ This preview is no longer valid. File %1 not opened الحقل %1 غير مفتوح - - TopLine - خط علوي - - - BottomLine - خط سفلي - - - LeftLine - خط أيسر - - - RightLine - خط أيمن - content المحتوى @@ -2857,153 +2891,29 @@ This preview is no longer valid. Wrong file format + + Chart Item + + + + First + + + + Second + + + + Thrid + + Object with name %1 already exists! - - - SQLEditDialog - Datasource - مصدر البيانات - - - Connection - الإتصال - - - Datasource Name - أسم مصدر البيانات - - - Subdetail - البيانات الفرعية - - - Master datasource - مصدر البيانات الرئيسي - - - Subquery mode - وضع الاستعلام الفرعي - - - Filter mode - وضع التصفية - - - Preview - معاينة - - - Hide Preview - إخفاء المعاينة - - - Child datasource - مصدر البيانات الفرعي - - - Data preview - معاينة البيانات - - - Cancel - إلغاء الأمر - - - Error - خطأ - - - Datasource Name is empty ! - أسم مصدر البيانات فارغ ! - - - SQL is empty ! - SQL فارغة ! - - - Datasource with name: "%1" already exists ! - مصدر البيانات بأسم: "%1" موجود مسبقاً ! - - - Datasource with name %1 already exist - مصدر البيانات بأسم: "%1" موجود مسبقاً - - - Connection is not specified - إتصال غير محدد - - - Refresh - تحديث - - - - SettingDialog - - Designer setting - إعدادات - - - Default font - الخط الإفتراضي - - - Grid - شبكة - - - Vertical grid step - تباعد الشبكة العمودي - - - Horizontal grid step - تباعد الشبكة الأفقي - - - - TextItemEditor - - Text Item Editor - محرر النص - - - Content - المحتوى - - - Data - جدول البيانات - - - Functions - الدوال - - - Editor settings - إعدادات المحرر - - - Editor font - محرر الخطوط - - - Cancel - إلغاء الأمر - - - - WaitForm - - Wait - انتظر - - - Please wait ... - يرجى الإنتظار ... + Datasource manager not found + diff --git a/translations/limereport_es.ts b/translations/limereport_es.ts new file mode 100644 index 0000000..5123997 --- /dev/null +++ b/translations/limereport_es.ts @@ -0,0 +1,3231 @@ + + + + + $ClassName$ + + $ClassName$ + + + + + ChartItemEditor + + Series + + + + Add + Agregar + + + Delete + Eliminar + + + Name + Nombre + + + Values field + Valores del campo + + + Color + + + + Type + Tipo + + + Labels field + Etiquetas del campo + + + Ok + Aceptar + + + Series editor + Editor de Series + + + Series name + Nombre de la Serie + + + + LRVariableDialog + + Variable + Variable + + + Name + Nombre + + + Value + Valor + + + Type + Tipo + + + Attention + Atención + + + Mandatory + Obligatorio + + + + LanguageSelectDialog + + Dialog + Dialogo + + + Language + Idioma + + + + LimeReport::AboutDialog + + About + Acerca de + + + Author + Autor + + + License + Licencia + + + Close + Cerrar + + + Lime Report + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Arin Alexander</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">arin_a@bk.ru</p></body></html> + + + + Version 1.1.1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/report/images/logo_100.png" height="100" style="float: left;" /><span style=" font-size:12pt; font-weight:600;">Report engine for </span><span style=" font-size:12pt; font-weight:600; color:#7faa18;">Qt</span><span style=" font-size:12pt; font-weight:600;"> framework</span></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">LimeReport - multi-platform C++ library written using Qt framework and intended for software developers that would like to add into their application capability to form report or print forms generated using templates.</span></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Official web site : </span><a href="www.limereport.ru"><span style=" font-size:11pt; text-decoration: underline; color:#0000ff;">www.limereport.ru</span></a></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; text-decoration: underline; color:#0000ff;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> +<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600; color:#000000;"><br /></p> +<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright 2015 Arin Alexander. All rights reserved.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/report/images/logo_100.png" height="100" style="float: left;" /><span style=" font-size:12pt; font-weight:600;">Motor de informes para el entorno de trabajo de </span> <span style = "font-size: 12pt; font-weight: 600; color: # 7faa18;"> Qt </span> <span style = "font-size: 12pt; font-weight : 600; "></span> </p> +<p align = "justify" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;" > <span style = "font-size: 11pt;"> LimeReport es una biblioteca de C ++ multiplataforma escrita para el entorno de trabajo de Qt y diseñada para desarrolladores de software que deseen agregar en su aplicación la capacidad para crear informes o imprimir formularios generados mediante plantillas. < / span> </p> +<p align = "justify" style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px; font-size: 11pt; "> <br /> </p> +<p align = "justify" style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px; font-size: 11pt; "> <br /> </p> +<p align = "justify" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;" > <span style = "font-size: 11pt;"> Sitio web oficial: </span> <a href="www.limereport.ru"> <span style = "font-size: 11pt; text-decoration: underline ; color: # 0000ff; "> www.limereport.ru </span> </a> </p> +<p align = "justify" style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; texto-sangría: 0px; fuente-tamaño: 11 puntos; texto-decoración: subrayado; color: # 0000ff; "> <br /> </p> +<p align = "justify" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;" > <span style = "font-size: 10pt; font-weight: 600;"> Esta biblioteca se distribuye con la esperanza de que sea útil, pero SIN NINGUNA GARANTÍA; sin ni siquiera la garantía implícita de COMERCIABILIDAD o APTITUD PARA UN PROPÓSITO PARTICULAR. </span> </p> +<p align = "justify" style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px; font-size: 10pt; font-weight: 600; color: # 000000; "> <br /> </p> +<p align = "justify" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;" > <span style = "font-size: 10pt;">Derechos reservados 2015 Arin Alexander. Todos los derechos reservados. + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">(c) 2015 Arin Alexander arin_a@bk.ru</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC1"></a><span style=" font-family:'sans-serif'; font-weight:600;">G</span><span style=" font-family:'sans-serif'; font-weight:600;">NU LESSER GENERAL PUBLIC LICENSE</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Version 2.1, February 1999</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Copyright (C) 1991, 1999 Free Software Foundation, Inc.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Everyone is permitted to copy and distribute verbatim copies</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">of this license document, but changing it is not allowed.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">[This is the first released version of the Lesser GPL. It also counts</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';"> as the successor of the GNU Library Public License, version 2, hence</span></p> +<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';"> the version number 2.1.]</span></p> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC2"></a><span style=" font-family:'sans-serif'; font-weight:600;">P</span><span style=" font-family:'sans-serif'; font-weight:600;">reamble</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">We call this license the &quot;Lesser&quot; General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The former contains code derived from the library, whereas the latter must be combined with the library in order to run.</span></p> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC3"></a><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">T</span><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">ERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">0.</span><span style=" font-family:'sans-serif';"> This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called &quot;this License&quot;). Each licensee is addressed as &quot;you&quot;.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">A &quot;library&quot; means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">The &quot;Library&quot;, below, refers to any such software library or work which has been distributed under these terms. A &quot;work based on the Library&quot; means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term &quot;modification&quot;.)</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">&quot;Source code&quot; for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">1.</span><span style=" font-family:'sans-serif';"> You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">2.</span><span style=" font-family:'sans-serif';"> You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:</span></p> +<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'sans-serif';" style=" margin-top:19px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">a)</span><span style=" font-size:16px;"> The modified work must itself be a software library.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">b)</span><span style=" font-size:16px;"> You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">c)</span><span style=" font-size:16px;"> You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:19px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">d)</span><span style=" font-size:16px;"> If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.</span></li></ul> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:38px; margin-right:19px; -qt-block-indent:1; text-indent:0px;"><span style=" font-family:'sans-serif';">(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">3.</span><span style=" font-family:'sans-serif';"> You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">This option is useful when you wish to copy part of the code of the Library into a program that is not a library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">4.</span><span style=" font-family:'sans-serif';"> You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">5.</span><span style=" font-family:'sans-serif';"> A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a &quot;work that uses the Library&quot;. Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">However, linking a &quot;work that uses the Library&quot; with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a &quot;work that uses the library&quot;. The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">When a &quot;work that uses the Library&quot; uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">6.</span><span style=" font-family:'sans-serif';"> As an exception to the Sections above, you may also combine or link a &quot;work that uses the Library&quot; with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:</span></p> +<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'sans-serif';" style=" margin-top:19px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">a)</span><span style=" font-size:16px;"> Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable &quot;work that uses the Library&quot;, as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">b)</span><span style=" font-size:16px;"> Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">c)</span><span style=" font-size:16px;"> Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">d)</span><span style=" font-size:16px;"> If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:19px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">e)</span><span style=" font-size:16px;"> Verify that the user has already received a copy of these materials or that you have already sent this user a copy.</span></li></ul> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">For an executable, the required form of the &quot;work that uses the Library&quot; must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">7.</span><span style=" font-family:'sans-serif';"> You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:</span></p> +<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'sans-serif';" style=" margin-top:19px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">a)</span><span style=" font-size:16px;"> Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:19px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">b)</span><span style=" font-size:16px;"> Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.</span></li></ul> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">8.</span><span style=" font-family:'sans-serif';"> You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">9.</span><span style=" font-family:'sans-serif';"> You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">10.</span><span style=" font-family:'sans-serif';"> Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">11.</span><span style=" font-family:'sans-serif';"> If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">12.</span><span style=" font-family:'sans-serif';"> If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">13.</span><span style=" font-family:'sans-serif';"> The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and &quot;any later version&quot;, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">14.</span><span style=" font-family:'sans-serif';"> If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">NO WARRANTY</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">15.</span><span style=" font-family:'sans-serif';"> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">16.</span><span style=" font-family:'sans-serif';"> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">END OF TERMS AND CONDITIONS</span></p> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC4"></a><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">H</span><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">ow to Apply These Terms to Your New Libraries</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the &quot;copyright&quot; line and a pointer to where the full notice is found.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace'; font-style:italic;">one line to give the library's name and an idea of what it does.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Copyright (C) </span><span style=" font-family:'monospace'; font-style:italic;">year</span><span style=" font-family:'monospace';"> </span><span style=" font-family:'monospace'; font-style:italic;">name of author</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace'; font-style:italic;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">This library is free software; you can redistribute it and/or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">modify it under the terms of the GNU Lesser General Public</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">License as published by the Free Software Foundation; either</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">version 2.1 of the License, or (at your option) any later version.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">This library is distributed in the hope that it will be useful,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">but WITHOUT ANY WARRANTY; without even the implied warranty of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Lesser General Public License for more details.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">You should have received a copy of the GNU Lesser General Public</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">License along with this library; if not, write to the Free Software</span></p> +<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Also add information on how to contact you by electronic and paper mail.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">You should also get your employer (if you work as a programmer) or your school, if any, to sign a &quot;copyright disclaimer&quot; for the library, if necessary. Here is a sample; alter the names:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Yoyodyne, Inc., hereby disclaims all copyright interest in</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">the library `Frob' (a library for tweaking knobs) written</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">by James Random Hacker.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace'; font-style:italic;">signature of Ty Coon</span><span style=" font-family:'monospace';">, 1 April 1990</span></p> +<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Ty Coon, President of Vice</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">That's all there is to it!</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">(c) 2015 Arin Alexander arin_a@bk.ru</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC1"></a><span style=" font-family:'sans-serif'; font-weight:600;">G</span><span style=" font-family:'sans-serif'; font-weight:600;">LICENCIA PUBLICA GENERAL DE MENORES DE NU</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Versión 2.1, febrero de 1999</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Copyright (C) 1991, 1999 Free Software Foundation, Inc.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Todos están autorizados a copiar y distribuir copias textuales.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">de este documento de licencia, pero no está permitido cambiarlo.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">[Esta es la primera versión lanzada de Lesser GPL. Tambien cuenta</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';"> como el sucesor de la Licencia Pública de la Biblioteca GNU, versión 2, de ahí</span></p> +<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';"> el número de versión 2.1.]</span></p> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC2"></a><span style=" font-family:'sans-serif'; font-weight:600;">P</span><span style=" font-family:'sans-serif'; font-weight:600;">reamble</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Las licencias para la mayoría de los programas están diseñadas para quitarle la libertad de compartir y cambiar. Por el contrario, las licencias públicas generales de GNU están destinadas a garantizar su libertad de compartir y cambiar el software libre, para garantizar que el software sea gratuito para todos sus usuarios. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Esta licencia, la Licencia de Público General Menor, se aplica a algunos paquetes de software especialmente designados, generalmente bibliotecas, de la Free Software Foundation y otros autores que deciden usarla. También puede usarlo, pero le sugerimos que primero piense detenidamente si esta licencia o la Licencia pública general es la mejor estrategia para usar en un caso particular, según las explicaciones a continuación. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Cuando hablamos de software libre, nos referimos a la libertad de uso, no al precio. Nuestras licencias públicas generales están diseñadas para garantizar que usted tenga la libertad de distribuir copias de software gratuito (y puede cobrar por este servicio si lo desea); que recibe el código fuente o puede obtenerlo si lo desea; que puede cambiar el software y usar partes de él en nuevos programas gratuitos; y que está informado de que puede hacer estas cosas. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Para proteger sus derechos, necesitamos hacer restricciones que prohíban a los distribuidores negarle estos derechos o pedirle que renuncie a estos derechos. Estas restricciones se traducen en ciertas responsabilidades para usted si distribuye copias de la biblioteca o si la modifica.</span></p> + +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Por ejemplo, si distribuye copias de la biblioteca, ya sea de forma gratuita o por una tarifa, debe otorgar a los destinatarios todos los derechos que le otorgamos. Debe asegurarse de que ellos también reciban o puedan obtener el código fuente. Si vincula otro código con la biblioteca, debe proporcionar archivos de objetos completos a los destinatarios, para que puedan volver a vincularlos con la biblioteca después de realizar cambios en la biblioteca y volver a compilarla. Y debe mostrarles estos términos para que conozcan sus derechos. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Protegemos sus derechos con un método de dos pasos: (1) protegemos los derechos de autor de la biblioteca y (2) le ofrecemos esta licencia, que le da permiso legal para copiar, distribuir y / o modificar la biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Para proteger a cada distribuidor, queremos dejar muy claro que no hay garantía para la biblioteca gratuita. Además, si la biblioteca es modificada por alguien más y se transmite, los destinatarios deben saber que lo que tienen no es la versión original, por lo que la reputación del autor original no se verá afectada por problemas que puedan ser introducidos por otros. </ Span > </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Finalmente, las patentes de software representan una amenaza constante para la existencia de cualquier programa gratuito. Deseamos asegurarnos de que una empresa no pueda restringir efectivamente a los usuarios de un programa gratuito al obtener una licencia restrictiva de un titular de una patente. Por lo tanto, insistimos en que cualquier licencia de patente obtenida para una versión de la biblioteca debe ser consistente con la plena libertad de uso especificada en esta licencia. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> La mayoría del software GNU, incluidas algunas bibliotecas, está cubierto por la Licencia Pública General de GNU. Esta licencia, la licencia pública general menor de GNU, se aplica a ciertas bibliotecas designadas y es bastante diferente de la licencia pública general ordinaria. Utilizamos esta licencia para ciertas bibliotecas con el fin de permitir la vinculación de esas bibliotecas con programas no libres.</span></p> + +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Cuando un programa está vinculado con una biblioteca, ya sea estáticamente o utilizando una biblioteca compartida, la combinación de los dos es legalmente una obra combinada, un derivado de la biblioteca original. Por lo tanto, la Licencia Pública General ordinaria permite dicha vinculación solo si la combinación completa cumple con sus criterios de libertad. La licencia pública general de Lesser permite criterios más laxos para vincular otro código con la biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Llamamos a esta licencia el & quot; Lesser & quot; Licencia pública general porque hace menos para proteger la libertad del usuario que la licencia pública general ordinaria. También proporciona a otros desarrolladores de software libre una ventaja menor sobre los programas no gratuitos de la competencia. Estas desventajas son la razón por la que usamos la Licencia Pública General ordinaria para muchas bibliotecas. Sin embargo, la licencia Lesser ofrece ventajas en ciertas circunstancias especiales. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Por ejemplo, en raras ocasiones, puede haber una necesidad especial de fomentar el uso más amplio posible de una determinada biblioteca, para que se convierta en un estándar de facto. Para lograr esto, se debe permitir que los programas no libres utilicen la biblioteca. Un caso más frecuente es que una biblioteca gratuita hace el mismo trabajo que las bibliotecas no libres ampliamente utilizadas. En este caso, hay poco que ganar al limitar la biblioteca gratuita únicamente al software libre, por lo que usamos la Licencia pública general menor. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> En otros casos, el permiso para usar una biblioteca particular en programas no libres permite que una mayor cantidad de personas utilicen una gran cantidad de software libre. Por ejemplo, el permiso para usar la Biblioteca GNU C en programas no libres permite que muchas más personas utilicen todo el sistema operativo GNU, así como su variante, el sistema operativo GNU / Linux.</span></p> + +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Aunque la Licencia pública general menor protege menos la libertad de los usuarios, garantiza que el usuario de un programa vinculado a la Biblioteca tenga la libertad y los medios para ejecutar dicho programa utilizando una versión modificada de la Biblioteca. </ span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Los términos y condiciones precisos para la copia, distribución y modificación se encuentran a continuación. Preste mucha atención a la diferencia entre un trabajo basado en la biblioteca & quot; y un & quot; trabajo que utiliza la biblioteca & quot ;. El primero contiene código derivado de la biblioteca, mientras que el último debe combinarse con la biblioteca para poder ejecutarse. </span> </p> +<p style = "margin-top: 15px; margin-bottom: 15px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <a name = "SEC3"> </a> <span style = "font-family: 'sans-serif'; font-weight: 600; color: # 333333;"> T </span> <span style = "font-family: 'sans-serif'; font-weight: 600; color: # 333333; "> ERMS Y CONDICIONES PARA LA COPIA, DISTRIBUCIÓN Y MODIFICACIÓN </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 0. </span> <span style = "font-family: 'sans-serif';"> Este Acuerdo de licencia se aplica a cualquier biblioteca de software u otro programa que contenga un aviso colocado por el titular de los derechos de autor u otra parte autorizada que indique que se puede distribuir de acuerdo con los términos de esta Licencia pública general menor (también denominada "esta Licencia"). Cada licenciatario se direcciona como & quot; usted & quot ;. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> A & quot; library & quot; significa una colección de funciones de software y / o datos preparados para estar convenientemente vinculados con programas de aplicación (que utilizan algunas de esas funciones y datos) para formar ejecutables. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> La & quot; Biblioteca & quot ;, a continuación, se refiere a cualquier biblioteca de software o trabajo que se haya distribuido bajo estos términos. Un "trabajo basado en la Biblioteca" significa la Biblioteca o cualquier trabajo derivado bajo la ley de derechos de autor: es decir, un trabajo que contiene la Biblioteca o una parte de ella, ya sea textualmente o con modificaciones y / o traducido directamente a otro idioma. (De aquí en adelante, la traducción se incluye sin limitación en el término "modificación").</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">& quot; Código fuente & quot; para un trabajo significa la forma preferida del trabajo para hacer modificaciones al mismo. Para una biblioteca, el código fuente completo significa todo el código fuente de todos los módulos que contiene, más cualquier archivo de definición de interfaz asociado, además de los scripts utilizados para controlar la compilación e instalación de la biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Las actividades que no sean la copia, distribución y modificación no están cubiertas por esta Licencia; Están fuera de su alcance. El acto de ejecutar un programa utilizando la Biblioteca no está restringido, y la salida de dicho programa está cubierta solo si su contenido constituye un trabajo basado en la Biblioteca (independientemente del uso de la Biblioteca en una herramienta para escribirlo). Si eso es cierto, depende de lo que haga la Biblioteca y del programa que la utiliza. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 1. </span> <span style = "font-family: 'sans-serif';"> Puede copiar y distribuir copias literales de el código fuente completo de la Biblioteca a medida que lo reciba, en cualquier medio, siempre que publique de forma visible y adecuada en cada copia un aviso de copyright y una renuncia de garantía adecuados; mantenga intactos todos los avisos que se refieren a esta Licencia ya la ausencia de cualquier garantía; y distribuya una copia de esta Licencia junto con la Biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Usted puede cobrar una tarifa por el acto físico de transferir una copia, y puede, a opción suya, ofrecer una garantía de protección a cambio de una tarifa.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">2.</span><span style=" font-family:'sans-serif';">Puede modificar su copia o copias de la Biblioteca o cualquier parte de ella, formando así un trabajo basado en la Biblioteca, y copiar y distribuir dichas modificaciones o trabajos según los términos de la Sección 1 anterior, siempre que cumpla con todas estas condiciones : </span> </p> +<ul style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"> <li style = "font-family: ' sans-serif '; " style = "margin-top: 19px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> a) </span> <span style =" font-size: 16px; "> El trabajo modificado debe ser una biblioteca de software. </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> b) </span> <span style =" font-size: 16px; "> Debe hacer que los archivos modificados contengan avisos importantes que indiquen que cambió los archivos y fecha de cualquier cambio. </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> c) </span> <span style =" font-size: 16px; "> Debe hacer que la totalidad del trabajo tenga licencia sin cargo para todos los terceros bajo los términos de esta Licencia. </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 19px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> d) </span> <span style =" font-size: 16px; "> Si una instalación en la Biblioteca modificada se refiere a una función o una tabla de datos, suministrado por un programa de aplicación que utiliza la instalación, aparte de como un argumento pasado cuando se invoca la instalación, debe hacer un esfuerzo de buena fe para asegurarse de que, en el caso de que una aplicación no suministre dicha función o tabla, la instalación aún opera, y realiza cualquier parte de su propósito sigue siendo significativa. </span> </li> </ul> +<p style = "margin-top: 15px; margin-bottom: 15px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 1; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> (Por ejemplo, una función en una biblioteca para calcular raíces cuadradas tiene un propósito que está completamente bien definido independientemente de la aplicación. Por lo tanto, la Subsección 2d requiere que cualquier aplicación sea suministrada la función o tabla utilizada por esta función debe ser opcional: si la aplicación no la proporciona, la función de raíz cuadrada aún debe calcular las raíces cuadradas.)</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Estos requisitos se aplican a la obra modificada en su conjunto. Si las secciones identificables de ese trabajo no se derivan de la Biblioteca, y pueden considerarse razonablemente trabajos independientes e independientes en sí mismas, entonces esta Licencia y sus términos no se aplican a esas secciones cuando los distribuye como trabajos separados. Pero cuando distribuye las mismas secciones como parte de un todo, que es un trabajo basado en la Biblioteca, la distribución del todo debe estar en los términos de esta Licencia, cuyos permisos para otros licenciatarios se extienden a todo el conjunto y, por lo tanto, a cada uno. y cada parte, independientemente de quién lo escribió. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Por lo tanto, no es la intención de esta sección reclamar derechos o impugnar sus derechos a trabajar escritos completamente por usted; más bien, la intención es ejercer el derecho de controlar la distribución de trabajos derivados o colectivos basados ​​en la Biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Además, la mera agregación de otro trabajo no basado en la Biblioteca con la Biblioteca (o con un trabajo basado en la Biblioteca) en un volumen de un medio de almacenamiento o distribución no lo hace ponga el otro trabajo bajo el alcance de esta Licencia. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 3. </span> <span style = "font-family: 'sans-serif';"> Puede optar por aplicar los términos de la Licencia Pública General GNU ordinaria en lugar de esta Licencia a una copia dada de la Biblioteca. Para hacer esto, debe modificar todos los avisos que se refieren a esta Licencia, de modo que se refieran a la Licencia Pública General de GNU ordinaria, versión 2, en lugar de a esta Licencia. (Si ha aparecido una versión más nueva que la versión 2 de la Licencia Pública General de GNU ordinaria, puede especificar esa versión si lo desea). No haga ningún otro cambio en estos avisos. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Una vez que se realiza este cambio en una copia dada, es irreversible para esa copia, por lo que la Licencia Pública General GNU ordinaria se aplica a todas las copias subsiguientes y trabajos derivados realizados a partir de esa copia.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Esta opción es útil cuando desea copiar parte del código de la Biblioteca en un programa que no es una biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 4. </span> <span style = "font-family: 'sans-serif';"> Puede copiar y distribuir la Biblioteca ( o una parte o derivado de él, en la Sección 2) en código objeto o en forma ejecutable bajo los términos de las Secciones 1 y 2 anteriores, siempre que lo acompañe con el código fuente completo legible por máquina correspondiente, que debe ser distribuido bajo los términos de Las secciones 1 y 2 anteriores en un medio utilizado habitualmente para el intercambio de software. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Si la distribución del código del objeto se realiza ofreciendo acceso a la copia desde un lugar designado, el acceso equivalente para copiar el código fuente desde el mismo lugar satisface el requisito de distribuir la fuente código, aunque los terceros no están obligados a copiar la fuente junto con el código objeto. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 5. </span> <span style = "font-family: 'sans-serif';"> Un programa que no contiene ningún derivado La parte de la Biblioteca, pero está diseñada para trabajar con la Biblioteca al compilarse o vincularse con ella, se denomina trabajo que utiliza la Biblioteca & quot ;. Tal trabajo, de forma aislada, no es un trabajo derivado de la Biblioteca y, por lo tanto, queda fuera del alcance de esta Licencia. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Sin embargo, al vincular un trabajo & quot; que utiliza la Biblioteca & quot; con la Biblioteca crea un ejecutable que es un derivado de la Biblioteca (porque contiene partes de la Biblioteca), en lugar de un trabajo que usa la biblioteca & quot ;. El ejecutable está cubierto por esta Licencia. La Sección 6 establece los términos para la distribución de tales ejecutables.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Cuando un & quot; trabajo que utiliza la Biblioteca & quot; utiliza material de un archivo de encabezado que forma parte de la Biblioteca, el código objeto para el trabajo puede ser un trabajo derivado de la Biblioteca, aunque el código fuente no lo sea. Si esto es cierto es especialmente significativo si el trabajo se puede vincular sin la Biblioteca, o si el trabajo es en sí mismo una biblioteca. El umbral para que esto sea cierto no está definido con precisión por la ley. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Si tal archivo de objeto usa solo parámetros numéricos, estructuras de datos y elementos de acceso, y macros pequeñas y funciones en línea pequeñas (diez líneas o menos de longitud), entonces el uso de el archivo de objeto no está restringido, independientemente de si es legalmente un trabajo derivado. (Los archivos ejecutables que contienen este código de objeto más partes de la Biblioteca aún se incluirán en la Sección 6). </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> De lo contrario, si el trabajo es un derivado de la Biblioteca, puede distribuir el código objeto para el trabajo según los términos de la Sección 6. Cualquier archivo ejecutable que contenga ese trabajo también está incluido en la Sección 6, estén o no vinculados directamente con la propia Biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 6. </span> <span style = "font-family: 'sans-serif';"> Como excepción a las Secciones anteriores, también puede combinar o vincular un trabajo & quot; que utiliza la Biblioteca & quot; con la Biblioteca para producir un trabajo que contenga partes de la Biblioteca, y distribuir ese trabajo según los términos que usted elija, siempre que los términos permitan la modificación del trabajo para el uso propio del cliente y la ingeniería inversa para depurar dichas modificaciones.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Debe dar un aviso destacado con cada copia del trabajo que se utiliza en la Biblioteca y que la Biblioteca y su uso están cubiertos por esta Licencia. Debe proporcionar una copia de esta Licencia. Si el trabajo durante la ejecución muestra avisos de derechos de autor, debe incluir entre ellos el aviso de copyright de la Biblioteca, así como una referencia que indique al usuario la copia de esta Licencia. Además, debes hacer una de estas cosas: </span> </p> +<ul style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"> <li style = "font-family: ' sans-serif '; " style = "margin-top: 19px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> a) </span> <span style =" font-size: 16px; "> Acompañe el trabajo con el código fuente completo legible por máquina correspondiente para la Biblioteca, incluidos los cambios se utilizaron en el trabajo (que debe distribuirse en las Secciones 1 y 2 anteriores); y, si el trabajo es un ejecutable vinculado con la Biblioteca, con el trabajo completo "legible por máquina" que utiliza la Biblioteca como código de objeto y / o código fuente, para que el usuario pueda modificar la Biblioteca y luego volver a vincular para producir un ejecutable modificado que contiene la biblioteca modificada. (Se entiende que el usuario que cambia el contenido de los archivos de definiciones en la Biblioteca no necesariamente podrá recompilar la aplicación para usar las definiciones modificadas). </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> b) </span> <span style =" font-size: 16px; "> Use un mecanismo de biblioteca compartida adecuado para enlazar con la Biblioteca. Un mecanismo adecuado es uno que (1) utiliza en tiempo de ejecución una copia de la biblioteca ya presente en el sistema informático del usuario, en lugar de copiar las funciones de la biblioteca en el ejecutable, y (2) funcionará correctamente con una versión modificada de la biblioteca, si el usuario instala uno, siempre que la versión modificada sea compatible con la interfaz con la versión con la que se realizó el trabajo. </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> c) </span> <span style =" font-size: 16px; "> Acompañe el trabajo con una oferta por escrito, válida por al menos tres años, para dar el mismo usuario los materiales especificados en la subsección 6a, arriba, por un cargo que no supera el costo de realizar esta distribución.</span></li> +<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">d)</span><span style=" font-size:16px;"> Si la distribución del trabajo se realiza ofreciendo acceso a la copia desde un lugar designado, ofrezca un acceso equivalente para copiar los materiales especificados anteriormente desde el mismo lugar. </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 19px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> e) </span> <span style =" font-size: 16px; "> Verifique que el usuario ya haya recibido una copia de estos materiales o que ya haya enviado este usuario es una copia. </span> </li> </ul> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Para un ejecutable, la forma requerida del trabajo & quot; que utiliza la Biblioteca & quot; debe incluir todos los datos y programas de utilidad necesarios para reproducir el ejecutable desde él. Sin embargo, como excepción especial, los materiales a distribuir no necesitan incluir nada que se distribuya normalmente (en forma de fuente o binario) con los componentes principales (compilador, kernel, etc.) del sistema operativo en el que se ejecuta el ejecutable. , a menos que ese componente acompañe al ejecutable. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Puede suceder que este requisito contradiga las restricciones de licencia de otras bibliotecas propietarias que normalmente no acompañan al sistema operativo. Tal contradicción significa que no puede usarlos a ellos y a la Biblioteca juntos en un ejecutable que distribuya.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">7.</span><span style=" font-family:'sans-serif';"> Puede ubicar las instalaciones de la biblioteca que son un trabajo basado en la biblioteca lado a lado en una sola biblioteca junto con otras instalaciones de la biblioteca que no están cubiertas por esta Licencia, y distribuir dicha biblioteca combinada, siempre que la distribución separada del trabajo basada en la Biblioteca y de las demás instalaciones de la biblioteca están permitidas, y siempre que haga estas dos cosas: </span> </p> +<ul style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"> <li style = "font-family: ' sans-serif '; " style = "margin-top: 19px; margin-bottom: 0px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> a) </span> <span style =" font-size: 16px; "> Acompañe la biblioteca combinada con una copia del mismo trabajo basado en la Biblioteca, sin combinar Cualquier otra biblioteca. Esto debe distribuirse según los términos de las Secciones anteriores. </span> </li> +<li style = "font-family: 'sans-serif';" style = "margin-top: 0px; margin-bottom: 19px; margin-left: 38px; margin-right: 19px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font -size: 16px; font-weight: 600; "> b) </span> <span style =" font-size: 16px; "> Dé un aviso destacado a la biblioteca combinada sobre el hecho de que parte de ella se basa en el trabajo en la Biblioteca, y explicando dónde encontrar la forma no combinada que acompaña al mismo trabajo. </span> </li> </ul> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 8. </span> <span style = "font-family: 'sans-serif';"> No puede copiar, modificar, sublicenciar , haga un enlace o distribuya la Biblioteca, excepto lo dispuesto expresamente en esta Licencia. Cualquier intento de copiar, modificar, sublicenciar, vincular o distribuir la Biblioteca de otra manera será nulo y terminará automáticamente sus derechos bajo esta Licencia. Sin embargo, a las partes que hayan recibido copias o derechos de usted bajo esta Licencia no se les dará por terminadas sus licencias siempre y cuando dichas partes sigan cumpliendo con todos los requisitos.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">9.</span><span style=" font-family:'sans-serif';"> No está obligado a aceptar esta Licencia, ya que no la ha firmado. Sin embargo, nada más le otorga permiso para modificar o distribuir la Biblioteca o sus trabajos derivados. Estas acciones están prohibidas por la ley si no acepta esta Licencia. Por lo tanto, al modificar o distribuir la Biblioteca (o cualquier trabajo basado en la Biblioteca), usted indica que acepta esta Licencia para hacerlo, y todos sus términos y condiciones para copiar, distribuir o modificar la Biblioteca o los trabajos basados ​​en ella. < / span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 10. </span> <span style = "font-family: 'sans-serif';"> Cada vez que redistribuya la Biblioteca (o cualquier trabajo basado en la Biblioteca), el destinatario recibe automáticamente una licencia del licenciador original para copiar, distribuir, vincular o modificar la Biblioteca sujeto a estos términos y condiciones. No puede imponer restricciones adicionales al ejercicio de los derechos de los beneficiarios otorgados en este documento. Usted no es responsable de hacer cumplir el cumplimiento de esta Licencia por parte de terceros. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 11. </span> <span style = "font-family: 'sans-serif';"> If, como consecuencia de un tribunal Sentencia o alegación de infracción de patente o por cualquier otro motivo (no limitado a cuestiones de patentes), se le imponen condiciones (ya sea por orden judicial, acuerdo o de otra manera) que contradigan las condiciones de esta Licencia, no lo eximen de las condiciones. de esta Licencia. Si no puede realizar la distribución para satisfacer simultáneamente sus obligaciones bajo esta Licencia y cualquier otra obligación pertinente, como consecuencia, no podrá distribuir la Biblioteca en absoluto. Por ejemplo, si una licencia de patente no permitiera la redistribución de la Biblioteca de todos los que reciben copias directa o indirectamente a través de usted, la única forma en que podría satisfacerla y esta Licencia sería abstenerse totalmente de la distribución de la Biblioteca. Biblioteca. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Si alguna parte de esta sección se considera inválida o inaplicable en cualquier circunstancia particular, se pretende que el resto de la sección se aplique, y la sección en su totalidad se debe aplicar en otras circunstancias</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">No es el propósito de esta sección inducirlo a infringir ninguna patente u otros reclamos de derechos de propiedad o impugnar la validez de dichos reclamos; Esta sección tiene el único propósito de proteger la integridad del sistema de distribución de software libre que se implementa mediante prácticas de licencia pública. Muchas personas han hecho contribuciones generosas a la amplia gama de software distribuido a través de ese sistema, confiando en la aplicación consistente de ese sistema; Depende del autor / donante decidir si está dispuesto a distribuir software a través de cualquier otro sistema y un licenciatario no puede imponer esa elección. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Esta sección pretende aclarar completamente lo que se cree que es una consecuencia del resto de esta Licencia. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 12. </span> <span style = "font-family: 'sans-serif';"> Si la distribución y / o uso de la Biblioteca está restringida en ciertos países ya sea por patentes o por interfaces con derechos de autor, el titular original de los derechos de autor que coloca a la Biblioteca bajo esta Licencia puede agregar una limitación de distribución geográfica explícita excluyendo esos países, de modo que la distribución se permite solo en o entre países no excluidos. . En tal caso, esta Licencia incorpora la limitación como si estuviera escrita en el cuerpo de esta Licencia. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 13. </span> <span style = "font-family: 'sans-serif';"> La Free Software Foundation puede publicar revisados ​​y / o nuevas versiones de la Licencia Pública General Menor de vez en cuando. Estas nuevas versiones serán similares en espíritu a la versión actual, pero pueden diferir en detalle para abordar nuevos problemas o inquietudes. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> A cada versión se le asigna un número de versión distintivo. Si la Biblioteca especifica un número de versión de esta Licencia que se le aplica y & quot; cualquier versión posterior & quot ;, tiene la opción de seguir los términos y condiciones de esa versión o de cualquier versión posterior publicada por la Free Software Foundation. Si la Biblioteca no especifica un número de versión de licencia, puede elegir cualquier versión publicada por la Free Software Foundation.</span></p> +<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">14.</span><span style=" font-family:'sans-serif';"> Si desea incorporar partes de la Biblioteca a otros programas gratuitos cuyas condiciones de distribución son incompatibles con estos, escriba al autor para pedirle permiso. Para el software cuyo copyright es Free Software Foundation, escriba a Free Software Foundation; A veces hacemos excepciones para esto. Nuestra decisión se guiará por los dos objetivos de preservar el estado gratuito de todos los derivados de nuestro software libre y de promover el uso compartido y la reutilización del software en general. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> SIN GARANTÍA </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 15. </span> <span style = "font-family: 'sans-serif';"> PORQUE LA BIBLIOTECA TIENE LICENCIA GRATUITA , NO EXISTE GARANTÍA PARA LA BIBLIOTECA, HASTA EL GRADO PERMITIDO POR LA LEY APLICABLE. EXCEPTO CUANDO OTRA MANERA ESTABLECIDO EN ESCRIBIR LOS TITULARES DEL DERECHO DE AUTOR Y / O OTRAS PARTES PROPORCIONAN LA BIBLIOTECA "COMO ESTÁ" SIN GARANTÍA DE NINGÚN TIPO, YA SEA EXPRESA O IMPLÍCITA, INCLUYENDO, PERO NO LIMITADO A, LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD Y ADECUACIÓN PARA UN PROPÓSITO PARTICULAR. TODO EL RIESGO EN CUANTO A LA CALIDAD Y EL RENDIMIENTO DE LA BIBLIOTECA ESTÁ CON USTED. DEBE QUE LA BIBLIOTECA PRUEBA DEFECTUOSO, USTED ASUME EL COSTO DE TODO EL SERVICIO, LA REPARACIÓN O LA CORRECCIÓN NECESARIOS. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif'; font-weight: 600;"> 16. </span> <span style = "font-family: 'sans-serif';"> EN NINGÚN CASO, A MENOS QUE ES NECESARIO LA LEY APLICABLE O ESTÁ DE ACUERDO EN ESCRIBIR CUALQUIER RESPONSABLE DE DERECHOS DE AUTOR, O CUALQUIER OTRA PARTE QUE PUEDE MODIFICAR Y / O REDISTRAR LA BIBLIOTECA PERMITIDA ANTERIORMENTE, SERÁ RESPONSABLE DE DAÑOS POR ARCHIVOS, INCLUYENDO DAÑOS GENERALES, ESPECIALES, INCIDENTALES O CONSEQUÍTICOS, DEFECTUIDOS EN EL ARTÍCULO NO SE PUEDE UTILIZAR LA BIBLIOTECA (INCLUYENDO PERO NO LIMITADA A LA PÉRDIDA DE DATOS O LOS DATOS QUE SE RENDIDOS NO PRECISO O PÉRDIDAS SOSTENIDAS POR USTED O TERCERAS PARTES O LA FALTA DE LA BIBLIOTECA PARA OPERAR CON CUALQUIER OTRO SOFTWARE), INCLUSO SI HAY ALGÚN VENDEDOR U OTRA PARTE. AVISO DE LA POSIBILIDAD DE DICHOS DAÑOS.</span></p> +<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">FIN DE LOS TÉRMINOS Y CONDICIONES </span> </p> +<p style = "margin-top: 15px; margin-bottom: 15px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <a name = "SEC4"> </a> <span style = "font-family: 'sans-serif'; font-weight: 600; color: # 333333;"> H </span> <span style = "font-family: 'sans-serif'; font-weight: 600; color: # 333333; "> Cómo aplicar estos términos a sus nuevas bibliotecas </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Si desarrolla una nueva biblioteca y desea que sea de la mayor utilidad posible para el público, le recomendamos que sea un software gratuito que todos puedan redistribuir y cambiar. Puede hacerlo permitiendo la redistribución bajo estos términos (o, alternativamente, bajo los términos de la Licencia Pública General ordinaria). </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> Para aplicar estos términos, adjunte los siguientes avisos a la biblioteca. Es más seguro adjuntarlos al inicio de cada archivo fuente para transmitir de manera más efectiva la exclusión de la garantía; y cada archivo debe tener al menos el & quot; copyright & quot; línea y un puntero donde se encuentra el aviso completo. </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace'; font-style: italic;"> una línea para dar el nombre de la biblioteca y una idea de lo que hace. </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Copyright (C) </span> <span style = "font-family: 'monospace'; font-style: italic;"> year </span> <span style = " font-family: 'monospace'; "> </span> <span style =" font-family: 'monospace'; font-style: italic; "> nombre del autor </span> </p> +<p style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent : 0px; font-family: 'monospace'; font-style: italic; "> <br /> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Esta biblioteca es software libre; puedes redistribuirlo y / o</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">modifíquelo bajo los términos del Público General Menor GNU </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';">> licencia publicada por la Free Software Foundation; ya sea </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> versión 2.1 de la Licencia, o (a su elección) cualquier versión posterior. </span> </p> +<p style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent : 0px; font-family: 'monospace'; "> <br /> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Esta biblioteca se distribuye con la esperanza de que sea útil, </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> MERCHANTABILITY o FITNESS PARA UN PROPÓSITO PARTICULAR. Ver el GNU </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Lesser General Public License para más detalles. </span> </p> +<p style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent : 0px; font-family: 'monospace'; "> <br /> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Debería haber recibido una copia del Público General Menor de GNU</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Licencia junto con esta biblioteca; si no, escriba al Software Libre </span> </p> +<p style = "margin-top: 0px; margin-bottom: 15px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 EE. UU. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> También agregue información sobre cómo contactarlo por correo electrónico y en papel. </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> También debe hacer que su empleador (si trabaja como programador) o su escuela, si corresponde, firme un & quot; renuncia de derechos de autor & quot; para la biblioteca, si es necesario. Aquí hay una muestra; alterar los nombres: </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Yoyodyne, Inc., por la presente renuncia a todo interés de copyright en </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> la biblioteca `Frob '(una biblioteca para ajustes de mandos) escrita </span> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> por James Random Hacker. </span> </p> +<p style = "- qt -agraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent : 0px; font-family: 'monospace'; "> <br /> </p> +<p style = "margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace'; font-style: italic;"> firma de Ty Coon </span> <span style = "font-family: 'monospace';">, 1 de abril de 1990 </span> </ p> +<p style = "margin-top: 0px; margin-bottom: 15px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'monospace';"> Ty Coon, Presidente de Vice </span> </p> +<p style = "margin-top: 19px; margin-bottom: 19px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px;"> <span style = "font-family: 'sans-serif';"> ¡Eso es todo!</span></p></body></html> + + + + LimeReport::AlignmentPropItem + + Left + Izquierda + + + Right + Derecha + + + Center + Centro + + + Justify + Justificado + + + Top + Arriba + + + Botom + Abajo + + + horizontal + horizontal + + + vertical + vertical + + + + LimeReport::BandDesignIntf + + connected to + conectado a + + + Bring to top + Traer al frente + + + Send to back + Enviar al fondo + + + Auto height + Alto automático + + + Splittable + Separable + + + DataBand + Banda de Datos + + + DataHeaderBand + Banda de datos Encabezado + + + DataFooterBand + Banda de datos Pie + + + ReportHeader + Encabezado del reporte + + + ReportFooter + Pie del reporte + + + PageHeader + Encabezado de Página + + + PageFooter + Pie de página + + + SubDetailBand + Banda de Sub detalle + + + SubDetailHeaderBand + Banda de sub detalle Encabezado + + + SubDetailFooterBand + Banda de sub detalle Pie + + + GroupBandHeader + Banda de grupo Encabezado + + + GroupBandFooter + Banda de grupo Pie + + + TearOffBand + Banda de cortado + + + Keep bottom space + Mantener espacio inferior + + + Cut + Cortar + + + Copy + Copiar + + + Print if empty + Imprimir si está vacío + + + + LimeReport::BaseDesignIntf + + Copy + Copiar + + + Cut + Cortar + + + Paste + Pegar + + + Bring to top + Traer al frente + + + Send to back + Enviar atras + + + No borders + Sin bordes + + + All borders + Todos los bordes + + + Create Horizontal Layout + Crear diseño horizontal + + + Create Vertical Layout + Crear diseño vertical + + + + LimeReport::ConnectionDesc + + defaultConnection + Conexión por defecto + + + + LimeReport::ConnectionDialog + + Connection + Conexión + + + Connection Name + Nombre de conexión + + + Server + Servidor + + + User + Usuario + + + Password + Contraseña + + + Database + Base de Datos + + + Auto connect + Auto conectar + + + Check connection + Probar conexión + + + Cancel + Cancelar + + + Connection succsesfully established! + Conexión establecida satisfactoriamente! + + + Connection Name is empty + El Nombre de la conexión esta vacía + + + Driver + + + + ... + + + + Ok + + + + Error + + + + Connection with name + Conexión con nombre + + + Use default application connection + Utilice la conexión de aplicación predeterminada + + + Dont keep credentals in lrxml + No mantener credentals en el lrxml + + + defaultConnection + Conexión por defecto + + + already exists! + ¡ya existe! + + + Port + Puerto + + + + LimeReport::DataBand + + Data + Datos + + + Use alternate background color + Usar color de fondo alternativo + + + Keep footer together + Mantener pie de página junto + + + Keep subdetail together + Mantener subdetalles juntos + + + Slice last row + Cortar la última fila + + + Start from new page + Empezar desde nueva página + + + Start new page + Inciar nueva página + + + + LimeReport::DataBrowser + + Attention + Atención + + + Datasources + Orígenes de Datos + + + Add database connection + Agregar conexion a base de datos + + + ... + + + + Add new datasource + Agregar origen de datos + + + View data + Ver datos + + + Change datasource + Cambiar origen de datos + + + Delete datasource + Eliminar origen de datos + + + Show error + Mostrar error + + + Variables + + + + Add new variable + Agregar variable + + + Edit variable + Editar variable + + + Delete variable + Borrarvariable + + + System variables + Variables del sistema + + + Error + + + + Grab variable + Capturar variable + + + Report variables + Variables de informe + + + External variables + Variables externas + + + Do you really want to delete "%1" connection? + Realmente quieres eliminar la conexión "%1"? + + + Do you really want to delete "%1" datasource? + ¿Realmente quieres eliminar el origen de datos "%1"? + + + Do you really want to delete variable "%1"? + ¿Realmente quieres eliminar la variable "%1"? + + + + LimeReport::DataFooterBand + + DataFooter + Pie de datos + + + Print always + Imprimir siempre + + + + LimeReport::DataHeaderBand + + DataHeader + Encabezado de datos + + + Reprint on each page + Re-imprimir en cada página + + + Repeat on each row + Repetir en cada fila + + + Print always + Imprimir simpre + + + + LimeReport::DataSourceManager + + Connection "%1" is not open + La conexión "%1" no está abierta + + + Variable "%1" not found! + ¡No se encontró la variable "%1"! + + + invalid connection + conexión inválida + + + Database "%1" not found + No se encontró la base de datos "%1" + + + Datasource "%1" not found! + ¡Fuente de datos "%1" no encontrada! + + + Connection with name "%1" already exists! + ¡La conexión con el nombre "%1" ya existe! + + + Datasource with name "%1" already exists! + ¡La fuente de datos con nombre "%1" ya existe! + + + Unknown parameter "%1" for variable "%2" found! + Se encontró un parámetro desconocido "%1" para la variable "%2". + + + + LimeReport::DataSourceModel + + Datasources + Orígenes de Datos + + + Variables + + + + External variables + Variables externas + + + + LimeReport::DialogDesignerManager + + Edit Widgets + Editar objeto + + + Widget Box + Caja de objeto + + + Object Inspector + Inspector de objeto + + + Property Editor + Editor de propiedades + + + Signals && Slots Editor + Editor de Señales y eventos + + + Resource Editor + Editor de recursos + + + Action Editor + Editor de acciones + + + + LimeReport::EnumPropItem + + Default + Por defecto + + + Portrait + Retrato + + + Landscape + Apaisado (Horizontal) + + + NoneAutoWidth + Sin ancho automático + + + MaxWordLength + Max. largo palabra + + + MaxStringLength + Max. Largo cadena + + + TransparentMode + Modo transparente + + + OpaqueMode + Modo opaco + + + Angle0 + Angulo 0 + + + Angle90 + Angulo 90 + + + Angle180 + Angulo 180 + + + Angle270 + Angulo 270 + + + Angle45 + Angulo 45 + + + Angle315 + Angulo 315 + + + DateTime + FechaHora + + + Double + Doble + + + NoBrush + Sin brocha + + + SolidPattern + Patrón sólido + + + Dense1Pattern + Patrón Denso1 + + + Dense2Pattern + Patrón Denso2 + + + Dense3Pattern + Patrón Denso3 + + + Dense4Pattern + Patrón Denso4 + + + Dense5Pattern + Patrón Denso5 + + + Dense6Pattern + Patrón Denso6 + + + Dense7Pattern + Patrón Denso7 + + + HorPattern + Patrón Horizontal + + + VerPattern + Patrón Vertical + + + CrossPattern + Patrón cruzado + + + BDiagPattern + Patrón Diag.B + + + FDiagPattern + Patrón Diag.F + + + LeftToRight + Izquierda A Derecha + + + RightToLeft + Derecha A Izquierda + + + LayoutDirectionAuto + Dirección diseño automática + + + LeftItemAlign + Alinear objeto a la izquierda + + + RightItemAlign + Alinear objeto a la derecha + + + CenterItemAlign + Centrar objeto + + + ParentWidthItemAlign + Alinear objeto con acho de padre + + + DesignedItemAlign + Personalizado + + + HorizontalLine + Linea horizontal + + + VerticalLine + Linea vertical + + + Ellipse + Elipse + + + Rectangle + Rectangulo + + + Page + Página + + + Band + Banda + + + Horizontal + + + + Vertical + + + + VerticalUniform + Vertical uniforme + + + Pie + Pastel + + + VerticalBar + Barra vertical + + + HorizontalBar + Barra horizontal + + + LegendAlignTop + Alinear Leyenda Arriba + + + LegendAlignCenter + Centrar leyenda + + + LegendAlignBottom + Alinear Leyenda Abajo + + + TitleAlignLeft + Alinear titulo a la izquierda + + + TitleAlignRight + Alinear titulo a la derecha + + + TitleAlignCenter + Centrar titulo + + + Layout + Diseño + + + Table + Tabla + + + + LimeReport::FlagsPropItem + + NoLine + Sin borde + + + TopLine + Borde superior + + + BottomLine + Borde inferior + + + LeftLine + Borde izquierdo + + + RightLine + Borde derecho + + + AllLines + Todos los bordes + + + + LimeReport::FontEditorWidget + + Font bold + Negrita + + + Font Italic + Cursiva + + + Font Underline + Subrayada + + + + LimeReport::FontPropItem + + bold + negrita + + + italic + cursiva + + + underline + subrayada + + + size + tamaño + + + family + familia + + + + LimeReport::GroupBandFooter + + GroupFooter + Pie de grupo + + + + LimeReport::GroupBandHeader + + GroupHeader + Encabezado de grupo + + + Group field not found + Campo de grupo no encontrado + + + Datasource "%1" not found! + ¡Fuente de datos "%1" no encontrada! + + + + LimeReport::GroupFunction + + Field "%1" not found + Campo "%1" no encontrado + + + Variable "%1" not found + Variable "%1" no encontrada + + + Item "%1" not found + Objeto "%1" no encontrado + + + Wrong script syntax "%1" + Sintaxis de la secuencia de comandos incorrecta "%1" + + + + LimeReport::ImageItem + + Image + Imagen + + + Watermark + Marca de agua + + + Ext. + Ext. + + + + LimeReport::ItemLocationPropItem + + Band + Banda + + + Page + Página + + + + LimeReport::ItemsAlignmentEditorWidget + + Bring to top + Traer al frente + + + Send to back + Enviar al fondo + + + Align to left + Alinear a la izquierda + + + Align to right + Alinear a la derecha + + + Align to vertical center + Centrar verticalmente + + + Align to top + Alinear arriba + + + Align to bottom + Alinear abajo + + + Align to horizontal center + Centrar horizontalmente + + + Set same height + Fijar mismo alto + + + Set same width + Fijar mismo ancho + + + + LimeReport::ItemsBordersEditorWidget + + Top line + Linea superior + + + Bottom line + Linea inferior + + + Left line + Linea izquierda + + + Right line + Linea derecha + + + No borders + Sin bordes + + + All borders + Todos los bordes + + + + LimeReport::MasterDetailProxyModel + + Field: "%1" not found in "%2" child datasource + Campo: "%1" no ha encontrado en la fuente de datos secundaria "%2" + + + Field: "%1" not found in "%2" master datasource + Campo: "%1" no encontrado en la fuente de datos maestra "%2" + + + + LimeReport::ModelToDataSource + + model is destroyed + modelo esta destruido + + + + LimeReport::ObjectBrowser + + Objects + Objetos + + + + LimeReport::ObjectInspectorWidget + + Clear + Limpiar + + + Filter + Filtrar + + + + LimeReport::PDFExporter + + Export to PDF + Exportar a PDF + + + + LimeReport::PageFooter + + Page Footer + Pie de página + + + Print on first page + Imprimir en primera página + + + Print on last page + Imprimir en última página + + + + LimeReport::PageHeader + + Page Header + Encabezado de página + + + + LimeReport::PageItemDesignIntf + + Paste + Pegar + + + Page is TOC + Página es TOC + + + Reset page number + Restablecer número de página + + + Full page + Página completa + + + Set page size to printer + Establecer el tamaño de página a la impresora + + + + LimeReport::PreviewReportWidget + + Form + Desde + + + Report file name + Nombre del archivo del reporte + + + %1 file name + %1 nombre de archivo + + + + LimeReport::PreviewReportWindow + + Preview + Vista previa + + + View + Ver + + + Report + Reporte + + + toolBar + Barra herramientas + + + Print + Imprimir + + + Ctrl+P + + + + Zoom In + Acercar + + + Zoom Out + Alejar + + + Prior Page + Página anterior + + + Next Page + Página siguiente + + + Close Preview + Cerrar vista previa + + + Edit Mode + Modo edición + + + Save to file + Guardar en archivo + + + Show errors + Mostrar errores + + + First Page + Primera página + + + First page + Primera página + + + Last Page + Ultima página + + + Print To PDF + Imprimir en PDF + + + Page: + Página: + + + of %1 + de %1 + + + Fit page width + Ajustar ancho de página + + + Fit page + Ajustar a página + + + One to one + Tamaño real + + + Font + Fuente + + + Text align + Alinear texto + + + Esc + + + + Show Toolbar + Mostrar barra herramientas + + + Show toolbar + Mostrar barra herramientas + + + toolBar_2 + barra herramientas_2 + + + InsertTextItem + Insertar objeto de texto + + + Add new TextItem + Agregar nuevo objeto de texto + + + Selection Mode + Modo de selección + + + Delete Item + Eliminar objeto + + + Del + Supr + + + + LimeReport::ProxyHolder + + Datasource has been invalidated + Fuente de datos ha sido invalidada + + + + LimeReport::QObjectPropertyModel + + leftMargin + Margen izquierdo + + + rightMargin + Margen derecho + + + topMargin + Margen superior + + + bottomMargin + Margen inferior + + + objectName + Nombre del objeto + + + borders + Bordes + + + geometry + geometria + + + itemAlign + Alineación del objeto + + + pageOrientation + Orientación de la página + + + pageSize + Tamaño de página + + + TopLine + Linea superior + + + BottomLine + Linea inferior + + + LeftLine + Linea izquierda + + + RightLine + Linea derecha + + + reprintOnEachPage + Re-imprimir en cada página + + + borderLineSize + Grosor de borde + + + autoHeight + Alto automático + + + backgroundColor + Color de fondo + + + columnCount + Cantidad de columnas + + + columnsFillDirection + Dirección llenado columnas + + + datasource + fuente de datos + + + keepBottomSpace + Conservar espacio inferior + + + keepFooterTogether + Mantener pie junto + + + keepSubdetailTogether + Mantener sub-detalle junto + + + printIfEmpty + imprimir si está vacío + + + sliceLastRow + cortar la última fila + + + splittable + Separable + + + alignment + Alineación + + + angle + Angulo + + + autoWidth + Ancho automático + + + backgroundMode + Modo de fondo + + + backgroundOpacity + Opacidad de fondo + + + content + contenido + + + font + fuente + + + fontColor + Color de fuente + + + foregroundOpacity + opacidad de primer plano + + + itemLocation + Ubicación del objeto + + + margin + margen + + + stretchToMaxHeight + estirar a la altura máxima + + + trimValue + Recortar Valor + + + lineWidth + Ancho de linea + + + opacity + opacidad + + + penStyle + estilo de pluma + + + shape + forma + + + shapeBrush + forma del pincel + + + shapeBrushColor + forma del pincel color + + + Property Name + Propiedad + + + Property value + Valor + + + Warning + Advertencia + + + gridStep + Distancia en rejilla + + + fullPage + Página completa + + + oldPrintMode + Modo de impresión viejo + + + borderColor + Color de borde + + + resetPageNumber + Restablecer número de página + + + alternateBackgroundColor + Color de fondo alternativo + + + backgroundBrushStyle + Estilo de bocha de fondo + + + startFromNewPage + Empezar desde nueva página + + + startNewPage + empezar nueva página + + + adaptFontToSize + adaptar fuente al tamaño + + + allowHTML + Permitir HTML + + + allowHTMLInFields + permitir HTML en campos + + + followTo + Permitir hasta + + + format + formato + + + lineSpacing + Espaciado entre líneas + + + textIndent + sangría de texto + + + textLayoutDirection + Dirección del diseño del texto + + + underlineLineSize + grosor del subrayado + + + underlines + subrayar + + + valueType + Tipo de valor + + + securityLevel + nivel seguridad + + + testValue + valor de prueba + + + whitespace + espacio en blanco + + + resourcePath + ruta de recursos + + + scale + escala + + + cornerRadius + radio de esquina + + + shapeColor + color de la forma + + + layoutType + tipo de diseño + + + barcodeType + tipo código barrras + + + barcodeWidth + ancho código barras + + + foregroundColor + color de primer plano + + + inputMode + modo de entrada + + + pdf417CodeWords + palabras del código pdf417 + + + autoSize + tamaño automático + + + center + centrado + + + field + campo + + + image + imagen + + + keepAspectRatio + mantener la relación de aspecto + + + columnsCount + recuento de columnas + + + useAlternateBackgroundColor + usar color de fondo alternativo + + + printBeforePageHeader + imprimir antes del encabezado de página + + + maxScalePercent + porcentaje máximo de escala + + + printOnFirstPage + Imprimir en la primera página + + + printOnLastPage + Imprimir en la última página + + + printAlways + imprimir siempre + + + repeatOnEachRow + repetir en cada fila + + + condition + condición + + + groupFieldName + nombre del grupo de campos + + + keepGroupTogether + mantener grupo junto + + + endlessHeight + altura sin fin + + + extendedHeight + alto extendido + + + isExtendedInDesignMode + es el modo de diseño extendido + + + pageIsTOC + la página es TOC + + + setPageSizeToPrinter + ajsutar tamaño de página a la impresora + + + fillInSecondPass + completar segundo paso + + + chartTitle + Titulo del gráfico + + + chartType + tipo gráfico + + + drawLegendBorder + dibujar borde de leyenda + + + labelsField + campo de etiquetas + + + legendAlign + Alinear leyenda + + + series + series + + + titleAlign + alinear titulo + + + watermark + marca de agua + + + keepTopSpace + conservar espacio superior + + + printable + imprimible + + + variable + + + + replaceCRwithBR + reemplazar CR con BR + + + hideIfEmpty + ocultar si está vacío + + + hideEmptyItems + ocultar objetos vacíos + + + useExternalPainter + utilizar pintor externo + + + layoutSpacing + espaciado de diseño + + + printerName + nombre impresora + + + fontLetterSpacing + espaciado entre letra y fuente + + + hideText + Ocultar texto + + + option3 + Opción3 + + + + LimeReport::RectMMPropItem + + width + ancho + + + height + alto + + + + LimeReport::RectPropItem + + width + ancho + + + height + alto + + + + LimeReport::ReportDesignWidget + + Report file name + Nombre de archivo del reporte + + + Script + + + + Error + + + + Wrong file format + Formato de archivo incorrecto + + + Translations + Traducciones + + + + LimeReport::ReportDesignWindow + + About + Acerca de + + + New Report + Nuevo Reporte + + + Edit Mode + Modo de edición + + + Undo + Deshacer + + + Redo + Rehacer + + + Copy + Copiar + + + Paste + Pegar + + + Cut + Cortar + + + Settings + Configuración + + + Use grid + Usar cuadricula + + + Use magnet + Usar Imán + + + Text Item + Elemento de texto + + + Save Report + Guardar Reporte + + + Save Report As + Guardar reporte como + + + Load Report + Cargar Reporte + + + Delete item + Eliminar elemento + + + Zoom In + Acercarse + + + Zoom Out + Alejarse + + + Render Report + Generar reporte + + + Edit layouts mode + Modo de edición de diseño + + + Horizontal layout + Diseño horizontal + + + Report Tools + Herramientas de reporte + + + Main Tools + Herramientas principales + + + Font + Fuente + + + Text alignment + Alineación del texto + + + Items alignment + Alineación de elementos + + + Borders + Bordes + + + Report bands + Bandas del reporte + + + Report Header + Encabezado del reporte + + + Report Footer + Pie del Reporte + + + Page Header + Encabezado de página + + + Page Footer + Pie de página + + + Data + Datos + + + Data Header + Encabezado de Datos + + + Data Footer + Pie de Datos + + + SubDetail + Sub-Detalle + + + SubDetailHeader + Encabezado de Sub-Detalle + + + SubDetailFooter + Pie de Sub-Detalle + + + GroupHeader + Encabezado de grupo + + + GroupFooter + Pie de Grupo + + + File + Archivo + + + Edit + Editar + + + Info + Información + + + Recent Files + Archivos recientes + + + Object Inspector + Inspector de objectos + + + Report structure + Estructura del reporte + + + Data Browser + Navegador de datos + + + Report file name + Nombre de archivo del reporte + + + Rendering report + Generando reporte + + + Abort + Abortar + + + page rendered + página generada + + + Warning + Advertencia + + + File "%1" not found! + ¡No se encontró el archivo "%1"! + + + New Report Page + Nueva página para el reporte + + + Delete Report Page + Eliminar página del reporte + + + Script Browser + Navegador de Script + + + Tear-off Band + Banda de corte + + + Delete dialog + Eliminar dialogo + + + Add new dialog + Agregar nuevo dialogo + + + Widget Box + Caja de Widget + + + Property Editor + Editor de propiedades + + + Action Editor + Editor de acción + + + Resource Editor + Editor de recursos + + + SignalSlot Editor + Editor de señales + + + Dialog Designer Tools + Herramientas de diseño de Dialogos + + + Report has been modified! Do you want save the report? + ¡El reporte ha sido modificado! ¿Quieres guardar el reporte? + + + Hide left panel | Alt+L + Ocultar panel izquierdo | Alt + L + + + Hide right panel | Alt+R + Ocultar panel derecho | Alt + L + + + Vertical layout + Diseño vertical + + + + LimeReport::ReportEnginePrivate + + Error + + + + Preview + Vista previa + + + Report File Change + Repore cambios en archivo + + + The report file "%1" has changed names or been deleted. + +This preview is no longer valid. + El archivo del informe "%1" ha cambiado los nombres o se ha eliminado. + +Esta vista previa ya no es válida. + + + Language %1 already exists + El idioma %1 ya existe + + + Designer not found! + Diseñador no encontrado! + + + %1 file name + Nombre de archivo %1 + + + + LimeReport::ReportFooter + + Report Footer + Pie reporte + + + + LimeReport::ReportHeader + + Report Header + Encabezado reporte + + + + LimeReport::ReportRender + + Error + + + + Databand "%1" not found + Banda de datos "%1" no encontrada + + + Wrong using function %1 + Error al utilizar la función %1 + + + page index out of range + índice de página fuera de rango + + + + LimeReport::SQLEditDialog + + Connection + Conexión + + + Cancel + Cancelar + + + Attention + Atención + + + Datasource + Fuente de datos + + + Datasource Name + Nombre de fuente de datos + + + Subdetail + Sub-detalle + + + Master datasource + Fuente de datos primaria + + + Subquery mode + Modo de sub consulta + + + Filter mode + Modo de filtrado + + + SQL + SQL + + + Preview + Vista previa + + + Hide Preview + Ocultar vista previa + + + Child datasource + Fuente de datos hija + + + Fields map + Mapa de campos + + + ... + + + + Data preview + Vista previa de datos + + + Ok + Aceptar + + + Error + + + + Datasource with name %1 already exist + La fuente de datos con el nombre %1 ya existe + + + Connection is not specified + La conexión no está especificada + + + Refresh + Refrescar + + + defaultConnection + Conexión por defecto + + + Datasource Name is empty! + Nombre de la fuente de datos está vacío! + + + SQL is empty! + SQL está vacío! + + + Datasource with name: "%1" already exists! + Fuente de datos con nombre: "%1" ya existe! + + + CSV + + + + Separator + Separador + + + ; + + + + Use first row as header + Usa la primera fila como encabezado + + + + LimeReport::ScriptBrowser + + Form + De + + + Functions + Funciones + + + ... + + + + Dialogs + Dialogos + + + Type + Tipo + + + Name + Nombre + + + NO CATEGORY + NO CATEGORIA + + + Error + + + + Dialog with name: %1 already exists + Diálogo con nombre: %1 ya existe + + + ui file must cointain QDialog instead QWidget or QMainWindow + El archivo ui debe contener QDialog en lugar de QWidget o QMainWindow + + + wrong file format + formato de archivo incorrecto + + + + LimeReport::ScriptEditor + + Form + De + + + Data + Datos + + + Functions + Funciones + + + + LimeReport::ScriptEngineContext + + Dialog with name: %1 can`t be created + Diálogo con nombre: %1 no puede ser creado + + + Error + + + + + LimeReport::ScriptEngineManager + + Value + Valor + + + BandName + Nombre de banda + + + Format + Formato + + + Precision + Precisión + + + Locale + Idioma + + + CurrencySymbol + Símbolo de moneda + + + Variable %1 not found + Variable %1 no encontrada + + + Name + Nombre + + + GROUP FUNCTIONS + Funciones de grupo + + + FieldName + Nombre campo + + + Field %1 not found in %2! + ¡El campo %1 no se encuentra en %2! + + + SYSTEM + SISTEMA + + + NUMBER + NUMEROS + + + DATE&TIME + FECHA Y HORA + + + GENERAL + + + + Datasource + Fuente datos + + + ValueField + Valor campo + + + KeyField + Campo clave + + + KeyFieldValue + Valor campo clave + + + Unique identifier + Identificador único + + + Content + Contenido + + + Indent + Sangrar + + + datasourceName + Nombre de fuente de datos + + + Function manager with name "%1" already exists! + ¡El administrador de funciones con el nombre "%1" ya existe! + + + RowIndex + Índice de fila + + + + LimeReport::SettingDialog + + Designer setting + Configuración de diseñador + + + Default font + Fuente predeterminada + + + Grid + Cuadrícula + + + Vertical grid step + Espaciado de rejilla vertical + + + Horizontal grid step + Espaciado de rejilla horizontal + + + Suppress absent fields and variables warning + Suprimir campos ausentes y variables de advertencia. + + + Use dark theme + Usar tema oscuro + + + Language + Idioma + + + Designer settings + Configuracion del diseñador + + + Script editor settings + Configuracion del editor de scripts + + + Font + Fuente + + + Indent size + Tamaño de sangría + + + Report settings + Configuración de informes + + + Theme + Tema + + + + LimeReport::SubDetailBand + + SubDetail + Sub-Detalle + + + + LimeReport::SubDetailHeaderBand + + SubDetailHeader + Encabezado sub-detalle + + + + LimeReport::TearOffBand + + Tear-off Band + Banda de corte + + + + LimeReport::TextAlignmentEditorWidget + + Text align left + Alinear texto a la izquierda + + + Text align center + Centrar texto + + + Text align right + Alinear texto a la derecha + + + Text align justify + Justificar texto + + + Text align top + Alinear texto arriba + + + Text align bottom + Alinear texto abajo + + + + LimeReport::TextItem + + Edit + Editar + + + Auto height + Altura automática + + + Allow HTML + Permitir HTML + + + Allow HTML in fields + Permitir HTML en los campos + + + Stretch to max height + Estirar a la altura máxima + + + Error + + + + TextItem " %1 " already has folower " %2 " + Objeto de texto "%1" ya tiene el siguiente "%2" + + + Transparent + Transparente + + + TextItem " %1 " not found! + Objeto de texto "%1" no encontrado! + + + Watermark + Marca de agua + + + Hide if empty + Ocultar si está vacío + + + + LimeReport::TextItemEditor + + Cancel + Cancelar + + + Text Item Editor + Editor de objeto de texto + + + Content + Contenido + + + Ok + Aceptar + + + Ctrl+Return + Ctrl+Intro + + + Esc + + + + + LimeReport::TranslationEditor + + Form + De + + + Languages + Idiomas + + + ... + + + + Pages + Páginas + + + Strings + Cadenas + + + Source Text + Texto fuente + + + Translation + Traducción + + + Checked + Revisada + + + Report Item + Objeto del reporte + + + Property + Propiedad + + + Source text + Texto fuente + + + + LimeReport::VariablesHolder + + variable with name + variable con el nombre + + + already exists! + ¡ya existe! + + + does not exists! + no existe! + + + + QObject + + Data + Datos + + + DataHeader + Encabezado datos + + + DataFooter + Pie datos + + + GroupHeader + Encabezado grupo + + + GroupFooter + Pie grupo + + + Page Footer + Pie de página + + + Page Header + Encabezado de página + + + Report Footer + Pie de reporte + + + Report Header + Cabezado de reporte + + + SubDetail + Sub-Detalle + + + SubDetailHeader + Encabezado sub-detalle + + + SubDetailFooter + Pie sub-detalle + + + alignment + alineación + + + Barcode Item + Objeto código barras + + + HLayout + diseño horizontal + + + Image Item + Objeto Imagen + + + Shape Item + Objeto de forma + + + itemLocation + Ubicación del objeto + + + Text Item + Objeto de texto + + + Invalid connection! %1 + ¡Conexión inválida! %1 + + + Master datasouce "%1" not found! + No se encontró la fuente de datos maestra "%1"! + + + Child + Hijo + + + and child + y hijo + + + datasouce "%1" not found! + fuente de datos "%1" no encontrada! + + + Attention! + ¡Atención! + + + Selected elements have different parent containers + Los elementos seleccionados tienen diferentes contenedores padre + + + Function %1 not found or have wrong arguments + La función %1 no se encuentra o tiene argumentos incorrectos + + + bool + + + + QColor + + + + content + contenido + + + datasource + fuente datos + + + field + campo + + + enum + enumerar + + + flags + opciones + + + QFont + + + + QImage + + + + int + + + + qreal + + + + QRect + + + + QRectF + + + + geometry + geometria + + + mm + + + + QString + + + + File %1 not opened + Archivo %1 no abierto + + + Content string is empty + La cadena de contenido está vacía + + + Content is empty + El contenido esta vacio + + + Wrong file format + Formato de archivo incorrecto + + + Tear-off Band + Banda de corte + + + Chart Item + Objeto gráfico + + + First + Primero + + + Second + Segundo + + + Thrid + Tercero + + + Master datasource "%1" not found! + ¡No se encontró la fuente de datos maestra "%1"! + + + Object with name %1 already exists! + ¡El objeto con nombre %1 ya existe! + + + Datasource manager not found + Administrador de fuente de datos no encontrado + + + Export to PDF + Exportar a PDF + + + VLayout + Diseño vertical + + + Default + Por defecto + + + diff --git a/translations/limereport_es_ES.qm b/translations/limereport_es_ES.qm deleted file mode 100644 index a7fe947..0000000 Binary files a/translations/limereport_es_ES.qm and /dev/null differ diff --git a/translations/limereport_es_ES.ts b/translations/limereport_es_ES.ts deleted file mode 100644 index 7aeadaf..0000000 --- a/translations/limereport_es_ES.ts +++ /dev/null @@ -1,2535 +0,0 @@ - - - - - LRVariableDialog - - Variable - Variable - - - Name - Nombre - - - Value - Valor - - - Type - Tipo - - - Attention - Atención - - - - LimeReport::AVariablesHolder - - variable with name - variable con el nombre - - - already exists !! - ya existe !! - - - does not exists !! - no existe !! - - - - LimeReport::AboutDialog - - About - Acerca de - - - Author - Autor - - - License - Licencia - - - Close - Cerrar - - - Lime Report - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Arin Alexander</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">arin_a@bk.ru</p></body></html> - - - - Version 1.1.1 - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/report/images/logo_100.png" height="100" style="float: left;" /><span style=" font-size:12pt; font-weight:600;">Report engine for </span><span style=" font-size:12pt; font-weight:600; color:#7faa18;">Qt</span><span style=" font-size:12pt; font-weight:600;"> framework</span></p> -<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">LimeReport - multi-platform C++ library written using Qt framework and intended for software developers that would like to add into their application capability to form report or print forms generated using templates.</span></p> -<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">Official web site : </span><a href="www.limereport.ru"><span style=" font-size:11pt; text-decoration: underline; color:#0000ff;">www.limereport.ru</span></a></p> -<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; text-decoration: underline; color:#0000ff;"><br /></p> -<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></p> -<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; font-weight:600; color:#000000;"><br /></p> -<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright 2015 Arin Alexander. All rights reserved.</span></p></body></html> - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">(c) 2015 Arin Alexander arin_a@bk.ru</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC1"></a><span style=" font-family:'sans-serif'; font-weight:600;">G</span><span style=" font-family:'sans-serif'; font-weight:600;">NU LESSER GENERAL PUBLIC LICENSE</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Version 2.1, February 1999</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Copyright (C) 1991, 1999 Free Software Foundation, Inc.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Everyone is permitted to copy and distribute verbatim copies</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">of this license document, but changing it is not allowed.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">[This is the first released version of the Lesser GPL. It also counts</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';"> as the successor of the GNU Library Public License, version 2, hence</span></p> -<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';"> the version number 2.1.]</span></p> -<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC2"></a><span style=" font-family:'sans-serif'; font-weight:600;">P</span><span style=" font-family:'sans-serif'; font-weight:600;">reamble</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">We call this license the &quot;Lesser&quot; General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a &quot;work based on the library&quot; and a &quot;work that uses the library&quot;. The former contains code derived from the library, whereas the latter must be combined with the library in order to run.</span></p> -<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC3"></a><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">T</span><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">ERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">0.</span><span style=" font-family:'sans-serif';"> This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called &quot;this License&quot;). Each licensee is addressed as &quot;you&quot;.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">A &quot;library&quot; means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">The &quot;Library&quot;, below, refers to any such software library or work which has been distributed under these terms. A &quot;work based on the Library&quot; means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term &quot;modification&quot;.)</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">&quot;Source code&quot; for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">1.</span><span style=" font-family:'sans-serif';"> You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">2.</span><span style=" font-family:'sans-serif';"> You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:</span></p> -<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'sans-serif';" style=" margin-top:19px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">a)</span><span style=" font-size:16px;"> The modified work must itself be a software library.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">b)</span><span style=" font-size:16px;"> You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">c)</span><span style=" font-size:16px;"> You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:19px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">d)</span><span style=" font-size:16px;"> If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.</span></li></ul> -<p style=" margin-top:15px; margin-bottom:15px; margin-left:38px; margin-right:19px; -qt-block-indent:1; text-indent:0px;"><span style=" font-family:'sans-serif';">(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">3.</span><span style=" font-family:'sans-serif';"> You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">This option is useful when you wish to copy part of the code of the Library into a program that is not a library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">4.</span><span style=" font-family:'sans-serif';"> You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">5.</span><span style=" font-family:'sans-serif';"> A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a &quot;work that uses the Library&quot;. Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">However, linking a &quot;work that uses the Library&quot; with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a &quot;work that uses the library&quot;. The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">When a &quot;work that uses the Library&quot; uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">6.</span><span style=" font-family:'sans-serif';"> As an exception to the Sections above, you may also combine or link a &quot;work that uses the Library&quot; with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:</span></p> -<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'sans-serif';" style=" margin-top:19px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">a)</span><span style=" font-size:16px;"> Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable &quot;work that uses the Library&quot;, as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">b)</span><span style=" font-size:16px;"> Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">c)</span><span style=" font-size:16px;"> Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">d)</span><span style=" font-size:16px;"> If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:19px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">e)</span><span style=" font-size:16px;"> Verify that the user has already received a copy of these materials or that you have already sent this user a copy.</span></li></ul> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">For an executable, the required form of the &quot;work that uses the Library&quot; must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">7.</span><span style=" font-family:'sans-serif';"> You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:</span></p> -<ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'sans-serif';" style=" margin-top:19px; margin-bottom:0px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">a)</span><span style=" font-size:16px;"> Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.</span></li> -<li style=" font-family:'sans-serif';" style=" margin-top:0px; margin-bottom:19px; margin-left:38px; margin-right:19px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16px; font-weight:600;">b)</span><span style=" font-size:16px;"> Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.</span></li></ul> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">8.</span><span style=" font-family:'sans-serif';"> You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">9.</span><span style=" font-family:'sans-serif';"> You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">10.</span><span style=" font-family:'sans-serif';"> Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">11.</span><span style=" font-family:'sans-serif';"> If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">12.</span><span style=" font-family:'sans-serif';"> If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">13.</span><span style=" font-family:'sans-serif';"> The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and &quot;any later version&quot;, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">14.</span><span style=" font-family:'sans-serif';"> If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">NO WARRANTY</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">15.</span><span style=" font-family:'sans-serif';"> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600;">16.</span><span style=" font-family:'sans-serif';"> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> -<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">END OF TERMS AND CONDITIONS</span></p> -<p style=" margin-top:15px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a name="SEC4"></a><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">H</span><span style=" font-family:'sans-serif'; font-weight:600; color:#333333;">ow to Apply These Terms to Your New Libraries</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the &quot;copyright&quot; line and a pointer to where the full notice is found.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace'; font-style:italic;">one line to give the library's name and an idea of what it does.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Copyright (C) </span><span style=" font-family:'monospace'; font-style:italic;">year</span><span style=" font-family:'monospace';"> </span><span style=" font-family:'monospace'; font-style:italic;">name of author</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace'; font-style:italic;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">This library is free software; you can redistribute it and/or</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">modify it under the terms of the GNU Lesser General Public</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">License as published by the Free Software Foundation; either</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">version 2.1 of the License, or (at your option) any later version.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">This library is distributed in the hope that it will be useful,</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">but WITHOUT ANY WARRANTY; without even the implied warranty of</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Lesser General Public License for more details.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">You should have received a copy of the GNU Lesser General Public</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">License along with this library; if not, write to the Free Software</span></p> -<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">Also add information on how to contact you by electronic and paper mail.</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">You should also get your employer (if you work as a programmer) or your school, if any, to sign a &quot;copyright disclaimer&quot; for the library, if necessary. Here is a sample; alter the names:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Yoyodyne, Inc., hereby disclaims all copyright interest in</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">the library `Frob' (a library for tweaking knobs) written</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">by James Random Hacker.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace'; font-style:italic;">signature of Ty Coon</span><span style=" font-family:'monospace';">, 1 April 1990</span></p> -<p style=" margin-top:0px; margin-bottom:15px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Ty Coon, President of Vice</span></p> -<p style=" margin-top:19px; margin-bottom:19px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'sans-serif';">That's all there is to it!</span></p></body></html> - - - - - LimeReport::AlignmentPropItem - - Left - Izquierda - - - Right - Derecha - - - Center - Centro - - - Justify - Justificado - - - Top - Arriba - - - Botom - Abajo - - - horizontal - horizontal - - - vertical - vertical - - - - LimeReport::BandDesignIntf - - connected to - conectado a - - - Bring to top - - - - Send to back - - - - Auto height - - - - Splittable - - - - DataBand - - - - DataHeaderBand - - - - DataFooterBand - - - - ReportHeader - - - - ReportFooter - - - - PageHeader - - - - PageFooter - - - - SubDetailBand - - - - SubDetailHeaderBand - - - - SubDetailFooterBand - - - - GroupBandHeader - - - - GroupBandFooter - - - - TearOffBand - - - - Keep bottom space - - - - Start from new page - - - - Start new page - - - - - LimeReport::BaseDesignIntf - - Copy - - - - Cut - - - - Paste - - - - Bring to top - - - - Send to back - - - - No borders - - - - All borders - - - - - LimeReport::ConnectionDesc - - defaultConnection - - - - - LimeReport::ConnectionDialog - - Connection - Conexión - - - Connection Name - Nombre de conexión - - - Server - Servidor - - - User - Usuario - - - Password - Contraseña - - - Database - Base de Datos - - - Auto connect - Auto conectar - - - Check connection - Probar conexión - - - Cancel - Cancelar - - - Connection succsesfully established! - Conexión establecida satisfactoriamente! - - - Connection Name is empty - El Nombre de la conexión esta vacía - - - Driver - - - - ... - - - - Ok - - - - Error - - - - Connection with name - - - - already exists - ya existe - - - Use default application connection - - - - Dont keep credentals in lrxml - - - - defaultConnection - - - - already exists! - - - - Port - - - - - LimeReport::ContentItemDesignIntf - - Variable %1 not found - Variable %1 no encontrada - - - - LimeReport::DataBand - - Data - Datos - - - - LimeReport::DataBrowser - - Attention - Atención - - - Datasources - Orígenes de Datos - - - Add database connection - Agregar conexion a base de datos - - - ... - - - - Add new datasource - Agregar origen de datos - - - View data - Ver datos - - - Change datasource - Cambiar origen de datos - - - Delete datasource - Eliminar origen de datos - - - Show error - Mostrar error - - - Variables - - - - Add new variable - Agregar variable - - - Edit variable - Editar variable - - - Delete variable - Borrarvariable - - - Do you really want to delete "%1" connection ? - Realmente quieres borrar la conexion "%1"? - - - User variables - Variables de usuario - - - System variables - Variables del sistema - - - Error - - - - Grab variable - - - - Report variables - - - - External variables - - - - Do you really want to delete "%1" connection? - - - - Do you really want to delete "%1" datasource? - - - - Do you really want to delete variable "%1"? - - - - - LimeReport::DataFooterBand - - DataFooter - - - - - LimeReport::DataHeaderBand - - DataHeader - - - - - LimeReport::DataSourceManager - - Connection "%1" is not open - - - - Variable "%1" not found! - - - - invalid connection - - - - Database "%1" not found - - - - Datasource "%1" not found! - - - - Connection with name "%1" already exists! - - - - Datasource with name "%1" already exists! - - - - - LimeReport::DataSourceModel - - Datasources - Orígenes de Datos - - - Variables - - - - External variables - - - - - LimeReport::EnumPropItem - - Default - - - - Portrait - - - - Landscape - - - - NoneAutoWidth - - - - MaxWordLength - - - - MaxStringLength - - - - TransparentMode - - - - OpaqueMode - - - - Angle0 - - - - Angle90 - - - - Angle180 - - - - Angle270 - - - - Angle45 - - - - Angle315 - - - - DateTime - - - - Double - - - - NoBrush - - - - SolidPattern - - - - Dense1Pattern - - - - Dense2Pattern - - - - Dense3Pattern - - - - Dense4Pattern - - - - Dense5Pattern - - - - Dense6Pattern - - - - Dense7Pattern - - - - HorPattern - - - - VerPattern - - - - CrossPattern - - - - BDiagPattern - - - - FDiagPattern - - - - LeftToRight - - - - RightToLeft - - - - LayoutDirectionAuto - - - - LeftItemAlign - - - - RightItemAlign - - - - CenterItemAlign - - - - ParentWidthItemAlign - - - - DesignedItemAlign - - - - HorizontalLine - - - - VerticalLine - - - - Ellipse - - - - Rectangle - - - - Page - - - - Band - - - - Horizontal - - - - Vertical - - - - VerticalUniform - - - - - LimeReport::FlagsPropItem - - NoLine - - - - TopLine - - - - BottomLine - - - - LeftLine - - - - RightLine - - - - - LimeReport::FontEditorWidget - - Font bold - - - - Font Italic - - - - Font Underline - - - - - LimeReport::FontPropItem - - bold - - - - italic - - - - underline - - - - size - - - - family - - - - - LimeReport::GroupBandFooter - - GroupFooter - - - - - LimeReport::GroupBandHeader - - GroupHeader - - - - Group field not found - - - - Datasource "%1" not found! - - - - - LimeReport::GroupFunction - - Field "%1" not found - - - - Variable "%1" not found - - - - Item "%1" not found - - - - Wrong script syntax "%1" - - - - - LimeReport::ImageItem - - Image - - - - - LimeReport::ItemLocationPropItem - - Band - - - - Page - - - - - LimeReport::ItemsAlignmentEditorWidget - - Bring to top - - - - Send to back - - - - Align to left - - - - Align to right - - - - Align to vertical center - - - - Align to top - - - - Align to bottom - - - - Align to horizontal center - - - - Set same height - - - - Set same width - - - - - LimeReport::ItemsBordersEditorWidget - - Top line - - - - Bottom line - - - - Left line - - - - Right line - - - - No borders - - - - All borders - - - - - LimeReport::MasterDetailProxyModel - - Field: "%1" not found in "%2" child datasource - - - - Field: "%1" not found in "%2" master datasource - - - - - LimeReport::ModelToDataSource - - model is destroyed - - - - - LimeReport::ObjectBrowser - - Objects - - - - - LimeReport::PageFooter - - Page Footer - - - - - LimeReport::PageHeader - - Page Header - - - - - LimeReport::PageItemDesignIntf - - Paste - - - - - LimeReport::PreviewReportWidget - - Form - - - - PDF file name - - - - Report file name - - - - - LimeReport::PreviewReportWindow - - Preview - - - - View - - - - Report - - - - toolBar - - - - Print - - - - Ctrl+P - - - - Zoom In - - - - Zoom Out - - - - Prior Page - - - - Next Page - - - - Close Preview - - - - Edit Mode - - - - Save to file - - - - Show errors - - - - First Page - - - - First page - - - - Last Page - - - - Print To PDF - - - - Page: - - - - of %1 - - - - Fit page width - - - - Fit page - - - - One to one - - - - Font - - - - Text align - - - - Esc - - - - Show Toolbar - - - - Show toolbar - - - - - LimeReport::ProxyHolder - - Datasource has been invalidated - - - - - LimeReport::QObjectPropertyModel - - leftMargin - - - - rightMargin - - - - topMargin - - - - bottomMargin - - - - objectName - - - - borders - - - - geometry - - - - itemAlign - - - - pageOrientation - - - - pageSize - - - - TopLine - - - - BottomLine - - - - LeftLine - - - - RightLine - - - - reprintOnEachPage - - - - borderLineSize - - - - autoHeight - - - - backgroundColor - - - - columnCount - - - - columnsFillDirection - - - - datasource - - - - keepBottomSpace - - - - keepFooterTogether - - - - keepSubdetailTogether - - - - printIfEmpty - - - - sliceLastRow - - - - splittable - - - - alignment - - - - angle - - - - autoWidth - - - - backgroundMode - - - - backgroundOpacity - - - - content - - - - font - - - - fontColor - - - - foregroundOpacity - - - - itemLocation - - - - margin - - - - stretchToMaxHeight - - - - trimValue - - - - lineWidth - - - - opacity - - - - penStyle - - - - shape - - - - shapeBrush - - - - shapeBrushColor - - - - Property Name - - - - Property value - - - - Warning - - - - gridStep - - - - fullPage - - - - oldPrintMode - - - - borderColor - - - - resetPageNumber - - - - alternateBackgroundColor - - - - backgroundBrushStyle - - - - startFromNewPage - - - - startNewPage - - - - adaptFontToSize - - - - allowHTML - - - - allowHTMLInFields - - - - followTo - - - - format - - - - lineSpacing - - - - textIndent - - - - textLayoutDirection - - - - underlineLineSize - - - - underlines - - - - valueType - - - - securityLevel - - - - testValue - - - - whitespace - - - - resourcePath - - - - scale - - - - cornerRadius - - - - shapeColor - - - - layoutType - - - - barcodeType - - - - barcodeWidth - - - - foregroundColor - - - - inputMode - - - - pdf417CodeWords - - - - autoSize - - - - center - - - - field - - - - image - - - - keepAspectRatio - - - - columnsCount - - - - useAlternateBackgroundColor - - - - printBeforePageHeader - - - - maxScalePercent - - - - printOnFirstPage - - - - printOnLastPage - - - - printAlways - - - - repeatOnEachRow - - - - condition - - - - groupFieldName - - - - keepGroupTogether - - - - - LimeReport::RectMMPropItem - - width - - - - height - - - - - LimeReport::RectPropItem - - width - - - - height - - - - - LimeReport::ReportDesignWidget - - Report file name - - - - Script - - - - Error - - - - Wrong file format - - - - - LimeReport::ReportDesignWindow - - About - Acerca de - - - New Report - - - - Edit Mode - - - - Undo - - - - Redo - - - - Copy - - - - Paste - - - - Cut - - - - Settings - - - - Use grid - - - - Use magnet - - - - Text Item - - - - Save Report - - - - Save Report As - - - - Load Report - - - - Delete item - - - - Zoom In - - - - Zoom Out - - - - Render Report - - - - Edit layouts mode - - - - Horizontal layout - - - - Report Tools - - - - Main Tools - - - - Font - - - - Text alignment - - - - Items alignment - - - - Borders - - - - Report bands - - - - Report Header - - - - Report Footer - - - - Page Header - - - - Page Footer - - - - Data - Datos - - - Data Header - - - - Data Footer - - - - SubDetail - - - - SubDetailHeader - - - - SubDetailFooter - - - - GroupHeader - - - - GroupFooter - - - - File - - - - Edit - - - - Info - - - - Recent Files - - - - Object Inspector - - - - Report structure - - - - Data Browser - - - - Report file name - - - - Rendering report - - - - Abort - - - - page rendered - - - - Warning - - - - File "%1" not found! - - - - New Report Page - - - - Delete Report Page - - - - Script Browser - - - - Tear-off Band - - - - Report has been modified! Do you want save the report? - - - - Hide left panel | Alt+L - - - - Hide right panel | Alt+R - - - - - LimeReport::ReportEnginePrivate - - Error - - - - Preview - - - - Report File Change - - - - The report file "%1" has changed names or been deleted. - -This preview is no longer valid. - - - - - LimeReport::ReportFooter - - Report Footer - - - - - LimeReport::ReportHeader - - Report Header - - - - - LimeReport::ReportRender - - Error - - - - Databand "%1" not found - - - - Wrong using function %1 - - - - page index out of range - - - - - LimeReport::SQLEditDialog - - Connection - Conexión - - - Cancel - Cancelar - - - Attention - Atención - - - Datasource - - - - Datasource Name - - - - Subdetail - - - - Master datasource - - - - Subquery mode - - - - Filter mode - - - - SQL - - - - Preview - - - - Hide Preview - - - - Child datasource - - - - Fields map - - - - ... - - - - Data preview - - - - Ok - - - - Error - - - - Datasource with name %1 already exist - - - - Connection is not specified - - - - Refresh - - - - defaultConnection - - - - Datasource Name is empty! - - - - SQL is empty! - - - - Datasource with name: "%1" already exists! - - - - - LimeReport::ScriptBrowser - - Form - - - - Functions - - - - ... - - - - Dialogs - - - - Type - Tipo - - - Name - Nombre - - - NO CATEGORY - - - - Error - - - - Dialog with name: %1 already exists - - - - ui file must cointain QDialog instead QWidget or QMainWindow - - - - wrong file format - - - - - LimeReport::ScriptEngineContext - - Dialog with name: %1 can`t be created - - - - - LimeReport::ScriptEngineManager - - Value - Valor - - - BandName - - - - Format - - - - Precision - - - - Locale - - - - CurrencySymbol - - - - Variable %1 not found - Variable %1 no encontrada - - - Name - Nombre - - - GROUP FUNCTIONS - - - - SYSTEM - - - - NUMBER - - - - DATE&TIME - - - - GENERAL - - - - Seconds - - - - - LimeReport::SettingDialog - - Designer setting - - - - Default font - - - - Grid - - - - Vertical grid step - - - - Horizontal grid step - - - - Designer Setting - - - - Report Setting - - - - Suppress absent fields and variables warning - - - - - LimeReport::SubDetailBand - - SubDetail - - - - - LimeReport::SubDetailHeaderBand - - SubDetailHeader - - - - - LimeReport::TearOffBand - - Tear-off Band - - - - - LimeReport::TextAlignmentEditorWidget - - Text align left - - - - Text align center - - - - Text align right - - - - Text align justify - - - - Text align top - - - - Text align bottom - - - - - LimeReport::TextItem - - Edit - - - - Auto height - - - - Allow HTML - - - - Allow HTML in fields - - - - Stretch to max height - - - - Error - - - - TextItem " %1 " already has folower " %2 " - - - - TextItem " %1 " not found! - - - - - LimeReport::TextItemEditor - - Cancel - Cancelar - - - Text Item Editor - - - - Content - - - - Data - Datos - - - Functions - - - - Editor settings - - - - Editor font - - - - ... - - - - Ok - - - - Ctrl+Return - - - - Esc - - - - - LimeReport::VariablesHolder - - variable with name - variable con el nombre - - - already exists !! - ya existe !! - - - does not exists !! - no existe !! - - - already exists! - - - - does not exists! - - - - - QObject - - Data - Datos - - - DataHeader - - - - DataFooter - - - - GroupHeader - - - - GroupFooter - - - - Page Footer - - - - Page Header - - - - Report Footer - - - - Report Header - - - - SubDetail - - - - SubDetailHeader - - - - SubDetailFooter - - - - alignment - - - - Barcode Item - - - - HLayout - - - - Image Item - - - - Shape Item - - - - itemLocation - - - - Text Item - - - - Invalid connection! %1 - - - - Master datasouce "%1" not found! - - - - Child - - - - and child - - - - datasouce "%1" not found! - - - - Attention! - - - - Selected elements have different parent containers - - - - Function %1 not found or have wrong arguments - - - - bool - - - - QColor - - - - content - - - - datasource - - - - field - - - - enum - - - - flags - - - - QFont - - - - QImage - - - - int - - - - qreal - - - - QRect - - - - QRectF - - - - geometry - - - - mm - - - - QString - - - - File %1 not opened - - - - Content string is empty - - - - Content is empty - - - - Wrong file format - - - - Tear-off Band - - - - Master datasource "%1" not found! - - - - Object with name %1 already exists! - - - - diff --git a/translations/limereport_fr.ts b/translations/limereport_fr.ts index 63df088..5ea10c5 100644 --- a/translations/limereport_fr.ts +++ b/translations/limereport_fr.ts @@ -1,6 +1,72 @@ + + $ClassName$ + + + $ClassName$ + + + + + ChartItemEditor + + + Series editor + Editeur de séries + + + + Series + Séries + + + + Add + Ajouter + + + + Delete + Supprimer + + + + Name + Nom + + + + Values field + Valeur + + + + Color + Couleur + + + + Type + Type + + + + Labels field + Valeurs + + + + Ok + + + + + Series name + Séries + + LRVariableDialog @@ -9,26 +75,44 @@ Variable - + Name Nom - + Value Valeur - + Type Type - + + Mandatory + Obligatoire + + + Attention + + LanguageSelectDialog + + + Dialog + + + + + Language + Langue + + LimeReport::AboutDialog @@ -254,150 +338,154 @@ p, li { white-space: pre-wrap; } LimeReport::BandDesignIntf - + DataBand bande de données - + DataHeaderBand En-tête de données - + DataFooterBand - Bande de pied de données + Pied de données - + ReportHeader - En-tête du rapport + En-tête de rapport - + ReportFooter - Pied du rapport + Pied de rapport - + PageHeader En-tête de page - + PageFooter Pied de page - + SubDetailBand - Bande de sous-détails + Sous-détails - + SubDetailHeaderBand En-tête de sous-détails - + SubDetailFooterBand Pied de sous-détails - + GroupBandHeader - Bande de groupe d'en-tête + Groupe d'en-tête - + GroupBandFooter - Bande de groupe de pieds + Groupe de pieds - + TearOffBand Bande détachable - + connected to Connecté à - + Bring to top Placer au premier-plan - + Send to back Placer en arrière-plan - - + + Auto height Hauteur automatique - - + + Splittable Divisible - - - Keep bottom space - Garder l'espace inférieur - - - - Start from new page - Démarrer depuis une nouvelle page + + Keep bottom space + Conserver l'espace inférieur - - - Start new page - Démarrer une nouvelle page + + + Print if empty + Imprimer si vide LimeReport::BaseDesignIntf - + Copy Copier - + Cut Couper - + Paste Coller - + Bring to top Placer au premier-plan - + Send to back Placer en arrière-plan - + + Create Horizontal Layout + Créer une disposition horizontale + + + + Create Vertical Layout + Créer une disposition verticale + + + No borders Aucune bordure - + All borders Toutes les bordures @@ -405,8 +493,8 @@ p, li { white-space: pre-wrap; } LimeReport::ConnectionDesc - - + + defaultConnection Connexion par défaut @@ -442,7 +530,7 @@ p, li { white-space: pre-wrap; } Port - + @@ -472,7 +560,7 @@ p, li { white-space: pre-wrap; } Dont keep credentals in lrxml - Ne pas enregistrer les informations personnelles + Ne pas enregistrer les informations personnelles dans lrxml @@ -528,6 +616,42 @@ p, li { white-space: pre-wrap; } Data Données + + + + Use alternate background color + Utiliser les Couleurs de fond alternative + + + + + Keep footer together + Joindre avec le pied + + + + + Keep subdetail together + Joindre avec le sous-détail + + + + + Slice last row + Couper la dernière rangée + + + + + Start from new page + Démarrer depuis une nouvelle page + + + + + Start new page + Démarrer une nouvelle page + LimeReport::DataBrowser @@ -563,7 +687,7 @@ p, li { white-space: pre-wrap; } Add new datasource - Ajouter une nouvelle source de données + Ajouter une source de données @@ -611,45 +735,45 @@ p, li { white-space: pre-wrap; } Saisir une variable - - - - + + + + Attention - + Do you really want to delete "%1" connection? - Voulez-vous vraiment supprimer la connexion "%1"? + Voulez-vous vraiment supprimer la connexion %1? - + Report variables Variables du rapport - + System variables Variables système - + External variables Variables externe - + Do you really want to delete "%1" datasource? Vouz-vous vraiment supprimer la source de donnée "%1"? - + Do you really want to delete variable "%1"? Vouz-vous vraiment supprimer la variable "%1"? - + Error Erreur @@ -657,57 +781,81 @@ p, li { white-space: pre-wrap; } LimeReport::DataFooterBand - + DataFooter Pied de données + + + + Print always + Toujours imprimé + LimeReport::DataHeaderBand - + DataHeader En-tête de données + + + + Reprint on each page + Imprimer dans chaque page + + + + + Repeat on each row + Répéter dans chaque ligne + + + + + Print always + Toujours imprimé + LimeReport::DataSourceManager - + Connection "%1" is not open La connexion "%1" n'est pas ouverte - + Variable "%1" not found! Variable "%1" introuvable! - - + + Datasource "%1" not found! Source de donnée "%1" introuvable! - + Connection with name "%1" already exists! La connexion avec le nom "%1" existe déja! - - + + Datasource with name "%1" already exists! La source de donnée avec le nom "%1" existe déja! - + Database "%1" not found Base de données "%1 introuvable - + invalid connection Connexion invalide @@ -715,303 +863,401 @@ p, li { white-space: pre-wrap; } LimeReport::DataSourceModel - + Datasources Source de données - + Variables - + External variables Variables externe + + LimeReport::DialogDesignerManager + + + Edit Widgets + Editeur de Widgets + + + + Widget Box + Widgets + + + + Object Inspector + Explorateur d'objets + + + + Property Editor + Editeur de propriété + + + + Signals && Slots Editor + Editeur de Signaux & Slots + + + + Resource Editor + Editeur de ressource + + + + Action Editor + Editeur d'action + + LimeReport::EnumPropItem Default - + Défaut Portrait - + Landscape - + Paysage NoneAutoWidth - + Aucune largeur automatique MaxWordLength - + Longueur de mot maximale MaxStringLength - + Longueur de chaîne maximale TransparentMode - + Mode transparence OpaqueMode - + Mode opaque Angle0 - + Angle90 - + Angle180 - + Angle270 - + Angle45 - + Angle315 - + DateTime - + Date & Heure Double - + NoBrush - + Aucun motif SolidPattern - + Motif solide Dense1Pattern - + Motif dense 1 Dense2Pattern - + Motif dense 2 Dense3Pattern - + Motif dense 3 Dense4Pattern - + Motif dense 4 Dense5Pattern - + Motif dense 5 Dense6Pattern - + Motif dense 6 Dense7Pattern - + Motif dense 7 HorPattern - + Motif horizontal VerPattern - + Motif vertical CrossPattern - + Motif croisé BDiagPattern - + FDiagPattern - + LeftToRight - + De gauche à droite RightToLeft - + De droite à gauche LayoutDirectionAuto - + Orientation de mise en page auto LeftItemAlign - + Aligner l'élement à gauche RightItemAlign - + Aligner l'élement à droite CenterItemAlign - + Aligner l'élement au centre ParentWidthItemAlign - + Aligner à la largeur du parent DesignedItemAlign - + Alignement par défaut HorizontalLine - + Ligne horizontale VerticalLine - + Ligne verticale Ellipse - + Ellipse Rectangle - + Rectangle Page - + Page Band - + Bande Horizontal - + Horizontal Vertical - + Vertical VerticalUniform - + Uniforme verticale + + + + Pie + Sphère + + + + VerticalBar + Barre verticale + + + + HorizontalBar + Barre horizontale + + + + LegendAlignTop + Aligner la légende en haut + + + + LegendAlignCenter + Aligner la légende au centre + + + + LegendAlignBottom + Aligner la légende en bas + + + + TitleAlignLeft + Aligner le titre à gauche + + + + TitleAlignRight + Aligner le titre à droite + + + + TitleAlignCenter + Aligner le titre au centre + + + + Layout + Disposition + + + + Table + Tableau LimeReport::FlagsPropItem - + NoLine - + Aucune ligne + + + + TopLine + Ligne supérieur - TopLine - Ligne supérieur + BottomLine + Ligne inférieur - BottomLine - Ligne inférieur + LeftLine + Ligne gauche - LeftLine - Ligne gauche + RightLine + Ligne droite - RightLine - Ligne droite + AllLines + Toutes les lignes LimeReport::FontEditorWidget - + Font bold - Caractères en gras + Gras - + Font Italic - Caractères en italique + Italique - + Font Underline - Caractères Soulignées + Souligné @@ -1071,22 +1317,22 @@ p, li { white-space: pre-wrap; } LimeReport::GroupFunction - + Field "%1" not found - Champ "%1 introuvable + Champ %1 introuvable - + Variable "%1" not found - Variable "%1" introuvable + Variable %1 introuvable - + Wrong script syntax "%1" Syntaxe incorrecte du script "%1" - + Item "%1" not found Elément "%1" introuvable @@ -1094,7 +1340,13 @@ p, li { white-space: pre-wrap; } LimeReport::ImageItem - + + + Watermark + Filigrane + + + Image Image @@ -1104,12 +1356,12 @@ p, li { white-space: pre-wrap; } Band - + Bande Page - + Page @@ -1168,32 +1420,32 @@ p, li { white-space: pre-wrap; } LimeReport::ItemsBordersEditorWidget - + Top line - ligne plus haut + ligne haute - + Bottom line - Ligne plus bas + Ligne basse - + Left line Ligne gauche - + Right line Ligne droite - + No borders Aucune bordure - + All borders Toutes les bordures @@ -1201,12 +1453,12 @@ p, li { white-space: pre-wrap; } LimeReport::MasterDetailProxyModel - + Field: "%1" not found in "%2" child datasource Le champ: "%1"est introuvable dans la source de donnée enfant "%2" - + Field: "%1" not found in "%2" master datasource Le champ: "%1"est introuvable dans la source de donnée principale "%2" @@ -1214,7 +1466,7 @@ p, li { white-space: pre-wrap; } LimeReport::ModelToDataSource - + model is destroyed Le modèle a été supprimé @@ -1222,18 +1474,38 @@ p, li { white-space: pre-wrap; } LimeReport::ObjectBrowser - + Objects Objets + + LimeReport::PDFExporter + + + Export to PDF + Exporter au format PDF + + LimeReport::PageFooter - + Page Footer Pied de page + + + + Print on first page + Imprimer dans la première page + + + + + Print on last page + Imprimer dans la dernière page + LimeReport::PageHeader @@ -1246,10 +1518,34 @@ p, li { white-space: pre-wrap; } LimeReport::PageItemDesignIntf - + Paste Coller + + + + Page is TOC + Table de contenus + + + + + Reset page number + Réinitialiser le numéro de page + + + + + Full page + Page entière + + + + + Set page size to printer + Adapterr la taille de la page à l'imprimante + LimeReport::PreviewReportWidget @@ -1259,12 +1555,12 @@ p, li { white-space: pre-wrap; } Formulaire - - PDF file name - Nom du fichier PDF + + %1 file name + %1 nom de fichier - + Report file name Nom du fichier du rapport @@ -1289,7 +1585,7 @@ p, li { white-space: pre-wrap; } toolBar - Barre d'outil + Barre d'outils @@ -1365,7 +1661,7 @@ p, li { white-space: pre-wrap; } Last Page - Dernièr page + Dernière page @@ -1390,30 +1686,30 @@ p, li { white-space: pre-wrap; } Show Toolbar - Afficher la barre d'outil + Afficher la barre d'outils Show toolbar - Afficher la barre d'outil + Afficher la barre d'outils - + Page: - + Font Police - + Text align Alignement de texte - + of %1 de %1 @@ -1421,7 +1717,7 @@ p, li { white-space: pre-wrap; } LimeReport::ProxyHolder - + Datasource has been invalidated La source de donnée n'a pas été validée @@ -1506,7 +1802,7 @@ p, li { white-space: pre-wrap; } borderLineSize - Taille de la lignes de bordure + Taille de la ligne de bordure @@ -1527,7 +1823,7 @@ p, li { white-space: pre-wrap; } columnsFillDirection - Direction de remplissage des colonnes + Orientation de remplissage des colonnes @@ -1567,7 +1863,7 @@ p, li { white-space: pre-wrap; } alignment - Alignement + Alignement @@ -1652,12 +1948,12 @@ p, li { white-space: pre-wrap; } shapeBrush - Brosse de forme + Forme du pinceau shapeBrushColor - Couleur de brosse de forme + Couleur du pinceau @@ -1693,7 +1989,7 @@ p, li { white-space: pre-wrap; } backgroundBrushStyle - Style de brosse de fond + Remplissage de la forme @@ -1708,7 +2004,7 @@ p, li { white-space: pre-wrap; } adaptFontToSize - Adapter la police à lataille + Adapter la police à la taille @@ -1743,7 +2039,7 @@ p, li { white-space: pre-wrap; } textLayoutDirection - Disposition du texte + Orientation du texte @@ -1858,7 +2154,7 @@ p, li { white-space: pre-wrap; } useAlternateBackgroundColor - Utiliser les couleurs de fond alternative + Couleurs de fond alternative @@ -1906,17 +2202,117 @@ p, li { white-space: pre-wrap; } Joindre avec le groupe - + + endlessHeight + Hauteur illimitée + + + + extendedHeight + Hauteur étendue + + + + isExtendedInDesignMode + Mode de style étendu + + + + pageIsTOC + Table des contenus + + + + setPageSizeToPrinter + Adapterr la taille de la page à l'imprimante + + + + fillInSecondPass + Remplir le deuxieme passage + + + + chartTitle + Titre du graphe + + + + chartType + Type de graphe + + + + drawLegendBorder + Dessiner les bordures de la légende + + + + labelsField + Libellé + + + + legendAlign + Alignement de la légende + + + + series + Séries + + + + titleAlign + Alignement du titre + + + + watermark + Filigrane + + + + keepTopSpace + Garder l'espace inférieur + + + + printable + Imprimable + + + + variable + Variable + + + + replaceCRwithBR + Remplacer CR par BR + + + + hideIfEmpty + Masquer si vide + + + + hideEmptyItems + Masquer les éléments vides + + + Property Name - Nom de la propriété + Propriété - + Property value - Valeur de la propriété + Valeur - + Warning Avertissement @@ -1954,22 +2350,27 @@ p, li { white-space: pre-wrap; } LimeReport::ReportDesignWidget - + Script Script - + + Translations + Traductions + + + Report file name Nom du rapport - + Error Erreur - + Wrong file format Format de fichier incorrect @@ -1977,311 +2378,349 @@ p, li { white-space: pre-wrap; } LimeReport::ReportDesignWindow - + New Report Nouveau rapport - + New Report Page Nouvelle page - + Delete Report Page Supprimer une page - + Edit Mode Mode d'édition - + Undo Annuler - + Redo Répéter - + Copy Copier - + Paste Coller - + Cut Couper - + Settings Paramètres - + Use grid Utiliser la grille - + Use magnet Utiliser l'aimant - + Text Item Elément de texte - + Save Report Enregistrer le rapport - + Save Report As Enregistrer le rapport sous - + Load Report Ouvrir un rapport - + Delete item Supprimer élément - + Zoom In Zoom avant - + Zoom Out Zoom arrière - + Render Report Afficher l'aperçu du rapport - + Edit layouts mode Modifier le mode de mise en forme - + Horizontal layout Mise en page horizontale - + + Vertical layout + Disposition verticale + + + About A propos - Hide left panel - Masquer le panneau de gauche - - - Hide right panel - Masquer le panneau de droite - - - + Hide left panel | Alt+L - + Masquer le volet gauche - + Hide right panel | Alt+R - + Masquer le volet droite - + + Delete dialog + Supprimer la boite du dialogue + + + + Add new dialog + Ajouter une boite de dialogue + + + Report Tools Outils de rapport - + Main Tools Outils principales - + Font Police - + Text alignment Alignement de texte - + Items alignment Alignement des éléments - + Borders Bordures - + Report bands Bandesde rapport - + Report Header En-tête du rapport - + Report Footer Pied de rapport - + Page Header En-tête de page - + Page Footer Pied de page - + Data Données - + Data Header En-tête de données - + Data Footer Pied de données - + SubDetail Sous-détails - + SubDetailHeader En-tête de sous-détails - + SubDetailFooter Pied de sous-détails - + GroupHeader En-tête de groupe - + GroupFooter Pied de groupe - + Tear-off Band Bande détachable - + File Fichier - + Edit Edition - + Info - + Recent Files Fichiers récents - + + Object Inspector Inspecteur d'objets - + Report structure Structure du rapport - + + Widget Box + Boite de Widget + + + + Property Editor + Editeur de propriété + + + + Action Editor + Editeur d'action + + + + Resource Editor + Editeur de ressource + + + + SignalSlot Editor + Editeur de Signaux & Slots + + + + Dialog Designer Tools + Boite à outils du Designer + + + Data Browser Navigateur de données - + Script Browser Navigateur de script - + Report has been modified! Do you want save the report? Le rapport a été modifié! Voulez-vous l'enregistrer? - - + + Report file name Nom du fichier du rapport - + Rendering report Afficher l'aperçu du rapport - + Abort Quitter - + page rendered du rendu de la page - + Warning Avertissement - + File "%1" not found! Fichier "%1" introuvable! @@ -2289,22 +2728,27 @@ p, li { white-space: pre-wrap; } LimeReport::ReportEnginePrivate - + Preview Aperçu avant impression - + Error Erreur - + + %1 file name + %1 nom de fichier + + + Report File Change Nom du fichier changé - + The report file "%1" has changed names or been deleted. This preview is no longer valid. @@ -2312,6 +2756,16 @@ This preview is no longer valid. Cet aperçu n'est plus valide. + + + Designer not found! + Designer introuvable! + + + + Language %1 already exists + La langue %1 existe déja + LimeReport::ReportFooter @@ -2332,25 +2786,24 @@ Cet aperçu n'est plus valide. LimeReport::ReportRender - - - - + + + Error Erreur - + page index out of range Indice de la page dépassé - + Databand "%1" not found Bande de données "%1 introuvable - + Wrong using function %1 Utilisation incorrecte de la fonction "%1" @@ -2399,7 +2852,7 @@ Cet aperçu n'est plus valide. - + Preview Aperçu @@ -2470,18 +2923,18 @@ Cet aperçu n'est plus valide. La source de donnée avec le nom "%1" existe déja! - - + + Attention - + Connection is not specified La connexion n'est pas spécifiée - + Refresh Actualiser @@ -2524,177 +2977,265 @@ Cet aperçu n'est plus valide. Nom - + NO CATEGORY AUCUNE CATEGORIE - - - + + + Error Erreur - + Dialog with name: %1 already exists Le dialogue avec le nom "%1" existe déja - + ui file must cointain QDialog instead QWidget or QMainWindow Le fichier ui doit contenir un QDialog au lieu de QWidget ou QMainWindow - + wrong file format Format de fichier incorrect + + LimeReport::ScriptEditor + + + Form + Formulaire + + + + Data + Données + + + + Functions + Fonctions + + LimeReport::ScriptEngineContext - + Dialog with name: %1 can`t be created Le dialogue avec le nom "%1" ne peut pas être crée + + + + Error + Erreur + LimeReport::ScriptEngineManager - + GROUP FUNCTIONS Fonctions de groupe - + + + - - - - - - + + + + Value Valeur - - + + BandName Nom de la bande - + + Function manager with name "%1" already exists! + la fonction avec le nom \"%1\" existe déja + + + + FieldName + Nom du champ + + + Variable %1 not found Variable "%1" introuvable - + + Field %1 not found in %2! + Champ "%1 introuvable dans %2! + + + SYSTEM Système - - - + + + NUMBER Nombre + + + - - - - + Format - + Precision Précision - - + + Locale Local - - - - - - + + + + + + DATE&TIME - DATE&HEURE + Date&Heure - - Seconds - - - - + CurrencySymbol Symbolde de la monnaie - - - + + + + + + + GENERAL - + General - - - + + + Name Nom + + + Datasource + Source de donnée + + + + ValueField + Valeur + + + + KeyField + Clé + + + + KeyFieldValue + Valeur de la clé + + + + Unique identifier + Identifiant unique + + + + Content + Contenu + + + + Indent + Indenter + + + + datasourceName + Nom de source de donnée + LimeReport::SettingDialog - + Designer setting Paramètres du Designer - + Designer Setting Paramètres du Designer - + Default font Police par défaut - + Grid Grille - + Vertical grid step Grille verticale - + Horizontal grid step Grille horizontale - + + Language + Langue + + + + Use dark theme + Utiliser le thème sombre + + + Report Setting Paramètres du rapport - + Suppress absent fields and variables warning Effacer les messages d'absences de champs et d'avertissement de variables @@ -2726,33 +3267,33 @@ Cet aperçu n'est plus valide. LimeReport::TextAlignmentEditorWidget - + Text align left Aligner le texte à gauche - - + + Text align center Aligner le texte au milieu - + Text align right Aligner le texte à droite - + Text align justify Justifier le texte - + Text align top Aligner le texte en haut - + Text align bottom Aligner le texte en bas @@ -2760,48 +3301,66 @@ Cet aperçu n'est plus valide. LimeReport::TextItem - - + + Edit Edition - - + + Auto height Hauteur automatique - - + + Allow HTML Interpréter HTML - - + + Allow HTML in fields Interpréter HTML dans les champs - - + + Stretch to max height Etirer à la hauteur maximale - - + + + Transparent + Transparent + + + + + Watermark + Filigrane + + + + + Hide if empty + Masquer si vide + + + + Error Erreur - + TextItem " %1 " already has folower " %2 " L'élément texte " %1 " a toujours un copain " %2 " - + TextItem " %1 " not found! Elément "%1" introuvable! @@ -2819,58 +3378,107 @@ Cet aperçu n'est plus valide. Contenu - - Data - Données - - - - Functions - Fonctions - - - + Editor settings Paramètres de l'éditeur - + Editor font Police - + ... - + Ok - + Ctrl+Return Ctrl+Arrière - + Cancel Annuler - + Esc Echap + + LimeReport::TranslationEditor + + + Form + Formulaire + + + + Languages + Langues + + + + + ... + + + + + Pages + Pages + + + + Strings + Chaînes de caractère + + + + Source Text + Texte source + + + + Translation + Traduction + + + + Checked + Vérifié + + + + Report Item + Element du rapport + + + + Property + Propriété + + + + Source text + Texte source + + LimeReport::VariablesHolder - + variable with name La variable avec le nom @@ -2882,7 +3490,7 @@ Cet aperçu n'est plus valide. - + does not exists! n'existe pas! @@ -2892,45 +3500,45 @@ Cet aperçu n'est plus valide. - + Data Données - + DataHeader En-tête de données - + DataFooter Pied de données - + GroupHeader En-tête de groupe - + GroupFooter Pied de groupe - + - + Page Footer Pied de page - + Page Header En-tête de page @@ -2949,67 +3557,67 @@ Cet aperçu n'est plus valide. - + SubDetail Sous-détails - + SubDetailHeader En-tête de sous-détails - + SubDetailFooter Pied de sous-détails - + Tear-off Band Bande détachable - + alignment - Alignement + Alignement - + Barcode Item Elément de code barre - + HLayout - - + + Image Item - + Shape Item - + itemLocation - - + + Text Item @@ -3020,170 +3628,210 @@ Cet aperçu n'est plus valide. Connexion invalidé %1 - + Master datasource "%1" not found! Source de donnée principale "%1" introuvable! - + Master datasouce "%1" not found! Source de donnée principale "%1" introuvable! - + Child Enfant - + and child est enfant - + datasouce "%1" not found! Source de donnée "%1" introuvable! - + bool - - + + QColor - + content Contenu - - + + + datasource Source de donnée - - + + field Champ - + enum - - + + flags - + QFont - + QImage - + int - - + + qreal - + QRect - + QRectF - + geometry - + QString - + + Attention! - + + Selected elements have different parent containers Les éléments sélectionnés ont un parent différent - + Object with name %1 already exists! L'objet avec le nom "%1" existe déja! - + Function %1 not found or have wrong arguments La fonction %1 est introuvable ou contient des paramètres incorrects + + + Datasource manager not found + Gestionnaire de source de donnée introuvable + mm - + Wrong file format Format de fichier incorrect - + File %1 not opened Fichier "%1" n'est pas ouvert - + Content string is empty Contenu vide - + Content is empty Contenu vide + + + + Chart Item + Elément du graphe + + + + First + Prémier + + + + Second + Second + + + + Thrid + Troisième + + + + VLayout + + + + + + Export to PDF + Exporter au format PDF + diff --git a/translations/limereport_ru.qm b/translations/limereport_ru.qm index 57a32c9..12ec753 100644 Binary files a/translations/limereport_ru.qm and b/translations/limereport_ru.qm differ diff --git a/translations/limereport_ru.ts b/translations/limereport_ru.ts index ef748e7..4329fe8 100644 --- a/translations/limereport_ru.ts +++ b/translations/limereport_ru.ts @@ -1,6 +1,60 @@ + + $ClassName$ + + $ClassName$ + $ClassName$ + + + + ChartItemEditor + + Series editor + Редактор рядов данных + + + Series + Ряд + + + Add + Добавить + + + Delete + Удалить + + + Name + Имя + + + Values field + Поле значений + + + Color + Цвет + + + Type + Тип + + + Labels field + Поле меток + + + Ok + Ок + + + Series name + Название ряда + + LRVariableDialog @@ -9,7 +63,7 @@ Name - Имя переменной + Имя Value @@ -23,6 +77,21 @@ Attention Внимание + + Mandatory + Обязательная + + + + LanguageSelectDialog + + Dialog + Диалог + + + Language + Язык + LimeReport::AboutDialog @@ -226,11 +295,11 @@ p, li { white-space: pre-wrap; } horizontal - горизонтально + Горизонтально vertical - вертикально + Вертикально @@ -293,7 +362,7 @@ p, li { white-space: pre-wrap; } TearOffBand - Полоса для отрывания + Полоса отрыва SubDetailBand @@ -309,11 +378,19 @@ p, li { white-space: pre-wrap; } Keep bottom space - Сохранять нижний отступ + Сохранять отступ снизу Print if empty - Печатать если пустой + Печатать, если пустое + + + Cut + Вырезать + + + Copy + Копировать @@ -346,6 +423,18 @@ p, li { white-space: pre-wrap; } All borders Внешние границы + + Create Horizontal Layout + Создать Горизонтальную Компановку + + + Create Vertical Layout + Создать Вертикальную Компановку + + + Lock item geometry + Блокировать изменения геометрии + LimeReport::ConnectionDesc @@ -366,7 +455,7 @@ p, li { white-space: pre-wrap; } Connection Name - Название + Наименование Соединения Driver @@ -410,7 +499,7 @@ p, li { white-space: pre-wrap; } Connection Name is empty - Наименование соединения не указано + Наименование Соединения не указано Connection with name @@ -426,7 +515,7 @@ p, li { white-space: pre-wrap; } Dont keep credentals in lrxml - Не хранить логин с паролем в lrxml + Не хранить учетные данные в lrxml defaultConnection @@ -448,16 +537,16 @@ p, li { white-space: pre-wrap; } Данные - Keep footer together - Привязать колонтитул к данными + Use alternate background color + Использовать альтернативный цвет фона Keep subdetail together Привязать подчиненные данные - Slice last row - Разрезать последнюю запись + Keep footer together + Привязать завершение данных Start from new page @@ -465,7 +554,11 @@ p, li { white-space: pre-wrap; } Start new page - Начинать новую станицу + Начинать новую страницу + + + Slice last row + Разрезать последнюю запись @@ -480,7 +573,7 @@ p, li { white-space: pre-wrap; } Add new datasource - Добавить новый источник данных + Добавить источник данных View data @@ -504,7 +597,7 @@ p, li { white-space: pre-wrap; } Add new variable - Добавить новую переменную + Добавить переменную Edit variable @@ -528,7 +621,7 @@ p, li { white-space: pre-wrap; } ... - + ... Grab variable @@ -544,7 +637,7 @@ p, li { white-space: pre-wrap; } Do you really want to delete "%1" connection? - Вы действительно хотите удалить "%1" соединение? + Вы действительно хотите удалить соединение "%1"? Do you really want to delete "%1" datasource? @@ -559,7 +652,7 @@ p, li { white-space: pre-wrap; } LimeReport::DataFooterBand DataFooter - Подвал данных + Завершение данных Print always @@ -574,7 +667,7 @@ p, li { white-space: pre-wrap; } Reprint on each page - Печать на каждой странице + Печатать на каждой странице Repeat on each row @@ -613,7 +706,11 @@ p, li { white-space: pre-wrap; } Datasource with name "%1" already exists! - Источник данных с именем: "%1" уже существует! + Источник данных "%1" уже существует! + + + Unknown parameter "%1" for variable "%2" found! + Обнаружен неизвестный параметр "%1" для переменной "%2"! @@ -631,6 +728,37 @@ p, li { white-space: pre-wrap; } Внешние переменные + + LimeReport::DialogDesignerManager + + Edit Widgets + Панель Инструментов + + + Widget Box + Панель Виджетов + + + Object Inspector + Инспектор Объектов + + + Property Editor + Редактор Свойств + + + Signals && Slots Editor + Редактор Сигналов и Свойств + + + Resource Editor + Обозреватель Ресурсов + + + Action Editor + Редактор Действий + + LimeReport::EnumPropItem @@ -645,6 +773,14 @@ p, li { white-space: pre-wrap; } Landscape Альбомная + + Layout + Компоновка + + + Table + Таблица + NoneAutoWidth Нет @@ -663,7 +799,7 @@ p, li { white-space: pre-wrap; } OpaqueMode - Заливка + Непрозрачный Angle0 @@ -699,71 +835,71 @@ p, li { white-space: pre-wrap; } NoBrush - Нет заливки + Нет заполнения SolidPattern - Сплошная заливка + Сплошное заполнение Dense1Pattern - + Плотное заполнение 1 Dense2Pattern - + Плотное заполнение 2 Dense3Pattern - + Плотное заполнение 3 Dense4Pattern - + Плотное заполнение 4 Dense5Pattern - + Плотное заполнение 5 Dense6Pattern - + Плотное заполнение 6 Dense7Pattern - + Плотное заполнение 7 HorPattern - + Горизонтальное заполнение VerPattern - + Вертикальное заполнение CrossPattern - + Перекрестное заполнение BDiagPattern - + Обратное диагональное заполнение FDiagPattern - + Прямое диагональное заполнение LeftToRight - Слева на право + Слева направо RightToLeft - С права на лево + Справа налево LayoutDirectionAuto - Авто + Автоматически LeftItemAlign @@ -795,7 +931,7 @@ p, li { white-space: pre-wrap; } Ellipse - Элипс + Эллипс Rectangle @@ -821,9 +957,65 @@ p, li { white-space: pre-wrap; } VerticalUniform Вертикально равномерно + + Pie + Круговая + + + VerticalBar + Вертикальная панель + + + HorizontalBar + Горизонтальная панель + + + LegendAlignTop + Легенда сверху + + + LegendAlignCenter + Легенда по центру + + + LegendAlignBottom + Легенда снизу + + + TitleAlignLeft + Название слева + + + TitleAlignRight + Название справа + + + TitleAlignCenter + Название по центру + + + Millimeters + Миллиметры + + + Inches + Дюймы + + + Scale + Масштабировать + + + Split + Разделять на части + LimeReport::FlagsPropItem + + AllLines + Все границы + NoLine Нет границ @@ -887,7 +1079,7 @@ p, li { white-space: pre-wrap; } LimeReport::GroupBandFooter GroupFooter - Подвал группы + Завершение группы @@ -921,15 +1113,23 @@ p, li { white-space: pre-wrap; } Wrong script syntax "%1" - Неправильный синтаксис скрипта "%1" + Неверный синтаксис скрипта "%1" LimeReport::ImageItem + + Ext. + Внешний + Image Изображение + + Watermark + Водный знак + LimeReport::ItemLocationPropItem @@ -1005,7 +1205,7 @@ p, li { white-space: pre-wrap; } No borders - Удалить границы + Нет границ All borders @@ -1016,11 +1216,11 @@ p, li { white-space: pre-wrap; } LimeReport::MasterDetailProxyModel Field: "%1" not found in "%2" child datasource - Поле: "%1" не найдено в подчиненном источнике данных "%2" + Поле "%1" не найдено в подчиненном источнике данных "%2" Field: "%1" not found in "%2" master datasource - Поле: "%1" не найдено в главном источнике данных "%2" + Поле "%1" не найдено в главном источнике данных "%2" @@ -1037,12 +1237,42 @@ p, li { white-space: pre-wrap; } Объекты + + LimeReport::ObjectInspectorWidget + + Clear + Очистить + + + Filter + Фильтр + + + Translate properties + Переводить имена свойств + + + + LimeReport::PDFExporter + + Export to PDF + Экспортировать в PDF + + LimeReport::PageFooter Page Footer Нижний колонтитул + + Print on first page + Печатать на первой странице + + + Print on last page + Печатать на последней странице + LimeReport::PageHeader @@ -1057,6 +1287,22 @@ p, li { white-space: pre-wrap; } Paste Вставить + + Page is TOC + Содержание отчета + + + Reset page number + Сбросить номер страницы + + + Full page + На всю страницу + + + Set page size to printer + Отправить параметры страницы в принтер + LimeReport::PreviewReportWidget @@ -1064,14 +1310,14 @@ p, li { white-space: pre-wrap; } Form Форма - - PDF file name - Имя PDF файла - Report file name Имя файла отчета + + %1 file name + %1 имя файла + LimeReport::PreviewReportWindow @@ -1127,10 +1373,6 @@ p, li { white-space: pre-wrap; } First Page Первая страница - - First page - Первая страница - Last Page Последняя страница @@ -1153,7 +1395,7 @@ p, li { white-space: pre-wrap; } Ctrl+P - + Ctrl+P Fit page width @@ -1175,10 +1417,6 @@ p, li { white-space: pre-wrap; } Show Toolbar Показать панель инструментов - - Show toolbar - Показать панель иструментов - Font Шрифт @@ -1187,12 +1425,44 @@ p, li { white-space: pre-wrap; } Text align Выравнивание текста + + First page + Первая страница + + + Show toolbar + Показать панель инструментов + + + toolBar_2 + Редактирование + + + InsertTextItem + Вставить текстовый элемент + + + Add new TextItem + Текстовый элемент + + + Selection Mode + Режим выбора + + + Delete Item + Удалить элемент + + + Del + Удалить + LimeReport::ProxyHolder Datasource has been invalidated - Источник данных находится в недействительном состоянии + Источник данных недействителен @@ -1201,10 +1471,6 @@ p, li { white-space: pre-wrap; } Property Name Свойство - - Property value - Значение - fullPage Страница целиком @@ -1489,6 +1755,10 @@ p, li { white-space: pre-wrap; } shapeBrushColor Цвет кисти + + replaceCRwithBR + Заменять CR на BR + allowHTML Разрешить HTML @@ -1519,7 +1789,7 @@ p, li { white-space: pre-wrap; } columnCount - Количество колонок + Количество столбцов securityLevel @@ -1543,7 +1813,7 @@ p, li { white-space: pre-wrap; } layoutType - Тип группировки + Тип компановки barcodeType @@ -1551,7 +1821,7 @@ p, li { white-space: pre-wrap; } barcodeWidth - + Ширина штрихкода foregroundColor @@ -1559,11 +1829,11 @@ p, li { white-space: pre-wrap; } inputMode - + Режим ввода pdf417CodeWords - + Слов pdf417 useAlternateBackgroundColor @@ -1587,26 +1857,123 @@ p, li { white-space: pre-wrap; } repeatOnEachRow - Печатать на каждой странице + Повторять на каждой строке + + + Property value + Значение + + + endlessHeight + Бесконечная высота + + + extendedHeight + Увеличенная высота + + + isExtendedInDesignMode + Увеличить в режиме редактирования + + + pageIsTOC + Содержание отчета + + + setPageSizeToPrinter + Отправить параметры страницы в принтер + + + fillInSecondPass + Заполнять вторым проходом + + + chartTitle + Заголовок диаграммы + + + chartType + Тип диаграммы + + + drawLegendBorder + Отображать границы Легенды + + + labelsField + Поле меток + + + legendAlign + Расположение легенды + + + series + Ряд данных + + + titleAlign + Расположение Названия watermark Водяной знак - replaceCRwithBR - Заменять CR на BR - - - - LimeReport::RectMMPropItem - - width - ширина + keepTopSpace + Сохранять отступ сверху - height - высота + printable + Печатать + + + hideIfEmpty + Скрывать, если пустое + + + variable + Переменная + + + hideEmptyItems + Скрывать пустые элементы + + + useExternalPainter + Использовать внешний отрисовщик + + + layoutSpacing + Интервал + + + printerName + Имя принтера + + + fontLetterSpacing + Межсимвольный интервал + + + hideText + Скрывать текст + + + option3 + + + + units + Единицы измерения + + + geometryLocked + Геометрия заблокирована + + + printBehavior + Режим печати @@ -1620,11 +1987,22 @@ p, li { white-space: pre-wrap; } высота + + LimeReport::RectUnitPropItem + + width + ширина + + + height + высота + + LimeReport::ReportDesignWidget Report file name - Файл отчета + Имя файла отчета Script @@ -1636,7 +2014,11 @@ p, li { white-space: pre-wrap; } Wrong file format - Неправильный формат файла + Неверный формат файла + + + Translations + Переводы @@ -1719,11 +2101,15 @@ p, li { white-space: pre-wrap; } Edit layouts mode - Режим редактирования группировок + Режим редактирования компоновок Horizontal layout - Горизонтальная группировка + Горизонтальная компоновка + + + Vertical layout + Вертикальная компоновка About @@ -1807,7 +2193,7 @@ p, li { white-space: pre-wrap; } Tear-off Band - Полоса для отрывания + Полоса отрыва File @@ -1871,15 +2257,59 @@ p, li { white-space: pre-wrap; } Report has been modified! Do you want save the report? - Отчет был изменен! Хотите его сохранить? + Отчет был изменен! Сохранить изменения? Hide left panel | Alt+L - Скрыть левую панель | Alt+L + Спрятать левую панель | Alt+L Hide right panel | Alt+R - Скрыть правую панель | Alt+R + Спрятать правую панель | Alt+R + + + Delete dialog + Удалить диалог + + + Add new dialog + Добавить диалог + + + Widget Box + Панель Виджетов + + + Property Editor + Редактор Свойств + + + Action Editor + Редактор Действий + + + Resource Editor + Обозреватель Ресурсов + + + SignalSlot Editor + Редактор Сигналов и Слотов + + + Dialog Designer Tools + Панель Инструментов + + + Lock selected items + Заблокировать выбранные элементы + + + Unlock selected items + Разблокировать выбранные элементы + + + Select one level items + Выбрать все элементы одного уровня @@ -1902,6 +2332,18 @@ p, li { white-space: pre-wrap; } This preview is no longer valid. Файл отчета "%1" изменил имя или был удален. + + Designer not found! + Дизайнер не найден! + + + Language %1 already exists + Язык %1 уже существует + + + %1 file name + %1 имя файла + LimeReport::ReportFooter @@ -1925,11 +2367,11 @@ This preview is no longer valid. Databand "%1" not found - Банд "%1" не найден + Раздел "%1" не найден Wrong using function %1 - Не правильное использование функции %1 + Неверное использование функции %1 page index out of range @@ -1994,10 +2436,6 @@ This preview is no longer valid. Error Ошибка - - Datasource with name %1 already exist - Источник данных с именем: "%1" уже существует - Attention Внимание @@ -2016,7 +2454,7 @@ This preview is no longer valid. ... - + ... Ok @@ -2028,7 +2466,7 @@ This preview is no longer valid. Datasource Name is empty! - Имя источника данных не заполнено! + Имя источника данных не указано! SQL is empty! @@ -2036,7 +2474,27 @@ This preview is no longer valid. Datasource with name: "%1" already exists! - Источник данных с именем: "%1" уже существует! + Источник данных %1 уже существует! + + + Datasource with name %1 already exist + Источник данных %1 уже существует + + + CSV + + + + Separator + Разделитель + + + ; + ; + + + Use first row as header + Первая строка как заголовок @@ -2063,7 +2521,7 @@ This preview is no longer valid. Name - Имя переменной + Имя NO CATEGORY @@ -2073,31 +2531,50 @@ This preview is no longer valid. Error Ошибка - - Dialog with name: %1 already exists - Диалог с именем %1 уже существует - ui file must cointain QDialog instead QWidget or QMainWindow - ui файл должен содержать QDialog вместо QWidget или QMainWindow + файл ui должен содержать QDialog вместо QWidget или QMainWindow wrong file format - неправильный формат файла + неверный формат файла + + + Dialog with name: %1 already exists + Диалог %1 уже существует + + + + LimeReport::ScriptEditor + + Form + Форма + + + Data + Данные + + + Functions + Функции LimeReport::ScriptEngineContext Dialog with name: %1 can`t be created - Диалог с именем: %1 не может быть создан + Диалог %1 не может быть создан + + + Error + Ошибка LimeReport::ScriptEngineManager BandName - Имя банда + Имя раздела Value @@ -2125,7 +2602,7 @@ This preview is no longer valid. Name - Имя переменной + Имя GROUP FUNCTIONS @@ -2148,8 +2625,52 @@ This preview is no longer valid. ОБЩИЕ - Seconds - Секунды + Function manager with name "%1" already exists! + Менеджер функций с именем %1 уже существует! + + + FieldName + Имя поля + + + Field %1 not found in %2! + Поле %1 не найдено в %2! + + + Datasource + Источник данных + + + ValueField + Поле Значения + + + KeyField + Ключевое Поле + + + KeyFieldValue + Значение Ключевого Поля + + + Unique identifier + Уникальный идентификатор + + + Content + Содержимое + + + Indent + Отступ + + + datasourceName + Имя источника данных + + + RowIndex + Индекс строки @@ -2175,16 +2696,40 @@ This preview is no longer valid. Горизонтальный шаг сетки - Designer Setting + Suppress absent fields and variables warning + Не выводить сообщения об отсутствии полей или переменных + + + Language + Язык + + + Designer settings Настройки дизайнера - Report Setting + Script editor settings + Настройки редактора скриптов + + + Font + Шрифт + + + Indent size + Отступ + + + Report settings Настройки отчета - Suppress absent fields and variables warning - Не выводить сообщения об отсутствия полей или переменных + Theme + Тема + + + Report units + Единицы измерения @@ -2205,7 +2750,7 @@ This preview is no longer valid. LimeReport::TearOffBand Tear-off Band - Полоса для отрывания + Полоса отрыва @@ -2263,11 +2808,23 @@ This preview is no longer valid. TextItem " %1 " already has folower " %2 " - Текстовый элемент "%1" уже следует за "%2" + Текстовый элемент %1 уже следует за %2 TextItem " %1 " not found! - Текстовый элемент "%1" не найден! + Текстовый элемент %1 не найден! + + + Transparent + Прозрачный + + + Watermark + Водный знак + + + Hide if empty + Скрывать, если пустое @@ -2280,30 +2837,10 @@ This preview is no longer valid. Content Содержимое - - Functions - Функции - - - Editor settings - Настройки - - - Editor font - Шрифт редактора - Cancel Отмена - - Data - Данные - - - ... - - Ok Ок @@ -2317,6 +2854,53 @@ This preview is no longer valid. + + LimeReport::TranslationEditor + + Form + Форма + + + Languages + Языки + + + ... + ... + + + Pages + Страницы + + + Strings + Строки + + + Source Text + Исходный текст + + + Translation + Перевод + + + Checked + Проверенный + + + Report Item + Элемент Отчета + + + Property + Свойство + + + Source text + Исходный текст + + LimeReport::VariablesHolder @@ -2388,12 +2972,16 @@ This preview is no longer valid. Barcode Item - Элемент штрих код + Штрих код HLayout Горизонтальная компоновка + + VLayout + Вертикальная компоновка + Image Item Элемент изображение @@ -2424,7 +3012,7 @@ This preview is no longer valid. datasouce "%1" not found! - источник данных "%1" не найден! + источник данных %1 не найден! Attention! @@ -2472,11 +3060,11 @@ This preview is no longer valid. Master datasouce "%1" not found! - Главный источник данных "%1" не найден! + Главный источник данных %1 не найден! bool - + Логическое QColor @@ -2492,11 +3080,11 @@ This preview is no longer valid. int - + Целое qreal - + Дробь QRect @@ -2520,19 +3108,71 @@ This preview is no longer valid. Tear-off Band - Полоса для отрывания + Полоса отрыва Wrong file format - Неправильный формат файла + Неверный формат файла Master datasource "%1" not found! - Главный источник данных "%1" не найден! + Главный источник данных %1 не найден! Object with name %1 already exists! - Объект с именем %1 уже существует! + Объект %1 уже существует! + + + Chart Item + Диаграмма + + + First + Первый + + + Second + Второй + + + Thrid + Третий + + + Datasource manager not found + Менеджер источников данных не найден + + + Export to PDF + Экспортировать в PDF + + + Default + По умолчанию + + + margin + Поля + + + '' + + + + Millimeters + Миллиметры + + + Inches + Дюймы + + + Dark + Темная + + + Light + Светлая diff --git a/translations/limereport_zh.ts b/translations/limereport_zh.ts index e75cc4f..52bb301 100644 --- a/translations/limereport_zh.ts +++ b/translations/limereport_zh.ts @@ -1,6 +1,60 @@ + + $ClassName$ + + $ClassName$ + $ClassName$ + + + + ChartItemEditor + + Series editor + 数据系列编辑器 + + + Series + 数据系列 + + + Add + 增加 + + + Delete + 删除 + + + Name + 名称 + + + Values field + 取值字段 + + + Color + 颜色 + + + Type + 类型 + + + Labels field + 标签字段 + + + Ok + 确定 + + + Series name + 系列名称 + + LRVariableDialog @@ -23,6 +77,21 @@ Attention 注意 + + Mandatory + 必要 + + + + LanguageSelectDialog + + Dialog + 对话框 + + + Language + 语言 + LimeReport::AboutDialog @@ -296,7 +365,7 @@ p, li { white-space: pre-wrap; } connected to - 连接到 + 连接到 Bring to top @@ -320,23 +389,15 @@ p, li { white-space: pre-wrap; } Start from new page - 从新页开始 + 从新页开始 Start new page - 开始新页 + 开始新页 - Cut - 剪切 - - - Copy - 复制 - - - Print if empty - 为空时打印 + Keep top space + 保持顶部距离 @@ -369,6 +430,10 @@ p, li { white-space: pre-wrap; } All borders 所有边框 + + Create Horizontal Layout + 创建水平布局 + LimeReport::ConnectionDesc @@ -397,7 +462,7 @@ p, li { white-space: pre-wrap; } Server - 服务器 + 服务器 Port @@ -453,11 +518,11 @@ p, li { white-space: pre-wrap; } Connection with name - 连接 + 连接 already exists! - 已经存在! + 已经存在! defaultConnection @@ -471,24 +536,8 @@ p, li { white-space: pre-wrap; } 数据带 - Keep footer together - 保持页脚 - - - Keep subdetail together - 保持子细节脚 - - - Slice last row - 分割末行 - - - Start from new page - 从新页开始 - - - Start new page - 开始新页 + Use alternate background color + 使用交替背景色 @@ -584,10 +633,6 @@ p, li { white-space: pre-wrap; } DataFooter 数据带脚 - - Print always - 始终打印 - LimeReport::DataHeaderBand @@ -595,18 +640,6 @@ p, li { white-space: pre-wrap; } DataHeader 数据带头 - - Reprint on each page - 重新打印每页 - - - Repeat on each row - 每行重复 - - - Print always - 始终打印 - LimeReport::DataSourceManager @@ -654,6 +687,37 @@ p, li { white-space: pre-wrap; } 外部变量 + + LimeReport::DialogDesignerManager + + Edit Widgets + 编辑组件 + + + Widget Box + 组件盒 + + + Object Inspector + 对象观察器 + + + Property Editor + 属性编辑器 + + + Signals && Slots Editor + 信号槽编辑器 + + + Resource Editor + 资源编辑器 + + + Action Editor + 动作编辑器 + + LimeReport::EnumPropItem @@ -844,6 +908,42 @@ p, li { white-space: pre-wrap; } VerticalUniform 均匀垂直 + + Pie + 饼状图 + + + VerticalBar + 柱状图 + + + HorizontalBar + 条形图 + + + LegendAlignTop + 图例靠上对齐 + + + LegendAlignCenter + 图例居中 + + + LegendAlignBottom + 图例靠下对齐 + + + TitleAlignLeft + 标题左对齐 + + + TitleAlignRight + 标题右对齐 + + + TitleAlignCenter + 标题居中 + LimeReport::FlagsPropItem @@ -867,6 +967,10 @@ p, li { white-space: pre-wrap; } RightLine 右边框 + + AllLines + + LimeReport::FontEditorWidget @@ -940,7 +1044,7 @@ p, li { white-space: pre-wrap; } Wrong script syntax "%1" - 脚本语法错误 "%1" + 脚本语法错误 "%1" Item "%1" not found @@ -953,6 +1057,10 @@ p, li { white-space: pre-wrap; } Image 图像 + + Watermark + 水印 + LimeReport::ItemLocationPropItem @@ -1066,6 +1174,14 @@ p, li { white-space: pre-wrap; } Page Footer 页脚 + + Print on first page + 首页时打印 + + + Print on last page + 末页时打印 + LimeReport::PageHeader @@ -1080,6 +1196,22 @@ p, li { white-space: pre-wrap; } Paste 粘贴 + + Page is TOC + 目录页面 + + + Reset page number + 重置页数 + + + Full page + 全页 + + + Set page size to printer + 适合打印机纸张大小 + LimeReport::PreviewReportWidget @@ -1196,7 +1328,7 @@ p, li { white-space: pre-wrap; } Page: - 页数: + 页数: Font @@ -1612,13 +1744,73 @@ p, li { white-space: pre-wrap; } Warning 警告 + + endlessHeight + 无限高度 + + + extendedHeight + 扩展高度 + + + isExtendedInDesignMode + 设计模式扩展 + + + pageIsTOC + 目录页面 + + + setPageSizeToPrinter + 适合打印机纸张 + + + fillInSecondPass + 二次填充 + + + chartTitle + 图表标题 + + + chartType + 图表类型 + + + drawLegendBorder + 显示图例边框 + + + labelsField + 标签字段 + + + legendAlign + 图例对齐 + + + series + 数据系列 + + + titleAlign + 标题对齐 + watermark 水印 - replaceCRwithBR - BR替换回车 + keepTopSpace + 保持顶部距离 + + + printable + + + + variable + @@ -1661,6 +1853,10 @@ p, li { white-space: pre-wrap; } Wrong file format 文件格式错误 + + Translations + 翻译 + LimeReport::ReportDesignWindow @@ -1894,7 +2090,7 @@ p, li { white-space: pre-wrap; } page rendered - 报表生成 + 报表生成 Warning @@ -1904,6 +2100,38 @@ p, li { white-space: pre-wrap; } File "%1" not found! 未找到文件 "%1"! + + Delete dialog + 删除对话框 + + + Add new dialog + 新增对话框 + + + Widget Box + 组件盒 + + + Property Editor + 属性编辑器 + + + Action Editor + 动作编辑器 + + + Resource Editor + 资源编辑器 + + + SignalSlot Editor + 信号槽编辑器 + + + Dialog Designer Tools + 对话框设计工具 + LimeReport::ReportEnginePrivate @@ -1927,6 +2155,14 @@ This preview is no longer valid. 预览已无效。 + + Designer not found! + 设计器未找到! + + + Language %1 already exists + 语言 %1 已存在 + LimeReport::ReportFooter @@ -2111,12 +2347,31 @@ This preview is no longer valid. 文件格式错误 + + LimeReport::ScriptEditor + + Form + 表格 + + + Data + 数据 + + + Functions + 函数 + + LimeReport::ScriptEngineContext Dialog with name: %1 can`t be created 无法创建对话框 %1 + + Error + 错误 + LimeReport::ScriptEngineManager @@ -2160,10 +2415,6 @@ This preview is no longer valid. DATE&TIME 日期时间 - - Seconds - - CurrencySymbol 货币符号 @@ -2176,6 +2427,50 @@ This preview is no longer valid. Name 名称 + + Function manager with name "%1" already exists! + 函数管理器 %1 已存在! + + + FieldName + 字段名 + + + Field %1 not found in %2! + 在 %2 中找不到字段 %1 ! + + + Datasource + 数据源 + + + ValueField + 值字段 + + + KeyField + 键名字段 + + + KeyFieldValue + 键字段值 + + + Unique identifier + 唯一标识符 + + + Content + 内容内容 + + + Indent + 缩进 + + + datasourceName + 数据源名称 + LimeReport::SettingDialog @@ -2211,6 +2506,14 @@ This preview is no longer valid. Suppress absent fields and variables warning 抑制缺失字段及变量警告 + + Language + 语言 + + + Use dark theme + 使用暗色主题 + LimeReport::SubDetailBand @@ -2294,6 +2597,14 @@ This preview is no longer valid. TextItem " %1 " not found! 未找到文本框 "%1"! + + Transparent + 透明 + + + Watermark + 水印 + LimeReport::TextItemEditor @@ -2305,14 +2616,6 @@ This preview is no longer valid. Content 内容 - - Data - 数据 - - - Functions - 函数 - Editor settings 编辑器设置 @@ -2342,19 +2645,66 @@ This preview is no longer valid. + + LimeReport::TranslationEditor + + Form + 表格 + + + Languages + 语言 + + + ... + ... + + + Pages + + + + Strings + 字符串 + + + Source Text + 源文 + + + Translation + 译文 + + + Checked + 选中 + + + Report Item + 报表组件 + + + Property + 属性 + + + Source text + 源文 + + LimeReport::VariablesHolder variable with name - 变量 + 变量 already exists! - 已存在! + 已存在! does not exists! - 不存在! + 不存在! @@ -2457,7 +2807,7 @@ This preview is no longer valid. and child - 子数据源 + 子数据源 datasouce "%1" not found! @@ -2465,11 +2815,11 @@ This preview is no longer valid. bool - bool + QColor - QColor + content @@ -2485,35 +2835,35 @@ This preview is no longer valid. enum - enum + flags - flags + QFont - QFont + QImage - QImage + int - int + qreal - qreal + QRect - QRect + QRectF - QRectF + geometry @@ -2521,7 +2871,7 @@ This preview is no longer valid. QString - QString + Attention! @@ -2559,5 +2909,25 @@ This preview is no longer valid. Content is empty 字符串为空 + + Chart Item + 图表组件 + + + First + 第一 + + + Second + 第二 + + + Thrid + 第三 + + + Datasource manager not found + 数据源管理器未找到 +