Beispiel #1
0
void push_headers(HEADER *header) {
	int num;
	ADDRESS *adr;
	
	push_text("subject");		PUSH_TEXT(header->env->real_subj);
	push_text("message_id");	PUSH_TEXT(header->env->message_id);
	push_text("type"); PUSH_TEXT( TYPE(header->content) );
	push_text("subtype"); PUSH_TEXT(header->content->subtype);
	push_text("encoding"); PUSH_TEXT( ENCODING(header->content->encoding) );
	push_text("length"); push_int(header->content->length);
	
	PUSH_MAPPING_si("lines", header->lines);
	PUSH_MAPPING_si("mime", header->mime);
	PUSH_MAPPING_si("flagged", header->flagged);
	PUSH_MAPPING_si("tagged", header->tagged);
	PUSH_MAPPING_si("deleted", header->deleted);
	PUSH_MAPPING_si("replied", header->replied);
	PUSH_MAPPING_si("date_sent", header->date_sent);
	PUSH_MAPPING_si("date_received", header->received);
	push_text("env");
		PUSH_ADDRESS("from",from);
		PUSH_ADDRESS_LIST("to",to);
		PUSH_ADDRESS_LIST("cc",cc);
		PUSH_ADDRESS_LIST("bcc",bcc);
		PUSH_ADDRESS("sender",sender);
		PUSH_ADDRESS("reply_to",reply_to);
		PUSH_ADDRESS("return_path",return_path);
		f_aggregate_mapping(14);
	f_aggregate_mapping(30);
}
Beispiel #2
0
void image_hrz_f__decode(INT32 args)
{
  image_hrz_f_decode(args);
  push_static_text("image");
  stack_swap();
  f_aggregate_mapping(2);
}
Beispiel #3
0
static void f_cache_status(INT32 args)
{
    struct cache *c = LTHIS->cache;
    pop_n_elems(args);
    push_constant_text("hits");
    push_int64(c->hits);
    push_constant_text("misses");
    push_int64(c->misses);
    push_constant_text("stale");
    push_int64(c->stale);
    push_constant_text("size");
    push_int64(c->size);
    push_constant_text("entries");
    push_int64(c->entries);
    push_constant_text("max_size");
    push_int64(c->max_size);

    /* Relative from last call */
    push_constant_text("sent_bytes");
    push_int(c->sent_data);
    c->sent_data=0;
    push_constant_text("num_request");
    push_int(c->num_requests);
    c->num_requests=0;
    push_constant_text("received_bytes");
    push_int(c->received_data);
    c->received_data=0;
    f_aggregate_mapping( 18 );
}
Beispiel #4
0
void f_stat(INT32 args) {
	pop_n_elems(args);
	PUSH_MAPPING_si("total", THIS->ctx->msgcount);
	PUSH_MAPPING_si("new",   THIS->ctx->new);
	PUSH_MAPPING_si("unread",THIS->ctx->unread);
	PUSH_MAPPING_si("tagged",THIS->ctx->tagged);
	PUSH_MAPPING_si("seen",  THIS->ctx->msgcount-THIS->ctx->new );
	f_aggregate_mapping(10);
}
Beispiel #5
0
static void image_ttf_face_names(INT32 args)
{
   int n,i;
   int has[8]={0,0,0,0,0,0,0,0}; /* iso8859=20, unicode=30, any=1 */
   char *hasname[8]={"copyright","family","style","full",
		     "expose","version","postscript","trademark"};
   struct array *a,*b;

   image_ttf_face__names(args);

   if (sp[-1].type!=T_ARRAY)
      Pike_error("Image.TTF.Face->names(): internal error, weird _names()\n");

   a=sp[-1].u.array;

   n=0;
   for (i=0; i<a->size; i++)
   {
      int ihas=1;
      int what;
      b=a->item[i].u.array;

      what=b->item[3].u.integer;
      if (what>=8 || what<0) continue; /* weird */
      switch (b->item[0].u.integer*100+b->item[1].u.integer)
      {
	 case 301: /* M$:  unicode */
	 case 300: /* M$:  unicode (?) */
	    ihas=30;
	    break;
	 case 202: /* ISO: iso-8859-1 */
	    ihas=20;
	    break;
      }
      if (ihas<has[what]) continue; /* worse */

      push_text(hasname[what]);

      if (ihas==30) /* unicode, M$ but weird enough correct byteorder */
      {
	 ptrdiff_t n = b->item[4].u.string->len/2;
	 struct pike_string *ps=begin_wide_shared_string(n,1);
	 p_wchar1 *d=STR1(ps);
	 p_wchar0 *s=STR0(b->item[4].u.string);
	 while (n--) *(d++)=((p_wchar1)s[0]<<8)|(p_wchar1)s[1],s+=2;
	 push_string(end_shared_string(ps));
      }
      else
	 push_svalue(b->item+4);

      n++;
   }
   f_aggregate_mapping(n*2);
   stack_swap();
   pop_stack();
}
Beispiel #6
0
/*! @decl mapping(string:float) get_point(int point)
 */
static void f_path_element_get_point(INT32 args)
{
  int i;
  get_all_args("get_point", args, "%d", &i);
  i++; // index includes header
  if (i > 0 && i < THIS->element->header.length)
    {
      push_text( "x" );
      push_float(THIS->element[i].point.x);
      push_text( "y" );
      push_float(THIS->element[i].point.y);
      f_aggregate_mapping(4);
    }
  else
    push_undefined();
}
Beispiel #7
0
/*! @decl mapping localeconv()
 *!
 *! The localeconv() function returns a mapping with settings for
 *! the current locale. This mapping contains all values
 *! associated with the locale categories @[LC_NUMERIC] and
 *! @[LC_MONETARY].
 *!
 *! @mapping
 *!   @member string "decimal_point"
 *!     The decimal-point character used to format
 *!     non-monetary quantities.
 *!
 *!   @member string "thousands_sep"
 *!     The character used to separate groups of digits to
 *!     the left of the decimal-point character in
 *! 	formatted non-monetary quantities.
 *!
 *!   @member string "int_curr_symbol"
 *!     The international currency symbol applicable to
 *!     the current locale, left-justified within a
 *!     four-character space-padded field. The character
 *!     sequences should match with those specified in ISO
 *!     4217 Codes for the Representation of Currency and
 *!     Funds.
 *!
 *!   @member string "currency_symbol"
 *!     The local currency symbol applicable to the
 *!     current locale.
 *!
 *!   @member string "mon_decimal_point"
 *!     The decimal point used to format monetary quantities.
 *!
 *!   @member string "mon_thousands_sep"
 *!     The separator for groups of digits to the left of
 *!     the decimal point in formatted monetary quantities.
 *!
 *!   @member string "positive_sign"
 *!     The string used to indicate a non-negative-valued
 *!     formatted monetary quantity.
 *!
 *!   @member string "negative_sign"
 *!     The string used to indicate a negative-valued
 *!     formatted monetary quantity.
 *!
 *!   @member int "int_frac_digits"
 *!     The number of fractional digits (those to the
 *!     right of the decimal point) to be displayed in an
 *!     internationally formatted monetary quantity.
 *!
 *!   @member int "frac_digits"
 *!     The number of fractional digits (those  to  the
 *!     right of the decimal point) to be displayed in a
 *!     formatted monetary quantity.
 *!
 *!   @member int(0..1) "p_cs_precedes"
 *!     Set to 1 or 0 if the currency_symbol respectively
 *!     precedes or succeeds the value for a non-negative
 *!     formatted monetary quantity.
 *!
 *!   @member int(0..1) "p_sep_by_space"
 *!     Set to 1 or 0 if the currency_symbol respectively
 *!     is or is not separated by a space from the value
 *!     for a non-negative formatted monetary quantity.
 *!
 *!   @member int(0..1) "n_cs_precedes"
 *!     Set to 1 or 0 if the currency_symbol respectively
 *!     precedes or succeeds the value for a negative
 *!     formatted monetary quantity.
 *!
 *!   @member int(0..1) "n_sep_by_space"
 *!     Set to 1 or 0 if the currency_symbol respectively
 *!     is or is not separated by a space from the value
 *!     for a negative formatted monetary quantity.
 *!
 *!   @member int(0..4) "p_sign_posn"
 *!     Set to a value indicating the positioning of the
 *!     positive_sign for a non-negative formatted
 *!     monetary quantity. The value of p_sign_posn is
 *!     interpreted according to the following:
 *!
 *!     @int
 *!       @value 0
 *!         Parentheses surround the quantity and currency_symbol.
 *!       @value 1
 *!         The sign string precedes the quantity and currency_symbol.
 *!       @value 2
 *!         The sign string succeeds the quantity and currency_symbol.
 *!       @value 3
 *!         The sign string immediately precedes the currency_symbol.
 *!       @value 4
 *!         The sign string immediately succeeds the currency_symbol.
 *!     @endint
 *!
 *!   @member int "n_sign_posn"
 *!     Set to a value indicating the positioning of the
 *!     negative_sign for a negative formatted monetary
 *!     quantity. The value of n_sign_posn is interpreted
 *!     according to the rules described under p_sign_posn.
 *! @endmapping
 *!
 *! @seealso
 *!   @[bindtextdomain], @[textdomain], @[gettext], @[dgettext], @[dcgettext], @[setlocale]
 */
void f_localeconv(INT32 args)
{
  struct lconv *locale; /* Information about the current locale */
  struct svalue *save_sp = Pike_sp;

  locale = localeconv();

#define MAPSTR(key) do {		\
    push_text(TOSTR(key));	\
    push_text(locale->key);		\
  } while(0)
#define MAPINT(key) do {		\
    push_text(TOSTR(key));	\
    push_int(locale->key);		\
  } while(0)

  MAPSTR(decimal_point);
  MAPSTR(thousands_sep);
  MAPSTR(int_curr_symbol);
  MAPSTR(currency_symbol);
  MAPSTR(mon_decimal_point);
  MAPSTR(mon_thousands_sep);
  MAPSTR(positive_sign);
  MAPSTR(negative_sign);

  /*
   * MAPCHAR(grouping);
   * MAPCHAR(mon_grouping);
   */

  MAPINT(int_frac_digits);
  MAPINT(frac_digits);
  MAPINT(p_cs_precedes);
  MAPINT(p_sep_by_space);
  MAPINT(n_cs_precedes);
  MAPINT(n_sep_by_space);
  MAPINT(p_sign_posn);
  MAPINT(n_sign_posn);

  f_aggregate_mapping(Pike_sp - save_sp);

  stack_pop_n_elems_keep_top(args);
}
Beispiel #8
0
static void pextsStartElement(void *ctx, const xmlChar *name, const xmlChar **atts)
{
  int              npairs;
  const xmlChar  **tmp;
  
  DBG_FUNC_ENTER();
  if (CB_ABSENT(startElementSAX)) {
    DBG_FUNC_LEAVE();
    return;
  }

  THIS->ctxt = (xmlParserCtxtPtr)ctx;
  
  push_object(this_object());
  safe_push_text(name);
  if (atts) {
    npairs = 0;
    tmp = atts;
    while (tmp && *tmp) {
      safe_push_text(*tmp);
      tmp++;
      safe_push_text(*tmp);
      tmp++;
      npairs += 2;
    }
    f_aggregate_mapping(npairs);
  } else {
    push_int(0);
  }
  push_svalue(&THIS->user_data);
  
  CB_CALL(startElementSAX, 4);
  pop_stack();
  
  DBG_FUNC_LEAVE();
}
Beispiel #9
0
static void make_colors(void)
{
   static struct color
   {
      int r,g,b;
      char *name;
      struct pike_string *pname;
   } c[]={
#define COLOR(name,R,G,B) \
   {R,G,B,name,NULL},
#include "colors.h"
#undef COLOR
   };
   int i;
   const int n=sizeof(c)/sizeof(c[0]);

   for (i=0; (size_t)i<sizeof(html_color)/sizeof(html_color[0]); i++)
      html_color[i].pname=make_shared_string(html_color[i].name);

   for (i=0;i<n;i++)
   {
      struct color_struct *cs;
      push_text(c[i].name);
      copy_shared_string(c[i].pname,sp[-1].u.string);

      push_object(clone_object(image_color_program,0));
      cs=get_storage(sp[-1].u.object,image_color_program);
      cs->rgb.r=(COLORTYPE)c[i].r;
      cs->rgb.g=(COLORTYPE)c[i].g;
      cs->rgb.b=(COLORTYPE)c[i].b;
      RGB_TO_RGBL(cs->rgbl,cs->rgb);
      copy_shared_string(cs->name,c[i].pname);
   }
   f_aggregate_mapping(n*2);
   colors=sp[-1].u.mapping;
   sp--;
   dmalloc_touch_svalue(sp);

   for (i=0;i<n;i++)
   {
      push_int(c[i].r);
      push_int(c[i].g);
      push_int(c[i].b);
      f_aggregate(3);
   }
   f_aggregate(n);
   colortable=clone_object(image_colortable_program,1);
   if (!colortable)
      Pike_fatal("couldn't create colortable\n");

   push_int(12);
   push_int(12);
   push_int(12);
   push_int(1);
   safe_apply(colortable,"cubicles",4);
   pop_stack();

   for (i=0;i<n;i++)
      push_string(c[i].pname);
   f_aggregate(n);

   colornames=sp[-1].u.array;
   sp--;
   dmalloc_touch_svalue(sp);
}
Beispiel #10
0
/*! @decl mapping|int evaluate(string script, int|void version)
 *!
 *! Evaluates the passed script (that is, compiles it and then executes)
 *! and returns a mapping with the execution results. The passed version is
 *! set only for the passed script, it doesn't affect the globally used JS
 *! version.
 *!
 *! @param script
 *! Text of the JavaScript program to evaluate.
 *!
 *! @param version
 *! One of the JavaScript version constants.
 *!
 *! @returns
 *! A mapping containing the script output and the return value:
 *!
 *!  @mapping
 *!   @member string "output"
 *!     The script output - that is strings output using the write and
 *!     writeln functions. Might be "" if no output was produced.
 *!
 *!   @member string "result"
 *!     The script result (the value used in the 'return' JavaScript
 *!     statement). Might be "" if the script returned no value or an
 *!     undefined value.
 *!  @end_mapping
 */
