[gs-cvs] rev 7867 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Sun Apr 22 04:50:26 PDT 2007
Author: leonardo
Date: 2007-04-22 04:50:25 -0700 (Sun, 22 Apr 2007)
New Revision: 7867
Modified:
trunk/gs/src/ifont.h
trunk/gs/src/ifont42.h
trunk/gs/src/zbfont.c
trunk/gs/src/zfcid1.c
trunk/gs/src/zfont42.c
Log:
Fix (TT fonts) : A faster seeking through 'sfnts' array.
DETAILS :
This is a partial fix for bug 688971
"huge performace problem (with large TT font?)".
Patch from SaGS.
src\zfont42.c::string_array_access_proc() is now caches
the string index used last, and starts the next search from there.
This info in stored together with the ref to 'sfnts', and
consists of index of the string (.mru_sfnts_index) and total number
of data bytes that precede this string (.mru_sfnts_pos).
If passing NULL for the 2 new parameters, string_array_access_proc()
beheaves at it did before and starts the search from the beginning.
Otherwise it does one of:
- search forward from the mru string (possibly returning data from
it, without actually skipping anything), if new position >=
current's string starting position;
- search backwards from current string if requested position is in
the 2nd half of the fragment before the current string;
- search forward from the beginning if in 1st half.
The old garbager descriptor for gs_type42_data_s assumed
'ref' fields only. Now it is changed to account new fields,
which are not 'ref'.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/ifont.h
===================================================================
--- trunk/gs/src/ifont.h 2007-04-21 02:33:44 UTC (rev 7866)
+++ trunk/gs/src/ifont.h 2007-04-22 11:50:25 UTC (rev 7867)
@@ -26,6 +26,9 @@
/* The structure given below is 'client data' from the viewpoint */
/* of the library. font-type objects (t_struct/st_font, "t_fontID") */
/* point directly to a gs_font. */
+/* Note: From the GC point of view, it is handled as an array of refs, followed by */
+/* non-relocatable data starting with u.type42.mru_sfnts_index; this also */
+/* means all members of union _fs must start with the same number of refs */
typedef struct font_data_s {
ref dict; /* font dictionary object */
@@ -45,6 +48,9 @@
ref sfnts;
ref CIDMap; /* for CIDFontType 2 fonts */
ref GlyphDirectory;
+ /* the following are used to optimize lookups into sfnts */
+ uint mru_sfnts_index; /* index of most recently used sfnts string */
+ ulong mru_sfnts_pos; /* data bytes before sfnts string at index mru_sfnts_index */
} type42;
struct _fc0 {
ref GlyphDirectory;
@@ -63,7 +69,11 @@
/* st_font_data is exported for zdefault_make_font in zfont.c. */
extern_st(st_font_data);
#define public_st_font_data() /* in zbfont.c */\
- gs_public_st_ref_struct(st_font_data, font_data, "font_data")
+ private struct_proc_clear_marks(font_data_clear_marks);\
+ private struct_proc_enum_ptrs(font_data_enum_ptrs);\
+ private struct_proc_reloc_ptrs(font_data_reloc_ptrs);\
+ gs_public_st_complex_only(st_font_data, font_data, "font_data",\
+ font_data_clear_marks, font_data_enum_ptrs, font_data_reloc_ptrs, 0)
#define pfont_data(pfont) ((font_data *)((pfont)->client_data))
#define pfont_dict(pfont) (&pfont_data(pfont)->dict)
Modified: trunk/gs/src/ifont42.h
===================================================================
--- trunk/gs/src/ifont42.h 2007-04-21 02:33:44 UTC (rev 7866)
+++ trunk/gs/src/ifont42.h 2007-04-22 11:50:25 UTC (rev 7867)
@@ -46,7 +46,9 @@
* (because of the strange behavior of odd-length strings), 1 for CIDMap.
* Return code : 0 - success, <0 - error,
* >0 - number of accessible bytes (client must cycle).
+ * - mru_index/pos are used as a hint where to start searching; NULLs for no hint.
*/
-int string_array_access_proc(const gs_memory_t *mem, const ref *, int, ulong, uint, const byte **);
+int string_array_access_proc(const gs_memory_t *mem, const ref *, int, ulong, uint,
+ uint *mru_index, ulong *mru_pos, const byte **);
#endif /* ifont42_INCLUDED */
Modified: trunk/gs/src/zbfont.c
===================================================================
--- trunk/gs/src/zbfont.c 2007-04-21 02:33:44 UTC (rev 7866)
+++ trunk/gs/src/zbfont.c 2007-04-22 11:50:25 UTC (rev 7867)
@@ -34,8 +34,25 @@
#include "istruct.h"
#include "store.h"
-/* Structure descriptor */
+/* Structure descriptor and GC procedures for font_data */
public_st_font_data();
+private
+CLEAR_MARKS_PROC(font_data_clear_marks)
+{
+ ref_struct_clear_marks(cmem, vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, pstype);
+}
+private
+ENUM_PTRS_BEGIN_PROC(font_data_enum_ptrs)
+{
+ return ref_struct_enum_ptrs(mem, vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, index, pep, pstype, gcst);
+}
+ENUM_PTRS_END_PROC
+private
+RELOC_PTRS_BEGIN(font_data_reloc_ptrs)
+{
+ ref_struct_reloc_ptrs(vptr, offset_of(font_data, u.type42.mru_sfnts_index)/*size*/, pstype, gcst);
+}
+RELOC_PTRS_END
/* <string|name> <font_dict> .buildfont3 <string|name> <font> */
/* Build a type 3 (user-defined) font. */
Modified: trunk/gs/src/zfcid1.c
===================================================================
--- trunk/gs/src/zfcid1.c 2007-04-21 02:33:44 UTC (rev 7866)
+++ trunk/gs/src/zfcid1.c 2007-04-22 11:50:25 UTC (rev 7867)
@@ -95,7 +95,7 @@
return prgnum->value.intval;
default: /* array type */
code = string_array_access_proc(pfont->memory, pcidmap, 1, cid * gdbytes,
- gdbytes, &data);
+ gdbytes, NULL, NULL, &data);
if (code < 0)
return code;
Modified: trunk/gs/src/zfont42.c
===================================================================
--- trunk/gs/src/zfont42.c 2007-04-21 02:33:44 UTC (rev 7866)
+++ trunk/gs/src/zfont42.c 2007-04-22 11:50:25 UTC (rev 7867)
@@ -73,6 +73,8 @@
pfont = *ppfont;
pdata = pfont_data(pfont);
ref_assign(&pdata->u.type42.sfnts, &sfnts);
+ pdata->u.type42.mru_sfnts_index = 0;
+ pdata->u.type42.mru_sfnts_pos = 0;
make_null_new(&pdata->u.type42.CIDMap);
ref_assign(&pdata->u.type42.GlyphDirectory, &GlyphDirectory);
pfont->data.string_proc = z42_string_proc;
@@ -167,15 +169,35 @@
*/
int
string_array_access_proc(const gs_memory_t *mem,
- const ref *psa, int modulus, ulong offset,
- uint length, const byte **pdata)
+ const ref *psa, int modulus, ulong offset, uint length,
+ uint *mru_index, ulong *mru_pos,
+ const byte **pdata)
{
- ulong left = offset;
- uint index = 0;
+ ulong left;
+ uint index;
+ bool backwards;
if (length == 0)
return 0;
- for (;; ++index) {
+ if (mru_index && mru_pos && offset >= (*mru_pos >> 1)) {
+ /* offset in or after mru string */
+ /* OR offset in 2nd half of the fragment before the mru string */
+ backwards = (*mru_pos > offset);
+ if (backwards) {
+ index = *mru_index - 1; /* 1st string to examine */
+ left = *mru_pos - offset; /* how many bytes to seek backwards */
+ } else {
+ index = *mru_index; /* 1st string to examine */
+ left = offset - *mru_pos; /* how many bytes to seek forward */
+ }
+ } else {
+ /* no mru */
+ /* OR offset in 1st half of the fragment before the mru string */
+ backwards = false;
+ index = 0;
+ left = offset;
+ }
+ for (;;) {
ref rstr;
int code = array_get(mem, psa, index, &rstr);
uint size;
@@ -190,13 +212,29 @@
* the additional byte is padding and should be ignored.
*/
size = r_size(&rstr) & -modulus;
+ if (backwards) {
+ if (left <= size) {
+ left = size - left;
+ backwards = false;
+ /* "index" does not change */
+ } else {
+ left -= size;
+ --index;
+ continue;
+ }
+ }
if (left < size) {
*pdata = rstr.value.const_bytes + left;
+ if (mru_index)
+ *mru_index = index;
+ if (mru_pos)
+ *mru_pos = offset - left;
if (left + length > size)
return size - left;
return 0;
}
left -= size;
+ ++index;
}
}
@@ -362,7 +400,8 @@
const byte ** pdata)
{
return string_array_access_proc(pfont->memory, &pfont_data(pfont)->u.type42.sfnts, 2,
- offset, length, pdata);
+ offset, length, &pfont_data(pfont)->u.type42.mru_sfnts_index,
+ &pfont_data(pfont)->u.type42.mru_sfnts_pos, pdata);
}
private int
More information about the gs-cvs
mailing list