Back to index

texmacs  1.0.7.15
Functions
cmap_write.h File Reference
#include "cmap.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

pdf_objCMap_create_stream (CMap *cmap, int flags)
pdf_objCMap_ToCode_stream (CMap *cmap, const char *cmap_name, CIDSysInfo *csi, int cmap_type, unsigned char *used_slot, int flags)

Function Documentation

pdf_obj* CMap_create_stream ( CMap cmap,
int  flags 
)

Definition at line 243 of file cmap_write.c.

{
  pdf_obj         *stream;
  pdf_obj         *stream_dict;
  CIDSysInfo      *csi;
  struct sbuf      wbuf;
  struct rangeDef *ranges;
  unsigned char   *codestr;
  int              i, j, count = 0;

  if (!cmap || !CMap_is_valid(cmap)) {
    WARN("Invalid CMap");
    return NULL;
  }

  if (cmap->type == CMAP_TYPE_IDENTITY)
    return NULL;

  stream      = pdf_new_stream(STREAM_COMPRESS);
  stream_dict = pdf_stream_dict(stream);

  csi = CMap_get_CIDSysInfo(cmap);
  if (!csi) {
    csi = (cmap->type != CMAP_TYPE_TO_UNICODE) ?
      &CSI_IDENTITY : &CSI_UNICODE;
  }

  if (cmap->type != CMAP_TYPE_TO_UNICODE) {
    pdf_obj *csi_dict;

    csi_dict = pdf_new_dict();
    pdf_add_dict(csi_dict,
               pdf_new_name("Registry"),
               pdf_new_string(csi->registry, strlen(csi->registry)));
    pdf_add_dict(csi_dict,
               pdf_new_name("Ordering"),
               pdf_new_string(csi->ordering, strlen(csi->ordering)));
    pdf_add_dict(csi_dict,
               pdf_new_name("Supplement"),
               pdf_new_number(csi->supplement));

    pdf_add_dict(stream_dict,
               pdf_new_name("Type"),
               pdf_new_name("CMap"));
    pdf_add_dict(stream_dict,
               pdf_new_name("CMapName"),
               pdf_new_name(cmap->name));
    pdf_add_dict(stream_dict,
               pdf_new_name("CIDSystemInfo"), csi_dict);
    if (cmap->wmode != 0)
      pdf_add_dict(stream_dict,
                 pdf_new_name("WMode"),
                 pdf_new_number(cmap->wmode));
  }

  /* TODO:
   * Predefined CMaps need not to be embedded.
   */
  if (cmap->useCMap) {
    ERROR("UseCMap found (not supported yet)...");
    if (CMap_is_Identity(cmap->useCMap)) { /* not sure */
      if (CMap_get_wmode(cmap) == 1) {
       pdf_add_dict(stream_dict,
                   pdf_new_name("UseCMap"),
                   pdf_new_name("Identity-V"));
      } else {
       pdf_add_dict(stream_dict,
                   pdf_new_name("UseCMap"),
                   pdf_new_name("Identity-H"));
      }
    } else {
      long     res_id;
      pdf_obj *ucmap_ref;

      res_id = pdf_findresource("CMap", CMap_get_name(cmap->useCMap));
      if (res_id >= 0) {
       ucmap_ref = pdf_get_resource_reference(res_id);
      } else {
       pdf_obj *ucmap_obj;

       ucmap_obj = CMap_create_stream(cmap->useCMap, 0);
       if (!ucmap_obj) {
         ERROR("Uh ah. I cannot continue...");
       }

       res_id = pdf_defineresource("CMap",
                                CMap_get_name(cmap->useCMap),
                                ucmap_obj, PDF_RES_FLUSH_IMMEDIATE);
       ucmap_ref = pdf_get_resource_reference(res_id);
      }
      pdf_add_dict(stream_dict, pdf_new_name("UseCMap"), ucmap_ref);
    }
  }

#define WBUF_SIZE 4096
  wbuf.buf = NEW(WBUF_SIZE, char);
  codestr  = NEW(cmap->profile.maxBytesIn, unsigned char);
  memset(codestr, 0, cmap->profile.maxBytesIn);

  wbuf.curptr = wbuf.buf;
  wbuf.limptr = wbuf.buf + WBUF_SIZE -
    2 * (cmap->profile.maxBytesIn + cmap->profile.maxBytesOut) + 16;

  /* Start CMap */
  pdf_add_stream(stream, (void *) CMAP_BEGIN, strlen(CMAP_BEGIN));

  wbuf.curptr += sprintf(wbuf.curptr, "/CMapName /%s def\n", cmap->name);
  wbuf.curptr += sprintf(wbuf.curptr, "/CMapType %d def\n" , cmap->type);
  if (cmap->wmode != 0 &&
      cmap->type != CMAP_TYPE_TO_UNICODE)
    wbuf.curptr += sprintf(wbuf.curptr, "/WMode %d def\n", cmap->wmode);

#define CMAP_CSI_FMT "/CIDSystemInfo <<\n\
  /Registry (%s)\n\
  /Ordering (%s)\n\
  /Supplement %d\n\
>> def\n"
  wbuf.curptr += sprintf(wbuf.curptr, CMAP_CSI_FMT,
                      csi->registry, csi->ordering, csi->supplement);
  pdf_add_stream(stream, wbuf.buf, (long)(wbuf.curptr - wbuf.buf));
  wbuf.curptr = wbuf.buf;

  /* codespacerange */
  ranges = cmap->codespace.ranges;
  wbuf.curptr += sprintf(wbuf.curptr,
                      "%d begincodespacerange\n", cmap->codespace.num);
  for (i = 0; i < cmap->codespace.num; i++) {
    *(wbuf.curptr)++ = '<';
    for (j = 0; j < ranges[i].dim; j++) {
      sputx(ranges[i].codeLo[j], &(wbuf.curptr), wbuf.limptr);
    }
    *(wbuf.curptr)++ = '>';
    *(wbuf.curptr)++ = ' ';
    *(wbuf.curptr)++ = '<';
    for (j = 0; j < ranges[i].dim; j++) {
      sputx(ranges[i].codeHi[j], &(wbuf.curptr), wbuf.limptr);
    }
    *(wbuf.curptr)++ = '>';
    *(wbuf.curptr)++ = '\n';
  }
  pdf_add_stream(stream, wbuf.buf, (long)(wbuf.curptr - wbuf.buf));
  wbuf.curptr = wbuf.buf;
  pdf_add_stream(stream,
               "endcodespacerange\n", strlen("endcodespacerange\n"));

  /* CMap body */
  if (cmap->mapTbl) {
    count = write_map(cmap->mapTbl,
                    0, codestr, 0, &wbuf, stream); /* Top node */
    if (count > 0) { /* Flush */
      char fmt_buf[32];
      if (count > 100)
       ERROR("Unexpected error....: %d", count);
      sprintf(fmt_buf, "%d beginbfchar\n", count);
      pdf_add_stream(stream, fmt_buf,  strlen(fmt_buf));
      pdf_add_stream(stream,
                   wbuf.buf, (long) (wbuf.curptr - wbuf.buf));
      pdf_add_stream(stream,
                   "endbfchar\n", strlen("endbfchar\n"));
      count = 0;
      wbuf.curptr = wbuf.buf;
    }
  }
  /* End CMap */
  pdf_add_stream(stream, CMAP_END, strlen(CMAP_END));

  RELEASE(codestr);
  RELEASE(wbuf.buf);

  return stream;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* CMap_ToCode_stream ( CMap cmap,
const char *  cmap_name,
CIDSysInfo csi,
int  cmap_type,
unsigned char *  used_slot,
int  flags 
)