Fix xref table - wrong total number of objects.

Update pdfioContentDrawImage to take x/y offsets and sizes.
This commit is contained in:
Michael R Sweet 2021-05-28 22:05:44 -04:00
parent fb853dadda
commit 94cb915885
No known key found for this signature in database
GPG Key ID: 999559A027815955
5 changed files with 86 additions and 23 deletions

View File

@ -68,9 +68,13 @@ pdfioContentClip(
bool // O - `true` on success, `false` on failure
pdfioContentDrawImage(
pdfio_stream_t *st, // I - Stream
const char *name) // I - Image name
const char *name, // I - Image name
float x, // I - X offset of image
float y, // I - Y offset of image
float w, // I - Width of image
float h) // I - Height of image
{
return (pdfioStreamPrintf(st, "/%s Do\n", name));
return (pdfioStreamPrintf(st, "q %g 0 0 %g %g %g cm/%s Do Q\n", w, h, x, y, name));
}
@ -962,7 +966,7 @@ pdfioFileCreateImageObject(
}
pdfioDictSetName(dict, "Type", "XObject");
pdfioDictSetName(dict, "SubType", "Image");
pdfioDictSetName(dict, "Subtype", "Image");
pdfioDictSetBoolean(dict, "Interpolate", interpolate);
obj = (copy_func)(dict, fd);
@ -974,6 +978,28 @@ pdfioFileCreateImageObject(
}
//
// 'pdfioImageGetHeight()' - Get the height of an image object.
//
float // O - Height in lines
pdfioImageGetHeight(pdfio_obj_t *obj) // I - Image object
{
return (pdfioDictGetNumber(obj->value.value.dict, "Height"));
}
//
// 'pdfioImageGetWidth()' - Get the width of an image object.
//
float // O - Width in columns
pdfioImageGetWidth(pdfio_obj_t *obj) // I - Image object
{
return (pdfioDictGetNumber(obj->value.value.dict, "Width"));
}
//
// 'copy_gif()' - Copy a GIF image.
//
@ -1094,7 +1120,8 @@ copy_jpeg(pdfio_dict_t *dict, // I - Dictionary
pdfioDictSetNumber(dict, "Width", width);
pdfioDictSetNumber(dict, "Height", height);
pdfioDictSetNumber(dict, "BitsPerComponent", 8);
pdfioDictSetName(dict, "ColorSpace", num_colors == 3 ? "CalRGB" : "CalGray");
// TODO: Add proper JPEG CalRGB/Gray color spaces
pdfioDictSetName(dict, "ColorSpace", num_colors == 3 ? "DeviceRGB" : "DeviceGray");
pdfioDictSetName(dict, "Filter", "DCTDecode");
obj = pdfioFileCreateObject(dict->pdf, dict);

View File

@ -79,7 +79,7 @@ extern const float pdfioSRGBWhitePoint[];
// PDF content drawing functions...
extern bool pdfioContentBeginText(pdfio_stream_t *st) PDFIO_PUBLIC;
extern bool pdfioContentClip(pdfio_stream_t *st, bool even_odd) PDFIO_PUBLIC;
extern bool pdfioContentDrawImage(pdfio_stream_t *st, const char *name) PDFIO_PUBLIC;
extern bool pdfioContentDrawImage(pdfio_stream_t *st, const char *name, float x, float y, float w, float h) PDFIO_PUBLIC;
extern bool pdfioContentEndText(pdfio_stream_t *st) PDFIO_PUBLIC;
extern bool pdfioContentFill(pdfio_stream_t *st, bool even_odd) PDFIO_PUBLIC;
extern bool pdfioContentFillAndStroke(pdfio_stream_t *st, bool even_odd) PDFIO_PUBLIC;
@ -129,17 +129,21 @@ extern bool pdfioContentTextNextLine(pdfio_stream_t *st) PDFIO_PUBLIC;
extern bool pdfioContentTextShow(pdfio_stream_t *st, const char *s, bool new_line) PDFIO_PUBLIC;
extern bool pdfioContentTextShowJustified(pdfio_stream_t *st, size_t num_fragments, const float *offsets, const char * const *fragments) PDFIO_PUBLIC;
// Resource helpers...
extern pdfio_obj_t *pdfioFileCreateFontObject(pdfio_file_t *pdf, const char *filename) PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateICCProfileObject(pdfio_file_t *pdf, const char *filename) PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateImageObject(pdfio_file_t *pdf, const char *filename, bool interpolate) PDFIO_PUBLIC;
// Image object helpers...
extern float pdfioImageGetHeight(pdfio_obj_t *obj) PDFIO_PUBLIC;
extern float pdfioImageGetWidth(pdfio_obj_t *obj) PDFIO_PUBLIC;
// Page dictionary helpers...
extern bool pdfioPageDictAddICCColorSpace(pdfio_dict_t *dict, const char *name, pdfio_obj_t *obj) PDFIO_PUBLIC;
extern bool pdfioPageDictAddCalibratedColorSpace(pdfio_dict_t *dict, const char *name, size_t num_colors, const float *white_point, float gamma) PDFIO_PUBLIC;
extern bool pdfioPageDictAddFont(pdfio_dict_t *dict, const char *name, pdfio_obj_t *obj) PDFIO_PUBLIC;
extern bool pdfioPageDictAddImage(pdfio_dict_t *dict, const char *name, pdfio_obj_t *obj) PDFIO_PUBLIC;
// Resource helpers...
extern pdfio_obj_t *pdfioFileCreateFontObject(pdfio_file_t *pdf, const char *filename) PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateICCProfileObject(pdfio_file_t *pdf, const char *filename) PDFIO_PUBLIC;
extern pdfio_obj_t *pdfioFileCreateImageObject(pdfio_file_t *pdf, const char *filename, bool interpolate) PDFIO_PUBLIC;
//
// C++ magic...

View File

@ -1294,7 +1294,7 @@ write_trailer(pdfio_file_t *pdf) // I - PDF file
// TODO: Look at adding support for xref streams...
xref_offset = _pdfioFileTell(pdf);
if (!_pdfioFilePrintf(pdf, "xref\n0 %lu \n0000000000 65535 f \n", (unsigned long)pdf->num_objs))
if (!_pdfioFilePrintf(pdf, "xref\n0 %lu \n0000000000 65535 f \n", (unsigned long)pdf->num_objs + 1))
{
_pdfioFileError(pdf, "Unable to write cross-reference table.");
ret = false;

View File

@ -38,11 +38,26 @@ pdfioObjClose(pdfio_obj_t *obj) // I - Object
// Write what remains for the object...
if (!obj->offset)
return (write_obj_header(obj)); // Just write the object value
{
// Write the object value
if (!write_obj_header(obj))
return (false);
}
else if (obj->stream)
return (pdfioStreamClose(obj->stream));
{
// Close the stream...
if (!pdfioStreamClose(obj->stream))
return (false);
}
else
return (true); // Already closed
{
// Already closed
return (true);
}
// If we get here we wrote the object header or closed the stream and still
// need to write the "endobj" line...
return (_pdfioFilePuts(obj->pdf, "endobj\n"));
}

View File

@ -321,6 +321,12 @@ write_page(pdfio_file_t *pdf, // I - PDF file
// TODO: Add font object support...
pdfio_dict_t *dict; // Page dictionary
pdfio_stream_t *st; // Page contents stream
float width, // Width of image
height; // Height of image
float swidth, // Scaled width
sheight, // Scaled height
tx, // X offset
ty; // Y offset
fputs("pdfioDictCreate: ", stdout);
@ -356,20 +362,31 @@ write_page(pdfio_file_t *pdf, // I - PDF file
else
return (1);
fputs("pdfioContentMatrixScale(72.0, 72.0): ", stdout);
if (pdfioContentMatrixScale(st, 72.0f, 72.0f))
fputs("pdfioImageGetWidth(): ", stdout);
if ((width = pdfioImageGetWidth(image)) > 0.0f)
puts("PASS");
else
return (1);
// fputs("pdfioContentTranslate(144.0, 144.0): ", stdout);
// if (pdfioContentMatrixTranslate(st, 144.0f, 144.0f))
// puts("PASS");
// else
// return (1);
fputs("pdfioImageGetHeight(): ", stdout);
if ((height = pdfioImageGetHeight(image)) > 0.0f)
puts("PASS");
else
return (1);
fputs("pdfioContentDrawImage(\"IM1\"): ", stdout);
if (pdfioContentDrawImage(st, "IM1"))
swidth = 400.0f;
sheight = swidth * height / width;
if (sheight > 600.0f)
{
sheight = 600.0f;
swidth = sheight * width / height;
}
tx = 0.5 * (595.28 - swidth);
ty = 0.5 * (792 - sheight);
printf("pdfioContentDrawImage(\"IM1\", x=%g, y=%g, w=%g, h=%g): ", tx, ty, swidth, sheight);
if (pdfioContentDrawImage(st, "IM1", tx, ty, swidth, sheight))
puts("PASS");
else
return (1);