示例#1
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSFillPolygon(Display *display, Drawable drawable, GC context,
               Coord *coord, int ncoords, int shape, int mode)
{
    int i;
    int pcount;

    if (output_flag == XOUT)
    {
        XFillPolygon(display, drawable, context,
                     (XPoint *)coord, ncoords, shape, mode);
    }
    else
    {
        XGCValues values;

        XGetGCValues(display, context, GCForeground | GCLineWidth, &values);

        if (ncoords <= 0)
        {
            return;
        }

        PSNewpath();
        PSSetPixel(display, values.foreground);
        PSMoveto(coord[0].x, coord[0].y);
        pcount = 0;

        for (i = 1; i < ncoords; i++)
        {
            PSLineto(coord[i].x, coord[i].y);

            /*
             * break it up into managable cuhnks
             */

            if (pcount > MAXSTROKES)
            {
                PSClosefill();
                PSMoveto(coord[i].x, coord[i].y);
                pcount = 0;
            }

            pcount++;
        }

        PSClosefill();
    }
}
示例#2
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSFillArc(Display *display, Drawable drawable, GC context,
           int x, int y, int w, int h, int angle1, int angle2)
{
    if (output_flag == XOUT)
    {
        XFillArc(display, drawable, context, x, y, w, h, angle1, angle2);
    }
    else
    {
        XGCValues values;

        XGetGCValues(display, context, GCForeground | GCLineWidth
                     | GCArcMode, &values);
        PSNewpath();
        PSSetPixel(display, values.foreground);
        PSSetLineWidth(values.line_width);

        if (values.arc_mode == ArcPieSlice)
            PSMoveto(x + w / 2, y + h / 2);

        PSArc(x + w / 2.0, y + h / 2.0, w / 2.0, angle1 / 64.0,
              angle2 / 64.0);
        PSClosefill();
    }
}
示例#3
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSDrawLine(Display *display, Drawable drawable, GC context,
            int x1, int y1, int x2, int y2)
{
    if (output_flag == XOUT)
    {
        XDrawLine(display, drawable, context, x1, y1, x2, y2);
    }
    else
    {
        /*
         * get the current foreground color from the graphics context
         */

        XGCValues values;

        XGetGCValues(display, context, GCForeground | GCLineWidth, &values);
        PSSetPixel(display, values.foreground);
        PSSetLineWidth(values.line_width);
        PSNewpath();
        PSMoveto(x1, y1);
        PSLineto(x2, y2);
        PSStroke();
    }
}
示例#4
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSDrawDot(Display *display, Drawable drawable, GC context, int x1, int y1)
{
    if (output_flag == XOUT)
    {
        XDrawLine(display, drawable, context, x1, y1, x1, y1 + 1);
    }
    else
    {
        /* Hack: this isn't a good way to draw PS dots */
        XGCValues values;

        XGetGCValues(display, context, GCForeground | GCLineWidth, &values);
        PSSetPixel(display, values.foreground);
        PSSetLineWidth(values.line_width);
        PSNewpath();
        PSMoveto(x1, y1);
        PSLineto(x1, y1 + 1);
        PSStroke();
    }
}
示例#5
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSFillRectangle(Display *display, Drawable drawable, GC context,
                 int x, int y, int w, int h)
{
    if (output_flag == XOUT)
    {
        XFillRectangle(display, drawable, context, x, y, w, h);
    }
    else
    {
        XGCValues values;

        XGetGCValues(display, context, GCForeground | GCLineWidth, &values);
        PSSetPixel(display, values.foreground);
        PSNewpath();
        PSMoveto(x, y);
        PSLineto(x + w, y);
        PSLineto(x + w, y + h);
        PSLineto(x, y + h);
        PSClosefill();
    }
}
示例#6
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSDrawText(Display *display, Drawable drawable, GC context, int x, int y,
            char *s)
{
    XFontStruct *finfo;
    int height;

    if (s == NULL)
        return;

    if (output_flag == XOUT)
    {
        XDrawImageString(display, drawable, context, x, y, s, strlen(s));
    }
    else
    {
        finfo = XQueryFont(display, context->gid);
        height = finfo->ascent + finfo->descent;
        PSFont(height);
        PSMoveto(x, y);
        PSShow(s);
    }
}
示例#7
0
/*
** We call this routine to emmit the PostScript code
** for the character we have loaded with load_char().
*/
void GlyphToType3::PSConvert(TTStreamWriter& stream)
{
    int i,j,k;

    assert(area_ctr == NULL);
    area_ctr=(double*)calloc(num_ctr, sizeof(double));
    memset(area_ctr, 0, (num_ctr*sizeof(double)));
    assert(check_ctr == NULL);
    check_ctr=(char*)calloc(num_ctr, sizeof(char));
    memset(check_ctr, 0, (num_ctr*sizeof(char)));
    assert(ctrset == NULL);
    ctrset=(int*)calloc(num_ctr, 2*sizeof(int));
    memset(ctrset, 0, (num_ctr*2*sizeof(int)));

    check_ctr[0]=1;
    area_ctr[0]=area(xcoor, ycoor, epts_ctr[0]+1);

    for (i=1; i<num_ctr; i++)
    {
        area_ctr[i]=area(xcoor+epts_ctr[i-1]+1, ycoor+epts_ctr[i-1]+1, epts_ctr[i]-epts_ctr[i-1]);
    }

    for (i=0; i<num_ctr; i++)
    {
        if (area_ctr[i]>0)
        {
            ctrset[2*i]=i;
            ctrset[2*i+1]=nearout(i);
        }
        else
        {
            ctrset[2*i]=-1;
            ctrset[2*i+1]=-1;
        }
    }

    /* Step thru the coutours. */
    /* I believe that a contour is a detatched */
    /* set of curves and lines. */
    for(i = j = k = 0;
        i != NOMOREOUTCTR && i < num_ctr;
        k = nextinctr(i, k), (k == NOMOREINCTR && (i = k = nextoutctr(i))))
    {
        // A TrueType contour consists of on-path and off-path points.
        // Two consecutive on-path points are to be joined with a
        // line; off-path points between on-path points indicate a
        // quadratic spline, where the off-path point is the control
        // point. Two consecutive off-path points have an implicit
        // on-path point midway between them.
        std::list<FlaggedPoint> points;

        // Represent flags and x/y coordinates as a C++ list
        for (; j <= epts_ctr[k]; j++)
        {
            if (!(tt_flags[j] & 1)) {
                points.push_back(FlaggedPoint(OFF_PATH, xcoor[j], ycoor[j]));
            } else {
                points.push_back(FlaggedPoint(ON_PATH, xcoor[j], ycoor[j]));
            }
        }

        if (points.size() == 0) {
            // Don't try to access the last element of an empty list
            continue;
        }

        // For any two consecutive off-path points, insert the implied
        // on-path point.
        FlaggedPoint prev = points.back();
        for (std::list<FlaggedPoint>::iterator it = points.begin();
             it != points.end();
             it++)
        {
            if (prev.flag == OFF_PATH && it->flag == OFF_PATH)
            {
                points.insert(it,
                              FlaggedPoint(ON_PATH,
                                           (prev.x + it->x) / 2,
                                           (prev.y + it->y) / 2));
            }
            prev = *it;
        }
        // Handle the wrap-around: insert a point either at the beginning
        // or at the end that has the same coordinates as the opposite point.
        // This also ensures that the initial point is ON_PATH.
        if (points.front().flag == OFF_PATH)
        {
            assert(points.back().flag == ON_PATH);
            points.insert(points.begin(), points.back());
        }
        else
        {
            assert(points.front().flag == ON_PATH);
            points.push_back(points.front());
        }

        // The first point
        stack(stream, 3);
        PSMoveto(stream, points.front().x, points.front().y);

        // Step through the remaining points
        std::list<FlaggedPoint>::const_iterator it = points.begin();
        for (it++; it != points.end(); /* incremented inside */)
        {
            const FlaggedPoint& point = *it;
            if (point.flag == ON_PATH)
            {
                stack(stream, 3);
                PSLineto(stream, point.x, point.y);
                it++;
            } else {
                std::list<FlaggedPoint>::const_iterator prev = it, next = it;
                prev--;
                next++;
                assert(prev->flag == ON_PATH);
                assert(next->flag == ON_PATH);
                stack(stream, 7);
                PSCurveto(stream,
                          prev->x, prev->y,
                          point.x, point.y,
                          next->x, next->y);
                it++;
                it++;
            }
        }
    }

    /* Now, we can fill the whole thing. */
    stack(stream, 1);
    stream.puts( pdf_mode ? "f" : "_cl" );

    /* Free our work arrays. */
    free(area_ctr);
    free(check_ctr);
    free(ctrset);
    area_ctr = NULL;
    check_ctr = NULL;
    ctrset = NULL;
} /* end of PSConvert() */
示例#8
0
/*
** We call this routine to emmit the PostScript code
** for the character we have loaded with load_char().
*/
void GlyphToType3::PSConvert(TTStreamWriter& stream)
{
    int j, k;

    /* Step thru the contours.
     * j = index to xcoor, ycoor, tt_flags (point data)
     * k = index to epts_ctr (which points belong to the same contour) */
    for(j = k = 0; k < num_ctr; k++)
    {
        // A TrueType contour consists of on-path and off-path points.
        // Two consecutive on-path points are to be joined with a
        // line; off-path points between on-path points indicate a
        // quadratic spline, where the off-path point is the control
        // point. Two consecutive off-path points have an implicit
        // on-path point midway between them.
        std::list<FlaggedPoint> points;

        // Represent flags and x/y coordinates as a C++ list
        for (; j <= epts_ctr[k]; j++)
        {
            if (!(tt_flags[j] & 1)) {
                points.push_back(FlaggedPoint(OFF_PATH, xcoor[j], ycoor[j]));
            } else {
                points.push_back(FlaggedPoint(ON_PATH, xcoor[j], ycoor[j]));
            }
        }

        if (points.size() == 0) {
            // Don't try to access the last element of an empty list
            continue;
        }

        // For any two consecutive off-path points, insert the implied
        // on-path point.
        FlaggedPoint prev = points.back();
        for (std::list<FlaggedPoint>::iterator it = points.begin();
             it != points.end();
             it++)
        {
            if (prev.flag == OFF_PATH && it->flag == OFF_PATH)
            {
                points.insert(it,
                              FlaggedPoint(ON_PATH,
                                           (prev.x + it->x) / 2,
                                           (prev.y + it->y) / 2));
            }
            prev = *it;
        }
        // Handle the wrap-around: insert a point either at the beginning
        // or at the end that has the same coordinates as the opposite point.
        // This also ensures that the initial point is ON_PATH.
        if (points.front().flag == OFF_PATH)
        {
            assert(points.back().flag == ON_PATH);
            points.insert(points.begin(), points.back());
        }
        else
        {
            assert(points.front().flag == ON_PATH);
            points.push_back(points.front());
        }

        // The first point
        stack(stream, 3);
        PSMoveto(stream, points.front().x, points.front().y);

        // Step through the remaining points
        std::list<FlaggedPoint>::const_iterator it = points.begin();
        for (it++; it != points.end(); /* incremented inside */)
        {
            const FlaggedPoint& point = *it;
            if (point.flag == ON_PATH)
            {
                stack(stream, 3);
                PSLineto(stream, point.x, point.y);
                it++;
            } else {
                std::list<FlaggedPoint>::const_iterator prev = it, next = it;
                prev--;
                next++;
                assert(prev->flag == ON_PATH);
                assert(next->flag == ON_PATH);
                stack(stream, 7);
                PSCurveto(stream,
                          prev->x, prev->y,
                          point.x, point.y,
                          next->x, next->y);
                it++;
                it++;
            }
        }
    }

    /* Now, we can fill the whole thing. */
    stack(stream, 1);
    stream.puts( pdf_mode ? "f" : "_cl" );
} /* end of PSConvert() */
示例#9
0
文件: psdriver.c 项目: PNCG/genesis
void
PSHeader(XWindowAttributes *info, float requested_scale, int box, int header)
{
    float   scale, scalex, scaley;
    float   tx, ty;
    int     bbxmin, bbxmax, bbymin, bbymax;
    long    clock;
    char    headerstr[200];
    char   *namestr;
    char   *ptr;
    char    clockstr[100];

    /*
     * --------------------------------------------
     *  calculate translation, scales, bounding box
     * --------------------------------------------
     */

    global_window_width = info->width;
    global_window_height = info->height;

    /*
     * calculate the scale factors in inches/screenpixel
     */

    scalex = PAGEWIDTH / global_window_width;
    scaley = PAGEHEIGHT / global_window_height;

    /*
     * use the smaller scale factor so everything will fit on the page
     */

    scale = requested_scale * ((scalex < scaley) ? scalex : scaley);

    /*
     * calculate the dots/screenpixel scale factor
     */

    pix_scale = scale * DPI;

    /*
     * convert to postscriptpoints/screenpixel
     */

    page_scale = scale * DEFAULTRES;

    /*
     * center it on the page for printer output
     * leave it at (0, 0) for file_output
     */

    if (file_output)
    {
        tx = 0.0;
        ty = 0.0;
    }
    else
    {
        tx = DEFAULTRES * (PAGEWIDTH - scale * global_window_width) / 2.0;
        ty = DEFAULTRES * (PAGEHEIGHT - scale * global_window_height) / 2.0;
    }

    /*
     * bounding box
     */

    bbxmin = tx;
    bbymin = ty;
    bbxmax = tx + page_scale * global_window_width + 1;
    bbymax = ty + page_scale * global_window_height + 1;

    /*
     * -----------
     *  COMMENTS
     * -----------
     */

    fprintf(PSfp, "%%!\n");
    fprintf(PSfp, "%%%%BoundingBox: %d %d %d %d\n",
            bbxmin, bbymin, bbxmax, bbymax);
    fprintf(PSfp, "%%%%EndComments\n");

    fprintf(PSfp, "initgraphics\n");
    fprintf(PSfp, "/M { moveto } def\n");
    fprintf(PSfp, "/L { lineto } def\n");
    fprintf(PSfp, "/A { arc } def\n");
    fprintf(PSfp, "/AN { arcn } def\n");
    fprintf(PSfp, "/S { stroke } def\n");
    fprintf(PSfp, "/N { newpath } def\n");
    fprintf(PSfp, "/C { closepath fill } def\n");
    fprintf(PSfp, "/G { setgray } def\n");

    if (box)
    {
        fprintf(PSfp, "0.5 G\n");
        PSNewpath();
        PSMoveto(bbxmin, global_window_height - bbymin);
        PSLineto(bbxmin, global_window_height - bbymax);
        PSLineto(bbxmax, global_window_height - bbymax);
        PSLineto(bbxmax, global_window_height - bbymin);
        PSLineto(bbxmin, global_window_height - bbymin);
        PSStroke();
        fprintf(PSfp, "0 G\n");
    }

    fprintf(PSfp, "%f %f translate\n", tx, ty);
    fprintf(PSfp, "%f %f scale\n", page_scale, page_scale);

    if (header)
    {
        if ((namestr = getenv("NAME")) == ((char *)NULL))
        {
            namestr = "";
        }

        time(&clock);
        strcpy(clockstr, ctime(&clock));

        if ((ptr = strchr(clockstr, '\n')))
        {
            *ptr = '\0';
        }

        sprintf(headerstr, "%s ::  %s ::  %s",
                clockstr, getcwd(NULL, 200), namestr);
        PSNewpath();
        PSFont(9);
        fprintf(PSfp, "15 15 M\n");
        PSShow(headerstr);
        PSStroke();
    }

    PSNewpath();
    PSMoveto(0, 0);
    PSLineto(0, global_window_height);
    PSLineto(global_window_width, global_window_height);
    PSLineto(global_window_width, 0);
    PSLineto(0, 0);
    fprintf(PSfp, "eoclip\n");
}
示例#10
0
文件: psdriver.c 项目: PNCG/genesis
void
XPSDrawLines(Display *display, Drawable drawable,
             GC context, Coord *coord, int ncoords, int mode)
{
    int i;
    int pcount;
    int nchunks;
    int chunksize;

    if (output_flag == XOUT)
    {
        /*
         * avoid the limit on the length of a multiple line vector
         * by doing it in multiple calls
         */

        nchunks = (ncoords - 1) / MAXCHUNK + 1;

        for (i = 0; i < nchunks; i++)
        {
            if ((chunksize = (ncoords - i * MAXCHUNK)) > MAXCHUNK)
            {
                chunksize = MAXCHUNK;
            }

            /*
             * Draw one point past to connect this chunk with the
             * next.  Don't do it for the last chunk.
             */

            if (i < nchunks - 1)
                chunksize++;

            XDrawLines(display, drawable, context,
                       (XPoint *)(coord + i * MAXCHUNK), chunksize, mode);
        }
    }
    else
    {
        XGCValues values;

        XGetGCValues(display, context, GCForeground | GCLineWidth, &values);

        if (ncoords <= 0)
        {
            return;
        }

        PSNewpath();
        PSSetPixel(display, values.foreground);
        PSSetLineWidth(values.line_width);
        PSMoveto(coord[0].x, coord[0].y);
        pcount = 0;

        for (i = 1; i < ncoords; i++)
        {
            if ((coord[i].x == coord[i - 1].x)
                && (coord[i].y == coord[i - 1].y) && i < ncoords - 1)
            {
                continue;
            }

            PSLineto(coord[i].x, coord[i].y);

            /*
             * break it up into managable cuhnks
             */

            if (pcount > MAXSTROKES)
            {
                PSStroke();
                PSNewpath();
                PSMoveto(coord[i].x, coord[i].y);
                pcount = 0;
            }

            pcount++;
        }

        PSStroke();
    }
}