diff --git a/Makefile b/Makefile index f4afacd..0c01501 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ prefix = /usr/local LIBOBJS = \ pdfio-array.o \ pdfio-common.o \ + pdfio-content.o \ pdfio-dict.o \ pdfio-file.o \ pdfio-object.o \ @@ -78,7 +79,7 @@ clean: # Install everything install: $(TARGETS) -mkdir -p $(DESTDIR)$(prefix)/include - cp pdfio.h $(DESTDIR)$(prefix)/include + cp pdfio.h pdfio-content.h $(DESTDIR)$(prefix)/include -mkdir -p $(DESTDIR)$(prefix)/lib cp libpdfio.a $(DESTDIR)$(prefix)/lib $(RANLIB) $(DESTDIR)$(prefix)/lib/libpdfio.a @@ -124,13 +125,14 @@ libpdfio.1.dylib: $(LIBOBJS) # pdfio test program -testpdfio: testpdfio.o libpdfio.a +testpdfio: testpdfio.o libpdfio.a $(CC) $(LDFLAGS) $(COMMONFLAGS) -o $@ testpdfio.o libpdfio.a $(LIBS) # Dependencies -$(OBJS): pdfio.h Makefile -$(LIBOBJS): pdfio-private.h +$(OBJS): pdfio.h Makefile +$(LIBOBJS): pdfio-private.h +pdfio-content.o: pdfio-content.h # Make documentation using Codedoc diff --git a/pdfio-content.c b/pdfio-content.c new file mode 100644 index 0000000..2bcf080 --- /dev/null +++ b/pdfio-content.c @@ -0,0 +1,978 @@ +// +// Content helper functions for pdfio. +// +// Copyright © 2021 by Michael R Sweet. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +// +// Include necessary headers... +// + +#include "pdfio-content.h" +#include + + +// +// Local functions... +// + +static bool write_string(pdfio_stream_t *st, const char *s); + + +// +// 'pdfioContentBeginText()' - Begin a text block. +// + +bool // O - `true` on success, `false` on failure +pdfioContentBeginText( + pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "BT\n")); +} + + +// +// 'pdfioContentClip()' - Clip output to the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentClip( + pdfio_stream_t *st, // I - Stream + bool even_odd) // I - Even/odd fill vs. non-zero winding rule +{ + return (pdfioStreamPuts(st, even_odd ? "W*\n" : "W\n")); +} + + +// +// 'pdfioContentDrawImage()' - Draw an image object. +// +// The object name must be part of the page dictionary resources, typically +// using the @link pdfioPageDictAddImage@ function. +// + +bool // O - `true` on success, `false` on failure +pdfioContentDrawImage( + pdfio_stream_t *st, // I - Stream + const char *name) // I - Image name +{ + return (pdfioStreamPrintf(st, "/%s Do\n", name)); +} + + +// +// 'pdfioContentEndText()' - End a text block. +// + +bool // O - `true` on success, `false` on failure +pdfioContentEndText(pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "ET\n")); +} + + +// +// 'pdfioContentFill()' - Fill the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentFill( + pdfio_stream_t *st, // I - Stream + bool even_odd) // I - Even/odd fill vs. non-zero winding rule +{ + return (pdfioStreamPuts(st, even_odd ? "f*\n" : "f\n")); +} + + +// +// 'pdfioContentFillAndStroke()' - Fill and stroke the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentFillAndStroke( + pdfio_stream_t *st, // I - Stream + bool even_odd) // I - Even/odd fill vs. non-zero winding +{ + return (pdfioStreamPuts(st, even_odd ? "B*\n" : "B\n")); +} + + +// +// 'pdfioContentMatrixConcat()' - Concatenate a matrix to the current graphics +// state. +// + +bool // O - `true` on success, `false` on failure +pdfioContentMatrixConcat( + pdfio_stream_t *st, // I - Stream + pdfio_matrix_t m) // I - Transform matrix +{ + return (pdfioStreamPrintf(st, "%g %g %g %g %g %g cm\n", m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1])); +} + + +// +// 'pdfioContentMatrixRotate()' - Rotate the current transform matrix. +// + +bool // O - `true` on success, `false` on failure +pdfioContentMatrixRotate( + pdfio_stream_t *st, // I - Stream + float degrees) // I - Rotation angle in degrees counter-clockwise +{ + double dcos = cos(degrees / M_PI); // Cosine + double dsin = sin(degrees / M_PI); // Sine + + return (pdfioStreamPrintf(st, "%g %g %g %g 0 0 cm\n", dcos, -dsin, dsin, dcos)); +} + + +// +// 'pdfioContentMatrixScale()' - Scale the current transform matrix. +// + +bool // O - `true` on success, `false` on failure +pdfioContentMatrixScale( + pdfio_stream_t *st, // I - Stream + float sx, // I - X scale + float sy) // I - Y scale +{ + return (pdfioStreamPrintf(st, "%g 0 0 %g 0 0 cm\n", sx, sy)); +} + + +// +// 'pdfioContentMatrixTranslate()' - Translate the current transform matrix. +// + +bool // O - `true` on success, `false` on failure +pdfioContentMatrixTranslate( + pdfio_stream_t *st, // I - Stream + float tx, // I - X offset + float ty) // I - Y offset +{ + return (pdfioStreamPrintf(st, "1 0 0 1 %g %g cm\n", tx, ty)); +} + + +// +// 'pdfioContentPathClose()' - Close the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathClose( + pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "h\n")); +} + + +// +// 'pdfioContentPathCurve()' - Add a Bezier curve with two control points. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathCurve( + pdfio_stream_t *st, // I - Stream + float x1, // I - X position 1 + float y1, // I - Y position 1 + float x2, // I - X position 2 + float y2, // I - Y position 2 + float x3, // I - X position 3 + float y3) // I - Y position 3 +{ + return (pdfioStreamPrintf(st, "%g %g %g %g %g %g c\n", x1, y1, x2, y2, x3, y3)); +} + + +// +// 'pdfioContentPathCurve13()' - Add a Bezier curve with an initial control point. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathCurve13( + pdfio_stream_t *st, // I - Stream + float x1, // I - X position 1 + float y1, // I - Y position 1 + float x3, // I - X position 3 + float y3) // I - Y position 3 +{ + return (pdfioStreamPrintf(st, "%g %g %g %g v\n", x1, y1, x3, y3)); +} + + +// +// 'pdfioContentPathCurve23()' - Add a Bezier curve with a trailing control point. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathCurve23( + pdfio_stream_t *st, // I - Stream + float x2, // I - X position 2 + float y2, // I - Y position 2 + float x3, // I - X position 3 + float y3) // I - Y position 3 +{ + return (pdfioStreamPrintf(st, "%g %g %g %g y\n", x2, y2, x3, y3)); +} + + +// +// 'pdfioContentPathLineTo()' - Add a straight line to the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathLineTo( + pdfio_stream_t *st, // I - Stream + float x, // I - X position + float y) // I - Y position +{ + return (pdfioStreamPrintf(st, "%g %g l\n", x, y)); +} + + +// +// 'pdfioContentPathMoveTo()' - Start a new subpath. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathMoveTo( + pdfio_stream_t *st, // I - Stream + float x, // I - X position + float y) // I - Y position +{ + return (pdfioStreamPrintf(st, "%g %g m\n", x, y)); +} + + +// +// 'pdfioContentPathRect()' - Add a rectangle to the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentPathRect( + pdfio_stream_t *st, // I - Stream + pdfio_rect_t *rect) // I - Rectangle +{ + return (pdfioStreamPrintf(st, "%g %g %g %g re\n", rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1)); +} + + +// +// 'pdfioContentRestore()' - Restore a previous graphics state. +// + +bool // O - `true` on success, `false` on failure +pdfioContentRestore( + pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "Q\n")); +} + + +// +// 'pdfioContentSave()' - Save the current graphics state. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSave(pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "q\n")); +} + + +// +// 'pdfioContentSetDashPattern()' - Set the stroke pattern. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetDashPattern( + pdfio_stream_t *st, // I - Stream + int phase, // I - Phase (offset within pattern) + int on, // I - On length + int off) // I - Off length +{ + return (pdfioStreamPrintf(st, "[%d %d] %d d\n", on, off, phase)); +} + + +// +// 'pdfioContentSetFillColorDeviceCMYK()' - Set device CMYK fill color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFillColorDeviceCMYK( + pdfio_stream_t *st, // I - Stream + float c, // I - Cyan value (0.0 to 1.0) + float m, // I - Magenta value (0.0 to 1.0) + float y, // I - Yellow value (0.0 to 1.0) + float k) // I - Black value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g %g %g %g k\n", c, m, y, k)); +} + + +// +// 'pdfioContentSetFillColorDeviceGray()' - Set the device gray fill color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFillColorDeviceGray( + pdfio_stream_t *st, // I - Stream + float g) // I - Gray value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g g\n", g)); +} + + +// +// 'pdfioContentSetFillColorDeviceRGB()' - Set the device RGB fill color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFillColorDeviceRGB( + pdfio_stream_t *st, // I - Stream + float r, // I - Red value (0.0 to 1.0) + float g, // I - Green value (0.0 to 1.0) + float b) // I - Blue value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g %g %g rg\n", r, g, b)); +} + + +// +// 'pdfioContentSetFillColorGray()' - Set the calibrated gray fill color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFillColorGray( + pdfio_stream_t *st, // I - Stream + float g) // I - Gray value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g sc\n", g)); +} + + +// +// 'pdfioContentSetFillColorRGB()' - Set the calibrated RGB fill color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFillColorRGB( + pdfio_stream_t *st, // I - Stream + float r, // I - Red value (0.0 to 1.0) + float g, // I - Green value (0.0 to 1.0) + float b) // I - Blue value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g %g %g sc\n", r, g, b)); +} + + +// +// 'pdfioContentSetFillColorSpace()' - Set the fill colorspace. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFillColorSpace( + pdfio_stream_t *st, // I - Stream + const char *name) // I - Color space name +{ + return (pdfioStreamPrintf(st, "/%s cs\n", name)); +} + + +// +// 'pdfioContentSetFlatness()' - Set the flatness tolerance. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetFlatness( + pdfio_stream_t *st, // I - Stream + float flatness) // I - Flatness value (0.0 to 100.0) +{ + return (pdfioStreamPrintf(st, "%g i\n", flatness)); +} + + +// +// 'pdfioContentSetLineCap()' - Set the line ends style. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetLineCap( + pdfio_stream_t *st, // I - Stream + pdfio_linecap_t lc) // I - Line cap value +{ + return (pdfioStreamPrintf(st, "%d J\n", lc)); +} + + +// +// 'pdfioContentSetLineJoin()' - Set the line joining style. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetLineJoin( + pdfio_stream_t *st, // I - Stream + pdfio_linejoin_t lj) // I - Line join value +{ + return (pdfioStreamPrintf(st, "%d j\n", lj)); +} + + +// +// 'pdfioContentSetLineWidth()' - Set the line width. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetLineWidth( + pdfio_stream_t *st, // I - Stream + float width) // I - Line width value +{ + return (pdfioStreamPrintf(st, "%g w\n", width)); +} + + +// +// 'pdfioContentSetMiterLimit()' - Set the miter limit. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetMiterLimit( + pdfio_stream_t *st, // I - Stream + float limit) // I - Miter limit value +{ + return (pdfioStreamPrintf(st, "%g M\n", limit)); +} + + +// +// 'pdfioContentSetStrokeColorDeviceCMYK()' - Set the device CMYK stroke color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetStrokeColorDeviceCMYK( + pdfio_stream_t *st, // I - Stream + float c, // I - Cyan value (0.0 to 1.0) + float m, // I - Magenta value (0.0 to 1.0) + float y, // I - Yellow value (0.0 to 1.0) + float k) // I - Black value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g %g %g %g K\n", c, m, y, k)); +} + + +// +// 'pdfioContentSetStrokeColorDeviceGray()' - Set the device gray stroke color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetStrokeColorDeviceGray( + pdfio_stream_t *st, // I - Stream + float g) // I - Gray value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g G\n", g)); +} + + +// +// 'pdfioContentSetStrokeColorDeviceRGB()' - Set the device RGB stroke color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetStrokeColorDeviceRGB( + pdfio_stream_t *st, // I - Stream + float r, // I - Red value (0.0 to 1.0) + float g, // I - Green value (0.0 to 1.0) + float b) // I - Blue value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g %g %g RG\n", r, g, b)); +} + + +// +// 'pdfioContentSetStrokeColorGray()' - Set the calibrated gray stroke color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetStrokeColorGray( + pdfio_stream_t *st, // I - Stream + float g) // I - Gray value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g SC\n", g)); +} + + +// +// 'pdfioContentSetStrokeColorRGB()' - Set the calibrated RGB stroke color. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetStrokeColorRGB( + pdfio_stream_t *st, // I - Stream + float r, // I - Red value (0.0 to 1.0) + float g, // I - Green value (0.0 to 1.0) + float b) // I - Blue value (0.0 to 1.0) +{ + return (pdfioStreamPrintf(st, "%g %g %g SC\n", r, g, b)); +} + + +// +// 'pdfioContentSetStrokeColorSpace()' - Set the stroke color space. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetStrokeColorSpace( + pdfio_stream_t *st, // I - Stream + const char *name) // I - Color space name +{ + return (pdfioStreamPrintf(st, "/%s CS\n", name)); +} + + +// +// 'pdfioContentSetTextCharacterSpacing()' - Set the spacing between characters. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextCharacterSpacing( + pdfio_stream_t *st, // I - Stream + float spacing) // I - Character spacing +{ + return (pdfioStreamPrintf(st, "%g Tc\n", spacing)); +} + + +// +// 'pdfioContentSetTextFont()' - Set the text font and size. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextFont( + pdfio_stream_t *st, // I - Stream + const char *name, // I - Font name + float size) // I - Font size +{ + return (pdfioStreamPrintf(st, "/%s %g Tf\n", name, size)); +} + + +// +// 'pdfioContentSetTextLeading()' - Set text leading (line height) value. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextLeading( + pdfio_stream_t *st, // I - Stream + float leading) // I - Leading (line height) value +{ + return (pdfioStreamPrintf(st, "%g TL\n", leading)); +} + + +// +// 'pdfioContentSetTextMatrix()' - Set the text transform matrix. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextMatrix( + pdfio_stream_t *st, // I - Stream + pdfio_matrix_t m) // I - Transform matrix +{ + return (pdfioStreamPrintf(st, "%g %g %g %g %g %g Tm\n", m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1])); +} + + +// +// 'pdfioContentSetTextRenderingMode()' - Set the text rendering mode. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextRenderingMode( + pdfio_stream_t *st, // I - Stream + pdfio_textrendering_t mode) // I - Text rendering mode +{ + return (pdfioStreamPrintf(st, "%d Tr\n", mode)); +} + + +// +// 'pdfioContentSetTextRise()' - Set the text baseline offset. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextRise( + pdfio_stream_t *st, // I - Stream + float rise) // I - Y offset +{ + return (pdfioStreamPrintf(st, "%g Ts\n", rise)); +} + + +// +// 'pdfioContentSetTextWordSpacing()' - Set the inter-word spacing. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextWordSpacing( + pdfio_stream_t *st, // I - Stream + float spacing) // I - Spacing between words +{ + return (pdfioStreamPrintf(st, "%g Tw\n", spacing)); +} + + +// +// 'pdfioContentSetTextXScaling()' - Set the horizontal scaling value. +// + +bool // O - `true` on success, `false` on failure +pdfioContentSetTextXScaling( + pdfio_stream_t *st, // I - Stream + float percent) // I - Horizontal scaling in percent +{ + return (pdfioStreamPrintf(st, "%g Tz\n", percent)); +} + + +// +// 'pdfioContentStroke()' - Stroke the current path. +// + +bool // O - `true` on success, `false` on failure +pdfioContentStroke(pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "S\n")); +} + + +// +// 'pdfioContentTextMoveLine()' - Move to the next line and offset. +// + +bool // O - `true` on success, `false` on failure +pdfioContentTextMoveLine( + pdfio_stream_t *st, // I - Stream + float tx, // I - X offset + float ty) // I - Y offset +{ + return (pdfioStreamPrintf(st, "%g %g TD\n", tx, ty)); +} + + +// +// 'pdfioContentTextMoveTo()' - Offset within the current line. +// + +bool // O - `true` on success, `false` on failure +pdfioContentTextMoveTo( + pdfio_stream_t *st, // I - Stream + float tx, // I - X offset + float ty) // I - Y offset +{ + return (pdfioStreamPrintf(st, "%g %g Td\n", tx, ty)); +} + + +// +// 'pdfioContentTextNextLine()' - Move to the next line. +// + +bool // O - `true` on success, `false` on failure +pdfioContentTextNextLine( + pdfio_stream_t *st) // I - Stream +{ + return (pdfioStreamPuts(st, "T*\n")); +} + + +// +// 'pdfioContentTextShow()' - Show text. +// + +bool // O - `true` on success, `false` on failure +pdfioContentTextShow( + pdfio_stream_t *st, // I - Stream + const char *s, // I - String to show + bool new_line) // I - Advance to the next line afterwards +{ + write_string(st, s); + + if (new_line) + return (pdfioStreamPuts(st, "\'\n")); + else + return (pdfioStreamPuts(st, "Tj\n")); +} + + +// +// 'pdfioContentTextShowJustified()' - Show justified text. +// + +bool // O - `true` on success, `false` on failure +pdfioContentTextShowJustified( + pdfio_stream_t *st, // I - Stream + size_t num_fragments, // I - Number of text fragments + const float *offsets, // I - Text offsets before fragments + const char * const *fragments) // I - Text fragments +{ + size_t i; // Looping var + + + // Write an array of offsets and string fragments... + if (!pdfioStreamPuts(st, "[")) + return (false); + + for (i = 0; i < num_fragments; i ++) + { + if (offsets[i] != 0.0f) + { + if (!pdfioStreamPrintf(st, "%g", offsets[i])) + return (false); + } + + if (fragments[i]) + { + if (!write_string(st, fragments[i])) + return (false); + } + } + + return (pdfioStreamPuts(st, "]TJ\n")); +} + + +// +// 'pdfioPageDictAddICCColorSpace()' - Add an ICC color space to the page +// dictionary. +// + +bool // O - `true` on success, `false` on failure +pdfioPageDictAddICCColorSpace( + pdfio_dict_t *dict, // I - Page dictionary + const char *name, // I - Color space name + pdfio_obj_t *obj) // I - ICC profile object +{ + (void)dict; + (void)name; + (void)obj; + + return (false); +} + + +// +// 'pdfioPageDictAddCalibratedColorSpace()' - Add a calibrated color space to +// the page dictionary. +// + +bool // O - `true` on success, `false` on failure +pdfioPageDictAddCalibratedColorSpace( + pdfio_dict_t *dict, // I - Page dictionary + const char *name, // I - Color space name + size_t num_colors, // I - Number of color components + const float *white_point, // I - CIE XYZ white point + float gamma) // I - Gamma value +{ + (void)dict; + (void)name; + (void)num_colors; + (void)white_point; + (void)gamma; + + return (false); +} + + +// +// 'pdfioPageDictAddFont()' - Add a font object to the page dictionary. +// + +bool // O - `true` on success, `false` on failure +pdfioPageDictAddFont( + pdfio_dict_t *dict, // I - Page dictionary + const char *name, // I - Font name + pdfio_obj_t *obj) // I - Font object +{ + (void)dict; + (void)name; + (void)obj; + + return (false); +} + + +// +// 'pdfioPageDictAddImage()' - Add an image object to the page dictionary. +// + +bool // O - `true` on success, `false` on failure +pdfioPageDictAddImage( + pdfio_dict_t *dict, // I - Page dictionary + const char *name, // I - Image name + pdfio_obj_t *obj) // I - Image object +{ + (void)dict; + (void)name; + (void)obj; + + return (false); +} + + +// +// 'pdfioFileCreateFontObject()' - Add a font object to a PDF file. +// + +pdfio_obj_t * // O - Object +pdfioFileCreateFontObject( + pdfio_file_t *pdf, // I - PDF file + const char *filename) // I - Filename +{ + (void)pdf; + (void)filename; + + return (NULL); +} + + +// +// 'pdfioFileCreateICCProfileObject()' - Add an ICC profile object to a PDF file. +// + +pdfio_obj_t * // O - Object +pdfioFileCreateICCProfileObject( + pdfio_file_t *pdf, // I - PDF file + const char *filename) // I - Filename +{ + (void)pdf; + (void)filename; + + return (NULL); +} + + +// +// 'pdfioFileCreateImageObject()' - Add an image object to a PDF file. +// + +pdfio_obj_t * // O - Object +pdfioFileCreateImageObject( + pdfio_file_t *pdf, // I - PDF file + const char *filename, // I - Filename + bool interpolate) // I - Interpolate image data? +{ + (void)pdf; + (void)filename; + (void)interpolate; + + return (NULL); +} + + +// +// 'write_string()' - Write a PDF string. +// + +static bool // O - `true` on success, `false` otherwise +write_string(pdfio_stream_t *st, // I - Stream + const char *s) // I - String +{ + const char *ptr; // Pointer into string + + + // Determine whether this is Unicode or just ASCII... + for (ptr = s; *ptr; ptr ++) + { + if (*ptr & 0x80) + break; + } + + if (*ptr) + { + // Unicode string... + int ch; // Unicode character + + if (!pdfioStreamPuts(st, "(")) + return (false); + + for (ptr = s; *ptr; ptr ++) + { + if ((*ptr & 0xe0) == 0xc0) + { + // Two-byte UTF-8 + ch = ((ptr[0] & 0x1f) << 6) | (ptr[1] & 0x3f); + ptr ++; + } + else if ((*ptr & 0xf0) == 0xe0) + { + // Three-byte UTF-8 + ch = ((ptr[0] & 0x0f) << 12) | ((ptr[1] & 0x3f) << 6) | (ptr[2] & 0x3f); + ptr += 2; + } + else if ((*ptr & 0xf8) == 0xf0) + { + // Four-byte UTF-8 + ch = ((ptr[0] & 0x07) << 18) | ((ptr[1] & 0x3f) << 12) | ((ptr[2] & 0x3f) << 6) | (ptr[3] & 0x3f); + ptr += 3; + } + else + ch = *ptr & 255; + + // Write a two-byte character... + if (!pdfioStreamPrintf(st, "%04X", ch)) + return (false); + } + if (!pdfioStreamPuts(st, ")")) + return (false); + } + else + { + // ASCII string... + const char *start = s; // Start of fragment + int level = 0; // Paren level + + if (!pdfioStreamPuts(st, "(")) + return (false); + + for (ptr = start; *ptr; ptr ++) + { + if (*ptr == '\\' || (*ptr == ')' && level == 0) || *ptr < ' ') + { + if (ptr > start) + { + if (!pdfioStreamWrite(st, start, (size_t)(ptr - start))) + return (false); + + start = ptr + 1; + } + + if (*ptr < ' ') + { + if (!pdfioStreamPrintf(st, "\\%03o", *ptr)) + return (false); + } + else if (!pdfioStreamPrintf(st, "\\%c", *ptr)) + return (false); + } + else if (*ptr == '(') + level ++; + else if (*ptr == ')') + level --; + } + + if (ptr > start) + { + if (!pdfioStreamPrintf(st, "%s)", start)) + return (false); + } + else if (!pdfioStreamPuts(st, ")")) + return (false); + } + + return (true); +} diff --git a/pdfio-content.h b/pdfio-content.h index 09ec0b4..bbd9d56 100644 --- a/pdfio-content.h +++ b/pdfio-content.h @@ -32,23 +32,16 @@ extern "C" { typedef enum pdfio_linecap_e // Line capping modes { - PDFIO_LINECAP_ = , // - PDFIO_LINECAP_ = , // - PDFIO_LINECAP_ = , // - PDFIO_LINECAP_ = , // - PDFIO_LINECAP_ = , // - PDFIO_LINECAP_ = , // - PDFIO_LINECAP_ = , // + PDFIO_LINECAP_BUTT, // Butt ends + PDFIO_LINECAP_ROUND, // Round ends + PDFIO_LINECAP_SQUARE // Square ends } pdfio_linecap_t; typedef enum pdfio_linejoin_e // Line joining modes { - PDFIO_LINEJOIN_ = , // - PDFIO_LINEJOIN_ = , // - PDFIO_LINEJOIN_ = , // - PDFIO_LINEJOIN_ = , // - PDFIO_LINEJOIN_ = , // - PDFIO_LINEJOIN_ = , // + PDFIO_LINEJOIN_MITER, // Miter joint + PDFIO_LINEJOIN_ROUND, // Round joint + PDFIO_LINEJOIN_BEVEL // Bevel joint } pdfio_linejoin_t; typedef float pdfio_matrix_t[3][2]; // Transform matrix @@ -94,20 +87,16 @@ extern bool pdfioContentMatrixConcat(pdfio_stream_t *st, pdfio_matrix_t m) PDFI extern bool pdfioContentMatrixRotate(pdfio_stream_t *st, float degrees) PDFIO_PUBLIC; extern bool pdfioContentMatrixScale(pdfio_stream_t *st, float sx, float sy) PDFIO_PUBLIC; extern bool pdfioContentMatrixTranslate(pdfio_stream_t *st, float tx, float ty) PDFIO_PUBLIC; -extern bool pdfioContentMoveTextLine(pdfio_stream_t *st, float tx, float ty) PDFIO_PUBLIC; -extern bool pdfioContentMoveTextTo(pdfio_stream_t *st, float x, float y, float leading) PDFIO_PUBLIC; -extern bool pdfioContentNextTextLine(pdfio_stream_t *st) PDFIO_PUBLIC; extern bool pdfioContentPathClose(pdfio_stream_t *st) PDFIO_PUBLIC; -extern bool pdfioContentPathCurveTo(pdfio_stream_t *st, float x, float y) PDFIO_PUBLIC; -extern bool pdfioContentPathEnd(pdfio_stream_t *st) PDFIO_PUBLIC; +extern bool pdfioContentPathCurve(pdfio_stream_t *st, float x1, float y1, float x2, float y2, float x3, float y3) PDFIO_PUBLIC; +extern bool pdfioContentPathCurve13(pdfio_stream_t *st, float x1, float y1, float x3, float y3) PDFIO_PUBLIC; +extern bool pdfioContentPathCurve23(pdfio_stream_t *st, float x2, float y2, float x3, float y3) PDFIO_PUBLIC; extern bool pdfioContentPathLineTo(pdfio_stream_t *st, float x, float y) PDFIO_PUBLIC; extern bool pdfioContentPathMoveTo(pdfio_stream_t *st, float x, float y) PDFIO_PUBLIC; -extern bool pdfioContentPathNew(pdfio_stream_t *st) PDFIO_PUBLIC; extern bool pdfioContentPathRect(pdfio_stream_t *st, pdfio_rect_t *rect) PDFIO_PUBLIC; extern bool pdfioContentRestore(pdfio_stream_t *st) PDFIO_PUBLIC; extern bool pdfioContentSave(pdfio_stream_t *st) PDFIO_PUBLIC; -extern bool pdfioContentSetCharacterSpacing(pdfio_stream_t *st, float spacing) PDFIO_PUBLIC; -extern bool pdfioContentSetDashPattern(pdfio_stream_t *st,) PDFIO_PUBLIC; +extern bool pdfioContentSetDashPattern(pdfio_stream_t *st, int phase, int on, int off) PDFIO_PUBLIC; extern bool pdfioContentSetFillColorDeviceCMYK(pdfio_stream_t *st, float c, float m, float y, float k) PDFIO_PUBLIC; extern bool pdfioContentSetFillColorDeviceGray(pdfio_stream_t *st, float g) PDFIO_PUBLIC; extern bool pdfioContentSetFillColorDeviceRGB(pdfio_stream_t *st, float r, float g, float b) PDFIO_PUBLIC; @@ -115,32 +104,36 @@ extern bool pdfioContentSetFillColorGray(pdfio_stream_t *st, float g) PDFIO_PUB extern bool pdfioContentSetFillColorRGB(pdfio_stream_t *st, float r, float g, float b) PDFIO_PUBLIC; extern bool pdfioContentSetFillColorSpace(pdfio_stream_t *st, const char *name) PDFIO_PUBLIC; extern bool pdfioContentSetFlatness(pdfio_stream_t *st, float f) PDFIO_PUBLIC; -extern bool pdfioContentSetFont(pdfio_stream_t *st, const char *name, float size) PDFIO_PUBLIC; extern bool pdfioContentSetLineCap(pdfio_stream_t *st, pdfio_linecap_t lc) PDFIO_PUBLIC; extern bool pdfioContentSetLineJoin(pdfio_stream_t *st, pdfio_linejoin_t lj) PDFIO_PUBLIC; -extern bool pdfioContentSetLineWidth(pdfio_stream_t *st, float w) PDFIO_PUBLIC; -extern bool pdfioContentSetMiterLimit(pdfio_stream_t *st, float l) PDFIO_PUBLIC; +extern bool pdfioContentSetLineWidth(pdfio_stream_t *st, float width) PDFIO_PUBLIC; +extern bool pdfioContentSetMiterLimit(pdfio_stream_t *st, float limit) PDFIO_PUBLIC; extern bool pdfioContentSetStrokeColorDeviceCMYK(pdfio_stream_t *st, float c, float m, float y, float k) PDFIO_PUBLIC; extern bool pdfioContentSetStrokeColorDeviceGray(pdfio_stream_t *st, float g) PDFIO_PUBLIC; extern bool pdfioContentSetStrokeColorDeviceRGB(pdfio_stream_t *st, float r, float g, float b) PDFIO_PUBLIC; extern bool pdfioContentSetStrokeColorGray(pdfio_stream_t *st, float g) PDFIO_PUBLIC; extern bool pdfioContentSetStrokeColorRGB(pdfio_stream_t *st, float r, float g, float b) PDFIO_PUBLIC; extern bool pdfioContentSetStrokeColorSpace(pdfio_stream_t *st, const char *name) PDFIO_PUBLIC; +extern bool pdfioContentSetTextCharacterSpacing(pdfio_stream_t *st, float spacing) PDFIO_PUBLIC; +extern bool pdfioContentSetTextFont(pdfio_stream_t *st, const char *name, float size) PDFIO_PUBLIC; extern bool pdfioContentSetTextLeading(pdfio_stream_t *st, float leading) PDFIO_PUBLIC; extern bool pdfioContentSetTextMatrix(pdfio_stream_t *st, pdfio_matrix_t m) PDFIO_PUBLIC; extern bool pdfioContentSetTextRenderingMode(pdfio_stream_t *st, pdfio_textrendering_t mode) PDFIO_PUBLIC; extern bool pdfioContentSetTextRise(pdfio_stream_t *st, float rise) PDFIO_PUBLIC; extern bool pdfioContentSetTextWordSpacing(pdfio_stream_t *st, float spacing) PDFIO_PUBLIC; extern bool pdfioContentSetTextXScaling(pdfio_stream_t *st, float percent) PDFIO_PUBLIC; -extern bool pdfioContentShowJustifiedText(pdfio_stream_t *st, size_t num_fragments, const float **offsets, const char * const *fragments) PDFIO_PUBLIC; -extern bool pdfioContentShowText(pdfio_stream_t *st, const char *s, bool new_line) PDFIO_PUBLIC; extern bool pdfioContentStroke(pdfio_stream_t *st) PDFIO_PUBLIC; +extern bool pdfioContentTextMoveLine(pdfio_stream_t *st, float tx, float ty) PDFIO_PUBLIC; +extern bool pdfioContentTextMoveTo(pdfio_stream_t *st, float tx, float ty) PDFIO_PUBLIC; +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; // Page dictionary helpers... -extern bool pdfioPageDictAddICCColorSpace(pdfio_dict_t *dict, const char *name, pdfio_obj_t *obj); -extern bool pdfioPageDictAddCalibratedColorSpace(pdfio_dict_t *dict, const char *name, size_t num_colors, const float *white_point, float gamma); -extern bool pdfioPageDictAddFont(pdfio_dict_t *dict, const char *name, pdfio_obj_t *obj); -extern bool pdfioPageDictAddImage(pdfio_dict_t *dict, const char *name, pdfio_obj_t *obj); +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; diff --git a/pdfio.xcodeproj/project.pbxproj b/pdfio.xcodeproj/project.pbxproj index 58c7175..988b76f 100644 --- a/pdfio.xcodeproj/project.pbxproj +++ b/pdfio.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 271EA705265B2B1000ACDD39 /* pdfio-content.c in Sources */ = {isa = PBXBuildFile; fileRef = 271EA703265B2B1000ACDD39 /* pdfio-content.c */; }; + 271EA706265B2B1000ACDD39 /* pdfio-content.h in Headers */ = {isa = PBXBuildFile; fileRef = 271EA704265B2B1000ACDD39 /* pdfio-content.h */; }; 273440C3263D727800FBFD63 /* pdfio-private.h in Headers */ = {isa = PBXBuildFile; fileRef = 273440B8263D727800FBFD63 /* pdfio-private.h */; }; 273440C4263D727800FBFD63 /* pdfio-string.c in Sources */ = {isa = PBXBuildFile; fileRef = 273440B9263D727800FBFD63 /* pdfio-string.c */; }; 273440C5263D727800FBFD63 /* pdfio-array.c in Sources */ = {isa = PBXBuildFile; fileRef = 273440BA263D727800FBFD63 /* pdfio-array.c */; }; @@ -46,6 +48,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 271EA703265B2B1000ACDD39 /* pdfio-content.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "pdfio-content.c"; sourceTree = ""; }; + 271EA704265B2B1000ACDD39 /* pdfio-content.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "pdfio-content.h"; sourceTree = ""; }; 273440B0263D6FE200FBFD63 /* libpdfio.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpdfio.a; sourceTree = BUILT_PRODUCTS_DIR; }; 273440B8263D727800FBFD63 /* pdfio-private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "pdfio-private.h"; sourceTree = ""; }; 273440B9263D727800FBFD63 /* pdfio-string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "pdfio-string.c"; sourceTree = ""; }; @@ -99,6 +103,8 @@ 273440DE263D732000FBFD63 /* pdfio.pc.in */, 273440BA263D727800FBFD63 /* pdfio-array.c */, 273440BB263D727800FBFD63 /* pdfio-common.c */, + 271EA704265B2B1000ACDD39 /* pdfio-content.h */, + 271EA703265B2B1000ACDD39 /* pdfio-content.c */, 273440BE263D727800FBFD63 /* pdfio-dict.c */, 273440BD263D727800FBFD63 /* pdfio-file.c */, 273440BC263D727800FBFD63 /* pdfio-object.c */, @@ -154,6 +160,7 @@ files = ( 273440CC263D727800FBFD63 /* pdfio.h in Headers */, 273440C3263D727800FBFD63 /* pdfio-private.h in Headers */, + 271EA706265B2B1000ACDD39 /* pdfio-content.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -244,6 +251,7 @@ 273440E4263DD7EA00FBFD63 /* pdfio-token.c in Sources */, 273440C7263D727800FBFD63 /* pdfio-object.c in Sources */, 273440C4263D727800FBFD63 /* pdfio-string.c in Sources */, + 271EA705265B2B1000ACDD39 /* pdfio-content.c in Sources */, 273440C6263D727800FBFD63 /* pdfio-common.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0;