Beispiel #1
0
static void
tickY(pixel **     const pixels,
      unsigned int const pixcols,
      unsigned int const pixrows,
      pixval       const maxval,
      unsigned int const xBias,
      unsigned int const yBias,
      pixel        const axisColor,
      unsigned int const tenth) {
/*----------------------------------------------------------------------------
   Put a tick mark 'tenth' tenths of the way along the Y axis and label it.

   'pixels' is the canvas on which to draw it; its dimensions are
   'pixcols' by 'pixrows' and has maxval 'maxval'.
-----------------------------------------------------------------------------*/
    unsigned int const pxrows = pixrows - yBias;
    unsigned int const tickRow = (tenth * (pxrows - 1)) / 10;
        /* Pixel row where the top of the tick goes */
    unsigned int const tickThickness = Sz(3);
        /* Thickness of the tick in pixels */
    
    char s[20];

    assert(tenth < 10);

    sprintf(s, "0.%d", 10 - tenth);
    ppmd_line(pixels, pixcols, pixrows, maxval,
              B(0, tickRow), B(tickThickness, tickRow),
              PPMD_NULLDRAWPROC, (char *) &axisColor);

    ppmd_text(pixels, pixcols, pixrows, maxval,
              B(Sz(-30), tickRow + Sz(5)),
              Sz(10), 0, s,
              PPMD_NULLDRAWPROC, (char *) &axisColor);
}
Beispiel #2
0
static void
writeLabel(pixel **                   const pixels,
           int                        const pixcols,
           int                        const pixrows,
           pixval                     const maxval,
           const struct colorSystem * const cs) {

    pixel rgbcolor;  /* color of text */
    char sysdesc[256];

    PPM_ASSIGN(rgbcolor, maxval, maxval, maxval);
    
    snprintfN(sysdesc, sizeof(sysdesc),
              "System: %s\n"
              "Primary illuminants (X, Y)\n"
              "     Red:  %0.4f, %0.4f\n"
              "     Green: %0.4f, %0.4f\n"
              "     Blue:  %0.4f, %0.4f\n"
              "White point (X, Y): %0.4f, %0.4f",
              cs->name, cs->xRed, cs->yRed, cs->xGreen, cs->yGreen,
              cs->xBlue, cs->yBlue, cs->xWhite, cs->yWhite);
    sysdesc[sizeof(sysdesc)-1] = '\0';  /* for robustness */

    ppmd_text(pixels, pixcols, pixrows, Maxval,
              pixcols / 3, Sz(24), Sz(12), 0, sysdesc,
              PPMD_NULLDRAWPROC, (char *) &rgbcolor);
}
Beispiel #3
0
static void
doTextHere(pixel **                   const pixels,
           unsigned int               const cols,
           unsigned int               const rows,
           pixval                     const maxval,
           const struct drawCommand * const commandP,
           struct drawState *         const drawStateP) {
    
    ppmd_text(pixels, cols, rows, maxval,
              drawStateP->currentPos.x,
              drawStateP->currentPos.y,
              commandP->u.textArg.height,
              commandP->u.textArg.angle,
              commandP->u.textArg.text,
              PPMD_NULLDRAWPROC,
              &drawStateP->color);
    
    {
        int left, top, right, bottom;
        
        ppmd_text_box(commandP->u.textArg.height, 0,
                      commandP->u.textArg.text,
                      &left, &top, &right, &bottom);
        

        drawStateP->currentPos.x +=
            ROUND((right-left) * cosdeg(commandP->u.textArg.angle));
        drawStateP->currentPos.y -=
            ROUND((right-left) * sindeg(commandP->u.textArg.angle));
    }
}
Beispiel #4
0
static void
labelAxes(pixel **     const pixels,
          unsigned int const pixcols,
          unsigned int const pixrows,
          pixval       const maxval,
          unsigned int const xBias,
          unsigned int const yBias,
          pixel        const axisColor,
          bool         const upvp) {
/*----------------------------------------------------------------------------
   Label the axes "x" and "y" or "u" and "v".
-----------------------------------------------------------------------------*/
    unsigned int const pxcols = pixcols - xBias;
    unsigned int const pxrows = pixrows - yBias;

    ppmd_text(pixels, pixcols, pixrows, maxval,
              B((98 * (pxcols - 1)) / 100 - Sz(11), pxrows + Sz(12)),
              Sz(10), 0, (upvp ? "u'" : "x"),
              PPMD_NULLDRAWPROC, (char *) &axisColor);
    ppmd_text(pixels,  pixcols, pixrows, maxval,
              B(Sz(-22), (2 * (pxrows - 1)) / 100 + Sz(5)),
              Sz(10), 0, (upvp ? "v'" : "y"),
              PPMD_NULLDRAWPROC, (char *) &axisColor);
}
Beispiel #5
0
static void
tickX(pixel **     const pixels,
      unsigned int const pixcols,
      unsigned int const pixrows,
      pixval       const maxval,
      unsigned int const xBias,
      unsigned int const yBias,
      pixel        const axisColor,
      unsigned int const tenth) {
/*----------------------------------------------------------------------------
   Put a tick mark 'tenth' tenths of the way along the X axis
   and label it.

   'pixels' is the canvas on which to draw it; its dimensions are
   'pixcols' by 'pixrows' and has maxval 'maxval'.
-----------------------------------------------------------------------------*/
    unsigned int const pxcols = pixcols - xBias;
    unsigned int const pxrows = pixrows - yBias;
    unsigned int const tickCol = (tenth * (pxcols - 1)) / 10;
        /* Pixel column where the left edge of the tick goes */
    unsigned int const tickThickness = Sz(3);
        /* Thickness of the tick in pixels */
    unsigned int const tickBottom = pxrows - Sz(1);
        /* Pixel row of the bottom of the tick */

    char s[20];

    assert(tenth < 10);

    sprintf(s, "0.%u", tenth);
    ppmd_line(pixels, pixcols, pixrows, maxval,
              B(tickCol, tickBottom),
              B(tickCol, tickBottom - tickThickness),
              PPMD_NULLDRAWPROC, (char *) &axisColor);
    ppmd_text(pixels, pixcols, pixrows, maxval,
              B(tickCol - Sz(11), pxrows + Sz(12)),
              Sz(10), 0, s, PPMD_NULLDRAWPROC, (char *) &axisColor);
}
Beispiel #6
0
static void
plotMonochromeWavelengths(
    pixel **                   const pixels,
    int                        const pixcols,
    int                        const pixrows,
    pixval                     const maxval,
    const struct colorSystem * const cs,
    bool                       const upvp,
    int                        const xBias,
    int                        const yBias) {

    int const pxcols = pixcols - xBias;
    int const pxrows = pixrows - yBias;

    int x;  /* The wavelength we're plotting */

    for (x = (upvp? 420 : 450);
         x <= 650;
         x += (upvp? 10 : (x > 470 && x < 600) ? 5 : 10)) {

        pixel rgbcolor;

        /* Ick.  Drop legends that overlap and twiddle position
           so they appear at reasonable positions with respect to
           the tongue.
        */

        if (!overlappingLegend(upvp, x)) {
            double cx, cy, cz, jr, jg, jb, jmax;
            char wl[20];
            int bx = 0, by = 0, tx, ty, r, g, b;
            int icx, icy;  /* Location of the color on the tongue */

            if (x < 520) {
                bx = Sz(-22);
                by = Sz(2);
            } else if (x < 535) {
                bx = Sz(-8);
                by = Sz(-6);
            } else {
                bx = Sz(4);
            }

            computeMonochromeColorLocation(x, pxcols, pxrows, upvp,
                                           &icx, &icy);

            /* Draw the tick mark */
            PPM_ASSIGN(rgbcolor, maxval, maxval, maxval);
            tx = icx + ((x < 520) ? Sz(-2) : ((x >= 535) ? Sz(2) : 0));
            ty = icy + ((x < 520) ? 0 : ((x >= 535) ? Sz(-1) : Sz(-2))); 
            ppmd_line(pixels, pixcols, pixrows, Maxval,
                      B(icx, icy), B(tx, ty),
                      PPMD_NULLDRAWPROC, (char *) &rgbcolor);

            /* The following flailing about sets the drawing color to
               the hue corresponding to the pure wavelength (constrained
               to the display gamut). */

            if (upvp) {
                double up, vp;
                up = ((double) icx) / (pxcols - 1);
                vp = 1.0 - ((double) icy) / (pxrows - 1);
                upvp_to_xy(up, vp, &cx, &cy);
                cz = 1.0 - (cx + cy);
            } else {
                cx = ((double) icx) / (pxcols - 1);
                cy = 1.0 - ((double) icy) / (pxrows - 1);
                cz = 1.0 - (cx + cy);
            }

            xyz_to_rgb(cs, cx, cy, cz, &jr, &jg, &jb);
            (void) constrain_rgb(&jr, &jg, &jb);

            /* Scale to max(rgb) = 1 */
            jmax = MAX(jr, MAX(jg, jb));
            if (jmax > 0) {
                jr = jr / jmax;
                jg = jg / jmax;
                jb = jb / jmax;
            }
            /* gamma correct from linear rgb to nonlinear rgb. */
            gamma_correct_rgb(cs, &jr, &jg, &jb);
            r = Maxval * jr;
            g = Maxval * jg;
            b = Maxval * jb;
            PPM_ASSIGN(rgbcolor, (pixval) r, (pixval) g, (pixval) b);

            sprintf(wl, "%d", x);
            ppmd_text(pixels, pixcols, pixrows, Maxval,
                      B(icx + bx, icy + by), Sz(6), 0, wl,
                      PPMD_NULLDRAWPROC, (char *) &rgbcolor);
        }
    }
}
Beispiel #7
0
static void
plotBlackBodyCurve(pixel **                   const pixels,
                   int                        const pixcols,
                   int                        const pixrows,
                   pixval                     const maxval,
                   bool                       const upvp,
                   int                        const xBias,
                   int                        const yBias) {

    int const pxcols = pixcols - xBias;
    int const pxrows = pixrows - yBias;

    double t;  /* temperature of black body */
    pixel rgbcolor;  /* color of the curve */
    int lx, ly;  /* Last point we've drawn on curve so far */

    PPM_ASSIGN(rgbcolor, 0, 0, 0);

    /* Plot black body curve from 1000 to 30000 kelvins. */

    for (t = 1000.0; t < 30000.0; t += 50.0) {
        double lambda, X = 0, Y = 0, Z = 0;
        int xb, yb;
        int ix;

        /* Determine X, Y, and Z for blackbody by summing color
           match functions over the visual range. */

        for (ix = 0, lambda = 380; lambda <= 780.0; ix++, lambda += 5) {
            double Me;

            /* Evaluate Planck's black body equation for the
               power at this wavelength. */

            Me = 3.74183e-16 * pow(lambda * 1e-9, -5.0) /
                (exp(1.4388e-2/(lambda * 1e-9 * t)) - 1.0);
            X += Me * cie_color_match[ix][0];
            Y += Me * cie_color_match[ix][1];
            Z += Me * cie_color_match[ix][2];
        }
        if (upvp) {
            double up, vp;
            xy_to_upvp(X / (X + Y + Z), Y / (X + Y + Z), &up, &vp);
            xb = (pxcols - 1) * up;
            yb = (pxrows - 1) - ((pxrows - 1) * vp);
        } else {
            xb = (pxcols - 1) * X / (X + Y + Z);
            yb = (pxrows - 1) - ((pxrows - 1) * Y / (X + Y + Z));
        }

        if (t > 1000) {
            ppmd_line(pixels, pixcols, pixrows, Maxval,
                      B(lx, ly), B(xb, yb), PPMD_NULLDRAWPROC,
                      (char *) &rgbcolor);

            /* Draw tick mark every 1000 kelvins */

            if ((((int) t) % 1000) == 0) {
                ppmd_line(pixels, pixcols, pixrows, Maxval,
                          B(lx, ly - Sz(2)), B(lx, ly + Sz(2)),
                          PPMD_NULLDRAWPROC, (char *) &rgbcolor);

                /* Label selected tick marks with decreasing density. */

                if (t <= 5000.1 || (t > 5000.0 && 
                                    ((((int) t) % 5000) == 0) &&
                                    t != 20000.0)) {
                    char bb[20];

                    sprintf(bb, "%g", t);
                    ppmd_text(pixels, pixcols, pixrows, Maxval,
                              B(lx - Sz(12), ly - Sz(4)), Sz(6), 0, bb,
                              PPMD_NULLDRAWPROC, (char *) &rgbcolor);
                }
  
            }
        }
        lx = xb;
        ly = yb;
    }
}
Beispiel #8
0
static void
drawAxes(pixel ** const pixels,
         int    const pixcols,
         int    const pixrows,
         pixval const maxval,
         bool   const upvp,
         int    const xBias,
         int    const yBias) {

    int const pxcols = pixcols - xBias;
    int const pxrows = pixrows - yBias;

    pixel rgbcolor;  /* Color of axes */
    int i;

    PPM_ASSIGN(rgbcolor, maxval, maxval, maxval);
    ppmd_line(pixels, pixcols, pixrows, maxval,
              B(0, 0), B(0, pxrows - 1), PPMD_NULLDRAWPROC,
              (char *) &rgbcolor);
    ppmd_line(pixels, pixcols, pixrows, maxval,
              B(0, pxrows - 1), B(pxcols - 1, pxrows - 1),
              PPMD_NULLDRAWPROC, (char *) &rgbcolor);
    
    /* Draw tick marks on X and Y axes every 0.1 units.  Also
       label axes.
    */
    
    for (i = 1; i <= 9; i += 1) {
        char s[20];

        /* X axis tick */

        sprintf(s, "0.%d", i);
        ppmd_line(pixels, pixcols, pixrows, maxval,
                  B((i * (pxcols - 1)) / 10, pxrows - Sz(1)),
                  B((i * (pxcols - 1)) / 10, pxrows - Sz(4)),
                  PPMD_NULLDRAWPROC, (char *) &rgbcolor);
        ppmd_text(pixels, pixcols, pixrows, maxval,
                  B((i * (pxcols - 1)) / 10 - Sz(11), pxrows + Sz(12)),
                  Sz(10), 0, s, PPMD_NULLDRAWPROC, (char *) &rgbcolor);

        /* Y axis tick */

        sprintf(s, "0.%d", 10 - i);
        ppmd_line(pixels, pixcols, pixrows, maxval,
                  B(0, (i * (pxrows - 1)) / 10),
                  B(Sz(3), (i * (pxrows - 1)) / 10),
                  PPMD_NULLDRAWPROC, (char *) &rgbcolor);

        ppmd_text(pixels, pixcols, pixrows, maxval,
                  B(Sz(-30), (i * (pxrows - 1)) / 10 + Sz(5)),
                  Sz(10), 0, s,
                  PPMD_NULLDRAWPROC, (char *) &rgbcolor);
    }
    ppmd_text(pixels, pixcols, pixrows, maxval,
              B((98 * (pxcols - 1)) / 100 - Sz(11), pxrows + Sz(12)),
              Sz(10), 0, (upvp ? "u'" : "x"),
              PPMD_NULLDRAWPROC, (char *) &rgbcolor);
    ppmd_text(pixels,  pixcols, pixrows, maxval,
              B(Sz(-22), (2 * (pxrows - 1)) / 100 + Sz(5)),
              Sz(10), 0, (upvp ? "v'" : "y"),
              PPMD_NULLDRAWPROC, (char *) &rgbcolor);
}
Beispiel #9
0
static void
executeScript(struct script * const scriptP,
              pixel **        const pixels,
              unsigned int    const cols,
              unsigned int    const rows,
              pixval          const maxval) {

    struct drawState drawState;
    unsigned int seq;
        /* Sequence number of current command (0 = first, etc.) */
    struct commandListElt * p;
        /* Pointer to current element in command list */

    initDrawState(&drawState, maxval);

    for (p = scriptP->commandListHeadP, seq = 0; p; p = p->nextP, ++seq) {
        const struct drawCommand * const commandP = p->commandP;

        if (verbose)
            pm_message("Command %u: %u", seq, commandP->verb);

        switch (commandP->verb) {
        case VERB_SETPOS:
            drawState.currentPos.x = commandP->u.setposArg.x;
            drawState.currentPos.y = commandP->u.setposArg.y;
            break;
        case VERB_SETLINETYPE:
            ppmd_setlinetype(commandP->u.setlinetypeArg.type);
            break;
        case VERB_SETLINECLIP:
            ppmd_setlineclip(commandP->u.setlineclipArg.clip);
            break;
        case VERB_SETCOLOR:
            drawState.color =
                ppm_parsecolor2(commandP->u.setcolorArg.colorName,
                                maxval, TRUE);
            break;
        case VERB_SETFONT: {
            FILE * ifP;
            const struct ppmd_font * fontP;
            ifP = pm_openr(commandP->u.setfontArg.fontFileName);
            ppmd_read_font(ifP, &fontP);
            ppmd_set_font(fontP);
            pm_close(ifP);
        } break;
        case VERB_LINE:
            ppmd_line(pixels, cols, rows, maxval,
                      commandP->u.lineArg.x0, commandP->u.lineArg.y0,
                      commandP->u.lineArg.x1, commandP->u.lineArg.y1,
                      PPMD_NULLDRAWPROC,
                      &drawState.color);
            break;
        case VERB_LINE_HERE: {
            struct pos endPos;

            endPos.x = drawState.currentPos.x + commandP->u.lineHereArg.right;
            endPos.y = drawState.currentPos.y + commandP->u.lineHereArg.down;

            ppmd_line(pixels, cols, rows, maxval,
                      drawState.currentPos.x, drawState.currentPos.y,
                      endPos.x, endPos.y,
                      PPMD_NULLDRAWPROC,
                      &drawState.color);
            drawState.currentPos = endPos;
        } break;
        case VERB_SPLINE3:
            ppmd_spline3(pixels, cols, rows, maxval,
                         commandP->u.spline3Arg.x0,
                         commandP->u.spline3Arg.y0,
                         commandP->u.spline3Arg.x1,
                         commandP->u.spline3Arg.y1,
                         commandP->u.spline3Arg.x2,
                         commandP->u.spline3Arg.y2,
                         PPMD_NULLDRAWPROC,
                         &drawState.color);
            break;
        case VERB_CIRCLE:
            ppmd_circle(pixels, cols, rows, maxval,
                        commandP->u.circleArg.cx,
                        commandP->u.circleArg.cy,
                        commandP->u.circleArg.radius,
                        PPMD_NULLDRAWPROC,
                        &drawState.color);
            break;
        case VERB_FILLEDCIRCLE:
            doFilledCircle(pixels, cols, rows, maxval, commandP, &drawState);
            break;
        case VERB_FILLEDRECTANGLE:
            ppmd_filledrectangle(pixels, cols, rows, maxval,
                                 commandP->u.filledrectangleArg.x,
                                 commandP->u.filledrectangleArg.y,
                                 commandP->u.filledrectangleArg.width,
                                 commandP->u.filledrectangleArg.height,
                                 PPMD_NULLDRAWPROC,
                                 &drawState.color);
            break;
        case VERB_TEXT:
            ppmd_text(pixels, cols, rows, maxval,
                      commandP->u.textArg.xpos,
                      commandP->u.textArg.ypos,
                      commandP->u.textArg.height,
                      commandP->u.textArg.angle,
                      commandP->u.textArg.text,
                      PPMD_NULLDRAWPROC,
                      &drawState.color);
            break;
        case VERB_TEXT_HERE:
            doTextHere(pixels, cols, rows, maxval, commandP, &drawState);
            break;
        }
    }
}