Exemplo n.º 1
0
static void
emit_hash (fz_context *ctx, emitter *e, pdfout_data *hash)
{
  pdfout_data *title = pdfout_data_hash_gets (ctx, hash, "title");
  pdfout_data *page = pdfout_data_hash_gets (ctx, hash, "page");
  int len;
  emit_indent (ctx, e);
  emit_title (ctx, e->out, title);
  
  fz_puts (ctx, e->out, " ");
  fz_puts (ctx, e->out, pdfout_data_scalar_get (ctx, page, &len));
  fz_puts (ctx, e->out, "\n");

  pdfout_data *kids = pdfout_data_hash_gets (ctx, hash, "kids");

  if (kids)
    {
      e->indent_level++;
      emit_array (ctx, e, kids);
      e->indent_level--;
    }
  
}
Exemplo n.º 2
0
static void
emit_title (fz_context *ctx, fz_output *out, pdfout_data *title)
{
  int len;

  char *title_str = pdfout_data_scalar_get(ctx, title, &len);

  if (memchr (title_str, '\n', len) == NULL)
    {
      fz_puts(ctx, out, title_str);
      return;
    }

  fz_warn (ctx, "title with newlines: '%s', replacing it with spaces",
	   title_str);
  char *copy = fz_strdup(ctx, title_str);
  for (int i = 0; i < strlen(copy); ++i) {
    if (copy[i] == '\n')
      copy[i] = ' ';
  }
  fz_puts (ctx, out, copy);
  free (copy);
}
Exemplo n.º 3
0
void
fz_output_pcl_bitmap(fz_output *out, const fz_bitmap *bitmap, fz_pcl_options *pcl)
{
    unsigned char *data, *out_data;
    int y, ss, rmask, line_size;
    fz_context *ctx;
    int num_blank_lines;
    int compression = -1;
    unsigned char *prev_row = NULL;
    unsigned char *out_row_mode_2 = NULL;
    unsigned char *out_row_mode_3 = NULL;
    int out_count;
    int max_mode_2_size;
    int max_mode_3_size;

    if (!out || !bitmap)
        return;

    ctx = out->ctx;

    if (pcl->features & HACK__IS_A_OCE9050)
    {
        /* Enter HPGL/2 mode, begin plot, Initialise (start plot), Enter PCL mode */
        fz_puts(out, "\033%1BBPIN;\033%1A");
    }

    pcl_header(out, pcl, 1, bitmap->xres);

    fz_var(prev_row);
    fz_var(out_row_mode_2);
    fz_var(out_row_mode_3);

    fz_try(ctx)
    {
        num_blank_lines = 0;
        rmask = ~0 << (-bitmap->w & 7);
        line_size = (bitmap->w + 7)/8;
        max_mode_2_size = line_size + (line_size/127) + 1;
        max_mode_3_size = line_size + (line_size/8) + 1;
        prev_row = fz_calloc(ctx, line_size, sizeof(unsigned char));
        out_row_mode_2 = fz_calloc(ctx, max_mode_2_size, sizeof(unsigned char));
        out_row_mode_3 = fz_calloc(ctx, max_mode_3_size, sizeof(unsigned char));

        /* Transfer raster graphics. */
        data = bitmap->samples;
        ss = bitmap->stride;
        for (y = 0; y < bitmap->h; y++, data += ss)
        {
            unsigned char *end_data = data + line_size;

            if ((end_data[-1] & rmask) == 0)
            {
                end_data--;
                while (end_data > data && end_data[-1] == 0)
                    end_data--;
            }
            if (end_data == data)
            {
                /* Blank line */
                num_blank_lines++;
                continue;
            }
            wind();

            /* We've reached a non-blank line. */
            /* Put out a spacing command if necessary. */
            if (num_blank_lines == y) {
                /* We're at the top of a page. */
                if (pcl->features & PCL_ANY_SPACING)
                {
                    if (num_blank_lines > 0)
                        fz_printf(out, "\033*p+%dY", num_blank_lines * bitmap->yres);
                    /* Start raster graphics. */
                    fz_puts(out, "\033*r1A");
                }
                else if (pcl->features & PCL_MODE_3_COMPRESSION)
                {
                    /* Start raster graphics. */
                    fz_puts(out, "\033*r1A");
                    for (; num_blank_lines; num_blank_lines--)
                        fz_puts(out, "\033*b0W");
                }
                else
                {
                    /* Start raster graphics. */
                    fz_puts(out, "\033*r1A");
                    for (; num_blank_lines; num_blank_lines--)
                        fz_puts(out, "\033*bW");
                }
            }

            /* Skip blank lines if any */
            else if (num_blank_lines != 0)
            {
                /* Moving down from current position causes head
                 * motion on the DeskJet, so if the number of lines
                 * is small, we're better off printing blanks.
                 *
                 * For Canon LBP4i and some others, <ESC>*b<n>Y
                 * doesn't properly clear the seed row if we are in
                 * compression mode 3.
                 */
                if ((num_blank_lines < MIN_SKIP_LINES && compression != 3) ||
                        !(pcl->features & PCL_ANY_SPACING))
                {
                    int mode_3ns = ((pcl->features & PCL_MODE_3_COMPRESSION) && !(pcl->features & PCL_ANY_SPACING));
                    if (mode_3ns && compression != 2)
                    {
                        /* Switch to mode 2 */
                        fz_puts(out, from3to2);
                        compression = 2;
                    }
                    if (pcl->features & PCL_MODE_3_COMPRESSION)
                    {
                        /* Must clear the seed row. */
                        fz_puts(out, "\033*b1Y");
                        num_blank_lines--;
                    }
                    if (mode_3ns)
                    {
                        for (; num_blank_lines; num_blank_lines--)
                            fz_puts(out, "\033*b0W");
                    }
                    else
                    {
                        for (; num_blank_lines; num_blank_lines--)
                            fz_puts(out, "\033*bW");
                    }
                }
                else if (pcl->features & PCL3_SPACING)
                    fz_printf(out, "\033*p+%dY", num_blank_lines * bitmap->yres);
                else
                    fz_printf(out, "\033*b%dY", num_blank_lines);
                /* Clear the seed row (only matters for mode 3 compression). */
                memset(prev_row, 0, line_size);
            }
            num_blank_lines = 0;

            /* Choose the best compression mode for this particular line. */
            if (pcl->features & PCL_MODE_3_COMPRESSION)
            {
                /* Compression modes 2 and 3 are both available. Try
                 * both and see which produces the least output data.
                 */
                int count3 = mode3compress(out_row_mode_3, data, prev_row, line_size);
                int count2 = mode2compress(out_row_mode_2, data, line_size);
                int penalty3 = (compression == 3 ? 0 : penalty_from2to3);
                int penalty2 = (compression == 2 ? 0 : penalty_from3to2);

                if (count3 + penalty3 < count2 + penalty2)
                {
                    if (compression != 3)
                        fz_puts(out, from2to3);
                    compression = 3;
                    out_data = (unsigned char *)out_row_mode_3;
                    out_count = count3;
                }
                else
                {
                    if (compression != 2)
                        fz_puts(out, from3to2);
                    compression = 2;
                    out_data = (unsigned char *)out_row_mode_2;
                    out_count = count2;
                }
            }
            else if (pcl->features & PCL_MODE_2_COMPRESSION)
            {
                out_data = out_row_mode_2;
                out_count = mode2compress(out_row_mode_2, data, line_size);
            }
            else
            {
                out_data = data;
                out_count = line_size;
            }

            /* Transfer the data */
            fz_printf(out, "\033*b%dW", out_count);
            fz_write(out, out_data, out_count);
        }

        /* end raster graphics and eject page */
        fz_puts(out, "\033*rB\f");

        if (pcl->features & HACK__IS_A_OCE9050)
        {
            /* Pen up, pen select, advance full page, reset */
            fz_puts(out, "\033%1BPUSP0PG;\033E");
        }
    }
    fz_always(ctx)
    {
        fz_free(ctx, prev_row);
        fz_free(ctx, out_row_mode_2);
        fz_free(ctx, out_row_mode_3);
    }
    fz_catch(ctx)
    {
        fz_rethrow(ctx);
    }
}
Exemplo n.º 4
0
static void
pcl_header(fz_output *out, fz_pcl_options *pcl, int num_copies, int xres)
{
    char odd_page_init[80];
    char even_page_init[80];

    make_init(pcl, odd_page_init, sizeof(odd_page_init), pcl->odd_page_init, xres);
    make_init(pcl, even_page_init, sizeof(even_page_init), pcl->even_page_init, xres);

    if (pcl->page_count == 0)
    {
        if (pcl->features & HACK__IS_A_LJET4PJL)
            fz_puts(out, "\033%-12345X@PJL\r\n@PJL ENTER LANGUAGE = PCL\r\n");
        fz_puts(out, "\033E"); /* reset printer */
        /* If the printer supports it, set the paper size */
        /* based on the actual requested size. */
        if (pcl->features & PCL_CAN_SET_PAPER_SIZE)
            fz_printf(out, "\033&l%dA", pcl->paper_size);
        /* If printer can duplex, set duplex mode appropriately. */
        if (pcl->features & PCL_HAS_DUPLEX)
        {
            if (pcl->duplex_set)
            {
                if (pcl->duplex)
                {
                    if (!pcl->tumble)
                        fz_puts(out, "\033&l1S");
                    else
                        fz_puts(out, "\033&l2S");
                }
                else
                    fz_puts(out, "\033&l0S");
            }
            else
            {
                /* default to duplex for this printer */
                fz_puts(out, "\033&l1S");
            }
        }
    }

    /* Put out per-page initialization. */
    /* in duplex mode the sheet is already in process, so there are some
     * commands which must not be sent to the printer for the 2nd page,
     * as this commands will cause the printer to eject the sheet with
     * only the 1st page printed. This commands are:
     * \033&l%dA (setting paper size)
     * \033&l%dH (setting paper tray)
     * in simplex mode we set this parameters for each page,
     * in duplex mode we set this parameters for each odd page
     */

    if ((pcl->features & PCL_HAS_DUPLEX) && pcl->duplex_set && pcl->duplex)
    {
        /* We are printing duplex, so change margins as needed */
        if (((pcl->page_count/num_copies)%2) == 0)
        {
            if (pcl->page_count != 0 && (pcl->features & PCL_CAN_SET_PAPER_SIZE))
            {
                fz_printf(out, "\033&l%dA", pcl->paper_size);
            }
            fz_puts(out, "\033&l0o0l0E");
            fz_puts(out, pcl->odd_page_init);
        }
        else
            fz_puts(out, pcl->even_page_init);
    }
    else
    {
        if (pcl->features & PCL_CAN_SET_PAPER_SIZE)
        {
            fz_printf(out, "\033&l%dA", pcl->paper_size);
        }
        fz_puts(out, "\033&l0o0l0E");
        fz_puts(out, pcl->odd_page_init);
    }

    fz_printf(out, "\033&l%dX", num_copies); /* # of copies */

    /* End raster graphics, position cursor at top. */
    fz_puts(out, "\033*rB\033*p0x0Y");

    /* The DeskJet and DeskJet Plus reset everything upon */
    /* receiving \033*rB, so we must reinitialize graphics mode. */
    if (pcl->features & PCL_END_GRAPHICS_DOES_RESET)
    {
        fz_puts(out, pcl->odd_page_init); /* Assume this does the right thing */
        fz_printf(out, "\033&l%dX", num_copies); /* # of copies */
    }

    /* Set resolution. */
    fz_printf(out, "\033*t%dR", xres);
    pcl->page_count++;
}