Gitweb links:

...log 
http://git.netsurf-browser.org/libnspdf.git/shortlog/d8835327fcc498795ac66bed330e741cef12ce29
...commit 
http://git.netsurf-browser.org/libnspdf.git/commit/d8835327fcc498795ac66bed330e741cef12ce29
...tree 
http://git.netsurf-browser.org/libnspdf.git/tree/d8835327fcc498795ac66bed330e741cef12ce29

The branch, master has been updated
       via  d8835327fcc498795ac66bed330e741cef12ce29 (commit)
       via  f022fe68dcb0703e01e6530263e3177ffec1c083 (commit)
       via  14ff03cff7400945afc3cd13d2f82e4450a3241e (commit)
      from  c4dd67804afc84fde84402649e5b32f2b00680c3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libnspdf.git/commit/?id=d8835327fcc498795ac66bed330e741cef12ce29
commit d8835327fcc498795ac66bed330e741cef12ce29
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    implement colour setting operations in render

diff --git a/src/graphics_state.h b/src/graphics_state.h
index ec158e0..e5cc2bf 100644
--- a/src/graphics_state.h
+++ b/src/graphics_state.h
@@ -29,16 +29,29 @@ struct graphics_state_color {
     enum graphics_state_colorspace space;
     union {
         float gray; /* default is 0 - black */
-        float rgb[3];
-        float cmyk[3];
-    };
+        struct {
+            float r;
+            float g;
+            float b;
+        } rgb;
+        struct {
+            float c;
+            float m;
+            float y;
+            float k;
+        } cmyk;
+    } u;
 };
 
 struct graphics_state_param {
     float ctm[6]; /* current transform matrix */
     /* clipping path */
-    struct graphics_state_color stroke_colour;
-    struct graphics_state_color other_colour;
+    struct {
+        struct graphics_state_color colour;
+    } stroke;
+    struct {
+        struct graphics_state_color colour;
+    } other;
     /* text state */
     float line_width;
     unsigned int line_cap;
diff --git a/src/page.c b/src/page.c
index eb80f0f..984228b 100644
--- a/src/page.c
+++ b/src/page.c
@@ -330,13 +330,67 @@ render_operation_h(struct graphics_state *gs)
 }
 
 static inline nspdferror
