Commit 91c3f3bc authored by jean-pierre charras's avatar jean-pierre charras

All: use a S expression to describe the page layout (title block and grid...

All: use a S expression to describe the page layout (title block and grid references). Work in progress.
This should  allow users to define their own page layout.
parent 3bddb98d
...@@ -3,9 +3,11 @@ downloads-by-cmake ...@@ -3,9 +3,11 @@ downloads-by-cmake
common/netlist_keywords.* common/netlist_keywords.*
common/netlist_lexer.h common/netlist_lexer.h
common/pcb_plot_params_lexer.h common/pcb_plot_params_lexer.h
common/page_layout_reader_keywords.cpp
common/fp_lib_table_keywords.* common/fp_lib_table_keywords.*
include/fp_lib_table_lexer.h include/fp_lib_table_lexer.h
include/netlist_lexer.h include/netlist_lexer.h
include/page_layout_reader_lexer.h
eeschema/cmp_library_lexer.h eeschema/cmp_library_lexer.h
eeschema/cmp_library_keywords.* eeschema/cmp_library_keywords.*
eeschema/template_fieldnames_keywords.* eeschema/template_fieldnames_keywords.*
......
...@@ -28,16 +28,22 @@ development libaries. ...@@ -28,16 +28,22 @@ development libaries.
After a fresh install you need the following packages to compile and run After a fresh install you need the following packages to compile and run
KiCad from source. KiCad from source.
CMake - Cross-platform make * bzr - Bazaar version control system
GLUT - The OpenGL Utility Library * CMake - Cross-platform make
wxGTK or wxWidgets - The wxWidgets GUI toolkit with GTK+ bindings * GLUT - The OpenGL Utility Library
* wxGTK or wxWidgets - The wxWidgets GUI toolkit with GTK+ bindings
Boost - Collection of portable C++ source libraries * Boost - Collection of portable C++ source libraries
Because boost is in the repository of kicad you don't need to install them. boost will be automagically downloaded and copied in kicad sources tree,
the first time you compile kicad.
Useful, but not required: Useful, but not required:
Doxygen - Documentation system for several programming languages * Doxygen - Documentation system for several programming languages
KiCad uses the Bazaar version control system to track source code changes,
and download the boost libraries needed by Kicad.
Be sure you bzr install also includes bzrtools.
boost libraries will be downloaded the first time you build Kicad.
Compiler and basic development tools Compiler and basic development tools
------------- -------------
......
Bazaar
------
KiCad uses the Bazaar version control system to track source code changes,
and download the boost libraries needed by Kicad.
The easiest way to get a copy of the KiCad source is to use Bazaar.
Bazaar can be download from http://wiki.bazaar.canonical.com.
Your best bet is to use the stand alone version of Bazaar
(which includes bzrtools, needed by Kicad) rather than one of
the Python specific versions.
Be sure bzrtools is also installed.
boost libraries will be downloaded the first time you build Kicad.
CMake
-----
KiCad uses CMake to generate the build files specific for the target platform KiCad uses CMake to generate the build files specific for the target platform
specified by the developer. This document attempts to define some of the more specified by the developer. This document attempts to define some of the more
common CMake and KiCad build configuration settings. You can use CMake either common CMake and KiCad build configuration settings. You can use CMake either
......
...@@ -26,10 +26,12 @@ languages. Only C is installed by default and C++ is required to build KiCad. ...@@ -26,10 +26,12 @@ languages. Only C is installed by default and C++ is required to build KiCad.
Bazaar Bazaar
------ ------
KiCad uses the Bazaar version control system to track source code changes. KiCad uses the Bazaar version control system to track source code changes,
and download the boost libraries needed by Kicad.
The easiest way to get a copy of the KiCad source is to use Bazaar. Bazaar The easiest way to get a copy of the KiCad source is to use Bazaar. Bazaar
can be download from http://http://wiki.bazaar.canonical.com/WindowsDownloads. can be download from http://wiki.bazaar.canonical.com/WindowsDownloads.
Your best bet is to use the stand alone version of Bazaar rather than one of Your best bet is to use the stand alone version of Bazaar
(which includes bzrtools, needed Kicad) rather than one of
the Python specific versions. the Python specific versions.
CMake CMake
...@@ -87,7 +89,7 @@ MinGW linker. ...@@ -87,7 +89,7 @@ MinGW linker.
Build and Install the wxWidgets Library Build and Install the wxWidgets Library
--------------------------------------- ---------------------------------------
The wxWidgets library is the base that KiCad is built upon. Version 2.9.4 The wxWidgets library is the base that KiCad is built upon. Version 2.9.4
or later of wxWidgets should be used on Windows. You may be able to build or later of wxWidgets *should be* used on Windows. You may be able to build
KiCad with older versions of wxWidgets but it is not recommended. wxWidgets KiCad with older versions of wxWidgets but it is not recommended. wxWidgets
can be downloaded from http://http://www.wxwidgets.org/downloads/ can be downloaded from http://http://www.wxwidgets.org/downloads/
...@@ -107,16 +109,10 @@ install the wxWidgets library into MinGW then enter the following commands: ...@@ -107,16 +109,10 @@ install the wxWidgets library into MinGW then enter the following commands:
If you want to install wxWidgets in MinGW then enter the following commands: If you want to install wxWidgets in MinGW then enter the following commands:
#mkdir Release #mkdir Release
#cd Release #cd Release
#../configure --prefix=/mingw --with-opengl #../configure --prefix=/mingw --enable-monolithic=no --disable-shared --with-opengl
#make && make install #make && make install
#move /mingw/lib/wxmsw*.dll /mingw/bin
The last command is critical so that the libraries are in the MinGW PATH wxWidgets will be statically linked to Kicad, which avoid issus with wxWidgets dlls
and can be found at run time. If you want to build a full debugging version
of wxWidgets, add --enable-debug to the configure command. If you are going
to use the GNU debugger, you may also want to build the debugging libraries
with the extra GDB debugging information by adding --enable-debug_gdb to the
configure command.
Download the KiCad Source Code Download the KiCad Source Code
------------------------------ ------------------------------
...@@ -229,5 +225,5 @@ To build the HTML developer documentation, run the following commands: ...@@ -229,5 +225,5 @@ To build the HTML developer documentation, run the following commands:
#cd <kicadSource>/build/debug #cd <kicadSource>/build/debug
#make doxygen-docs #make doxygen-docs
The documentation will be created in the <kicadSouce>/Documenation/html The documentation will be created in the <kicadSouce>/Documentation/html
directory. directory.
...@@ -9,6 +9,7 @@ Snow Leopard ...@@ -9,6 +9,7 @@ Snow Leopard
Requirements Requirements
* XCode Tools (http://developer.apple.com/tools/xcode) * XCode Tools (http://developer.apple.com/tools/xcode)
* bzr (bazaar)
* CMake (http://www.cmake.org) * CMake (http://www.cmake.org)
* wxWidgets 2.9 (http://www.wxwidgets.org/downloads) * wxWidgets 2.9 (http://www.wxwidgets.org/downloads)
* Doxygen (http://www.doxygen.nl) * Doxygen (http://www.doxygen.nl)
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.4.5" />
<title>KiCad 2010-xx-xx Release</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
border: 1px solid red;
*/
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
tt {
color: navy;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
font-family: sans-serif;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
div.sectionbody {
font-family: serif;
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
pre {
padding: 0;
margin: 0;
}
span#author {
color: #527bbd;
font-family: sans-serif;
font-weight: bold;
font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
font-family: sans-serif;
}
div#footer {
font-family: sans-serif;
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
div#footer-text {
float: left;
padding-bottom: 0.5em;
}
div#footer-badges {
float: right;
padding-bottom: 0.5em;
}
div#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.5em;
margin-bottom: 2.5em;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-family: sans-serif;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid silver;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid silver;
background: #f4f4f4;
padding: 0.5em;
}
div.quoteblock {
padding-left: 2.0em;
margin-right: 10%;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock {
padding-left: 2.0em;
margin-right: 10%;
}
div.verseblock > div.content {
white-space: pre;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 2px solid silver;
}
div.exampleblock > div.content {
border-left: 2px solid silver;
padding: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead {
font-family: sans-serif;
font-weight: bold;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
@media print {
div#footer-badges { display: none; }
}
div#toctitle {
color: #527bbd;
font-family: sans-serif;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */
div.sidebar-content {
background: #ffffee;
border: 1px solid silver;
padding: 0.5em;
}
div.sidebar-title, div.image-title {
color: #527bbd;
font-family: sans-serif;
font-weight: bold;
margin-top: 0.0em;
margin-bottom: 0.5em;
}
div.listingblock div.content {
border: 1px solid silver;
background: #f4f4f4;
padding: 0.5em;
}
div.quoteblock-attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock-content {
white-space: pre;
}
div.verseblock-attribution {
padding-top: 0.75em;
text-align: left;
}
div.exampleblock-content {
border-left: 2px solid silver;
padding-left: 0.5em;
}
/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
</head>
<body>
<div id="header">
<h1>KiCad 2010-xx-xx Release</h1>
</div>
<h2 id="_common">Common</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Actions can now be undo and redo
</p>
</li>
<li>
<p>
Menus and tooltips more clear
</p>
</li>
<li>
<p>
File history now in Open Recent submenu
</p>
</li>
<li>
<p>
Many new hotkeys added
</p>
</li>
<li>
<p>
Plot and print dialog rewritten
</p>
</li>
<li>
<p>
Remember last dialog position and tab
</p>
</li>
<li>
<p>
Better font shapes
</p>
</li>
<li>
<p>
Generation of bill of materials
</p>
</li>
<li>
<p>
Plot SVG output
</p>
</li>
</ul></div>
</div>
<h2 id="_kicad">KiCad</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Issue fixed when opening a project in a directory with a lot of subdirectories
</p>
</li>
<li>
<p>
If project is noname.pro no <tt>error</tt> will be displayed
</p>
</li>
</ul></div>
</div>
<h2 id="_eeschema">EESchema</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
New pin properties dialog
</p>
</li>
</ul></div>
</div>
<h2 id="_pcbnew">PCBNew</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Advanced layer setup
</p>
</li>
<li>
<p>
New panel for layer management
</p>
</li>
<li>
<p>
Support for net classes
</p>
</li>
<li>
<p>
Incorrect DRC error fixed, DRC min via and min track check
</p>
</li>
<li>
<p>
Handle local mask clearance and local net clearance
</p>
</li>
<li>
<p>
Handle zones in connectivity calculations
</p>
</li>
</ul></div>
</div>
<h2 id="_core">Core</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Many many bugfixes and cleanups
</p>
</li>
<li>
<p>
All comments translated to English
</p>
</li>
<li>
<p>
Moved to wxAUI and dialogs created with wxFormBuilder
</p>
</li>
<li>
<p>
Full support for Mac OS X with wxWidgets 2.9
</p>
</li>
</ul></div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2010-02-21 13:41:09 CEST
</div>
</div>
</body>
</html>
KiCad 2010-xx-xx Release
========================
== Common
* Actions can now be undo and redo
* Menus and tooltips more clear
* File history now in Open Recent submenu
* Many new hotkeys added
* Plot and print dialog rewritten
* Remember last dialog position and tab
* Better font shapes
* Generation of bill of materials
* Plot SVG output
== KiCad
* Issue fixed when opening a project in a directory with a lot of subdirectories.
* If project is noname.pro no `error` will be displayed
== EESchema
* New pin properties dialog
== PCBNew
* Plot DXF output
* Advanced layer setup
* New panel for layer management
* Support for net classes
* Incorrect DRC error fixed, DRC min via and min track check
* Handle local mask clearance and local net clearance
* Handle zones in connectivity calculations
== Core
* Many many bugfixes and cleanups
* All comments translated to English
* Moved to wxAUI and dialogs created with wxFormBuilder
* Full support for Mac OS X with wxWidgets 2.9
///////////////////////////////////////
This is a asciidoc formatted file, it can be converted
to PDF,(XHTML) and others. See asciidoc homepage.
///////////////////////////////////////
...@@ -76,6 +76,9 @@ set(COMMON_SRCS ...@@ -76,6 +76,9 @@ set(COMMON_SRCS
msgpanel.cpp msgpanel.cpp
netlist_keywords.cpp netlist_keywords.cpp
newstroke_font.cpp newstroke_font.cpp
page_layout_default_description.cpp
page_layout_reader_keywords.cpp
page_layout_reader.cpp
projet_config.cpp projet_config.cpp
ptree.cpp ptree.cpp
reporter.cpp reporter.cpp
...@@ -191,6 +194,15 @@ make_lexer( ...@@ -191,6 +194,15 @@ make_lexer(
FP_LIB_TABLE_T FP_LIB_TABLE_T
) )
# auto-generate page layout reader s-expression page_layout_reader_lexer.h
# and title_block_reader_keywords.cpp.
make_lexer(
${CMAKE_CURRENT_SOURCE_DIR}/page_layout_reader.keywords
${PROJECT_SOURCE_DIR}/include/page_layout_reader_lexer.h
${CMAKE_CURRENT_SOURCE_DIR}/page_layout_reader_keywords.cpp
TB_READER_T
)
# The dsntest may not build properly using MS Visual Studio. # The dsntest may not build properly using MS Visual Studio.
if(NOT MSVC) if(NOT MSVC)
# This one gets made only when testing. # This one gets made only when testing.
......
...@@ -519,6 +519,7 @@ int EDA_BASE_FRAME::WriteHotkeyConfig( struct EDA_HOTKEY_CONFIG* aDescList, ...@@ -519,6 +519,7 @@ int EDA_BASE_FRAME::WriteHotkeyConfig( struct EDA_HOTKEY_CONFIG* aDescList,
if( file ) if( file )
{ {
fputs( TO_UTF8( msg ), file ); fputs( TO_UTF8( msg ), file );
fclose( file );
} }
else else
{ {
......
/**
* @file page_layout_default_description.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
*
*
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <fctsys.h>
// height of the band reference grid 2.0 mm
// worksheet frame reference text size 1.3 mm
// default text size 1.5 mm
// default line width 0.15 mm
// frame ref pitch 50 mm
extern const wxString defaultPageLayout;
// Default page layout (sizes are in mm)
const wxString defaultPageLayout( wxT( "( page_layout\n"
"(setup (textsize 1.5 1.5) (linewidth 0.15) (textlinewidth 0.15) )"
"(rect (comment rect around the title block) (linewidth 0.15) (start 110 34) (end 2 2) )\n"
"(rect (start 0 0 ltcorner) (end 0 0 rbcorner) (repeat 2) (incrx 2) (incry 2) )\n"
"(line (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50) )\n"
"(tbtext \"1\" (pos 25 1 ltcorner) (font (size 1.3 1.3))(repeat 100) (incrx 50) )\n"
"(line (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50) )\n"
"(tbtext \"1\" (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50) )\n"
"(line (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50) )\n"
"(tbtext \"A\" (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center)(repeat 100) (incry 50) )\n"
"(line (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50) )\n"
"(tbtext \"A\" (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50) )\n"
"(tbtext \"Date: %D\" (pos 87 6.9) )\n"
"(line (start 110 5.5) end 2 5.5) )\n"
"(tbtext \"%K\" (pos 108 4.1) (comment Kicad version ) )\n"
"(line (start 110 8.5) end 2 8.5) )\n"
"(tbtext \"Rev: %R\" (pos 24 6.9)(font bold italic)(justify left) )\n"
"(tbtext \"Size: %Z\" (comment Paper format name)(pos 105 6.9) )\n"
"(tbtext \"Id: %S/%N\" (comment Sheet id)(pos 24 4.1) )\n"
"(line (start 110 12.5) end 2 12.5) )\n"
"(tbtext \"Title: %T\" (pos 108 10.7)(font bold (size 2 2)) )\n"
"(tbtext \"File: %F\" (pos 108 14.3) )\n"
"(line (start 110 18.5) end 2 18.5) )\n"
"(tbtext \"Sheet: %P\" (pos 108 17) )\n"
"(tbtext \"%Y\" (comment Company name) (pos 108 20)(font bold) )\n"
"(tbtext \"%C0\" (comment Comment 0) (pos 108 23) )\n"
"(tbtext \"%C1\" (comment Comment 0) (pos 108 26) )\n"
"(tbtext \"%C2\" (comment Comment 0) (pos 108 29) )\n"
"(tbtext \"%C3\" (comment Comment 0) (pos 108 32) )\n"
"(line (start 90 8.5) end 90 5.5) )\n"
"(line (start 26 8.5) end 26 2) )\n"
")\n") );
/**
* @file page_layout_reader.cpp
* @brief read an S expression of description of graphic items and texts
* to build a title block and page layout
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
*
*
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <fctsys.h>
#include <base_struct.h>
#include <worksheet.h>
#include <worksheet_shape_builder.h>
#include <vector2d.h>
#include <page_layout_reader_lexer.h>
// defaultPageLayout is the default page layout description
// using the S expr.
// see page_layout_default_shape.cpp
extern const wxString defaultPageLayout;
using namespace TB_READER_T;
/**
* Class PAGE_LAYOUT_READER_PARSER
* holds data and functions pertinent to parsing a S-expression file
* for a WORKSHEET_LAYOUT.
*/
class PAGE_LAYOUT_READER_PARSER : public PAGE_LAYOUT_READER_LEXER
{
DSIZE m_defaultTextSize; // Default text size, when not defined inside a tbtext
double m_defaultLineWidth;
double m_defaulTextLineWidth;
public:
PAGE_LAYOUT_READER_PARSER( const char* aLine, const wxString& aSource );
void Parse( WORKSHEET_LAYOUT* aLayout )
throw( PARSE_ERROR, IO_ERROR );
private:
/**
* Function parseInt
* parses an integer and constrains it between two values.
* @param aMin is the smallest return value.
* @param aMax is the largest return value.
* @return int - the parsed integer.
*/
int parseInt( int aMin, int aMax );
/**
* Function parseDouble
* parses a double
* @return double - the parsed double.
*/
double parseDouble();
void parseSetup() throw( IO_ERROR, PARSE_ERROR );
void parseGraphic( WORKSHEET_DATAITEM * aItem ) throw( IO_ERROR, PARSE_ERROR );
void parseText( WORKSHEET_DATAITEM_TEXT * aItem ) throw( IO_ERROR, PARSE_ERROR );
void parseCoordinate( POINT_COORD& aCoord) throw( IO_ERROR, PARSE_ERROR );
};
// PCB_PLOT_PARAMS_PARSER
PAGE_LAYOUT_READER_PARSER::PAGE_LAYOUT_READER_PARSER( const char* aLine, const wxString& aSource ) :
PAGE_LAYOUT_READER_LEXER( aLine, aSource )
{
m_defaultTextSize.x = m_defaultTextSize.y = TB_DEFAULT_TEXTSIZE;
m_defaultLineWidth = 0.0;
m_defaulTextLineWidth = 0.0;
}
void PAGE_LAYOUT_READER_PARSER::Parse( WORKSHEET_LAYOUT* aLayout )
throw( PARSE_ERROR, IO_ERROR )
{
T token;
WORKSHEET_DATAITEM * item;
LOCALE_IO toggle;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
if( token == T_LEFT )
token = NextTok();
if( token == T_page_layout )
continue;
switch( token )
{
case T_setup: // Defines default values for graphic items
parseSetup();
break;
case T_line:
item = new WORKSHEET_DATAITEM( WORKSHEET_DATAITEM::WS_SEGMENT );
parseGraphic( item );
aLayout->Append( item );
break;
case T_rect:
item = new WORKSHEET_DATAITEM( WORKSHEET_DATAITEM::WS_RECT );
parseGraphic( item );
aLayout->Append( item );
break;
case T_tbtext:
NeedSYMBOLorNUMBER();
item = new WORKSHEET_DATAITEM_TEXT( FromUTF8() );
parseText( (WORKSHEET_DATAITEM_TEXT*) item );
aLayout->Append( item );
break;
default:
Unexpected( CurText() );
break;
}
}
}
void PAGE_LAYOUT_READER_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
{
T token;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
switch( token )
{
case T_LEFT:
break;
case T_linewidth:
m_defaultLineWidth = parseDouble();
NeedRIGHT();
break;
case T_textsize:
m_defaultTextSize.x = parseDouble();
m_defaultTextSize.y = parseDouble();
NeedRIGHT();
break;
case T_textlinewidth:
m_defaulTextLineWidth = parseDouble();
NeedRIGHT();
break;
default:
Unexpected( CurText() );
break;
}
}
}
void PAGE_LAYOUT_READER_PARSER::parseGraphic( WORKSHEET_DATAITEM * aItem )
throw( IO_ERROR, PARSE_ERROR )
{
T token;
aItem->m_LineWidth = m_defaultLineWidth;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_comment: // Comment, search the closing ')'
while( ( token = NextTok() ) != T_RIGHT && token != T_EOF );
break;
case T_start:
parseCoordinate( aItem->m_Pos );
break;
case T_end:
parseCoordinate( aItem->m_End );
break;
case T_repeat:
aItem->m_RepeatCount = parseInt( -1, 100 );
NeedRIGHT();
break;
case T_incrx:
aItem->m_IncrementVector.x = parseDouble();
NeedRIGHT();
break;
case T_incry:
aItem->m_IncrementVector.y = parseDouble();
NeedRIGHT();
break;
case T_linewidth:
aItem->m_LineWidth = parseDouble();
NeedRIGHT();
break;
default:
Unexpected( CurText() );
break;
}
}
}
void PAGE_LAYOUT_READER_PARSER::parseText( WORKSHEET_DATAITEM_TEXT* aItem )
throw( IO_ERROR, PARSE_ERROR )
{
T token;
aItem->m_TextSize = m_defaultTextSize;
aItem->m_LineWidth = m_defaulTextLineWidth;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_comment: // Comment, search the closing ')'
while( ( token = NextTok() ) != T_RIGHT && token != T_EOF );
break;
case T_pos:
parseCoordinate( aItem->m_Pos );
break;
case T_repeat:
aItem->m_RepeatCount = parseInt( -1, 100 );
NeedRIGHT();
break;
case T_incrx:
aItem->m_IncrementVector.x = parseDouble();
NeedRIGHT();
break;
case T_incry:
aItem->m_IncrementVector.y = parseDouble();
NeedRIGHT();
break;
case T_incrlabel:
aItem->m_IncrementLabel = parseInt(INT_MIN, INT_MAX);
NeedRIGHT();
break;
case T_maxlen:
aItem->m_BoundingBoxSize.x = parseDouble();
NeedRIGHT();
break;
case T_maxheight:
aItem->m_BoundingBoxSize.y = parseDouble();
NeedRIGHT();
break;
case T_font:
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
switch( token )
{
case T_LEFT:
break;
case T_bold:
aItem->m_Flags |= USE_BOLD;
break;
case T_italic:
aItem->m_Flags |= USE_ITALIC;
break;
case T_size:
aItem->m_TextSize.x = parseDouble();
aItem->m_TextSize.y = parseDouble();
NeedRIGHT();
break;
case T_linewidth:
aItem->m_LineWidth = parseDouble();
NeedRIGHT();
break;
default:
Unexpected( CurText() );
break;
}
}
break;
case T_justify:
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
switch( token )
{
case T_center:
aItem->m_Hjustify = GR_TEXT_HJUSTIFY_CENTER;
aItem->m_Vjustify = GR_TEXT_VJUSTIFY_CENTER;
break;
case T_left:
aItem->m_Hjustify = GR_TEXT_HJUSTIFY_LEFT;
break;
case T_right:
aItem->m_Hjustify = GR_TEXT_HJUSTIFY_RIGHT;
break;
case T_top:
aItem->m_Vjustify = GR_TEXT_VJUSTIFY_TOP;
break;
case T_bottom:
aItem->m_Vjustify = GR_TEXT_VJUSTIFY_BOTTOM;
break;
default:
Unexpected( CurText() );
break;
}
}
break;
case T_rotate:
aItem->m_Orient = parseDouble();
NeedRIGHT();
break;
default:
Unexpected( CurText() );
break;
}
}
}
// parse an expression like " 25 1 ltcorner)"
void PAGE_LAYOUT_READER_PARSER::parseCoordinate( POINT_COORD& aCoord)
throw( IO_ERROR, PARSE_ERROR )
{
T token;
aCoord.m_Pos.x = parseDouble();
aCoord.m_Pos.y = parseDouble();
while( ( token = NextTok() ) != T_RIGHT )
{
switch( token )
{
case T_ltcorner:
aCoord.m_Anchor = LT_CORNER; // left top corner
break;
case T_lbcorner:
aCoord.m_Anchor = LB_CORNER; // left bottom corner
break;
case T_rbcorner:
aCoord.m_Anchor = RB_CORNER; // right bottom corner
break;
case T_rtcorner:
aCoord.m_Anchor = RT_CORNER; // right top corner
break;
default:
Unexpected( CurText() );
break;
}
}
}
int PAGE_LAYOUT_READER_PARSER::parseInt( int aMin, int aMax )
{
T token = NextTok();
if( token != T_NUMBER )
Expecting( T_NUMBER );
int val = atoi( CurText() );
if( val < aMin )
val = aMin;
else if( val > aMax )
val = aMax;
return val;
}
double PAGE_LAYOUT_READER_PARSER::parseDouble()
{
T token = NextTok();
if( token != T_NUMBER )
Expecting( T_NUMBER );
double val = strtod( CurText(), NULL );
return val;
}
void WORKSHEET_LAYOUT::SetDefaultLayout()
{
PAGE_LAYOUT_READER_PARSER lp_parser( defaultPageLayout, "default page" );
try
{
lp_parser.Parse( this );
}
catch( IO_ERROR ioe )
{
wxLogMessage( ioe.errorText );
}
}
page_layout
setup
linewidth
textlinewidth
textsize
comment
line
rect
polygon
tbtext
ltcorner
lbcorner
rbcorner
rtcorner
name
pos
start
end
maxlen
maxheight
font
bold
italic
size
justify
left
center
right
top
bottom
rotate
repeat
incrx
incry
incrlabel
/** /**
* @file title_block_shapes.cpp * @file title_block_shape.cpp
* @brief description of graphic items and texts to build a title block * @brief description of graphic items and texts to build a title block
*/ */
...@@ -39,265 +39,157 @@ ...@@ -39,265 +39,157 @@
#include <class_title_block.h> #include <class_title_block.h>
#include <worksheet_shape_builder.h> #include <worksheet_shape_builder.h>
#define GRID_REF_W Mm2mils( 1.8 ) // height of the band reference grid extern void SetDataList( WORKSHEET_LAYOUT& aDataList );
#define TEXTSIZE Mm2mils( 1.5 ) // worksheet text size
#define FRMREF_TXTSIZE Mm2mils( 1.3 ) // worksheet frame reference text size
#define VARIABLE_BLOCK_START_POSITION (TEXTSIZE * 10) WORKSHEET_DATAITEM_TEXT::WORKSHEET_DATAITEM_TEXT( const wxChar* aTextBase ) :
WORKSHEET_DATAITEM( WS_TEXT )
// The coordinates below are relative to the bottom right corner of page and
// will be subtracted from this origin.
#define BLOCK_OX Mm2mils( 106 )
#define BLOCK_KICAD_VERSION_X BLOCK_OX - TEXTSIZE
#define BLOCK_KICAD_VERSION_Y TEXTSIZE
#define BLOCK_REV_X Mm2mils( 22 )
#define BLOCK_REV_Y (TEXTSIZE * 3)
#define BLOCK_DATE_X BLOCK_OX - (TEXTSIZE * 15)
#define BLOCK_DATE_Y (TEXTSIZE * 3)
#define BLOCK_ID_SHEET_X Mm2mils( 22 )
#define BLOCK_ID_SHEET_Y TEXTSIZE
#define BLOCK_SIZE_SHEET_X BLOCK_OX - TEXTSIZE
#define BLOCK_SIZE_SHEET_Y (TEXTSIZE * 3)
#define BLOCK_TITLE_X BLOCK_OX - TEXTSIZE
#define BLOCK_TITLE_Y (TEXTSIZE * 5)
#define BLOCK_FULLSHEETNAME_X BLOCK_OX - TEXTSIZE
#define BLOCK_FULLSHEETNAME_Y (TEXTSIZE * 7)
#define BLOCK_FILENAME_X BLOCK_OX - TEXTSIZE
#define BLOCK_FILENAME_Y (TEXTSIZE * 9)
#define BLOCK_COMMENT_X BLOCK_OX - TEXTSIZE
#define BLOCK_COMPANY_Y (TEXTSIZE * 11)
#define BLOCK_COMMENT1_Y (TEXTSIZE * 13)
#define BLOCK_COMMENT2_Y (TEXTSIZE * 15)
#define BLOCK_COMMENT3_Y (TEXTSIZE * 17)
#define BLOCK_COMMENT4_Y (TEXTSIZE * 19)
// Text attributes set in m_Flags (ORed bits)
#define USE_BOLD 1 // has meaning for texts
#define USE_THICK_LINE 1 // equivalent to bold for lines
#define USE_ITALIC 2 // has meaning for texts
#define USE_TEXT_COLOR 4
#define SET_UPPER_LIMIT 8 // Flag used to calculate variable position items
// Work sheet structure type definitions.
enum TypeKi_WorkSheetData {
WS_TEXT,
WS_SEGMENT,
WS_UPPER_SEGMENT,
WS_LEFT_SEGMENT
};
// superior horizontal segment: should be after comments
// to know the exact position
Ki_WorkSheetData WS_MostUpperLine =
{
WS_UPPER_SEGMENT,
NULL,
BLOCK_OX, TEXTSIZE * 16,
0, TEXTSIZE * 16,
NULL
};
// Left vertical segment: should be after comments
// to know the exact position
Ki_WorkSheetData WS_MostLeftLine =
{
WS_LEFT_SEGMENT,
&WS_MostUpperLine,
BLOCK_OX, TEXTSIZE * 16,
BLOCK_OX, 0,
NULL
};
// horizontal segment between filename and comments
Ki_WorkSheetData WS_SeparatorLine =
{
WS_SEGMENT,
&WS_MostLeftLine,
BLOCK_OX, VARIABLE_BLOCK_START_POSITION,
0, VARIABLE_BLOCK_START_POSITION,
NULL
};
Ki_WorkSheetData WS_Date =
{
WS_TEXT,
&WS_SeparatorLine,
BLOCK_DATE_X, BLOCK_DATE_Y,
0, 0,
wxT( "Date: %D" )
};
Ki_WorkSheetData WS_Licence =
{
WS_TEXT,
&WS_Date,
BLOCK_KICAD_VERSION_X,BLOCK_KICAD_VERSION_Y,
0,
0,
wxT("%K") // Kicad version
};
Ki_WorkSheetData WS_Revision =
{
WS_TEXT,
&WS_Licence,
BLOCK_REV_X, BLOCK_REV_Y,
0, 0,
wxT( "Rev: %R" ),
USE_BOLD
};
Ki_WorkSheetData WS_SizeSheet =
{
WS_TEXT,
&WS_Revision,
BLOCK_SIZE_SHEET_X,BLOCK_SIZE_SHEET_Y,
0, 0,
wxT( "Size: %Z" ) // Paper format name
};
Ki_WorkSheetData WS_IdentSheet =
{
WS_TEXT,
&WS_SizeSheet,
BLOCK_ID_SHEET_X,BLOCK_ID_SHEET_Y,
0, 0,
wxT( "Id: %S/%N" )
};
Ki_WorkSheetData WS_Title =
{
WS_TEXT,
&WS_IdentSheet,
BLOCK_TITLE_X, BLOCK_TITLE_Y,
0, 0,
wxT( "Title: %T" ),
USE_BOLD
};
Ki_WorkSheetData WS_SheetFilename =
{ {
WS_TEXT, m_TextBase = aTextBase;
&WS_Title, m_IncrementLabel = 1;
BLOCK_FILENAME_X, BLOCK_FILENAME_Y, m_Hjustify = GR_TEXT_HJUSTIFY_LEFT;
0, 0, m_Vjustify = GR_TEXT_VJUSTIFY_CENTER;
wxT( "File: %F" ) m_Orient = 0.0;
}; m_TextSize.x = m_TextSize.y = TB_DEFAULT_TEXTSIZE;
}
Ki_WorkSheetData WS_FullSheetName =
void WORKSHEET_DATAITEM_TEXT::TransfertSetupToGraphicText( WS_DRAW_ITEM_TEXT* aGText )
{ {
WS_TEXT, aGText->SetHorizJustify( m_Hjustify ) ;
&WS_SheetFilename, aGText->SetVertJustify( m_Vjustify );
BLOCK_FULLSHEETNAME_X,BLOCK_FULLSHEETNAME_Y, aGText->SetOrientation( m_Orient * 10 ); // graphic text orient unit = 0.1 degree
0, }
0,
wxT( "Sheet: %P" ) // Full sheet name (sheet path) void WORKSHEET_DATAITEM_TEXT::IncrementLabel( int aIncr )
};
Ki_WorkSheetData WS_Company =
{ {
WS_TEXT, wxChar lbchar = m_TextBase[0];
&WS_FullSheetName, if( lbchar >= '0' && lbchar <= '9' )
BLOCK_COMMENT_X,BLOCK_COMPANY_Y, // A number is expected:
0, 0, m_FullText.Printf( wxT("%d"), aIncr + lbchar - '0' );
wxT("%Y"), // Company name else
USE_BOLD | SET_UPPER_LIMIT | USE_TEXT_COLOR m_FullText.Printf( wxT("%c"), aIncr + lbchar );
}; }
Ki_WorkSheetData WS_Comment1 = void WORKSHEET_DATAITEM_TEXT::SetConstrainedTextSize()
{ {
WS_TEXT, m_ConstrainedTextSize = m_TextSize;
&WS_Company,
BLOCK_COMMENT_X,BLOCK_COMMENT1_Y, if( m_BoundingBoxSize.x )
0, 0, {
wxT("%C1"), // Comment 1 bool italic = (m_Flags & USE_ITALIC) != 0;
SET_UPPER_LIMIT | USE_TEXT_COLOR int linewidth = 0;
}; int lenMsg = ReturnGraphicTextWidth( m_FullText, m_TextSize.x, italic, linewidth );
if( lenMsg > m_BoundingBoxSize.x )
Ki_WorkSheetData WS_Comment2 = m_ConstrainedTextSize.x = m_TextSize.x * m_BoundingBoxSize.x / lenMsg;
}
if( m_BoundingBoxSize.y )
{
if( m_ConstrainedTextSize.y > m_BoundingBoxSize.y )
m_ConstrainedTextSize.y = m_BoundingBoxSize.y;
}
}
const DPOINT WORKSHEET_DATAITEM::GetStartPos( int ii ) const
{ {
WS_TEXT, DPOINT pos;
&WS_Comment1, pos.x = m_Pos.m_Pos.x + ( m_IncrementVector.x * ii );
BLOCK_COMMENT_X,BLOCK_COMMENT2_Y, pos.y = m_Pos.m_Pos.y + ( m_IncrementVector.y * ii );
0, 0,
wxT("%C2"), // Comment 2 switch( m_Pos.m_Anchor )
SET_UPPER_LIMIT | USE_TEXT_COLOR {
}; case RB_CORNER: // right bottom corner
pos = m_RB_Corner - pos;
Ki_WorkSheetData WS_Comment3 = break;
case RT_CORNER: // right top corner
pos.x = m_RB_Corner.x - pos.x;
pos.y = m_LT_Corner.y + pos.y;
break;
case LB_CORNER: // left bottom corner
pos.x = m_LT_Corner.x + pos.x;
pos.y = m_RB_Corner.y - pos.y;
break;
case LT_CORNER: // left top corner
pos = m_LT_Corner + pos;
break;
}
return pos;
}
const wxPoint WORKSHEET_DATAITEM::GetStartPosUi( int ii ) const
{ {
WS_TEXT, DPOINT pos = GetStartPos( ii );
&WS_Comment2, pos = pos * m_WSunits2Iu;
BLOCK_COMMENT_X,BLOCK_COMMENT3_Y, return wxPoint( int(pos.x), int(pos.y) );
0, 0, }
wxT("%C3"), // Comment 3
SET_UPPER_LIMIT | USE_TEXT_COLOR const DPOINT WORKSHEET_DATAITEM::GetEndPos( int ii ) const
};
Ki_WorkSheetData WS_Comment4 =
{ {
WS_TEXT, DPOINT pos;
&WS_Comment3, pos.x = m_End.m_Pos.x + ( m_IncrementVector.x * ii );
BLOCK_COMMENT_X, BLOCK_COMMENT4_Y, pos.y = m_End.m_Pos.y + ( m_IncrementVector.y * ii );
0, 0, switch( m_End.m_Anchor )
wxT("%C4"), // Comment 4 {
SET_UPPER_LIMIT | USE_TEXT_COLOR case RB_CORNER: // right bottom corner
}; pos = m_RB_Corner - pos;
break;
case RT_CORNER: // right top corner
pos.x = m_RB_Corner.x - pos.x;
pos.y = m_LT_Corner.y + pos.y;
break;
// horizontal segment above COMPANY NAME case LB_CORNER: // left bottom corner
Ki_WorkSheetData WS_Segm3 = pos.x = m_LT_Corner.x + pos.x;
{ pos.y = m_RB_Corner.y - pos.y;
WS_SEGMENT, break;
&WS_Comment4,
BLOCK_OX, TEXTSIZE * 6,
0, TEXTSIZE * 6,
NULL
};
case LT_CORNER: // left top corner
pos = m_LT_Corner + pos;
break;
}
return pos;
}
// vertical segment of the left REV and SHEET const wxPoint WORKSHEET_DATAITEM::GetEndPosUi( int ii ) const
Ki_WorkSheetData WS_Segm4 =
{ {
WS_SEGMENT, DPOINT pos = GetEndPos( ii );
&WS_Segm3, pos = pos * m_WSunits2Iu;
BLOCK_REV_X + TEXTSIZE,TEXTSIZE * 4, return wxPoint( int(pos.x), int(pos.y) );
BLOCK_REV_X + TEXTSIZE, 0, }
NULL
};
Ki_WorkSheetData WS_Segm5 = bool WORKSHEET_DATAITEM::IsInsidePage( int ii ) const
{ {
WS_SEGMENT, DPOINT pos = GetStartPos( ii );
&WS_Segm4,
BLOCK_OX, TEXTSIZE * 2,
0, TEXTSIZE * 2,
NULL
};
if( m_RB_Corner.x < pos.x || m_LT_Corner.x > pos.x )
return false;
Ki_WorkSheetData WS_Segm6 = if( m_RB_Corner.y < pos.y || m_LT_Corner.y > pos.y )
{ return false;
WS_SEGMENT,
&WS_Segm5,
BLOCK_OX, TEXTSIZE * 4,
0, TEXTSIZE * 4,
NULL
};
pos = GetEndPos( ii );
Ki_WorkSheetData WS_Segm7 = if( m_RB_Corner.x < pos.x || m_LT_Corner.x > pos.x )
{ return false;
WS_SEGMENT,
&WS_Segm6,
BLOCK_OX - (TEXTSIZE * 11),TEXTSIZE * 4,
BLOCK_OX - (TEXTSIZE * 11),TEXTSIZE * 2,
NULL
};
#include <worksheet_shape_builder.h> if( m_RB_Corner.y < pos.y || m_LT_Corner.y > pos.y )
return false;
return true;
}
double WORKSHEET_DATAITEM::m_WSunits2Iu = 1.0;
DPOINT WORKSHEET_DATAITEM::m_RB_Corner;
DPOINT WORKSHEET_DATAITEM::m_LT_Corner;
WORKSHEET_LAYOUT dataList; // The layout shape
void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList( void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
const wxString& aPaperFormat, const wxString& aPaperFormat,
...@@ -306,178 +198,126 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList( ...@@ -306,178 +198,126 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
const TITLE_BLOCK& aTitleBlock, const TITLE_BLOCK& aTitleBlock,
EDA_COLOR_T aLineColor, EDA_COLOR_T aTextColor ) EDA_COLOR_T aLineColor, EDA_COLOR_T aTextColor )
{ {
wxSize textsize( TEXTSIZE * m_milsToIu, TEXTSIZE * m_milsToIu ); #define milsTomm (25.4/1000)
wxSize size_ref( FRMREF_TXTSIZE * m_milsToIu,
FRMREF_TXTSIZE * m_milsToIu );
wxString msg;
m_titleBlock = &aTitleBlock, m_titleBlock = &aTitleBlock,
m_paperFormat = &aPaperFormat, m_paperFormat = &aPaperFormat,
m_fileName = &aFileName, m_fileName = &aFileName,
m_sheetFullName = &aSheetPathHumanReadable; m_sheetFullName = &aSheetPathHumanReadable;
// Build the basic layout shape, if the layout list is empty
if( dataList.GetCount() == 0 )
dataList.SetDefaultLayout();
WORKSHEET_DATAITEM::m_WSunits2Iu = m_milsToIu / milsTomm;
// Left top corner position // Left top corner position
wxPoint lt_corner; DPOINT lt_corner;
lt_corner.x = m_LTmargin.x; lt_corner.x = m_LTmargin.x;
lt_corner.y = m_LTmargin.y; lt_corner.y = m_LTmargin.y;
WORKSHEET_DATAITEM::m_LT_Corner = lt_corner * milsTomm;
// Right bottom corner position // Right bottom corner position
wxPoint rb_corner; DPOINT rb_corner;
rb_corner.x = m_pageSize.x - m_RBmargin.x; rb_corner.x = m_pageSize.x - m_RBmargin.x;
rb_corner.y = m_pageSize.y - m_RBmargin.y; rb_corner.y = m_pageSize.y - m_RBmargin.y;
WORKSHEET_DATAITEM::m_RB_Corner = rb_corner * milsTomm;
// Draw the border. WS_DRAW_ITEM_TEXT* gtext;
int ii, jj, ipas, gxpas, gypas; int pensize;
bool bold;
bool italic = false;
EDA_COLOR_T color;
wxPoint pos = lt_corner; for( unsigned ii = 0; ; ii++ )
wxPoint end = rb_corner;
for( ii = 0; ii < 2; ii++ )
{ {
Append( new WS_DRAW_ITEM_RECT( WORKSHEET_DATAITEM* wsItem = dataList.GetItem( ii );
wxPoint( pos.x * m_milsToIu, pos.y * m_milsToIu ),
wxPoint( end.x * m_milsToIu, end.y * m_milsToIu ),
m_penSize, aLineColor ) );
pos.x += GRID_REF_W;
pos.y += GRID_REF_W;
end.x -= GRID_REF_W;
end.y -= GRID_REF_W;
}
ipas = ( rb_corner.x - lt_corner.x ) / PAS_REF; if( wsItem == NULL )
gxpas = ( rb_corner.x - lt_corner.x ) / ipas; break;
for( ii = lt_corner.x + gxpas, jj = 1; ipas > 0; ii += gxpas, jj++, ipas-- ) switch( wsItem->m_Type )
{ {
msg.Printf( wxT( "%d" ), jj ); case WORKSHEET_DATAITEM::WS_TEXT:
if( ii < rb_corner.x - PAS_REF / 2 )
{ {
Append( new WS_DRAW_ITEM_LINE( WORKSHEET_DATAITEM_TEXT * wsText = (WORKSHEET_DATAITEM_TEXT*)wsItem;
wxPoint( ii * m_milsToIu, lt_corner.y * m_milsToIu ), wsText->m_FullText = BuildFullText( wsText->m_TextBase );
wxPoint( ii * m_milsToIu, ( lt_corner.y + GRID_REF_W ) * m_milsToIu ), if( wsText->m_FullText.IsEmpty() )
m_penSize, aLineColor ) ); break;
}
Append( new WS_DRAW_ITEM_TEXT( msg,
wxPoint( ( ii - gxpas / 2 ) * m_milsToIu,
( lt_corner.y + GRID_REF_W / 2 ) * m_milsToIu ),
size_ref, m_penSize, aLineColor ) );
if( ii < rb_corner.x - PAS_REF / 2 ) bold = false;
{ pensize = wsText->GetPenSizeUi();
Append( new WS_DRAW_ITEM_LINE(
wxPoint( ii * m_milsToIu, rb_corner.y * m_milsToIu ),
wxPoint( ii * m_milsToIu, (rb_corner.y - GRID_REF_W ) * m_milsToIu ),
m_penSize, aLineColor ) );
}
Append( new WS_DRAW_ITEM_TEXT( msg, if( pensize == 0 )
wxPoint( ( ii - gxpas / 2 ) * m_milsToIu, pensize = m_penSize;
( rb_corner.y - GRID_REF_W / 2) * m_milsToIu ),
size_ref, m_penSize, aLineColor ) );
}
ipas = ( rb_corner.y - lt_corner.y ) / PAS_REF; color = aLineColor;
gypas = ( rb_corner.y - lt_corner.y ) / ipas;
for( ii = lt_corner.y + gypas, jj = 0; ipas > 0; ii += gypas, jj++, ipas-- ) if( wsText->m_Flags & USE_TEXT_COLOR )
{ color = aTextColor;
if( jj < 26 )
msg.Printf( wxT( "%c" ), jj + 'A' );
else // I hope 52 identifiers are enough...
msg.Printf( wxT( "%c" ), 'a' + jj - 26 );
if( ii < rb_corner.y - PAS_REF / 2 ) wsText->SetConstrainedTextSize();
{ wxSize textsize;
Append( new WS_DRAW_ITEM_LINE(
wxPoint( lt_corner.x * m_milsToIu, ii * m_milsToIu ),
wxPoint( ( lt_corner.x + GRID_REF_W ) * m_milsToIu, ii * m_milsToIu ),
m_penSize, aLineColor ) );
}
Append( new WS_DRAW_ITEM_TEXT( msg, textsize.x = KiROUND( wsText->m_ConstrainedTextSize.x
wxPoint( ( lt_corner.x + GRID_REF_W / 2 ) * m_milsToIu, * WORKSHEET_DATAITEM::m_WSunits2Iu );
( ii - gypas / 2 ) * m_milsToIu ), textsize.y = KiROUND( wsText->m_ConstrainedTextSize.y
size_ref, m_penSize, aLineColor ) ); * WORKSHEET_DATAITEM::m_WSunits2Iu );
if( ii < rb_corner.y - PAS_REF / 2 ) if( wsText->m_Flags & USE_BOLD )
{ {
Append( new WS_DRAW_ITEM_LINE( bold = true;
wxPoint( rb_corner.x * m_milsToIu, ii * m_milsToIu ), pensize = GetPenSizeForBold( std::min( textsize.x, textsize.y ) );
wxPoint( ( rb_corner.x - GRID_REF_W ) * m_milsToIu, ii * m_milsToIu ),
m_penSize, aLineColor ) );
}
Append( new WS_DRAW_ITEM_TEXT( msg,
wxPoint( ( rb_corner.x - GRID_REF_W / 2 ) * m_milsToIu,
( ii - gxpas / 2 ) * m_milsToIu ),
size_ref, m_penSize, aLineColor ) );
} }
int upperLimit = VARIABLE_BLOCK_START_POSITION; for( int jj = 0; jj < wsText->m_RepeatCount; )
rb_corner.x -= GRID_REF_W;
rb_corner.y -= GRID_REF_W;
WS_DRAW_ITEM_TEXT* gtext;
Ki_WorkSheetData* WsItem;
int pensize;
bool bold;
bool italic = false;
EDA_COLOR_T color;
for( WsItem = &WS_Segm7; WsItem != NULL; WsItem = WsItem->Pnext )
{ {
pos.x = (rb_corner.x - WsItem->m_Posx) * m_milsToIu; if( ! wsText->IsInsidePage( jj ) )
pos.y = (rb_corner.y - WsItem->m_Posy) * m_milsToIu; break;
Append( gtext = new WS_DRAW_ITEM_TEXT( wsText->m_FullText,
wsText->GetStartPosUi( jj ),
textsize,
pensize, color, italic, bold ) );
wsText->TransfertSetupToGraphicText( gtext );
msg.Empty(); jj++;
if( wsText->m_RepeatCount > 1 ) // Try to increment label
wsText->IncrementLabel( jj );
}
}
break;
if( WsItem->m_Type == WS_TEXT && WsItem->m_TextBase ) case WORKSHEET_DATAITEM::WS_SEGMENT:
msg = BuildFullText( WsItem->m_TextBase ); pensize = wsItem->GetPenSizeUi();
switch( WsItem->m_Type ) if( pensize == 0 )
{
case WS_TEXT:
if( msg.IsEmpty() )
break;
bold = false;
pensize = m_penSize; pensize = m_penSize;
color = aLineColor;
if( WsItem->m_Flags & USE_TEXT_COLOR )
color = aTextColor;
if( WsItem->m_Flags & USE_BOLD ) for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
{ {
bold = true; if( ! wsItem->IsInsidePage( jj ) )
pensize = GetPenSizeForBold( std::min( textsize.x, textsize.y ) ); break;
Append( new WS_DRAW_ITEM_LINE( wsItem->GetStartPosUi( jj ),
wsItem->GetEndPosUi( jj ),
pensize, aLineColor ) );
} }
Append( gtext = new WS_DRAW_ITEM_TEXT( msg, pos, textsize,
pensize, color, italic, bold ) );
gtext->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
if( WsItem->m_Flags & SET_UPPER_LIMIT )
upperLimit = std::max( upperLimit, WsItem->m_Posy + TEXTSIZE );
break; break;
case WS_UPPER_SEGMENT: case WORKSHEET_DATAITEM::WS_RECT:
pensize = wsItem->GetPenSizeUi();
if( pensize == 0 )
pensize = m_penSize;
if( upperLimit == 0 ) for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
{
if( ! wsItem->IsInsidePage( jj ) )
break; break;
case WS_LEFT_SEGMENT: Append( new WS_DRAW_ITEM_RECT( wsItem->GetStartPosUi( jj ),
WS_MostUpperLine.m_Posy = upperLimit; wsItem->GetEndPosUi( jj ),
WS_MostUpperLine.m_Endy = upperLimit; pensize, aLineColor ) );
WS_MostLeftLine.m_Posy = upperLimit; }
pos.y = (rb_corner.y - WsItem->m_Posy) * m_milsToIu;
case WS_SEGMENT:
end.x = rb_corner.x - WsItem->m_Endx;
end.y = rb_corner.y - WsItem->m_Endy;
Append( new WS_DRAW_ITEM_LINE( pos,
wxPoint( end.x * m_milsToIu, end.y * m_milsToIu ),
m_penSize, aLineColor ) );
break; break;
} }
} }
......
/** /**
* @file title_block_shapes_gost.cpp * @file title_block_shape_gost.h
* @brief description of graphic items and texts to build a title block * @brief description of graphic items and texts to build a title block
* using GOST standard * using GOST standard
*/ */
...@@ -43,6 +43,17 @@ ...@@ -43,6 +43,17 @@
#define TEXTSIZE 100 // worksheet text size #define TEXTSIZE 100 // worksheet text size
struct Ki_WorkSheetData
{
public:
int m_Type;
Ki_WorkSheetData* Pnext;
int m_Posx, m_Posy;
int m_Endx, m_Endy;
const wxChar* m_TextBase;
int m_Flags;
};
// Work sheet structure type definitions. // Work sheet structure type definitions.
enum TypeKi_WorkSheetData { enum TypeKi_WorkSheetData {
WS_OSN, WS_OSN,
......
...@@ -293,20 +293,17 @@ wxString WS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase ) ...@@ -293,20 +293,17 @@ wxString WS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
format = aTextbase[++ii]; format = aTextbase[++ii];
switch( format ) switch( format )
{ {
case '0':
case '1': case '1':
msg += m_titleBlock->GetComment1();
break;
case '2': case '2':
msg += m_titleBlock->GetComment2();
break;
case '3': case '3':
msg += m_titleBlock->GetComment3();
break;
case '4': case '4':
msg += m_titleBlock->GetComment4(); case '5':
case '6':
case '7':
case '8':
case '9':
msg += m_titleBlock->GetComment( format - '0');
break; break;
default: default:
...@@ -326,43 +323,42 @@ void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aCont ...@@ -326,43 +323,42 @@ void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aCont
throw( IO_ERROR ) throw( IO_ERROR )
{ {
// Don't write the title block information if there is nothing to write. // Don't write the title block information if there is nothing to write.
if( !m_title.IsEmpty() || !m_date.IsEmpty() || !m_revision.IsEmpty() bool isempty = true;
|| !m_company.IsEmpty() || !m_comment1.IsEmpty() || !m_comment2.IsEmpty() for( unsigned idx = 0; idx < m_tbTexts.GetCount(); idx++ )
|| !m_comment3.IsEmpty() || !m_comment4.IsEmpty() ) {
if( ! m_tbTexts[idx].IsEmpty() )
{
isempty = false;
break;
}
}
if( !isempty )
{ {
aFormatter->Print( aNestLevel, "(title_block\n" ); aFormatter->Print( aNestLevel, "(title_block\n" );
if( !m_title.IsEmpty() ) if( !GetTitle().IsEmpty() )
aFormatter->Print( aNestLevel+1, "(title %s)\n", aFormatter->Print( aNestLevel+1, "(title %s)\n",
aFormatter->Quotew( m_title ).c_str() ); aFormatter->Quotew( GetTitle() ).c_str() );
if( !m_date.IsEmpty() ) if( !GetDate().IsEmpty() )
aFormatter->Print( aNestLevel+1, "(date %s)\n", aFormatter->Print( aNestLevel+1, "(date %s)\n",
aFormatter->Quotew( m_date ).c_str() ); aFormatter->Quotew( GetDate() ).c_str() );
if( !m_revision.IsEmpty() ) if( !GetRevision().IsEmpty() )
aFormatter->Print( aNestLevel+1, "(rev %s)\n", aFormatter->Print( aNestLevel+1, "(rev %s)\n",
aFormatter->Quotew( m_revision ).c_str() ); aFormatter->Quotew( GetRevision() ).c_str() );
if( !m_company.IsEmpty() ) if( !GetCompany().IsEmpty() )
aFormatter->Print( aNestLevel+1, "(company %s)\n", aFormatter->Print( aNestLevel+1, "(company %s)\n",
aFormatter->Quotew( m_company ).c_str() ); aFormatter->Quotew( GetCompany() ).c_str() );
if( !m_comment1.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment 1 %s)\n",
aFormatter->Quotew( m_comment1 ).c_str() );
if( !m_comment2.IsEmpty() ) for( int ii = 0; ii < 3; ii++ )
aFormatter->Print( aNestLevel+1, "(comment 2 %s)\n", {
aFormatter->Quotew( m_comment2 ).c_str() ); if( !GetComment(ii).IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment %d %s)\n", ii+1,
if( !m_comment3.IsEmpty() ) aFormatter->Quotew( GetComment(1) ).c_str() );
aFormatter->Print( aNestLevel+1, "(comment 3 %s)\n", }
aFormatter->Quotew( m_comment3 ).c_str() );
if( !m_comment4.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment 4 %s)\n",
aFormatter->Quotew( m_comment4 ).c_str() );
aFormatter->Print( aNestLevel, ")\n\n" ); aFormatter->Print( aNestLevel, ")\n\n" );
} }
......
...@@ -39,49 +39,94 @@ struct IO_ERROR; ...@@ -39,49 +39,94 @@ struct IO_ERROR;
*/ */
class TITLE_BLOCK class TITLE_BLOCK
{ {
// Texts are stored in wxArraystring.
// textsIdx gives the index of known texts in
// this array
enum textsIdx
{
titleIdx = 0,
dateIdx,
revisionIdx,
companyIdx,
m_commentIdx
};
public: public:
// TITLE_BLOCK();
TITLE_BLOCK() {};
virtual ~TITLE_BLOCK() {}; // a virtual dtor seems needed to build virtual ~TITLE_BLOCK() {}; // a virtual dtor seems needed to build
// python lib without warning // python lib without warning
void SetTitle( const wxString& aTitle ) { m_title = aTitle; } void SetTitle( const wxString& aTitle )
const wxString& GetTitle() const { return m_title; } {
setTbText( titleIdx, aTitle );
}
const wxString& GetTitle() const
{
return getTbText( titleIdx );;
}
/** /**
* Function SetDate * Function SetDate
* sets the date field, and defaults to the current time and date. * sets the date field, and defaults to the current time and date.
*/ */
void SetDate( const wxString& aDate ) { m_date = aDate; } void SetDate( const wxString& aDate )
const wxString& GetDate() const { return m_date; } {
setTbText( dateIdx, aDate );
}
const wxString& GetDate() const
{
return getTbText( dateIdx );
}
void SetRevision( const wxString& aRevision )
{
setTbText( revisionIdx, aRevision );
}
const wxString& GetRevision() const
{
return getTbText( revisionIdx );
}
void SetRevision( const wxString& aRevision ) { m_revision = aRevision; } void SetCompany( const wxString& aCompany )
const wxString& GetRevision() const { return m_revision; } {
setTbText( companyIdx, aCompany );
}
void SetCompany( const wxString& aCompany ) { m_company = aCompany; } const wxString& GetCompany() const
const wxString& GetCompany() const { return m_company; } {
return getTbText( companyIdx );
}
void SetComment1( const wxString& aComment ) { m_comment1 = aComment; } void SetComment( int aIdx, const wxString& aComment )
const wxString& GetComment1() const { return m_comment1; } {
aIdx += m_commentIdx;
return setTbText( aIdx, aComment );
}
void SetComment2( const wxString& aComment ) { m_comment2 = aComment; } const wxString& GetComment( int aIdx ) const
const wxString& GetComment2() const { return m_comment2; } {
aIdx += m_commentIdx;
return getTbText( aIdx );
}
void SetComment3( const wxString& aComment ) { m_comment3 = aComment; } // Only for old code compatibility. Will be removed later
const wxString& GetComment3() const { return m_comment3; } void SetComment1( const wxString& aComment ) { SetComment( 0, aComment ); }
void SetComment2( const wxString& aComment ) { SetComment( 1, aComment ); }
void SetComment3( const wxString& aComment ) { SetComment( 2, aComment ); }
void SetComment4( const wxString& aComment ) { SetComment( 3, aComment ); }
const wxString& GetComment1( ) const { return GetComment( 0 ); }
const wxString& GetComment2( ) const { return GetComment( 1 ); }
const wxString& GetComment3( ) const { return GetComment( 2 ); }
const wxString& GetComment4( ) const { return GetComment( 3 ); }
void SetComment4( const wxString& aComment ) { m_comment4 = aComment; }
const wxString& GetComment4() const { return m_comment4; }
void Clear() void Clear()
{ {
m_title.clear(); m_tbTexts.Clear();
m_date.clear();
m_revision.clear();
m_company.clear();
m_comment1.clear();
m_comment2.clear();
m_comment3.clear();
m_comment4.clear();
} }
/** /**
...@@ -97,14 +142,24 @@ public: ...@@ -97,14 +142,24 @@ public:
throw( IO_ERROR ); throw( IO_ERROR );
private: private:
wxString m_title; wxArrayString m_tbTexts;
wxString m_date;
wxString m_revision; void setTbText( int aIdx, const wxString& aText )
wxString m_company; {
wxString m_comment1; if( (int)m_tbTexts.GetCount() <= aIdx )
wxString m_comment2; m_tbTexts.Add( wxEmptyString, aIdx + 1 - m_tbTexts.GetCount() );
wxString m_comment3; m_tbTexts[aIdx] = aText;
wxString m_comment4; }
const wxString& getTbText( int aIdx ) const
{
static const wxString m_emptytext;
if( (int)m_tbTexts.GetCount() > aIdx )
return m_tbTexts[aIdx];
else
return m_emptytext;
}
}; };
#endif // TITLE_BLOCK_H_ #endif // TITLE_BLOCK_H_
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define VECTOR2D_H_ #define VECTOR2D_H_
#include <cmath> #include <cmath>
#include <wx/gdicmn.h> #include <wx/gdicmn.h> // For wxPoint definition
/// Forward declaration for template friends /// Forward declaration for template friends
......
...@@ -7,24 +7,15 @@ ...@@ -7,24 +7,15 @@
#ifndef WORKSHEET_H_ #ifndef WORKSHEET_H_
#define WORKSHEET_H_ #define WORKSHEET_H_
// Forwadr declarations: #include <colors.h> // EDA_COLOR_T definition
// Forward declarations:
class EDA_DRAW_PANEL; class EDA_DRAW_PANEL;
class TITLE_BLOCK; class TITLE_BLOCK;
class PAGE_INFO; class PAGE_INFO;
#define PAS_REF 2000 // Pitch (in mils) of reference locations in worksheet #define PAS_REF 2000 // Pitch (in mils) of reference locations in worksheet
struct Ki_WorkSheetData
{
public:
int m_Type;
Ki_WorkSheetData* Pnext;
int m_Posx, m_Posy;
int m_Endx, m_Endy;
const wxChar* m_TextBase;
int m_Flags;
};
/** /**
* Function DrawPageLayout is a core function to draw the page layout with * Function DrawPageLayout is a core function to draw the page layout with
* the frame and the basic inscriptions. * the frame and the basic inscriptions.
......
...@@ -7,6 +7,156 @@ ...@@ -7,6 +7,156 @@
#ifndef WORKSHEET_SHAPE_BUILDER_H #ifndef WORKSHEET_SHAPE_BUILDER_H
#define WORKSHEET_SHAPE_BUILDER_H #define WORKSHEET_SHAPE_BUILDER_H
#include <vector2d.h>
#include <eda_text.h>
class WS_DRAW_ITEM_TEXT; // Forward declaration
#define TB_DEFAULT_TEXTSIZE 1.5 // default worksheet text size in mm
// Text attributes set in m_Flags (ORed bits)
#define USE_BOLD 1 // has meaning for texts
#define USE_THICK_LINE 1 // equivalent to bold for lines
#define USE_ITALIC 2 // has meaning for texts
#define USE_TEXT_COLOR 4
#define SET_UPPER_LIMIT 8 // Flag used to calculate variable position items
// A coordinate is relative to a page corner.
// Any of the 4 corners can be a reference.
// The default is the right bottom corner
enum corner_anchor
{
RB_CORNER, // right bottom corner
RT_CORNER, // right top corner
LB_CORNER, // left bottom corner
LT_CORNER, // left top corner
};
// a coordinate point
// The position is always relative to the corner anchor
// Note the coordinate is from the anchor point
// to the opposite corner.
class POINT_COORD
{
public:
DPOINT m_Pos;
int m_Anchor;
public:
POINT_COORD() { m_Anchor = RB_CORNER; }
POINT_COORD( DPOINT aPos, enum corner_anchor aAnchor = RB_CORNER )
{
m_Pos = aPos;
m_Anchor = aAnchor;
}
};
// Work sheet structure type definitions.
class WORKSHEET_DATAITEM
{
public:
enum WS_ItemType {
WS_TEXT,
WS_SEGMENT,
WS_RECT
};
WS_ItemType m_Type;
POINT_COORD m_Pos;
POINT_COORD m_End;
double m_LineWidth;
int m_Flags;
int m_RepeatCount; // repeat count for duplicate items
DPOINT m_IncrementVector; // For duplicate items: move vector
// for position increment
int m_IncrementLabel;
static double m_WSunits2Iu; // conversion factor between
// ws units (mils) and draw/plot units
static DPOINT m_RB_Corner; // cordinates of the right bottom corner
// (ws units)
static DPOINT m_LT_Corner; // cordinates of the left top corner
// (ws units)
public:
WORKSHEET_DATAITEM( WS_ItemType aType )
{
m_Type = aType;
m_Flags = 0;
m_RepeatCount = 1;
m_IncrementLabel = 0;
m_LineWidth = 0.0;
}
void SetStart( double aPosx, double aPosy, enum corner_anchor aAnchor = RB_CORNER )
{
m_Pos.m_Pos.x = aPosx;
m_Pos.m_Pos.y = aPosy;
m_Pos.m_Anchor = aAnchor;
}
void SetEnd( double aPosx, double aPosy, enum corner_anchor aAnchor = RB_CORNER )
{
m_End.m_Pos.x = aPosx;
m_End.m_Pos.y = aPosy;
m_End.m_Anchor = aAnchor;
}
const wxPoint GetStartPosUi( int ii = 0 ) const;
const wxPoint GetEndPosUi( int ii = 0 ) const;
const DPOINT GetStartPos( int ii = 0 ) const;
const DPOINT GetEndPos( int ii = 0 ) const;
bool IsInsidePage( int ii ) const;
int GetPenSizeUi() {return KiROUND( m_LineWidth * m_WSunits2Iu ); }
};
class WORKSHEET_DATAITEM_TEXT : public WORKSHEET_DATAITEM
{
public:
wxString m_TextBase; // The basic text, with format symbols
wxString m_FullText; // The expanded text, shown on screen
int m_IncrementLabel;
double m_Orient; // Orientation in degrees
enum EDA_TEXT_HJUSTIFY_T m_Hjustify;
enum EDA_TEXT_VJUSTIFY_T m_Vjustify;
DSIZE m_TextSize;
DSIZE m_BoundingBoxSize; // When not null, this is the max
// size of the full text.
// the text size will be modified
// to keep the full text insite this
// bound.
DSIZE m_ConstrainedTextSize;// Actual text size, if constrained by
// the m_BoundingBoxSize constraint
public:
WORKSHEET_DATAITEM_TEXT( const wxChar* aTextBase );
/**
* transfert the text justification and orientation
* to aGText
*/
void TransfertSetupToGraphicText( WS_DRAW_ITEM_TEXT* aGText );
/**
* Try to build text wihich is an increment of m_TextBase
* has meaning only if m_TextBase is a basic text (one char)
* If the basic char is a digit, build a number
* If the basic char is a letter, use the letter with ascii code
* aIncr + (basic char ascc code)
* @param aIncr = the increment value
* return the incremented label in m_FullText
*/
void IncrementLabel( int aIncr );
/**
* Calculates m_ConstrainedTextSize from m_TextSize
* to keep the X size and the full Y size of the text
* smaller than m_BoundingBoxSize
* if m_BoundingBoxSize.x or m_BoundingBoxSize.y > 0
* if m_BoundingBoxSize.x or m_BoundingBoxSize.y == 0
* the corresponding text size is not constrained
*/
void SetConstrainedTextSize();
};
/* /*
* Helper classes to handle basic graphic items used to raw/plot * Helper classes to handle basic graphic items used to raw/plot
...@@ -22,9 +172,11 @@ public: ...@@ -22,9 +172,11 @@ public:
enum WS_DRAW_TYPE { enum WS_DRAW_TYPE {
wsg_line, wsg_rect, wsg_poly, wsg_text wsg_line, wsg_rect, wsg_poly, wsg_text
}; };
protected: protected:
WS_DRAW_TYPE m_type; // wsg_line, wsg_rect, wsg_poly, wsg_text WS_DRAW_TYPE m_type; // wsg_line, wsg_rect, wsg_poly, wsg_text
EDA_COLOR_T m_color; EDA_COLOR_T m_color;
protected: protected:
WS_DRAW_ITEM_BASE( WS_DRAW_TYPE aType, EDA_COLOR_T aColor ) WS_DRAW_ITEM_BASE( WS_DRAW_TYPE aType, EDA_COLOR_T aColor )
{ {
...@@ -133,7 +285,8 @@ class WS_DRAW_ITEM_LIST ...@@ -133,7 +285,8 @@ class WS_DRAW_ITEM_LIST
wxSize m_pageSize; // the page size in mils wxSize m_pageSize; // the page size in mils
double m_milsToIu; // the scalar to convert pages units ( mils) double m_milsToIu; // the scalar to convert pages units ( mils)
// to draw/plot units. // to draw/plot units.
int m_penSize; // The line width for drawings. int m_penSize; // The default line width for drawings.
// used when an item has a pen size = 0
int m_sheetNumber; // the value of the sheet number, for basic inscriptions int m_sheetNumber; // the value of the sheet number, for basic inscriptions
int m_sheetCount; // the value of the number of sheets, in schematic int m_sheetCount; // the value of the number of sheets, in schematic
// for basic inscriptions, in schematic // for basic inscriptions, in schematic
...@@ -298,4 +451,52 @@ public: ...@@ -298,4 +451,52 @@ public:
}; };
/**
* WORKSHEET_LAYOUT handles the grpahic items list to draw/plot
* the title block and other items (page references ...
*/
class WORKSHEET_LAYOUT
{
std::vector <WORKSHEET_DATAITEM*> m_list;
public:
WORKSHEET_LAYOUT() {};
~WORKSHEET_LAYOUT() {ClearList(); }
void ClearList()
{
for( unsigned ii = 0; ii < m_list.size(); ii++ )
delete m_list[ii];
}
/**
* Add an item to the list of items
*/
void Append( WORKSHEET_DATAITEM* aItem )
{
m_list.push_back( aItem );
}
/**
* @return the item from its index aIdx, or NULL if does not exist
*/
WORKSHEET_DATAITEM* GetItem( unsigned aIdx ) const
{
if( aIdx < m_list.size() )
return m_list[aIdx];
else
return NULL;
}
/**
* @return the item count
*/
unsigned GetCount() const { return m_list.size(); }
/**
* Fills the list with the default layout shape
*/
void SetDefaultLayout();
};
#endif // WORKSHEET_SHAPE_BUILDER_H #endif // WORKSHEET_SHAPE_BUILDER_H
...@@ -64,37 +64,12 @@ static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) ); ...@@ -64,37 +64,12 @@ static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) );
// Helper function to print a float number without using scientific notation // Helper function to print a float number without using scientific notation
// and no trailing 0 // and no trailing 0
// We want to avoid scientific notation in S-expr files (not easy to read)
// for floating numbers.
// So we cannot always just use the %g or the %f format to print a fp number
// this helper function uses the %f format when needed, or %g when %f is
// not well working and then removes trailing 0
#if 0
// Does not work for aValue < 0.0001 and > 0.
// Will need to support exponents in DSNLEXER if we get exponents > 16, i.e. the "precision".
std::string double2str( double aValue )
{
char buf[50];
int len;
if( aValue != 0.0 && fabs( aValue ) <= 0.0001 )
{
len = sprintf( buf, "%.10f", aValue );
while( --len > 0 && buf[len] == '0' )
buf[len] = '\0';
if( buf[len] == '.' )
buf[len--] = '\0';
++len;
}
else
{
len = sprintf( buf, "%.10g", mm );
}
return std::string( buf, len );
}
#else
// this one handles 0.00001 ok, and 1.222222222222222 ok, previous did not.
std::string double2str( double aValue ) std::string double2str( double aValue )
{ {
char buf[50]; char buf[50];
...@@ -102,6 +77,8 @@ std::string double2str( double aValue ) ...@@ -102,6 +77,8 @@ std::string double2str( double aValue )
if( aValue != 0.0 && fabs( aValue ) <= 0.0001 ) if( aValue != 0.0 && fabs( aValue ) <= 0.0001 )
{ {
// For these small values, %f works fine,
// and %g gives an exponent
len = sprintf( buf, "%.16f", aValue ); len = sprintf( buf, "%.16f", aValue );
while( --len > 0 && buf[len] == '0' ) while( --len > 0 && buf[len] == '0' )
...@@ -114,12 +91,13 @@ std::string double2str( double aValue ) ...@@ -114,12 +91,13 @@ std::string double2str( double aValue )
} }
else else
{ {
// For these values, %g works fine, and sometimes %f
// gives a bad value (try aValue = 1.222222222222, with %.16f format!)
len = sprintf( buf, "%.16g", aValue ); len = sprintf( buf, "%.16g", aValue );
} }
return std::string( buf, len );; return std::string( buf, len );;
} }
#endif
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment