OK, in attachment are 2 patch files, please review.
First one fixes several problems:
1. The most outstanding bug is that the width and height should
exchange positions in BoundingBox!!
2. The logic to determine scale factor is a mess, including
several minor logical problems.
And I extract it into a separate function, because it will be
used in both Gdraws_setDimension and PSCreateFile.
Second patch is to adjust the position of BoundingBox.
- Qian
On 4/13/24 21:14, Waldek Hebisch wrote:
On Sat, Apr 13, 2024 at 05:25:17PM +0800, Qian Yun wrote:
One of the problems of postscript files generated by "draw" is that
it is not proper "embedded postscript file", aka "eps".
When trying to include such image files in latex document, there are
huge padding around image.
The problem is caused by "BoundingBox". We have "BoundingBox" in
generated PS file, but almost all utilities such as "ps2pdf",
"epstopdf" only recognize "BoundingBox" in the header comment section.
FriCAS generates "BoundingBox" in the middle of the PS file.
Following patch is a proof of concept to fix this issue.
After this patch, I can use "epstopdf" to convert PS file to
properly cropped pdf file.
Thanks for looking into this.
I think for a proper fix, a better way is to split "headerps"
into two and add a "boundingbox" patch in between?
Hmm, I would remove the '%!PS-Adobe-2.0' comment from 'header.ps'
(as you do). IIUC 'BoundingBox' comment is supposed to appear
just after '%!PS-Adobe-2.0', so it is natural to print both
together, like you do.
I have some doubts concerning use 'vwInfo.height' and 'vwInfo.width'.
Namely, 'Gdraws_setDimension' clearly make some effort to fit
image onto page (it put appropriate rescaling operation into .ps file).
So, it seems that 'Gdraws_setDimension' computes _real_ bounding
box and we should use it in 'BoundingBox' comment. Currently,
as you noted 'BoundingBox' comment is ignored and typical
images fit inside page, so nothing bad happens due to possibly
incorrect bouding box. But for people with big screens and
in case we make 'Gdraws_setDimension' smarter we should use
dimensions computed in 'Gdraws_setDimension' when emiting
'BoundingBox' comment. Which probably means that we should
propagate information from 'Gdraws_setDimension' to
'PSCreateFile'.
- Qian
--
You received this message because you are subscribed to the Google Groups "FriCAS -
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/fricas-devel/04cae6f4-5408-4cfe-89b0-c73fc5eeb585%40gmail.com.
diff --git a/src/graph/Gdraws/Gfun.c b/src/graph/Gdraws/Gfun.c
index e21defd4..f9bdd047 100644
--- a/src/graph/Gdraws/Gfun.c
+++ b/src/graph/Gdraws/Gfun.c
@@ -125,6 +125,15 @@ PSCreateFile(
return (psError);
}
else {
+ fprintf(ofp, "%%!PS-Adobe-2.0\n");
+
+ /* Write a Bounding Box for psfig etc. */
+ XWindowAttributes vwInfo;
+ XGetWindowAttributes(dsply, vw, &vwInfo);
+ float scale = Gdraws_computeScale(vw, tw);
+ fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n",
+ (int) (scale * vwInfo.width), (int) (scale * vwInfo.height));
+
i = 1;
while (i < psDrawNo) { /* loops through each file/procedure */
if (psData[i].flag) { /* if set, procedure/file is used */
@@ -230,11 +239,6 @@ Gdraws_setDimension(
fprintf(fp, "\t%d\t%d\t%d\tsetDim\n", twInfo.height - vwInfo.height,
vwInfo.height, vwInfo.width);
- /* Write a Bounding Box for psfig etc. */
-
- fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n",
- (int) (scale * vwInfo.width), (int) (scale * vwInfo.height));
-
fprintf(fp, "\tmaxX maxY\t0 0\trectangle\tclip\t%% set clip path\n\n");
return (fclose(fp));
}
diff --git a/src/graph/Gdraws/ps_files/header.ps b/src/graph/Gdraws/ps_files/header.ps
index e945bec4..037914ac 100644
--- a/src/graph/Gdraws/ps_files/header.ps
+++ b/src/graph/Gdraws/ps_files/header.ps
@@ -1,4 +1,3 @@
-%!PS-Adobe-2.0
%%DocumentFonts: Times-Roman
%%Creator: FriCAS
%%CreationDate: today
diff --git a/src/graph/Gdraws/Gfun.c b/src/graph/Gdraws/Gfun.c
index 808822aa..e21defd4 100644
--- a/src/graph/Gdraws/Gfun.c
+++ b/src/graph/Gdraws/Gfun.c
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include "Gdraws0.h"
#include "G.h"
@@ -61,6 +62,32 @@ filecopy(FILE * ifp, FILE * ofp)
putc(c, ofp);
}
+/*
+ * Gdraws_computeScale calculates a scale factor based on the
+ * dimensions of the picture and page size.
+ */
+
+float Gdraws_computeScale(Window vw, Window tw) {
+ XWindowAttributes vwInfo;
+ float pageWidth, pageHeight, scale;
+
+ XGetWindowAttributes(dsply, vw, &vwInfo);
+ pageWidth = 575.0;
+ pageHeight = 750.0;
+#if 0
+ pageWidth = (float) (DisplayWidth(dsply, scrn) / DisplayWidthMM(dsply, scrn));
+ pageWidth *= 160.0;
+ pageHeight = (float) (DisplayHeight(dsply, scrn) / DisplayHeightMM(dsply, scrn));
+ pageHeight *= 210.0;
+ fprintf(stderr, "%f, %f\n", pageWidth, pageHeight);
+#endif
+ if ((vwInfo.width > pageWidth) || (vwInfo.height > pageHeight)) {
+ scale = fminf(pageWidth / vwInfo.width, pageHeight / vwInfo.height);
+ } else {
+ scale = 1.0;
+ }
+ return scale;
+}
/*
* PSCreateFile generates the output file by using the order of defined
@@ -189,46 +216,24 @@ Gdraws_setDimension(
{
FILE *fp;
XWindowAttributes vwInfo, twInfo;
- float pageWidth, pageHeight, width;
fp = fopen(psData[scriptps].filename, "w");
XGetWindowAttributes(dsply, titleWindow, &twInfo);
XGetWindowAttributes(dsply, viewWindow, &vwInfo);
- pageWidth = 575.0;
- pageHeight = 750.0;
-
-#if 0
- pageWidth = (float) (DisplayWidth(dsply, scrn) / DisplayWidthMM(dsply, scrn));
- pageWidth *= 160.0;
- pageHeight = (float) (DisplayHeight(dsply, scrn) / DisplayHeightMM(dsply, scrn));
- pageHeight *= 210.0;
- fprintf(stderr, "%f, %f\n", pageWidth, pageHeight);
-#endif
fprintf(fp, "\n gsave\t%% save graphics state for clipping path\n\n");
- if ((vwInfo.height > pageWidth) || (vwInfo.height > pageHeight)) {
- width = (float) vwInfo.width;
- if (vwInfo.height > pageWidth) {
- width = pageWidth / width;
- fprintf(fp, "\t%f\t%f", width, width);
- }
- else {
- if (vwInfo.height > pageHeight)
- fprintf(fp, "\t%f\t%f", width, pageHeight / width);
- }
- }
- else {
- fprintf(fp, "\t%f\t%f", 1.0, 1.0);
- }
- fprintf(fp, "\tscale\n\n");
+
+ float scale = Gdraws_computeScale(viewWindow, titleWindow);
+ fprintf(fp, "\t%f\t%f\tscale\n\n", scale, scale);
fprintf(fp, "\t%d\t%d\t%d\tsetDim\n", twInfo.height - vwInfo.height,
vwInfo.height, vwInfo.width);
/* Write a Bounding Box for psfig etc. */
- fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n", vwInfo.height, vwInfo.width);
+ fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n",
+ (int) (scale * vwInfo.width), (int) (scale * vwInfo.height));
fprintf(fp, "\tmaxX maxY\t0 0\trectangle\tclip\t%% set clip path\n\n");
return (fclose(fp));