Make FontDictionary read-only

View: New views
2 Messages — Rating Filter:   Alert me  

Make FontDictionary read-only

by Alex Cherepanov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Make FontDirectory read-only to satisfy CET 24-13.ps.
Make LocalFontDirectory read-only for consistency with FontDirectory.
Use forced access operators to modify these dictionaries.
Create .forcesetmaxlength operator and modify .dictcopynew operatot
to ignore read-only status of the destination.

DIFFERENCES:
Probably, none.
The differences in 409-01.ps in enumeration order of .svn directory
is not important.
There are many differences in TypeIC fonts generated in PDF files, but
they don't result in the raster difference.

Also observed the following change in generated fonts. I don't yet know
the cause.

-<</Type/FontDescriptor/FontName/GBKXCW+MSTT31c27a/FontBBox[0 0 5523
343]/Flags 4
+<</Type/FontDescriptor/FontName/GBKXCW+MSTT31c27a/FontBBox[0 0 5523
343]/Flags 5
  /Ascent 343
  /CapHeight 343
  /Descent 0
  /ItalicAngle 0
  /StemV 828
+/AvgWidth 5560
+/MaxWidth 5560
+/MissingWidth 5560




Index: gs/src/zdict.c
===================================================================
--- gs/src/zdict.c (revision 7132)
+++ gs/src/zdict.c (working copy)
@@ -363,7 +363,7 @@
     check_type(*op1, t_dictionary);
     check_dict_read(*op1);
     check_type(*op, t_dictionary);
-    check_dict_write(*op);
+    check_dict_read(*op); /* This is the destination, but we ignore read-only status */
     /* This is only recognized in Level 2 mode. */
     if (!imemory->gs_lib_ctx->dict_auto_expand)
  return_error(e_undefined);
@@ -465,7 +465,7 @@
 
 /* <dict> <int> .setmaxlength - */
 private int
-zsetmaxlength(i_ctx_t *i_ctx_p)
+setmaxlength_impl(i_ctx_t *i_ctx_p, bool force)
 {
     os_ptr op = osp;
     os_ptr op1 = op - 1;
@@ -473,7 +473,11 @@
     int code;
 
     check_type(*op1, t_dictionary);
-    check_dict_write(*op1);
+    if (force) {
+      check_type(*op1, t_dictionary);
+    } else {
+      check_dict_write(*op1);
+    }
     check_type(*op, t_integer);
 #if arch_sizeof_int < arch_sizeof_long
     check_int_leu(*op, max_uint);
@@ -490,6 +494,24 @@
     return code;
 }
 
+
+/* <dict> <int> .setmaxlength - */
+private int
+zsetmaxlength(i_ctx_t *i_ctx_p)
+{
+    return setmaxlength_impl(i_ctx_p, false);
+}
+
+
+/* <dict> <int> .setmaxlength - */
+/* Mainly to grow a read-only FontDirectory */
+private int
+zforcesetmaxlength(i_ctx_t *i_ctx_p)
+{
+    return setmaxlength_impl(i_ctx_p, true);
+}
+
+
 /* ------ Initialization procedure ------ */
 
 /* We need to split the table because of the 16-element limit. */
@@ -517,6 +539,7 @@
     {"2.knownget", zknownget},
     {"1.knownundef", zknownundef},
     {"2.setmaxlength", zsetmaxlength},
