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