+gsc_to_device(struct graphics_state_color * gsc, uint32_t *c_out)
+{
+    uint32_t c;
+    unsigned int v;
+
+    switch (gsc->space) {
+    case GSDeviceGray:
+        v = gsc->u.gray * 255.0;
+        v = v & 0xff;
+        c = v | (v << 8) | (v << 16);
+        break;
+
+    case GSDeviceRGB:
+        v = gsc->u.rgb.r * 255.0;
+        c = v & 0xff;
+        v = gsc->u.rgb.g * 255.0;
+        v = v & 0xff;
+        c |= v << 8;
+        v = gsc->u.rgb.b * 255.0;
+        v = v & 0xff;
+        c |= v << 16;
+        break;
+
+    case GSDeviceCMYK:
+        /* no color profile, this will look shocking */
+        v = (1.0 - ((gsc->u.cmyk.c * (1.0 - gsc->u.cmyk.k)) + gsc->u.cmyk.k)) 
* 255.0;
+        c = v & 0xff;
+        v = (1.0 - ((gsc->u.cmyk.m * (1.0 - gsc->u.cmyk.k)) + gsc->u.cmyk.k)) 
* 255.0;
+        v = v & 0xff;
+        c |= v << 8;
+        v = (1.0 - ((gsc->u.cmyk.y * (1.0 - gsc->u.cmyk.k)) + gsc->u.cmyk.k)) 
* 255.0;
+        v = v & 0xff;
+        c |= v << 16;
+        /*        if (c != 0) printf("setting %f %f %f %f %x\n",
+                           gsc->u.cmyk.c,
+                           gsc->u.cmyk.m,
+                           gsc->u.cmyk.y,
+                           gsc->u.cmyk.k,
+                           c);
+        */
+        break;
+
+    default:
+        c = 0;
+        break;
+    }
+
+    *c_out = c;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
 render_operation_f(struct graphics_state *gs, struct nspdf_render_ctx* 
render_ctx)
 {
     struct nspdf_style style;
     style.stroke_type = NSPDF_OP_TYPE_NONE;
     style.stroke_colour = 0x01000000;
+
     style.fill_type = NSPDF_OP_TYPE_SOLID;
-    style.fill_colour = 0;
+    gsc_to_device(&gs->param_stack[gs->param_stack_idx].other.colour, 
&style.fill_colour);
 
     render_ctx->path(&style,
                      gs->path,
@@ -344,6 +398,7 @@ render_operation_f(struct graphics_state *gs, struct 
nspdf_render_ctx* render_ct
                      gs->param_stack[gs->param_stack_idx].ctm,
                      render_ctx->ctx);
     gs->path_idx = 0;
+
     return NSPDFERROR_OK;
 }
 
@@ -353,11 +408,13 @@ render_operation_S(struct graphics_state *gs, struct 
nspdf_render_ctx* render_ct
 {
     struct nspdf_style style;
 
-    style.stroke_type = NSPDF_OP_TYPE_SOLID;
-    style.stroke_colour = 0;
-    style.stroke_width = gs->param_stack[gs->param_stack_idx].line_width;
     style.fill_type = NSPDF_OP_TYPE_NONE;
     style.fill_colour = 0x01000000;
+
+    style.stroke_type = NSPDF_OP_TYPE_SOLID;
+    style.stroke_width = gs->param_stack[gs->param_stack_idx].line_width;
+    gsc_to_device(&gs->param_stack[gs->param_stack_idx].stroke.colour, 
&style.stroke_colour);
+
     render_ctx->path(&style,
                      gs->path,
                      gs->path_idx,
@@ -435,6 +492,186 @@ render_operation_cm(struct content_operation *operation, 
struct graphics_state *
                                gs->param_stack[gs->param_stack_idx].ctm);
 }
 
+
+static inline nspdferror
+set_gsc_grey(struct graphics_state_color *gsc, float gray)
+{
+    /* bounds check */
+    if (gray < 0.0) {
+        gray = 0.0;
+    } else if (gray > 1.0) {
+        gray = 1.0;
+    }
+
+    gsc->space = GSDeviceGray;
+    gsc->u.gray = gray;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_G(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_grey(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                        operation->u.number[0]);
+}
+
+static inline nspdferror
+render_operation_g(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_grey(&gs->param_stack[gs->param_stack_idx].other.colour,
+                        operation->u.number[0]);
+}
+
+static inline nspdferror
+set_gsc_rgb(struct graphics_state_color *gsc, float r, float g, float b)
+{
+    /* bounds check */
+    if (r < 0.0) {
+        r = 0.0;
+    } else if (r > 1.0) {
+        r = 1.0;
+    }
+    if (g < 0.0) {
+        g = 0.0;
+    } else if (g > 1.0) {
+        g = 1.0;
+    }
+    if (b < 0.0) {
+        b = 0.0;
+    } else if (b > 1.0) {
+        b = 1.0;
+    }
+
+    gsc->space = GSDeviceRGB;
+    gsc->u.rgb.r = r;
+    gsc->u.rgb.g = g;
+    gsc->u.rgb.b = b;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_RG(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_rgb(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2]);
+}
+
+static inline nspdferror
+render_operation_rg(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_rgb(&gs->param_stack[gs->param_stack_idx].other.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2]);
+}
+
+static inline nspdferror
+set_gsc_cmyk(struct graphics_state_color *gsc, float c, float m, float y, 
float k)
+{
+    /* bounds check */
+    if (c < 0.0) {
+        c = 0.0;
+    } else if (c > 1.0) {
+        c = 1.0;
+    }
+    if (y < 0.0) {
+        y = 0.0;
+    } else if (y > 1.0) {
+        y = 1.0;
+    }
+    if (m < 0.0) {
+        m = 0.0;
+    } else if (m > 1.0) {
+        m = 1.0;
+    }
+    if (k < 0.0) {
+        k = 0.0;
+    } else if (k > 1.0) {
+        k = 1.0;
+    }
+
+    gsc->space = GSDeviceCMYK;
+    gsc->u.cmyk.c = c;
+    gsc->u.cmyk.m = m;
+    gsc->u.cmyk.y = y;
+    gsc->u.cmyk.k = k;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_K(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cmyk(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2],
+                       operation->u.number[3]);
+}
+
+static inline nspdferror
+render_operation_k(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cmyk(&gs->param_stack[gs->param_stack_idx].other.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2],
+                       operation->u.number[3]);
+}
+
+static inline nspdferror
+set_gsc_cs(struct graphics_state_color *gsc, const char *spacename)
+{
+    if (strcmp(spacename, "DeviceGray") == 0) {
+        gsc->space = GSDeviceGray;
+        gsc->u.gray = 0.0;
+    } else if (strcmp(spacename, "DeviceRGB") == 0) {
+        gsc->space = GSDeviceRGB;
+        gsc->u.rgb.r = 0.0;
+        gsc->u.rgb.g = 0.0;
+        gsc->u.rgb.b = 0.0;
+    } else if (strcmp(spacename, "DeviceCMYK") == 0) {
+        gsc->space = GSDeviceCMYK;
+        gsc->u.cmyk.c = 0.0;
+        gsc->u.cmyk.m = 0.0;
+        gsc->u.cmyk.y = 0.0;
+        gsc->u.cmyk.k = 1.0;
+    } else {
+        /** \todo colourspace from name defined in the ColorSpace 
subdictionary of the current resource dictionary */
+        gsc->space = GSDeviceGray;
+        gsc->u.gray = 0.0;
+
+    }
+    //printf("cs %s %d\n", spacename, gsc->space);
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_CS(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cs(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                        operation->u.name);
+}
+
+static inline nspdferror
+render_operation_cs(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cs(&gs->param_stack[gs->param_stack_idx].other.colour,
+                        operation->u.name);
+}
+
 /**
  * Initialise the parameter stack
  *
@@ -574,6 +811,44 @@ nspdf_page_render(struct nspdf_doc *doc,
             res = render_operation_cm(operation, &gs);
             break;
 
+            /* colour operators */
+        case CONTENT_OP_G: /* gray stroking colour */
+            res = render_operation_G(operation, &gs);
+            break;
+
+        case CONTENT_OP_g: /* gray non-stroking colour */
+            res = render_operation_g(operation, &gs);
+            break;
+
+        case CONTENT_OP_RG: /* rgb stroking colour */
+            res = render_operation_RG(operation, &gs);
+            break;
+
+        case CONTENT_OP_rg: /* rgb non-stroking colour */
+            res = render_operation_rg(operation, &gs);
+            break;
+
+        case CONTENT_OP_K: /* CMYK stroking colour */
+            res = render_operation_K(operation, &gs);
+            break;
+
+        case CONTENT_OP_k: /* CMYK non-stroking colour */
+            res = render_operation_k(operation, &gs);
+            break;
+
+        case CONTENT_OP_CS: /* change stroking colourspace */
+            res = render_operation_CS(operation, &gs);
+            break;
+
+        case CONTENT_OP_cs: /* change non-stroking colourspace */
+            res = render_operation_cs(operation, &gs);
+            break;
+
+            //case CONTENT_OP_SC:
+            //case CONTENT_OP_sc:
+            //case CONTENT_OP_SCN:
+            //case CONTENT_OP_scn:
+
         default:
             printf("operator %s\n",
                nspdf__cos_content_operator_name(operation->operator));


commitdiff 
http://git.netsurf-browser.org/libnspdf.git/commit/?id=f022fe68dcb0703e01e6530263e3177ffec1c083
commit f022fe68dcb0703e01e6530263e3177ffec1c083
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    extend graphics state operation implementation

diff --git a/src/graphics_state.h b/src/graphics_state.h
new file mode 100644
index 0000000..ec158e0
--- /dev/null
+++ b/src/graphics_state.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018 Vincent Sanders <[email protected]>
+ *
+ * This file is part of libnspdf.
+ *
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * NetSurf PDF library graphics state
+ */
+
+#ifndef NSPDF__GRAPHICS_STATE_H_
+#define NSPDF__GRAPHICS_STATE_H_
+
+/**
+ * colourspaces
+ * \todo extend this with full list from section 4.5.2
+ */
+enum graphics_state_colorspace {
+    GSDeviceGray = 0, /* Default */
+    GSDeviceRGB,
+    GSDeviceCMYK,
+};
+
+struct graphics_state_color {
+    enum graphics_state_colorspace space;
+    union {
+        float gray; /* default is 0 - black */
+        float rgb[3];
+        float cmyk[3];
+    };
+};
+
+struct graphics_state_param {
+    float ctm[6]; /* current transform matrix */
+    /* clipping path */
+    struct graphics_state_color stroke_colour;
+    struct graphics_state_color other_colour;
+    /* text state */
+    float line_width;
+    unsigned int line_cap;
+    unsigned int line_join;
+    float miter_limit;
+    /* dash pattern */
+    /* rendering intent RelativeColorimetric */
+    bool stroke_adjustment;
+    /* blend mode: Normal */
+    /* soft mask */
+    /* alpha constant */
+    /* alpha source */
+
+    /* device dependant */
+    bool overprint;
+    float overprint_mode;
+    /* black generation */
+    /* undercolor removal */
+    /* transfer */
+    /* halftone */
+    float flatness;
+    float smoothness;
+};
+
+struct graphics_state {
+    float *path; /* current path */
+    unsigned int path_idx; /* current index into path */
+    unsigned int path_alloc; /* current number of path elements allocated */
+
+    struct graphics_state_param *param_stack; /* parameter stack */
+    unsigned int param_stack_idx;
+    unsigned int param_stack_alloc;
+};
+
+#endif
diff --git a/src/page.c b/src/page.c
index 08d993c..eb80f0f 100644
--- a/src/page.c
+++ b/src/page.c
@@ -15,6 +15,7 @@
 #include <stdio.h>
 #include <nspdf/page.h>
 
+#include "graphics_state.h"
 #include "cos_content.h"
 #include "cos_object.h"
 #include "pdf_doc.h"
@@ -32,6 +33,65 @@ struct page_table_entry {
 };
 
 /**
+ * multiply pdf matricies
+ *
+ * pdf specifies its 3 x 3 transform matrix as six values and three constants
+ *        | t[0] t[1]  0 |
+ *   Mt = | t[2] t[3]  0 |
+ *        | t[4] t[5]  1 |
+ *
+ * this multiples two such matricies together
+ *   Mo = Ma * Mb
+ *
+ * Basic matrix expansion is
+ *   | a b c |   | A B C |   | aA+bP+cU aB+bQ+cV aC+bR+cW |
+ *   | p q r | * | P Q R | = | pA+qP+rU pB+qQ+rV pC+qR+rW |
+ *   | u v w |   | U V W |   | uA+vP+wU uB+vQ+wV uC+vR+wW |
+ *
+ * With the a and b arrays substituted
+ *   | o[0] o[1] 0 |
+ *   | o[2] o[3] 0 | =
+ *   | o[4] o[5] 1 |
+ *
+ *   | a[0] a[1] 0 |   | b[0] b[1] 0 |
+ *   | a[2] a[3] 0 | * | b[2] b[3] 0 | =
+ *   | a[4] a[5] 1 |   | b[4] b[5] 1 |
+ *
+ *   | a[0]*b[0]+a[1]*b[2]      a[0]*b[1]+a[1]*b[3]      0 |
+ *   | a[2]*b[0]+a[3]*b[2]      a[2]*b[1]+a[3]*b[3]      0 |
+ *   | a[4]*b[0]+a[5]*b[2]+b[4] a[4]*b[1]+a[5]*b[3]+b[5] 1 |
+ *
+ * \param a The array of six values for matrix a
+ * \param b The array of six values for matrix b
+ * \param o An array to receive six values resulting from Ma * Mb may be same 
array as a or b
+ * \return NSPDFERROR_OK on success
+ */
+static nspdferror
+pdf_matrix_multiply(float *a, float *b, float *o)
+{
+    float out[6]; /* result matrix array */
+
+    out[0] = a[0]*b[0] + a[1]*b[2];
+    out[1] = a[0]*b[1] + a[1]*b[3];
+    out[2] = a[2]*b[0] + a[3]*b[2];
+    out[3] = a[2]*b[1] + a[3]*b[3];
+    out[4] = a[4]*b[0] + a[5]*b[2] + b[4];
+    out[5] = a[4]*b[1] + a[5]*b[3] + b[5];
+
+    /* calculate and then assign output to allow input and output arrays to
+     * overlap
+     */
+    o[0] = out[0];
+    o[1] = out[1];
+    o[2] = out[2];
+    o[3] = out[3];
+    o[4] = out[4];
+    o[5] = out[5];
+
+    return NSPDFERROR_OK;
+}
+
+/**
  * recursively decodes a page tree
  */
 nspdferror
@@ -210,53 +270,6 @@ nspdf_page_count(struct nspdf_doc *doc, unsigned int 
*pages_out)
     return NSPDFERROR_OK;
 }
 
-/**
- * colourspaces
- * \todo extend this with full list from section 4.5.2
- */
-enum graphics_state_colorspace {
-    GSDeviceGray = 0, /* Default */
-    GSDeviceRGB,
-    GSDeviceCMYK,
-};
-
-struct graphics_state_color {
-    enum graphics_state_colorspace space;
-    union {
-        float gray; /* default is 0 - black */
-        float rgb[3];
-        float cmyk[3];
-    };
-};
-
-struct graphics_state_param {
-    float ctm[6]; /* current transform matrix */
-    /* clipping path */
-    struct graphics_state_color stroke_colour;
-    struct graphics_state_color other_colour;
-    /* text state */
-    float line_width;
-    unsigned int line_cap;
-    unsigned int line_join;
-    float miter_limit;
-    /* dash pattern */
-    /* rendering intent RelativeColorimetric */
-    bool stroke_adjustment;
-    /* blend mode: Normal */
-    /* soft mask */
-    /* alpha constant */
-    /* alpha source */
-};
-
-struct graphics_state {
-    float *path; /* current path */
-    unsigned int path_idx; /* current index into path */
-    unsigned int path_alloc; /* current number of path elements allocated */
-
-    struct graphics_state_param *param_stack; /* parameter stack */
-    unsigned int param_stack_idx;
-    unsigned int param_stack_alloc;
-};
 
 static inline nspdferror
 render_operation_m(struct content_operation *operation, struct graphics_state 
*gs)
@@ -362,6 +375,34 @@ render_operation_w(struct content_operation *operation, 
struct graphics_state *g
 }
 
 static inline nspdferror
+render_operation_i(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].flatness = operation->u.number[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_M(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].miter_limit = operation->u.number[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_j(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].line_join = operation->u.i[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_J(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].line_cap = operation->u.i[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
 render_operation_q(struct graphics_state *gs)
 {
     gs->param_stack[gs->param_stack_idx + 1] = 
gs->param_stack[gs->param_stack_idx];
@@ -379,64 +420,6 @@ render_operation_Q(struct graphics_state *gs)
 }
 
 
-/**
- * multiply pdf matricies
- *
- * pdf specifies its 3 x 3 transform matrix as six values and three constants
- *        | t[0] t[1]  0 |
- *   Mt = | t[2] t[3]  0 |
- *        | t[4] t[5]  1 |
- *
- * this multiples two such matricies together
- *   Mo = Ma * Mb
- *
- * Basic matrix expansion is
- *   | a b c |   | A B C |   | aA+bP+cU aB+bQ+cV aC+bR+cW |
- *   | p q r | * | P Q R | = | pA+qP+rU pB+qQ+rV pC+qR+rW |
- *   | u v w |   | U V W |   | uA+vP+wU uB+vQ+wV uC+vR+wW |
- *
- * With the a and b arrays substituted
- *   | o[0] o[1] 0 |
- *   | o[2] o[3] 0 | =
- *   | o[4] o[5] 1 |
- *
- *   | a[0] a[1] 0 |   | b[0] b[1] 0 |
- *   | a[2] a[3] 0 | * | b[2] b[3] 0 | =
- *   | a[4] a[5] 1 |   | b[4] b[5] 1 |
- *
- *   | a[0]*b[0]+a[1]*b[2]      a[0]*b[1]+a[1]*b[3]      0 |
- *   | a[2]*b[0]+a[3]*b[2]      a[2]*b[1]+a[3]*b[3]      0 |
- *   | a[4]*b[0]+a[5]*b[2]+b[4] a[4]*b[1]+a[5]*b[3]+b[5] 1 |
- *
- * \param a The array of six values for matrix a
- * \param b The array of six values for matrix b
- * \param o An array to receive six values resulting from Ma * Mb may be same 
array as a or b
- * \return NSPDFERROR_OK on success
- */
-static nspdferror
-pdf_matrix_multiply(float *a, float *b, float *o)
-{
-    float out[6]; /* result matrix array */
-
-    out[0] = a[0]*b[0] + a[1]*b[2];
-    out[1] = a[0]*b[1] + a[1]*b[3];
-    out[2] = a[2]*b[0] + a[3]*b[2];
-    out[3] = a[2]*b[1] + a[3]*b[3];
-    out[4] = a[4]*b[0] + a[5]*b[2] + b[4];
-    out[5] = a[4]*b[1] + a[5]*b[3] + b[5];
-
-    /* calculate and then assign output to allow input and output arrays to
-     * overlap
-     */
-    o[0] = out[0];
-    o[1] = out[1];
-    o[2] = out[2];
-    o[3] = out[3];
-    o[4] = out[4];
-    o[5] = out[5];
-
-    return NSPDFERROR_OK;
-}
 
 /**
  * pre-multiply matrix
@@ -519,6 +502,7 @@ nspdf_page_render(struct nspdf_doc *doc,
          idx < page_content->length;
          idx++, operation++) {
         switch(operation->operator) {
+            /* path operations */
         case CONTENT_OP_m: /* move */
             res = render_operation_m(operation, &gs);
             break;
@@ -557,9 +541,25 @@ nspdf_page_render(struct nspdf_doc *doc,
             res = render_operation_S(&gs, render_ctx);
             break;
 
-        case CONTENT_OP_w:
+            /* graphics state operations */
+        case CONTENT_OP_w: /* line width */
             res = render_operation_w(operation, &gs);
-            //printf("line width:%f\n", 
gs.param_stack[gs.param_stack_idx].line_width);
+            break;
+
+        case CONTENT_OP_i: /* flatness */
+            res = render_operation_i(operation, &gs);
+            break;
+
+        case CONTENT_OP_j: /* line join style */
+            res = render_operation_j(operation, &gs);
+            break;
+
+        case CONTENT_OP_J: /* line cap style */
+            res = render_operation_J(operation, &gs);
+            break;
+
+        case CONTENT_OP_M: /* miter limit */
+            res = render_operation_M(operation, &gs);
             break;
 
         case CONTENT_OP_q: /* push parameter stack */


commitdiff 
http://git.netsurf-browser.org/libnspdf.git/commit/?id=14ff03cff7400945afc3cd13d2f82e4450a3241e
commit 14ff03cff7400945afc3cd13d2f82e4450a3241e
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>

    split out pdf matrix multiplication

diff --git a/src/page.c b/src/page.c
index c5ea8b8..08d993c 100644
--- a/src/page.c
+++ b/src/page.c
@@ -378,45 +378,78 @@ render_operation_Q(struct graphics_state *gs)
     return NSPDFERROR_OK;
 }
 
+
+/**
+ * multiply pdf matricies
+ *
+ * pdf specifies its 3 x 3 transform matrix as six values and three constants
+ *        | t[0] t[1]  0 |
+ *   Mt = | t[2] t[3]  0 |
+ *        | t[4] t[5]  1 |
+ *
+ * this multiples two such matricies together
+ *   Mo = Ma * Mb
+ *
+ * Basic matrix expansion is
+ *   | a b c |   | A B C |   | aA+bP+cU aB+bQ+cV aC+bR+cW |
+ *   | p q r | * | P Q R | = | pA+qP+rU pB+qQ+rV pC+qR+rW |
+ *   | u v w |   | U V W |   | uA+vP+wU uB+vQ+wV uC+vR+wW |
+ *
+ * With the a and b arrays substituted
+ *   | o[0] o[1] 0 |
+ *   | o[2] o[3] 0 | =
+ *   | o[4] o[5] 1 |
+ *
+ *   | a[0] a[1] 0 |   | b[0] b[1] 0 |
+ *   | a[2] a[3] 0 | * | b[2] b[3] 0 | =
+ *   | a[4] a[5] 1 |   | b[4] b[5] 1 |
+ *
+ *   | a[0]*b[0]+a[1]*b[2]      a[0]*b[1]+a[1]*b[3]      0 |
+ *   | a[2]*b[0]+a[3]*b[2]      a[2]*b[1]+a[3]*b[3]      0 |
+ *   | a[4]*b[0]+a[5]*b[2]+b[4] a[4]*b[1]+a[5]*b[3]+b[5] 1 |
+ *
+ * \param a The array of six values for matrix a
+ * \param b The array of six values for matrix b
+ * \param o An array to receive six values resulting from Ma * Mb may be same 
array as a or b
+ * \return NSPDFERROR_OK on success
+ */
+static nspdferror
+pdf_matrix_multiply(float *a, float *b, float *o)
+{
+    float out[6]; /* result matrix array */
+
+    out[0] = a[0]*b[0] + a[1]*b[2];
+    out[1] = a[0]*b[1] + a[1]*b[3];
+    out[2] = a[2]*b[0] + a[3]*b[2];
+    out[3] = a[2]*b[1] + a[3]*b[3];
+    out[4] = a[4]*b[0] + a[5]*b[2] + b[4];
+    out[5] = a[4]*b[1] + a[5]*b[3] + b[5];
+
+    /* calculate and then assign output to allow input and output arrays to
+     * overlap
+     */
+    o[0] = out[0];
+    o[1] = out[1];
+    o[2] = out[2];
+    o[3] = out[3];
+    o[4] = out[4];
+    o[5] = out[5];
+
+    return NSPDFERROR_OK;
+}
+
 /**
  * pre-multiply matrix
  */
 static inline nspdferror
 render_operation_cm(struct content_operation *operation, struct graphics_state 
*gs)
 {
-    float M[6]; /* result matrix */
-    /* M' = Mt * M */
-    /* M' = Mo * Mc where Mo is operation and Mc is graphics state ctm */
-    /* | a b c |   | A B C |   | aA+bP+cU aB+bQ+cV aC+bR+cW |
-     * | p q r | * | P Q R | = | pA+qP+rU pB+qQ+rV pC+qR+rW |
-     * | u v w |   | U V W |   | uA+vP+wU uB+vQ+wV uC+vR+wW |
-     *
-     * | o[0] o[1] 0 |   | c[0] c[1] 0 |   | o[0]*c[0]+o[1]*c[2]      
o[0]*c[1]+o[1]*c[3]      0 |
-     * | o[2] o[3] 0 | * | c[2] c[3] 0 | = | o[2]*c[0]+o[3]*c[2]      
o[2]*c[1]+o[3]*c[3]      0 |
-     * | o[4] o[5] 1 |   | c[4] c[5] 1 |   | o[4]*c[0]+o[5]*c[2]+c[4] 
o[4]*c[1]+o[5]*c[3]+c[5] 1 |
+    /* Mres = Mop * Mctm
+     * where Mop is operation and Mctm is graphics state ctm
      */
-    M[0] = operation->u.number[0] * 
gs->param_stack[gs->param_stack_idx].ctm[0] +
-           operation->u.number[1] * 
gs->param_stack[gs->param_stack_idx].ctm[2];
-    M[1] = operation->u.number[0] * 
gs->param_stack[gs->param_stack_idx].ctm[1] +
-           operation->u.number[1] * 
gs->param_stack[gs->param_stack_idx].ctm[3];
-    M[2] = operation->u.number[2] * 
gs->param_stack[gs->param_stack_idx].ctm[0] +
-           operation->u.number[3] * 
gs->param_stack[gs->param_stack_idx].ctm[2];
-    M[3] = operation->u.number[2] * 
gs->param_stack[gs->param_stack_idx].ctm[1] +
-           operation->u.number[3] * 
gs->param_stack[gs->param_stack_idx].ctm[3];
-    M[4] = operation->u.number[4] * 
gs->param_stack[gs->param_stack_idx].ctm[0] +
-           operation->u.number[5] * 
gs->param_stack[gs->param_stack_idx].ctm[2] +
-           gs->param_stack[gs->param_stack_idx].ctm[4];
-    M[5] = operation->u.number[4] * 
gs->param_stack[gs->param_stack_idx].ctm[1] +
-           operation->u.number[5] * 
gs->param_stack[gs->param_stack_idx].ctm[3] +
-           gs->param_stack[gs->param_stack_idx].ctm[5];
-
-    gs->param_stack[gs->param_stack_idx].ctm[0] = M[0];
-    gs->param_stack[gs->param_stack_idx].ctm[1] = M[1];
-    gs->param_stack[gs->param_stack_idx].ctm[2] = M[2];
-    gs->param_stack[gs->param_stack_idx].ctm[3] = M[3];
-    gs->param_stack[gs->param_stack_idx].ctm[4] = M[4];
-    gs->param_stack[gs->param_stack_idx].ctm[5] = M[5];
-    return NSPDFERROR_OK;
+    return pdf_matrix_multiply(operation->u.number,
+                               gs->param_stack[gs->param_stack_idx].ctm,
+                               gs->param_stack[gs->param_stack_idx].ctm);
 }
 
 /**


-----------------------------------------------------------------------

Summary of changes:
 src/graphics_state.h |   89 ++++++++++
 src/page.c           |  476 +++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 481 insertions(+), 84 deletions(-)
 create mode 100644 src/graphics_state.h

diff --git a/src/graphics_state.h b/src/graphics_state.h
new file mode 100644
index 0000000..e5cc2bf
--- /dev/null
+++ b/src/graphics_state.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 Vincent Sanders <[email protected]>
+ *
+ * This file is part of libnspdf.
+ *
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * NetSurf PDF library graphics state
+ */
+
+#ifndef NSPDF__GRAPHICS_STATE_H_
+#define NSPDF__GRAPHICS_STATE_H_
+
+/**
+ * colourspaces
+ * \todo extend this with full list from section 4.5.2
+ */
+enum graphics_state_colorspace {
+    GSDeviceGray = 0, /* Default */
+    GSDeviceRGB,
+    GSDeviceCMYK,
+};
+
+struct graphics_state_color {
+    enum graphics_state_colorspace space;
+    union {
+        float gray; /* default is 0 - black */
+        struct {
+            float r;
+            float g;
+            float b;
+        } rgb;
+        struct {
+            float c;
+            float m;
+            float y;
+            float k;
+        } cmyk;
+    } u;
+};
+
+struct graphics_state_param {
+    float ctm[6]; /* current transform matrix */
+    /* clipping path */
+    struct {
+        struct graphics_state_color colour;
+    } stroke;
+    struct {
+        struct graphics_state_color colour;
+    } other;
+    /* text state */
+    float line_width;
+    unsigned int line_cap;
+    unsigned int line_join;
+    float miter_limit;
+    /* dash pattern */
+    /* rendering intent RelativeColorimetric */
+    bool stroke_adjustment;
+    /* blend mode: Normal */
+    /* soft mask */
+    /* alpha constant */
+    /* alpha source */
+
+    /* device dependant */
+    bool overprint;
+    float overprint_mode;
+    /* black generation */
+    /* undercolor removal */
+    /* transfer */
+    /* halftone */
+    float flatness;
+    float smoothness;
+};
+
+struct graphics_state {
+    float *path; /* current path */
+    unsigned int path_idx; /* current index into path */
+    unsigned int path_alloc; /* current number of path elements allocated */
+
+    struct graphics_state_param *param_stack; /* parameter stack */
+    unsigned int param_stack_idx;
+    unsigned int param_stack_alloc;
+};
+
+#endif
diff --git a/src/page.c b/src/page.c
index c5ea8b8..984228b 100644
--- a/src/page.c
+++ b/src/page.c
@@ -15,6 +15,7 @@
 #include <stdio.h>
 #include <nspdf/page.h>
 
+#include "graphics_state.h"
 #include "cos_content.h"
 #include "cos_object.h"
 #include "pdf_doc.h"
@@ -32,6 +33,65 @@ struct page_table_entry {
 };
 
 /**
+ * multiply pdf matricies
+ *
+ * pdf specifies its 3 x 3 transform matrix as six values and three constants
+ *        | t[0] t[1]  0 |
+ *   Mt = | t[2] t[3]  0 |
+ *        | t[4] t[5]  1 |
+ *
+ * this multiples two such matricies together
+ *   Mo = Ma * Mb
+ *
+ * Basic matrix expansion is
+ *   | a b c |   | A B C |   | aA+bP+cU aB+bQ+cV aC+bR+cW |
+ *   | p q r | * | P Q R | = | pA+qP+rU pB+qQ+rV pC+qR+rW |
+ *   | u v w |   | U V W |   | uA+vP+wU uB+vQ+wV uC+vR+wW |
+ *
+ * With the a and b arrays substituted
+ *   | o[0] o[1] 0 |
+ *   | o[2] o[3] 0 | =
+ *   | o[4] o[5] 1 |
+ *
+ *   | a[0] a[1] 0 |   | b[0] b[1] 0 |
+ *   | a[2] a[3] 0 | * | b[2] b[3] 0 | =
+ *   | a[4] a[5] 1 |   | b[4] b[5] 1 |
+ *
+ *   | a[0]*b[0]+a[1]*b[2]      a[0]*b[1]+a[1]*b[3]      0 |
+ *   | a[2]*b[0]+a[3]*b[2]      a[2]*b[1]+a[3]*b[3]      0 |
+ *   | a[4]*b[0]+a[5]*b[2]+b[4] a[4]*b[1]+a[5]*b[3]+b[5] 1 |
+ *
+ * \param a The array of six values for matrix a
+ * \param b The array of six values for matrix b
+ * \param o An array to receive six values resulting from Ma * Mb may be same 
array as a or b
+ * \return NSPDFERROR_OK on success
+ */
+static nspdferror
+pdf_matrix_multiply(float *a, float *b, float *o)
+{
+    float out[6]; /* result matrix array */
+
+    out[0] = a[0]*b[0] + a[1]*b[2];
+    out[1] = a[0]*b[1] + a[1]*b[3];
+    out[2] = a[2]*b[0] + a[3]*b[2];
+    out[3] = a[2]*b[1] + a[3]*b[3];
+    out[4] = a[4]*b[0] + a[5]*b[2] + b[4];
+    out[5] = a[4]*b[1] + a[5]*b[3] + b[5];
+
+    /* calculate and then assign output to allow input and output arrays to
+     * overlap
+     */
+    o[0] = out[0];
+    o[1] = out[1];
+    o[2] = out[2];
+    o[3] = out[3];
+    o[4] = out[4];
+    o[5] = out[5];
+
+    return NSPDFERROR_OK;
+}
+
+/**
  * recursively decodes a page tree
  */
 nspdferror
@@ -210,53 +270,6 @@ nspdf_page_count(struct nspdf_doc *doc, unsigned int 
*pages_out)
     return NSPDFERROR_OK;
 }
 
-/**
- * colourspaces
- * \todo extend this with full list from section 4.5.2
- */
-enum graphics_state_colorspace {
-    GSDeviceGray = 0, /* Default */
-    GSDeviceRGB,
-    GSDeviceCMYK,
-};
-
-struct graphics_state_color {
-    enum graphics_state_colorspace space;
-    union {
-        float gray; /* default is 0 - black */
-        float rgb[3];
-        float cmyk[3];
-    };
-};
-
-struct graphics_state_param {
-    float ctm[6]; /* current transform matrix */
-    /* clipping path */
-    struct graphics_state_color stroke_colour;
-    struct graphics_state_color other_colour;
-    /* text state */
-    float line_width;
-    unsigned int line_cap;
-    unsigned int line_join;
-    float miter_limit;
-    /* dash pattern */
-    /* rendering intent RelativeColorimetric */
-    bool stroke_adjustment;
-    /* blend mode: Normal */
-    /* soft mask */
-    /* alpha constant */
-    /* alpha source */
-};
-
-struct graphics_state {
-    float *path; /* current path */
-    unsigned int path_idx; /* current index into path */
-    unsigned int path_alloc; /* current number of path elements allocated */
-
-    struct graphics_state_param *param_stack; /* parameter stack */
-    unsigned int param_stack_idx;
-    unsigned int param_stack_alloc;
-};
 
 static inline nspdferror
 render_operation_m(struct content_operation *operation, struct graphics_state 
*gs)
@@ -317,13 +330,67 @@ render_operation_h(struct graphics_state *gs)
 }
 
 static inline nspdferror
+gsc_to_device(struct graphics_state_color * gsc, uint32_t *c_out)
+{
+    uint32_t c;
+    unsigned int v;
+
+    switch (gsc->space) {
+    case GSDeviceGray:
+        v = gsc->u.gray * 255.0;
+        v = v & 0xff;
+        c = v | (v << 8) | (v << 16);
+        break;
+
+    case GSDeviceRGB:
+        v = gsc->u.rgb.r * 255.0;
+        c = v & 0xff;
+        v = gsc->u.rgb.g * 255.0;
+        v = v & 0xff;
+        c |= v << 8;
+        v = gsc->u.rgb.b * 255.0;
+        v = v & 0xff;
+        c |= v << 16;
+        break;
+
+    case GSDeviceCMYK:
+        /* no color profile, this will look shocking */
+        v = (1.0 - ((gsc->u.cmyk.c * (1.0 - gsc->u.cmyk.k)) + gsc->u.cmyk.k)) 
* 255.0;
+        c = v & 0xff;
+        v = (1.0 - ((gsc->u.cmyk.m * (1.0 - gsc->u.cmyk.k)) + gsc->u.cmyk.k)) 
* 255.0;
+        v = v & 0xff;
+        c |= v << 8;
+        v = (1.0 - ((gsc->u.cmyk.y * (1.0 - gsc->u.cmyk.k)) + gsc->u.cmyk.k)) 
* 255.0;
+        v = v & 0xff;
+        c |= v << 16;
+        /*        if (c != 0) printf("setting %f %f %f %f %x\n",
+                           gsc->u.cmyk.c,
+                           gsc->u.cmyk.m,
+                           gsc->u.cmyk.y,
+                           gsc->u.cmyk.k,
+                           c);
+        */
+        break;
+
+    default:
+        c = 0;
+        break;
+    }
+
+    *c_out = c;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
 render_operation_f(struct graphics_state *gs, struct nspdf_render_ctx* 
render_ctx)
 {
     struct nspdf_style style;
     style.stroke_type = NSPDF_OP_TYPE_NONE;
     style.stroke_colour = 0x01000000;
+
     style.fill_type = NSPDF_OP_TYPE_SOLID;
-    style.fill_colour = 0;
+    gsc_to_device(&gs->param_stack[gs->param_stack_idx].other.colour, 
&style.fill_colour);
 
     render_ctx->path(&style,
                      gs->path,
@@ -331,6 +398,7 @@ render_operation_f(struct graphics_state *gs, struct 
nspdf_render_ctx* render_ct
                      gs->param_stack[gs->param_stack_idx].ctm,
                      render_ctx->ctx);
     gs->path_idx = 0;
+
     return NSPDFERROR_OK;
 }
 
@@ -340,11 +408,13 @@ render_operation_S(struct graphics_state *gs, struct 
nspdf_render_ctx* render_ct
 {
     struct nspdf_style style;
 
-    style.stroke_type = NSPDF_OP_TYPE_SOLID;
-    style.stroke_colour = 0;
-    style.stroke_width = gs->param_stack[gs->param_stack_idx].line_width;
     style.fill_type = NSPDF_OP_TYPE_NONE;
     style.fill_colour = 0x01000000;
+
+    style.stroke_type = NSPDF_OP_TYPE_SOLID;
+    style.stroke_width = gs->param_stack[gs->param_stack_idx].line_width;
+    gsc_to_device(&gs->param_stack[gs->param_stack_idx].stroke.colour, 
&style.stroke_colour);
+
     render_ctx->path(&style,
                      gs->path,
                      gs->path_idx,
@@ -362,6 +432,34 @@ render_operation_w(struct content_operation *operation, 
struct graphics_state *g
 }
 
 static inline nspdferror
+render_operation_i(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].flatness = operation->u.number[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_M(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].miter_limit = operation->u.number[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_j(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].line_join = operation->u.i[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_J(struct content_operation *operation, struct graphics_state 
*gs)
+{
+    gs->param_stack[gs->param_stack_idx].line_cap = operation->u.i[0];
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
 render_operation_q(struct graphics_state *gs)
 {
     gs->param_stack[gs->param_stack_idx + 1] = 
gs->param_stack[gs->param_stack_idx];
@@ -378,47 +476,202 @@ render_operation_Q(struct graphics_state *gs)
     return NSPDFERROR_OK;
 }
 
+
+
 /**
  * pre-multiply matrix
  */
 static inline nspdferror
 render_operation_cm(struct content_operation *operation, struct graphics_state 
*gs)
 {
-    float M[6]; /* result matrix */
-    /* M' = Mt * M */
-    /* M' = Mo * Mc where Mo is operation and Mc is graphics state ctm */
-    /* | a b c |   | A B C |   | aA+bP+cU aB+bQ+cV aC+bR+cW |
-     * | p q r | * | P Q R | = | pA+qP+rU pB+qQ+rV pC+qR+rW |
-     * | u v w |   | U V W |   | uA+vP+wU uB+vQ+wV uC+vR+wW |
-     *
-     * | o[0] o[1] 0 |   | c[0] c[1] 0 |   | o[0]*c[0]+o[1]*c[2]      
o[0]*c[1]+o[1]*c[3]      0 |
-     * | o[2] o[3] 0 | * | c[2] c[3] 0 | = | o[2]*c[0]+o[3]*c[2]      
o[2]*c[1]+o[3]*c[3]      0 |
-     * | o[4] o[5] 1 |   | c[4] c[5] 1 |   | o[4]*c[0]+o[5]*c[2]+c[4] 
o[4]*c[1]+o[5]*c[3]+c[5] 1 |
+    /* Mres = Mop * Mctm
+     * where Mop is operation and Mctm is graphics state ctm
      */
-    M[0] = operation->u.number[0] * 
gs->param_stack[gs->param_stack_idx].ctm[0] +
-           operation->u.number[1] * 
gs->param_stack[gs->param_stack_idx].ctm[2];
-    M[1] = operation->u.number[0] * 
gs->param_stack[gs->param_stack_idx].ctm[1] +
-           operation->u.number[1] * 
gs->param_stack[gs->param_stack_idx].ctm[3];
-    M[2] = operation->u.number[2] * 
gs->param_stack[gs->param_stack_idx].ctm[0] +
-           operation->u.number[3] * 
gs->param_stack[gs->param_stack_idx].ctm[2];
-    M[3] = operation->u.number[2] * 
gs->param_stack[gs->param_stack_idx].ctm[1] +
-           operation->u.number[3] * 
gs->param_stack[gs->param_stack_idx].ctm[3];
-    M[4] = operation->u.number[4] * 
gs->param_stack[gs->param_stack_idx].ctm[0] +
-           operation->u.number[5] * 
gs->param_stack[gs->param_stack_idx].ctm[2] +
-           gs->param_stack[gs->param_stack_idx].ctm[4];
-    M[5] = operation->u.number[4] * 
gs->param_stack[gs->param_stack_idx].ctm[1] +
-           operation->u.number[5] * 
gs->param_stack[gs->param_stack_idx].ctm[3] +
-           gs->param_stack[gs->param_stack_idx].ctm[5];
-
-    gs->param_stack[gs->param_stack_idx].ctm[0] = M[0];
-    gs->param_stack[gs->param_stack_idx].ctm[1] = M[1];
-    gs->param_stack[gs->param_stack_idx].ctm[2] = M[2];
-    gs->param_stack[gs->param_stack_idx].ctm[3] = M[3];
-    gs->param_stack[gs->param_stack_idx].ctm[4] = M[4];
-    gs->param_stack[gs->param_stack_idx].ctm[5] = M[5];
+    return pdf_matrix_multiply(operation->u.number,
+                               gs->param_stack[gs->param_stack_idx].ctm,
+                               gs->param_stack[gs->param_stack_idx].ctm);
+}
+
+
+static inline nspdferror
+set_gsc_grey(struct graphics_state_color *gsc, float gray)
+{
+    /* bounds check */
+    if (gray < 0.0) {
+        gray = 0.0;
+    } else if (gray > 1.0) {
+        gray = 1.0;
+    }
+
+    gsc->space = GSDeviceGray;
+    gsc->u.gray = gray;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_G(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_grey(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                        operation->u.number[0]);
+}
+
+static inline nspdferror
+render_operation_g(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_grey(&gs->param_stack[gs->param_stack_idx].other.colour,
+                        operation->u.number[0]);
+}
+
+static inline nspdferror
+set_gsc_rgb(struct graphics_state_color *gsc, float r, float g, float b)
+{
+    /* bounds check */
+    if (r < 0.0) {
+        r = 0.0;
+    } else if (r > 1.0) {
+        r = 1.0;
+    }
+    if (g < 0.0) {
+        g = 0.0;
+    } else if (g > 1.0) {
+        g = 1.0;
+    }
+    if (b < 0.0) {
+        b = 0.0;
+    } else if (b > 1.0) {
+        b = 1.0;
+    }
+
+    gsc->space = GSDeviceRGB;
+    gsc->u.rgb.r = r;
+    gsc->u.rgb.g = g;
+    gsc->u.rgb.b = b;
+
     return NSPDFERROR_OK;
 }
 
+static inline nspdferror
+render_operation_RG(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_rgb(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2]);
+}
+
+static inline nspdferror
+render_operation_rg(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_rgb(&gs->param_stack[gs->param_stack_idx].other.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2]);
+}
+
+static inline nspdferror
+set_gsc_cmyk(struct graphics_state_color *gsc, float c, float m, float y, 
float k)
+{
+    /* bounds check */
+    if (c < 0.0) {
+        c = 0.0;
+    } else if (c > 1.0) {
+        c = 1.0;
+    }
+    if (y < 0.0) {
+        y = 0.0;
+    } else if (y > 1.0) {
+        y = 1.0;
+    }
+    if (m < 0.0) {
+        m = 0.0;
+    } else if (m > 1.0) {
+        m = 1.0;
+    }
+    if (k < 0.0) {
+        k = 0.0;
+    } else if (k > 1.0) {
+        k = 1.0;
+    }
+
+    gsc->space = GSDeviceCMYK;
+    gsc->u.cmyk.c = c;
+    gsc->u.cmyk.m = m;
+    gsc->u.cmyk.y = y;
+    gsc->u.cmyk.k = k;
+
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_K(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cmyk(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2],
+                       operation->u.number[3]);
+}
+
+static inline nspdferror
+render_operation_k(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cmyk(&gs->param_stack[gs->param_stack_idx].other.colour,
+                       operation->u.number[0],
+                       operation->u.number[1],
+                       operation->u.number[2],
+                       operation->u.number[3]);
+}
+
+static inline nspdferror
+set_gsc_cs(struct graphics_state_color *gsc, const char *spacename)
+{
+    if (strcmp(spacename, "DeviceGray") == 0) {
+        gsc->space = GSDeviceGray;
+        gsc->u.gray = 0.0;
+    } else if (strcmp(spacename, "DeviceRGB") == 0) {
+        gsc->space = GSDeviceRGB;
+        gsc->u.rgb.r = 0.0;
+        gsc->u.rgb.g = 0.0;
+        gsc->u.rgb.b = 0.0;
+    } else if (strcmp(spacename, "DeviceCMYK") == 0) {
+        gsc->space = GSDeviceCMYK;
+        gsc->u.cmyk.c = 0.0;
+        gsc->u.cmyk.m = 0.0;
+        gsc->u.cmyk.y = 0.0;
+        gsc->u.cmyk.k = 1.0;
+    } else {
+        /** \todo colourspace from name defined in the ColorSpace 
subdictionary of the current resource dictionary */
+        gsc->space = GSDeviceGray;
+        gsc->u.gray = 0.0;
+
+    }
+    //printf("cs %s %d\n", spacename, gsc->space);
+    return NSPDFERROR_OK;
+}
+
+static inline nspdferror
+render_operation_CS(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cs(&gs->param_stack[gs->param_stack_idx].stroke.colour,
+                        operation->u.name);
+}
+
+static inline nspdferror
+render_operation_cs(struct content_operation *operation,
+                   struct graphics_state *gs)
+{
+    return set_gsc_cs(&gs->param_stack[gs->param_stack_idx].other.colour,
+                        operation->u.name);
+}
+
 /**
  * Initialise the parameter stack
  *
@@ -486,6 +739,7 @@ nspdf_page_render(struct nspdf_doc *doc,
          idx < page_content->length;
          idx++, operation++) {
         switch(operation->operator) {
+            /* path operations */
         case CONTENT_OP_m: /* move */
             res = render_operation_m(operation, &gs);
             break;
@@ -524,9 +778,25 @@ nspdf_page_render(struct nspdf_doc *doc,
             res = render_operation_S(&gs, render_ctx);
             break;
 
-        case CONTENT_OP_w:
+            /* graphics state operations */
+        case CONTENT_OP_w: /* line width */
             res = render_operation_w(operation, &gs);
-            //printf("line width:%f\n", 
gs.param_stack[gs.param_stack_idx].line_width);
+            break;
+
+        case CONTENT_OP_i: /* flatness */
+            res = render_operation_i(operation, &gs);
+            break;
+
+        case CONTENT_OP_j: /* line join style */
+            res = render_operation_j(operation, &gs);
+            break;
+
+        case CONTENT_OP_J: /* line cap style */
+            res = render_operation_J(operation, &gs);
+            break;
+
+        case CONTENT_OP_M: /* miter limit */
+            res = render_operation_M(operation, &gs);
             break;
 
         case CONTENT_OP_q: /* push parameter stack */
@@ -541,6 +811,44 @@ nspdf_page_render(struct nspdf_doc *doc,
             res = render_operation_cm(operation, &gs);
             break;
 
+            /* colour operators */
+        case CONTENT_OP_G: /* gray stroking colour */
+            res = render_operation_G(operation, &gs);
+            break;
+
+        case CONTENT_OP_g: /* gray non-stroking colour */
+            res = render_operation_g(operation, &gs);
+            break;
+
+        case CONTENT_OP_RG: /* rgb stroking colour */
+            res = render_operation_RG(operation, &gs);
+            break;
+
+        case CONTENT_OP_rg: /* rgb non-stroking colour */
+            res = render_operation_rg(operation, &gs);
+            break;
+
+        case CONTENT_OP_K: /* CMYK stroking colour */
+            res = render_operation_K(operation, &gs);
+            break;
+
+        case CONTENT_OP_k: /* CMYK non-stroking colour */
+            res = render_operation_k(operation, &gs);
+            break;
+
+        case CONTENT_OP_CS: /* change stroking colourspace */
+            res = render_operation_CS(operation, &gs);
+            break;
+
+        case CONTENT_OP_cs: /* change non-stroking colourspace */
+            res = render_operation_cs(operation, &gs);
+            break;
+
+            //case CONTENT_OP_SC:
+            //case CONTENT_OP_sc:
+            //case CONTENT_OP_SCN:
+            //case CONTENT_OP_scn:
+
         default:
             printf("operator %s\n",
                nspdf__cos_content_operator_name(operation->operator));


-- 
PDF Manipulation Library

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to