Optimize PDF plot data size for property popups; fix unicode escape.
Adds a document-level action JSInit, which defines ShM function, allowing more compact data representation. Also reduces whitespaces.
This commit is contained in:
parent
b09ab2daab
commit
afe176abe2
|
@ -909,6 +909,8 @@ bool PDF_PLOTTER::StartPlot( const wxString& aPageNumber, const wxString& aPageN
|
|||
(it *could* be inherited via the Pages tree */
|
||||
m_fontResDictHandle = allocPdfObject();
|
||||
|
||||
m_jsNamesHandle = allocPdfObject();
|
||||
|
||||
/* Now, the PDF is read from the end, (more or less)... so we start
|
||||
with the page stream for page 1. Other more important stuff is written
|
||||
at the end */
|
||||
|
@ -980,31 +982,32 @@ void PDF_PLOTTER::emitOutlineNode( OUTLINE_NODE* node, int parentHandle, int nex
|
|||
startPdfObject( nodeHandle );
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"<< /Title %s\n"
|
||||
" /Parent %d 0 R\n",
|
||||
"<<\n"
|
||||
"/Title %s\n"
|
||||
"/Parent %d 0 R\n",
|
||||
encodeStringForPlotter(node->title ).c_str(),
|
||||
parentHandle);
|
||||
|
||||
if( nextNode > 0 )
|
||||
{
|
||||
fprintf( m_outputFile, " /Next %d 0 R\n", nextNode );
|
||||
fprintf( m_outputFile, "/Next %d 0 R\n", nextNode );
|
||||
}
|
||||
|
||||
if( prevNode > 0 )
|
||||
{
|
||||
fprintf( m_outputFile, " /Prev %d 0 R\n", prevNode );
|
||||
fprintf( m_outputFile, "/Prev %d 0 R\n", prevNode );
|
||||
}
|
||||
|
||||
if( node->children.size() > 0 )
|
||||
{
|
||||
fprintf( m_outputFile, " /Count %zd\n", -1 * node->children.size() );
|
||||
fprintf( m_outputFile, " /First %d 0 R\n", node->children.front()->entryHandle );
|
||||
fprintf( m_outputFile, " /Last %d 0 R\n", node->children.back()->entryHandle );
|
||||
fprintf( m_outputFile, "/Count %zd\n", -1 * node->children.size() );
|
||||
fprintf( m_outputFile, "/First %d 0 R\n", node->children.front()->entryHandle );
|
||||
fprintf( m_outputFile, "/Last %d 0 R\n", node->children.back()->entryHandle );
|
||||
}
|
||||
|
||||
if( node->actionHandle != -1 )
|
||||
{
|
||||
fprintf( m_outputFile, " /A %d 0 R\n", node->actionHandle );
|
||||
fprintf( m_outputFile, "/A %d 0 R\n", node->actionHandle );
|
||||
}
|
||||
|
||||
fputs( ">>\n", m_outputFile );
|
||||
|
@ -1114,10 +1117,11 @@ bool PDF_PLOTTER::EndPlot()
|
|||
startPdfObject( linkHandle );
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"<< /Type /Annot\n"
|
||||
" /Subtype /Link\n"
|
||||
" /Rect [%g %g %g %g]\n"
|
||||
" /Border [16 16 0]\n",
|
||||
"<<\n"
|
||||
"/Type /Annot\n"
|
||||
"/Subtype /Link\n"
|
||||
"/Rect [%g %g %g %g]\n"
|
||||
"/Border [16 16 0]\n",
|
||||
box.GetLeft(), box.GetBottom(), box.GetRight(), box.GetTop() );
|
||||
|
||||
wxString pageNumber;
|
||||
|
@ -1130,7 +1134,7 @@ bool PDF_PLOTTER::EndPlot()
|
|||
if( m_pageNumbers[ii] == pageNumber )
|
||||
{
|
||||
fprintf( m_outputFile,
|
||||
" /Dest [%d 0 R /FitB]\n"
|
||||
"/Dest [%d 0 R /FitB]\n"
|
||||
">>\n",
|
||||
m_pageHandles[ii] );
|
||||
|
||||
|
@ -1142,15 +1146,14 @@ bool PDF_PLOTTER::EndPlot()
|
|||
if( !pageFound )
|
||||
{
|
||||
// destination page is not being plotted, assign the NOP action to the link
|
||||
fprintf( m_outputFile,
|
||||
" /A << /Type /Action /S /NOP >>\n"
|
||||
">>\n" );
|
||||
fprintf( m_outputFile, "/A << /Type /Action /S /NOP >>\n"
|
||||
">>\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( m_outputFile,
|
||||
" /A << /Type /Action /S /URI /URI %s >>\n"
|
||||
"/A << /Type /Action /S /URI /URI %s >>\n"
|
||||
">>\n",
|
||||
encodeStringForPlotter( url ).c_str() );
|
||||
}
|
||||
|
@ -1162,7 +1165,7 @@ bool PDF_PLOTTER::EndPlot()
|
|||
{
|
||||
const BOX2D& box = menuPair.first;
|
||||
const std::vector<wxString>& urls = menuPair.second;
|
||||
wxString js = wxT( "var aParams = [ " );
|
||||
wxString js = wxT( "ShM([\n" );
|
||||
|
||||
for( const wxString& url : urls )
|
||||
{
|
||||
|
@ -1174,7 +1177,7 @@ bool PDF_PLOTTER::EndPlot()
|
|||
{
|
||||
wxString href = property.substr( property.Find( "http:" ) );
|
||||
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: '%s' }, " ),
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( property, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ) );
|
||||
}
|
||||
|
@ -1182,13 +1185,13 @@ bool PDF_PLOTTER::EndPlot()
|
|||
{
|
||||
wxString href = property.substr( property.Find( "https:" ) );
|
||||
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: '%s' }, " ),
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( property, CTX_JS_STR ),
|
||||
EscapeString( href, CTX_JS_STR ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: null }, " ),
|
||||
js += wxString::Format( wxT( "[\"%s\"],\n" ),
|
||||
EscapeString( property, CTX_JS_STR ) );
|
||||
}
|
||||
}
|
||||
|
@ -1202,7 +1205,7 @@ bool PDF_PLOTTER::EndPlot()
|
|||
{
|
||||
wxString menuText = wxString::Format( _( "Show Page %s" ), pageNumber );
|
||||
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: '#%d' }, " ),
|
||||
js += wxString::Format( wxT( "[\"%s\", \"#%d\"],\n" ),
|
||||
EscapeString( menuText, CTX_JS_STR ),
|
||||
static_cast<int>( ii ) );
|
||||
break;
|
||||
|
@ -1213,33 +1216,58 @@ bool PDF_PLOTTER::EndPlot()
|
|||
{
|
||||
wxString menuText = wxString::Format( _( "Open %s" ), url );
|
||||
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: '%s' }, " ),
|
||||
js += wxString::Format( wxT( "[\"%s\", \"%s\"],\n" ),
|
||||
EscapeString( menuText, CTX_JS_STR ),
|
||||
EscapeString( url, CTX_JS_STR ) );
|
||||
}
|
||||
}
|
||||
|
||||
js += wxT( "]; " );
|
||||
|
||||
js += wxT( "var cChoice = app.popUpMenuEx.apply\\( app, aParams \\); " );
|
||||
js += wxT( "if\\( cChoice != null && cChoice.substring\\( 0, 1 \\) == '#' \\)"
|
||||
" this.pageNum = parseInt\\( cChoice.slice\\( 1 \\) \\); " );
|
||||
js += wxT( "else if\\( cChoice != null && cChoice.substring\\( 0, 4 \\) == 'http' \\)"
|
||||
" app.launchURL\\( cChoice \\);" );
|
||||
js += wxT( "]);" );
|
||||
|
||||
startPdfObject( menuHandle );
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"<< /Type /Annot\n"
|
||||
" /Subtype /Link\n"
|
||||
" /Rect [%g %g %g %g]\n"
|
||||
" /Border [16 16 0]\n",
|
||||
"<<\n"
|
||||
"/Type /Annot\n"
|
||||
"/Subtype /Link\n"
|
||||
"/Rect [%g %g %g %g]\n"
|
||||
"/Border [16 16 0]\n",
|
||||
box.GetLeft(), box.GetBottom(), box.GetRight(), box.GetTop() );
|
||||
|
||||
fprintf( m_outputFile,
|
||||
" /A << /Type /Action /S /JavaScript /JS (%s) >>\n"
|
||||
"/A << /Type /Action /S /JavaScript /JS %s >>\n"
|
||||
">>\n",
|
||||
js.ToStdString().c_str() );
|
||||
encodeStringForPlotter( js ).c_str() );
|
||||
|
||||
closePdfObject();
|
||||
}
|
||||
|
||||
{
|
||||
startPdfObject( m_jsNamesHandle );
|
||||
|
||||
wxString js = R"JS(
|
||||
function ShM(aEntries) {
|
||||
var aParams = [];
|
||||
for (var i in aEntries) {
|
||||
aParams.push({
|
||||
cName: aEntries[i][0],
|
||||
cReturn: aEntries[i][1]
|
||||
})
|
||||
}
|
||||
|
||||
var cChoice = app.popUpMenuEx.apply(app, aParams);
|
||||
if (cChoice != null && cChoice.substring(0, 1) == '#') this.pageNum = parseInt(cChoice.slice(1));
|
||||
else if (cChoice != null && cChoice.substring(0, 4) == 'http') app.launchURL(cChoice);
|
||||
}
|
||||
)JS";
|
||||
|
||||
fprintf( m_outputFile,
|
||||
"<< /JavaScript\n"
|
||||
" << /Names\n"
|
||||
" [ (JSInit) << /Type /Action /S /JavaScript /JS %s >> ]\n"
|
||||
" >>\n"
|
||||
">>\n",
|
||||
encodeStringForPlotter( js ).c_str() );
|
||||
|
||||
closePdfObject();
|
||||
}
|
||||
|
@ -1303,10 +1331,12 @@ bool PDF_PLOTTER::EndPlot()
|
|||
"/Version /1.5\n"
|
||||
"/PageMode /UseOutlines\n"
|
||||
"/Outlines %d 0 R\n"
|
||||
"/Names %d 0 R\n"
|
||||
"/PageLayout /SinglePage\n"
|
||||
">>\n",
|
||||
m_pageTreeHandle,
|
||||
outlineHandle );
|
||||
outlineHandle,
|
||||
m_jsNamesHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -203,7 +203,7 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
|||
{
|
||||
unsigned int code = c;
|
||||
char buffer[16];
|
||||
snprintf( buffer, sizeof(buffer), "\\\\u%4.4X", code );
|
||||
snprintf( buffer, sizeof(buffer), "\\u%4.4X", code );
|
||||
converted += buffer;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.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
|
||||
|
@ -493,6 +493,7 @@ protected:
|
|||
|
||||
int m_pageTreeHandle; ///< Handle to the root of the page tree object
|
||||
int m_fontResDictHandle; ///< Font resource dictionary
|
||||
int m_jsNamesHandle; ///< Handle for Names dictionary with JS
|
||||
std::vector<int> m_pageHandles; ///< Handles to the page objects
|
||||
int m_pageStreamHandle; ///< Handle of the page content object
|
||||
int m_streamLengthHandle; ///< Handle to the deferred stream length
|
||||
|
|
Loading…
Reference in New Issue