+    {"2.forcesetmaxlength", zforcesetmaxlength},
  /*
  * In Level 2, >> is a synonym for .dicttomark, and undef for
  * .undef.  By giving the former their own entries, they will not be
Index: gs/lib/gs_dps1.ps
===================================================================
--- gs/lib/gs_dps1.ps (revision 7132)
+++ gs/lib/gs_dps1.ps (working copy)
@@ -34,13 +34,13 @@
 
 /SharedFontDirectory .FontDirectory .gcheck
  { .currentglobal false .setglobal
-   /LocalFontDirectory .FontDirectory dup maxlength dict copy
+   /LocalFontDirectory .FontDirectory dup maxlength dict copy readonly
    .forcedef % LocalFontDirectory is local, systemdict is global
    .setglobal .FontDirectory
  }
  { /LocalFontDirectory .FontDirectory
    .forcedef % LocalFontDirectory is local, systemdict is global
-   50 dict
+   50 dict readonly
  }
 ifelse def
 
@@ -74,18 +74,18 @@
  } odef
 % undefinefont has to take local/global VM into account.
 /undefinefont % <fontname> undefinefont -
- { .FontDirectory 1 .argindex .undef
+ { .FontDirectory 1 .argindex .forceundef
    .currentglobal
     { % Current mode is global; delete from local directory too.
       //systemdict /LocalFontDirectory .knownget
-       { 1 index .undef }
+       { 1 index .forceundef }
       if
     }
     { % Current mode is local; if there was a shadowed global
  % definition, copy it into the local directory.
       //systemdict /SharedFontDirectory .knownget
        { 1 index .knownget
-  { .FontDirectory 2 index 3 -1 roll put }
+  { .FontDirectory 2 index 3 -1 roll .forceput }
  if
        }
       if
@@ -126,7 +126,7 @@
   }
  ifelse
        } forall
-      pop counttomark 2 idiv { .undef } repeat pop
+      pop counttomark 2 idiv { .forceundef } repeat pop
     }
    if
    //SharedFontDirectory exch .dictcopynew pop
Index: gs/lib/gs_init.ps
===================================================================
--- gs/lib/gs_init.ps (revision 7132)
+++ gs/lib/gs_init.ps (working copy)
@@ -1206,7 +1206,7 @@
 (END PROCS) VMDEBUG
 
 % Define the font directory.
-/FontDirectory false .setglobal 100 dict true .setglobal
+/FontDirectory false .setglobal 100 dict readonly true .setglobal
 .forcedef % FontDirectory is local, systemdict is global
 
 % Define the encoding dictionary.
@@ -1705,7 +1705,7 @@
 /undefinefont where {
   pop /NullFont undefinefont
 } {
-  FontDirectory /NullFont .undef
+  FontDirectory /NullFont .forceundef
 } ifelse
 
 (END FONTS) VMDEBUG
@@ -2251,6 +2251,7 @@
 currentdict /.patterntypes .undef
 currentdict /.shadingtypes .undef
 currentdict /.wheredict .undef
+currentdict /.dictcopynew .undef
 end
 
 % Clean up VM, and enable GC.
@@ -2261,6 +2262,7 @@
   systemdict /.forcedef .undef % remove temptation
   systemdict /.forceput .undef % ditto
   systemdict /.forceundef .undef % ditto
+  systemdict /.forcesetmaxlength .undef
 } if
 WRITESYSTEMDICT not { systemdict readonly pop } if
 (END GC) VMDEBUG
Index: gs/lib/gs_fonts.ps
===================================================================
--- gs/lib/gs_fonts.ps (revision 7132)
+++ gs/lib/gs_fonts.ps (working copy)
@@ -490,11 +490,15 @@
                 % the font in LocalFontDirectory.
    .currentglobal
     { //systemdict /LocalFontDirectory .knownget
-       { 2 index 2 index .growput }
+        { dup dup .growdictlength .forcesetmaxlength
+          2 index 2 index .forceput
+        }
       if
     }
    if
-   dup .FontDirectory 4 -2 roll .growput
+   dup .FontDirectory
+   dup dup .growdictlength .forcesetmaxlength
+   4 -2 roll .forceput
                 % If the font originated as a resource, register it.
    currentfile .currentresourcefile eq { dup .registerfont } if
  } odef
@@ -1035,7 +1039,7 @@
                 % because it's different depending on language level.
            .currentglobal exch /.setglobal .systemvar exec
                 % Remove the fake definition, if any.
-           .FontDirectory 3 index .undef
+           .FontDirectory 3 index .forceundef
            1 index (r) file .loadfont .FontDirectory exch
            /.setglobal .systemvar exec
          }
@@ -1131,7 +1135,7 @@
         } ifelse
       } forall
     }
-FAKEFONTS { exch } if pop def   % don't bind, .current/setglobal get redefined
+FAKEFONTS { exch } if pop .bind executeonly def
 
 % Install initial fonts from Fontmap.
 /.loadinitialfonts

_______________________________________________
gs-code-review mailing list
gs-code-review@...
http://www.ghostscript.com/mailman/listinfo/gs-code-review

Re: Make FontDictionary read-only

by Igor V. Melichev :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ray, Alex,

I've got 3 remarks about this.

1. Would like to obtain Ray's comparison with Tek hardcopy.
Does Tek set readonly to FontDirectory ?
If not, I would drop this big change and change the
status to AOK.

2. If we accept this change, maybe it can be simplified a little bit.
I noticed Alex adds a call to .force* to gs_init.
My suggestion is to make FontDirectory to be read-only
*at*end* of gs_init, so that it is writable while gs_init works.
Alex, please check whether it gives a real simplification.
Please remember that for dictionaries the read-only feature is
a property of a dictionary rather than a property of the iref.

3.
> -<</Type/FontDescriptor/FontName/GBKXCW+MSTT31c27a/FontBBox[0 0 5523
> 343]/Flags 4
> +<</Type/FontDescriptor/FontName/GBKXCW+MSTT31c27a/FontBBox[0 0 5523
> 343]/Flags 5

I do not like different flags.
It can cause a different font substitution
in 3d party viewers and an additional load
to our Support. Alex, please work out why it happens.

Igor.


----- Original Message -----
From: "Alex Cherepanov" <alexcher@...>
To: "gs-code-review" <gs-code-review@...>
Sent: Wednesday, November 01, 2006 9:28 AM
Subject: [gs-code-review] Make FontDictionary read-only


> Make FontDirectory read-only to satisfy CET 24-13.ps.
> Make LocalFontDirectory read-only for consistency with FontDirectory.
> Use forced access operators to modify these dictionaries.
> Create .forcesetmaxlength operator and modify .dictcopynew operatot
> to ignore read-only status of the destination.
>
> DIFFERENCES:
> Probably, none.
> The differences in 409-01.ps in enumeration order of .svn directory
> is not important.
> There are many differences in TypeIC fonts generated in PDF files, but
> they don't result in the raster difference.
>
> Also observed the following change in generated fonts. I don't yet know
> the cause.
>
> -<</Type/FontDescriptor/FontName/GBKXCW+MSTT31c27a/FontBBox[0 0 5523
> 343]/Flags 4
> +<</Type/FontDescriptor/FontName/GBKXCW+MSTT31c27a/FontBBox[0 0 5523
> 343]/Flags 5
>  /Ascent 343
>  /CapHeight 343
>  /Descent 0
>  /ItalicAngle 0
>  /StemV 828
> +/AvgWidth 5560
> +/MaxWidth 5560
> +/MissingWidth 5560
>
>
>
>


--------------------------------------------------------------------------------


> Index: gs/src/zdict.c
> ===================================================================
> --- gs/src/zdict.c (revision 7132)
> +++ gs/src/zdict.c (working copy)
> @@ -363,7 +363,7 @@
>     check_type(*op1, t_dictionary);
>     check_dict_read(*op1);
>     check_type(*op, t_dictionary);
> -    check_dict_write(*op);
> +    check_dict_read(*op); /* This is the destination, but we ignore
> read-only status */
>     /* This is only recognized in Level 2 mode. */
>     if (!imemory->gs_lib_ctx->dict_auto_expand)
>  return_error(e_undefined);
> @@ -465,7 +465,7 @@
>
> /* <dict> <int> .setmaxlength - */
> private int
> -zsetmaxlength(i_ctx_t *i_ctx_p)
> +setmaxlength_impl(i_ctx_t *i_ctx_p, bool force)
> {
>     os_ptr op = osp;
>     os_ptr op1 = op - 1;
> @@ -473,7 +473,11 @@
>     int code;
>
>     check_type(*op1, t_dictionary);
> -    check_dict_write(*op1);
> +    if (force) {
> +      check_type(*op1, t_dictionary);
> +    } else {
> +      check_dict_write(*op1);
> +    }
>     check_type(*op, t_integer);
> #if arch_sizeof_int < arch_sizeof_long
>     check_int_leu(*op, max_uint);
> @@ -490,6 +494,24 @@
>     return code;
> }
>
> +
> +/* <dict> <int> .setmaxlength - */
> +private int
> +zsetmaxlength(i_ctx_t *i_ctx_p)
> +{
> +    return setmaxlength_impl(i_ctx_p, false);
> +}
> +
> +
> +/* <dict> <int> .setmaxlength - */
> +/* Mainly to grow a read-only FontDirectory */
> +private int
> +zforcesetmaxlength(i_ctx_t *i_ctx_p)
> +{
> +    return setmaxlength_impl(i_ctx_p, true);
> +}
> +
> +
> /* ------ Initialization procedure ------ */
>
> /* We need to split the table because of the 16-element limit. */
> @@ -517,6 +539,7 @@
>     {"2.knownget", zknownget},
>     {"1.knownundef", zknownundef},
>     {"2.setmaxlength", zsetmaxlength},
> +    {"2.forcesetmaxlength", zforcesetmaxlength},
>  /*
>  * In Level 2, >> is a synonym for .dicttomark, and undef for
>  * .undef.  By giving the former their own entries, they will not be
> Index: gs/lib/gs_dps1.ps
> ===================================================================
> --- gs/lib/gs_dps1.ps (revision 7132)
> +++ gs/lib/gs_dps1.ps (working copy)
> @@ -34,13 +34,13 @@
>
> /SharedFontDirectory .FontDirectory .gcheck
>  { .currentglobal false .setglobal
> -   /LocalFontDirectory .FontDirectory dup maxlength dict copy
> +   /LocalFontDirectory .FontDirectory dup maxlength dict copy readonly
>    .forcedef % LocalFontDirectory is local, systemdict is global
>    .setglobal .FontDirectory
>  }
>  { /LocalFontDirectory .FontDirectory
>    .forcedef % LocalFontDirectory is local, systemdict is global
> -   50 dict
> +   50 dict readonly
>  }
> ifelse def
>
> @@ -74,18 +74,18 @@
>  } odef
> % undefinefont has to take local/global VM into account.
> /undefinefont % <fontname> undefinefont -
> - { .FontDirectory 1 .argindex .undef
> + { .FontDirectory 1 .argindex .forceundef
>    .currentglobal
>     { % Current mode is global; delete from local directory too.
>       //systemdict /LocalFontDirectory .knownget
> -       { 1 index .undef }
> +       { 1 index .forceundef }
>       if
>     }
>     { % Current mode is local; if there was a shadowed global
>  % definition, copy it into the local directory.
>       //systemdict /SharedFontDirectory .knownget
>        { 1 index .knownget
> -   { .FontDirectory 2 index 3 -1 roll put }
> +   { .FontDirectory 2 index 3 -1 roll .forceput }
>  if
>        }
>       if
> @@ -126,7 +126,7 @@
>    }
>  ifelse
>        } forall
> -      pop counttomark 2 idiv { .undef } repeat pop
> +      pop counttomark 2 idiv { .forceundef } repeat pop
>     }
>    if
>    //SharedFontDirectory exch .dictcopynew pop
> Index: gs/lib/gs_init.ps
> ===================================================================
> --- gs/lib/gs_init.ps (revision 7132)
> +++ gs/lib/gs_init.ps (working copy)
> @@ -1206,7 +1206,7 @@
> (END PROCS) VMDEBUG
>
> % Define the font directory.
> -/FontDirectory false .setglobal 100 dict true .setglobal
> +/FontDirectory false .setglobal 100 dict readonly true .setglobal
> .forcedef % FontDirectory is local, systemdict is global
>
> % Define the encoding dictionary.
> @@ -1705,7 +1705,7 @@
> /undefinefont where {
>   pop /NullFont undefinefont
> } {
> -  FontDirectory /NullFont .undef
> +  FontDirectory /NullFont .forceundef
> } ifelse
>
> (END FONTS) VMDEBUG
> @@ -2251,6 +2251,7 @@
> currentdict /.patterntypes .undef
> currentdict /.shadingtypes .undef
> currentdict /.wheredict .undef
> +currentdict /.dictcopynew .undef
> end
>
> % Clean up VM, and enable GC.
> @@ -2261,6 +2262,7 @@
>   systemdict /.forcedef .undef % remove temptation
>   systemdict /.forceput .undef % ditto
>   systemdict /.forceundef .undef % ditto
> +  systemdict /.forcesetmaxlength .undef
> } if
> WRITESYSTEMDICT not { systemdict readonly pop } if
> (END GC) VMDEBUG
> Index: gs/lib/gs_fonts.ps
> ===================================================================
> --- gs/lib/gs_fonts.ps (revision 7132)
> +++ gs/lib/gs_fonts.ps (working copy)
> @@ -490,11 +490,15 @@
>                 % the font in LocalFontDirectory.
>    .currentglobal
>     { //systemdict /LocalFontDirectory .knownget
> -       { 2 index 2 index .growput }
> +        { dup dup .growdictlength .forcesetmaxlength
> +          2 index 2 index .forceput
> +        }
>       if
>     }
>    if
> -   dup .FontDirectory 4 -2 roll .growput
> +   dup .FontDirectory
> +   dup dup .growdictlength .forcesetmaxlength
> +   4 -2 roll .forceput
>                 % If the font originated as a resource, register it.
>    currentfile .currentresourcefile eq { dup .registerfont } if
>  } odef
> @@ -1035,7 +1039,7 @@
>                 % because it's different depending on language level.
>            .currentglobal exch /.setglobal .systemvar exec
>                 % Remove the fake definition, if any.
> -           .FontDirectory 3 index .undef
> +           .FontDirectory 3 index .forceundef
>            1 index (r) file .loadfont .FontDirectory exch
>            /.setglobal .systemvar exec
>          }
> @@ -1131,7 +1135,7 @@
>         } ifelse
>       } forall
>     }
> -FAKEFONTS { exch } if pop def   % don't bind, .current/setglobal get
> redefined
> +FAKEFONTS { exch } if pop .bind executeonly def
>
> % Install initial fonts from Fontmap.
> /.loadinitialfonts
>


--------------------------------------------------------------------------------


> _______________________________________________
> gs-code-review mailing list
> gs-code-review@...
> http://www.ghostscript.com/mailman/listinfo/gs-code-review
>

_______________________________________________
gs-code-review mailing list
gs-code-review@...
http://www.ghostscript.com/mailman/listinfo/gs-code-review
LightInTheBox - Buy quality products at wholesale price!