KiCad PCB EDA Suite
Loading...
Searching...
No Matches
easypc_design_settings.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <cmath>
23#include <cstring>
24#include <map>
25
26#include <boost/endian/conversion.hpp>
27
29#include <ki_exception.h>
30#include <title_block.h>
31#include <wx/datetime.h>
32#include <wx/strconv.h>
33#include <wx/translation.h>
34
35
36namespace EASYPC
37{
38
39namespace
40{
41
42 // FMTID_SummaryInformation {F29F85E0-4FF9-1068-AB91-08002B27B3D9} as stored
43 const uint8_t FMTID_SUMMARY[16] = { 0xE0, 0x85, 0x9F, 0xF2, 0xF9, 0x4F, 0x68, 0x10,
44 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 };
45
46 constexpr uint32_t VT_LPSTR = 30;
47 constexpr uint32_t VT_FILETIME = 64;
48 constexpr uint32_t PID_LASTSAVE_DTM = 13;
49
50 // Seconds between the FILETIME epoch (1601) and the Unix epoch
51 constexpr int64_t FILETIME_UNIX_OFFSET = 11644473600LL;
52
53} // namespace
54
55
56void FillTitleBlock( const DESIGN_DOCUMENT& aDoc, TITLE_BLOCK& aTitleBlock )
57{
58 // An OLE property set holding the design's document properties
59 const std::vector<uint8_t>& data = aDoc.SummaryInformation;
60
61 if( data.empty() )
62 return;
63
64 auto bytes = [&]( size_t aOffset, size_t aLen ) -> const uint8_t*
65 {
66 if( aOffset > data.size() || data.size() - aOffset < aLen )
67 THROW_IO_ERROR( wxString::Format( _( "Easy-PC SummaryInformation is cut short at %zu." ), aOffset ) );
68
69 return data.data() + aOffset;
70 };
71
72 auto u32 = [&]( size_t aOffset )
73 {
74 return boost::endian::load_little_u32( bytes( aOffset, 4 ) );
75 };
76
77 if( ( u32( 0 ) & 0xFFFF ) != 0xFFFE )
78 THROW_IO_ERROR( _( "Easy-PC SummaryInformation has no byte order mark." ) );
79
80 size_t section = 0;
81
82 for( uint32_t i = 0; i < u32( 24 ) && !section; ++i )
83 {
84 if( std::memcmp( bytes( 28 + size_t( i ) * 20, 16 ), FMTID_SUMMARY, 16 ) == 0 )
85 section = u32( 28 + size_t( i ) * 20 + 16 );
86 }
87
88 if( !section )
89 return;
90
91 static const wxCSConv cp1252( wxFONTENCODING_CP1252 );
92 std::map<uint32_t, wxString> text;
93 wxString saved;
94
95 for( uint32_t i = 0; i < u32( section + 4 ); ++i )
96 {
97 size_t entry = section + 8 + size_t( i ) * 8;
98 uint32_t pid = u32( entry );
99 size_t prop = section + u32( entry + 4 );
100 uint32_t type = u32( prop ) & 0xFFFF;
101
102 if( type == VT_LPSTR )
103 {
104 // The length counts the terminating NUL
105 uint32_t len = u32( prop + 4 );
106 const char* chars = reinterpret_cast<const char*>( bytes( prop + 8, len ) );
107 text[pid] = wxString( chars, cp1252, strnlen( chars, len ) );
108 }
109 else if( type == VT_FILETIME && pid == PID_LASTSAVE_DTM )
110 {
111 uint64_t ft = u32( prop + 4 ) | ( uint64_t( u32( prop + 8 ) ) << 32 );
112
113 if( ft )
114 saved = wxDateTime( time_t( int64_t( ft / 10000000ULL ) - FILETIME_UNIX_OFFSET ) ).FormatISODate();
115 }
116 }
117
118 aTitleBlock.SetTitle( text[2] );
119
120 if( !saved.IsEmpty() )
121 aTitleBlock.SetDate( saved );
122
123 // Subject, author, keywords and comments
124 for( int i = 0; i < 4; ++i )
125 aTitleBlock.SetComment( i, text[3 + i] );
126}
127
128
129PAGE_INFO PageForExtents( const BOX2L& aExtentsNm )
130{
131 const double needW = aExtentsNm.GetWidth() / 1e6 + 2 * PAGE_MARGIN_MM;
132 const double needH = aExtentsNm.GetHeight() / 1e6 + 2 * PAGE_MARGIN_MM;
133
134 for( PAGE_SIZE_TYPE type :
137 {
138 for( bool portrait : { false, true } )
139 {
140 PAGE_INFO page( type, portrait );
141
142 if( page.GetWidthMM() >= needW && page.GetHeightMM() >= needH )
143 return page;
144 }
145 }
146
148 user.SetWidthMM( std::ceil( needW ) );
149 user.SetHeightMM( std::ceil( needH ) );
150 return user;
151}
152
153} // namespace EASYPC
BOX2< VECTOR2L > BOX2L
Definition box2.h:916
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr size_type GetHeight() const
Definition box2.h:212
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition page_info.h:75
void SetWidthMM(double aWidthInMM)
Definition page_info.h:135
void SetHeightMM(double aHeightInMM)
Definition page_info.h:140
double GetHeightMM() const
Definition page_info.h:143
double GetWidthMM() const
Definition page_info.h:138
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition title_block.h:38
void SetComment(int aIdx, const wxString &aComment)
Definition title_block.h:98
void SetTitle(const wxString &aTitle)
Definition title_block.h:55
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
Definition title_block.h:68
Title block and page size, shared by the board and schematic builders.
Loading designs, library items and projects.
#define _(s)
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
PAGE_INFO PageForExtents(const BOX2L &aExtentsNm)
Easy-PC stores no page size, so the first of A4 to A0 then A to E, landscape before portrait,...
constexpr double PAGE_MARGIN_MM
Margin added on every side of the drawn extents before choosing a page, in millimetres.
void FillTitleBlock(const DESIGN_DOCUMENT &aDoc, TITLE_BLOCK &aTitleBlock)
Fill a title block from the design's SummaryInformation property set: title from Title,...
PAGE_SIZE_TYPE
Definition page_info.h:46
std::vector< uint8_t > SummaryInformation
the SummaryInformation stream, if any