static void ctx_evaluate(INT32 args)
{
  JSBool              ok;
  JSString           *str;
  jsval               rval;
  struct pike_string *script;
  INT32               version = -1, oldversion = -1;

  if (!THIS->ctx) {
    pop_n_elems(args);
    push_int(0);
    return;
  }
    
  switch(args) {
      case 2:
        get_all_args("evaluate", args, "%S%i", &script, &version);
        break;

      case 1:
        get_all_args("evaluate", args, "%S", &script);
        break;

      default:
        Pike_error("Not enough arguments\n");
  }

  if (version != -1)
    oldversion = JS_SetVersion(THIS->ctx, version);
    
  /* TODO: filename should indicate the actual location of the script */
  ok = JS_EvaluateScript(THIS->ctx, global,
                         script->str, script->len,
                         "Caudium/js", 0, &rval);

  if (oldversion != -1)
    JS_SetVersion(THIS->ctx, oldversion);
    
  pop_n_elems(args);
    
  if (!ok) {
    push_int(-1);
    return;
  }

  push_string(idx_output);
  if (THIS->output_buf && THIS->output_buf_last) {
    push_text(THIS->output_buf);
    memset(THIS->output_buf, 0, THIS->output_buf_len);
    THIS->output_buf_last = 0;
  } else
    push_text("");

  push_string(idx_result);
  if (!JSVAL_IS_NULL(rval) && !JSVAL_IS_VOID(rval)) {
    struct pike_string    *ret;
    unsigned char         *tmp = NULL, *tval;
    size_t                 blen = 0;
        
    str = JS_ValueToString(THIS->ctx, rval);
    push_text(JS_GetStringBytes(str));
  } else
    push_text("");

  f_aggregate_mapping(4);
}
Beispiel #11
0
static void image_xbm__decode( INT32 args )
{
  struct array *fg = NULL;
  struct array *bg = NULL;
  int invert=0, ele;
  struct pike_string *data;
  struct object *i=NULL, *a;
  get_all_args( "Image.XBM.decode", args, "%S", &data );


  if (args>1)
  {
    if (Pike_sp[1-args].type!=PIKE_T_MAPPING)
      Pike_error("Image.XBM._decode: illegal argument 2\n");
      
    push_svalue(Pike_sp+1-args);
    ref_push_string(param_fg); 
    f_index(2);
    if(!UNSAFE_IS_ZERO(Pike_sp-1))
    {
      if(Pike_sp[-1].type != PIKE_T_ARRAY || Pike_sp[-1].u.array->size != 3)
        Pike_error("Wrong type for foreground. Should be array(int(0..255))"
              " with 3 elements\n");
      for(ele=0; ele<3; ele++)
        if(Pike_sp[-1].u.array->item[ele].type != PIKE_T_INT
           ||Pike_sp[-1].u.array->item[ele].u.integer < 0
           ||Pike_sp[-1].u.array->item[ele].u.integer > 255)
          Pike_error("Wrong type for foreground. Should be array(int(0..255))"
                " with 3 elements\n");
      fg = Pike_sp[-1].u.array;
    }
    Pike_sp--;

    push_svalue(Pike_sp+1-args);
    ref_push_string(param_bg);
    f_index(2);
    if(!UNSAFE_IS_ZERO(Pike_sp-1))
    {
      if(Pike_sp[-1].type != PIKE_T_ARRAY || Pike_sp[-1].u.array->size != 3)
        Pike_error("Wrong type for background. Should be array(int(0..255))"
              " with 3 elements\n");
      for(ele=0; ele<3; ele++)
        if(Pike_sp[-1].u.array->item[ele].type != PIKE_T_INT
           ||Pike_sp[-1].u.array->item[ele].u.integer < 0
           ||Pike_sp[-1].u.array->item[ele].u.integer > 255)
          Pike_error("Wrong type for background. Should be array(int(0..255))"
                " with 3 elements\n");
      bg = Pike_sp[-1].u.array;
    }
    Pike_sp--;
    
    push_svalue(Pike_sp+1-args);
    ref_push_string(param_invert);
    f_index(2);
    invert = !UNSAFE_IS_ZERO(Pike_sp-1);
    Pike_sp--;
  }

  a = load_xbm( data );

  if(!fg)
  {
    if(invert)
    {
      apply(a, "invert", 0);
      i = (struct object *)debug_malloc_pass(Pike_sp[-1].u.object);
      Pike_sp--;
    }
    else
    {
      i = a;
      add_ref(a);
    }
  } else {
    if(!bg)
    {
      push_int(255);
      push_int(255);
      push_int(255);
      f_aggregate(3);
      bg = (struct array *)debug_malloc_pass(Pike_sp[-1].u.array);
      Pike_sp--;
    }
    if(invert)
    {
      struct array *tmp = fg;
      fg = bg;
      bg = fg;
    }
    apply(a, "xsize", 0);
    apply(a, "ysize", 0);
    push_int( bg->item[0].u.integer );
    push_int( bg->item[1].u.integer );
    push_int( bg->item[2].u.integer );
    i = clone_object( image_program, 5 );
    ref_push_object( i );
    push_int( fg->item[0].u.integer );
    push_int( fg->item[1].u.integer );
    push_int( fg->item[2].u.integer );

    apply( i, "paste_alpha_color", 4 );
  }
  
  pop_n_elems(args);
  push_constant_text( "alpha" );
  push_object( a );
    push_constant_text( "image" );
  if(i)
    push_object( i );
  else
    push_int( 0 );
  f_aggregate_mapping(4);
}
Beispiel #12
0
static void image_ttf_face_properties(INT32 args)
{
   int res;
   TT_Face_Properties prop;

   pop_n_elems(args);

   res=TT_Get_Face_Properties(THISf->face,&prop);
   if (res) my_tt_error("Image.TTF.Face->properties()","",res);

   push_text("num_Glyphs");   push_int(prop.num_Glyphs);
   push_text("max_Points");   push_int(prop.max_Points);
   push_text("max_Contours");   push_int(prop.max_Contours);
   push_text("num_Faces");   push_int(prop.num_Faces);

   push_text("header");
   if (prop.header)
   {
      push_text("Table_Version"); push_int(prop.header->Table_Version);
      push_text("Font_Revision"); push_int(prop.header->Font_Revision);
      push_text("CheckSum_Adjust"); push_int(prop.header->CheckSum_Adjust);
      push_text("Magic_Number"); push_int(prop.header->Magic_Number);
      push_text("Flags"); push_int(prop.header->Flags);
      push_text("Units_Per_EM"); push_int(prop.header->Units_Per_EM);
      push_text("Created");
      push_int(prop.header->Created[0]);
      push_int(prop.header->Created[1]);
      f_aggregate(2);
      push_text("Modified");
      push_int(prop.header->Modified[0]);
      push_int(prop.header->Modified[1]);
      f_aggregate(2);
      push_text("xMin"); push_int(prop.header->xMin);
      push_text("yMin"); push_int(prop.header->yMin);
      push_text("xMax"); push_int(prop.header->xMax);
      push_text("yMax"); push_int(prop.header->yMax);
      push_text("Mac_Style"); push_int(prop.header->Mac_Style);
      push_text("Lowest_Rec_PPEM"); push_int(prop.header->Lowest_Rec_PPEM);
      push_text("Font_Direction"); push_int(prop.header->Font_Direction);
      push_text("Index_To_Loc_Format");
      push_int(prop.header->Index_To_Loc_Format);
      push_text("Glyph_Data_Format");
      push_int(prop.header->Glyph_Data_Format);
      f_aggregate_mapping(17*2);
   }
   else push_int(0);

   push_text("horizontal");
   if (prop.horizontal)
   {
      push_text("Version"); push_int(prop.horizontal->Version);
      push_text("Ascender"); push_int(prop.horizontal->Ascender);
      push_text("Descender"); push_int(prop.horizontal->Descender);
      push_text("Line_Gap"); push_int(prop.horizontal->Line_Gap);
      push_text("advance_Width_Max"); push_int(prop.horizontal->advance_Width_Max);
      push_text("min_Left_Side_Bearing"); push_int(prop.horizontal->min_Left_Side_Bearing);
      push_text("min_Right_Side_Bearing"); push_int(prop.horizontal->min_Right_Side_Bearing);
      push_text("xMax_Extent"); push_int(prop.horizontal->xMax_Extent);
      push_text("caret_Slope_Rise"); push_int(prop.horizontal->caret_Slope_Rise);
      push_text("caret_Slope_Run"); push_int(prop.horizontal->caret_Slope_Run);
      push_text("metric_Data_Format"); push_int(prop.horizontal->metric_Data_Format);
      push_text("number_Of_HMetrics"); push_int(prop.horizontal->number_Of_HMetrics);
      f_aggregate_mapping(13*2);
   }
   else push_int(0);

   push_text("os2");
   if (prop.os2)
   {
      push_text("version"); push_int(prop.os2->version);
      push_text("xAvgCharWidth"); push_int(prop.os2->xAvgCharWidth);
      push_text("usWeightClass"); push_int(prop.os2->usWeightClass);
      push_text("usWidthClass"); push_int(prop.os2->usWidthClass);
      push_text("fsType"); push_int(prop.os2->fsType);
      push_text("ySubscriptXSize"); push_int(prop.os2->ySubscriptXSize);
      push_text("ySubscriptYSize"); push_int(prop.os2->ySubscriptYSize);
      push_text("ySubscriptXOffset"); push_int(prop.os2->ySubscriptXOffset);
      push_text("ySubscriptYOffset"); push_int(prop.os2->ySubscriptYOffset);
      push_text("ySuperscriptXSize"); push_int(prop.os2->ySuperscriptXSize);
      push_text("ySuperscriptYSize"); push_int(prop.os2->ySuperscriptYSize);
      push_text("ySuperscriptXOffset"); push_int(prop.os2->ySuperscriptXOffset);
      push_text("ySuperscriptYOffset"); push_int(prop.os2->ySuperscriptYOffset);
      push_text("yStrikeoutSize"); push_int(prop.os2->yStrikeoutSize);
      push_text("yStrikeoutPosition"); push_int(prop.os2->yStrikeoutPosition);
      push_text("sFamilyClass"); push_int(prop.os2->sFamilyClass);

      push_text("panose");
      push_string(make_shared_binary_string(prop.os2->panose,10));

      push_text("ulUnicodeRange1"); push_int(prop.os2->ulUnicodeRange1);
      push_text("ulUnicodeRange2"); push_int(prop.os2->ulUnicodeRange2);
      push_text("ulUnicodeRange3"); push_int(prop.os2->ulUnicodeRange3);
      push_text("ulUnicodeRange4"); push_int(prop.os2->ulUnicodeRange4);

      push_text("achVendID");
      push_string(make_shared_binary_string(prop.os2->achVendID,4));

      push_text("fsSelection"); push_int(prop.os2->fsSelection);
      push_text("usFirstCharIndex"); push_int(prop.os2->usFirstCharIndex);
      push_text("usLastCharIndex"); push_int(prop.os2->usLastCharIndex);
      push_text("sTypoAscender"); push_int(prop.os2->sTypoAscender);
      push_text("sTypoDescender"); push_int(prop.os2->sTypoDescender);
      push_text("sTypoLineGap"); push_int(prop.os2->sTypoLineGap);
      push_text("usWinAscent"); push_int(prop.os2->usWinAscent);
      push_text("usWinDescent"); push_int(prop.os2->usWinDescent);
      push_text("ulCodePageRange1"); push_int(prop.os2->ulCodePageRange1);
      push_text("ulCodePageRange2"); push_int(prop.os2->ulCodePageRange2);

      f_aggregate_mapping(32*2);
   }
   else push_int(0);

   push_text("postscript");
   if (prop.postscript)
   {
      push_text("FormatType"); push_int(prop.postscript->FormatType);
      push_text("italicAngle"); push_int(prop.postscript->italicAngle);
      push_text("underlinePosition"); push_int(prop.postscript->underlinePosition);
      push_text("underlineThickness"); push_int(prop.postscript->underlineThickness);
      push_text("isFixedPitch"); push_int(prop.postscript->isFixedPitch);
      push_text("minMemType42"); push_int(prop.postscript->minMemType42);
      push_text("maxMemType42"); push_int(prop.postscript->maxMemType42);
      push_text("minMemType1"); push_int(prop.postscript->minMemType1);
      push_text("maxMemType1"); push_int(prop.postscript->maxMemType1);
      f_aggregate_mapping(9*2);
   }
   else push_int(0);

   push_text("hdmx");
   if (prop.hdmx)
   {
      int i;

      push_text("version"); push_int(prop.hdmx->version);
      push_text("num_records"); push_int(prop.hdmx->num_records);
      push_text("records");

      for (i=0; i<prop.hdmx->num_records; i++)
      {
	 push_text("ppem"); push_int(prop.hdmx->records[i].ppem);
	 push_text("max_width"); push_int(prop.hdmx->records[i].max_width);
	 /*	 push_text("widths"); push_int(prop.hdmx->records[i].widths);*/
	 f_aggregate_mapping(2*2);
      }
      f_aggregate(prop.hdmx->num_records);

      f_aggregate_mapping(3*2);
   }
   else push_int(0);

   f_aggregate_mapping(9*2);
}