[gs-cvs] rev 8235 - trunk/gs/src

ken at ghostscript.com ken at ghostscript.com
Mon Sep 10 01:31:43 PDT 2007


Author: ken
Date: 2007-09-10 01:31:42 -0700 (Mon, 10 Sep 2007)
New Revision: 8235

Modified:
   trunk/gs/src/gdevpdtc.c
   trunk/gs/src/gdevpdte.c
   trunk/gs/src/gdevpdtt.c
   trunk/gs/src/gdevpdtt.h
Log:
Update pdfwrite to handle type 0 fonts with type 1 or type 2 descendant fonts.

DETAILS
Bug #689212 "irregular baselines - gs pdfwrite changes CFF to Type 3"

There was previously no code in pdfwrite to handle type 0 fonts with type 1 descendant 
fonts. This caused pdfwrite to 'fall back' to the default implementartion which converts
glyphs to a type 3 bitmap font.

This change is to enable scalable fonts to be embedded in the output. NB it is not 
possible, in PDF, to construct a type 0 font with anything other than CIDFonts as 
descendants, and we must therefore output one or more type 1 fonts to do the job.

1. (gdevpdtt.c) in scan_cmap_text add a case to handle a type 1 descendant font. The main
    work is done in this routine; we create a list of glyph name indices representing 
    each of the input character codes and later we use pdf_obtain_font_resource_unencoded
    and the TEXT_FROM_GLYPHS operation to mark the font usage, and create an 'encoded'
    string for output.

    If font->procs.next_char_glyph returns a glyph name index, then we simply add it to
    our list, if it returns a character code (a CMap can map a character code in the type
    0 font to a character code in a descendant font) then we use the descendant font
    'procs.encode_char' to get a glyph.

    Once we have a complete list of glyphs, we pass it to
    pdf_obtain_font_resource_unencoded to add the glyphs to the encoding, and return a
    string where the character codes match the newly created/modified encoding.

    Finally we pass the encoded string and glyph list to process_text_modify_width, using
    the descendant font.

    A couple of minor points; its possible to change descendant fonts in the middle of a
    string, and we need to cope with that, hence the copying of the last glyph in the list
    when a font_change occurs. Its possible to return a different pdfont if we run out of
    encoding positions in the current one, which can result in multiple type 1 fonts in
    the output.

2. We need to use the function adjust_first_last_char, which was defined private in
   gdevpdte.c, so this has been made public.

3. A prototype for adjust_first_last_char has been added to gdevpdtt.h

4. The function reserve_char_code_in_pdfont was written to handle single glyphs, it can
   now be called with multiple glyphs. The loop for re-using positions in the encoding
   with /.notdef codes didn't use the 'last_reserved_char' argument, which meant that it
   kept returning the same position. To prevent this it now pays attention to the
   'last_reserved_char' argument.

5. Finally, the routine pdf_make_text_glyphs_table_unencoded, which calls
   reserve_char_code_in_pdfont also did not previously expect to be called with multiple
   glyphs. The loop below do_unkown has been modified to use a local variable, instead of
   pdfont->u.simple.last_reserved_char. THis means that, should an error occur, the value
   of pdfont->u.simple.last_reserved_char will not be modified.


EXPECTED DIFFERENCES
A progression with pdfwrite 456-01.ps. The old code converts a font to bitmaps,
now we write out the copy of source input Type 1 font

Modified: trunk/gs/src/gdevpdtc.c
===================================================================
--- trunk/gs/src/gdevpdtc.c	2007-09-09 00:59:22 UTC (rev 8234)
+++ trunk/gs/src/gdevpdtc.c	2007-09-10 08:31:42 UTC (rev 8235)
@@ -344,11 +344,13 @@
     gs_text_enum_t scan = *(gs_text_enum_t *)pte;
     int wmode = font->WMode, code, rcode = 0;
     pdf_font_resource_t *pdsubf0 = NULL;
-    gs_font *subfont0 = NULL;
+    gs_font *subfont0 = NULL, *saved_subfont = NULL;
     uint index = scan.index, xy_index = scan.xy_index, start_index = index;
     uint font_index0 = 0x7badf00d;
     bool done = false;
     pdf_char_glyph_pairs_t p;
+    gs_glyph *type1_glyphs = 0;
+    int num_type1_glyphs = 0;
 
     p.num_all_chars = 1;
     p.num_unused_chars = 1;
@@ -362,7 +364,7 @@
 	pdf_font_resource_t *pdsubf;
 	gs_font *subfont = NULL;
 	gs_point wxy;
-	bool font_change;
+	bool font_change = 0;
 
 	code = gx_path_current_point(pte->path, &pte->origin);
 	if (code < 0)
@@ -383,8 +385,12 @@
 		done = true;
 		break;
 	    }
-	    if (code < 0)
-		return code;
+	    if (code < 0){
+		if (type1_glyphs)
+		    gs_free_object(pdev->pdf_memory, type1_glyphs, 
+				    "Temporary storage for CFF descendant glyphs");
+	    	return code;
+	    }
 	    subfont = scan.fstack.items[scan.fstack.depth].font;
 	    font_index = scan.fstack.items[scan.fstack.depth].index;
 	    scan.xy_index++;
@@ -392,6 +398,31 @@
 		glyph = GS_MIN_CID_GLYPH;
 	    cid = glyph - GS_MIN_CID_GLYPH;
 	    switch (subfont->FontType) {
+		case ft_encrypted:
+		case ft_encrypted2:{
+		    if (glyph == GS_MIN_CID_GLYPH) {
+			glyph = subfont->procs.encode_char(subfont, chr, GLYPH_SPACE_NAME);
+    		    }
+        	    if(type1_glyphs) {
+			gs_glyph *temp = (gs_glyph *)gs_alloc_bytes(pdev->pdf_memory, 
+					sizeof(gs_glyph) * (num_type1_glyphs + 1), 
+					"Temporary storage for CFF descendant glyphs");
+			memcpy(temp, type1_glyphs, sizeof(gs_glyph) * num_type1_glyphs);
+			gs_free_object(pdev->pdf_memory, type1_glyphs, 
+				"Temporary storage for CFF descendant glyphs");
+			type1_glyphs = temp;
+		    }else
+			type1_glyphs = (gs_glyph *)gs_alloc_bytes(pdev->pdf_memory, 
+				    sizeof(gs_glyph) * (num_type1_glyphs + 1), 
+				    "Temporary storage for CFF descendant glyphs");
+		    type1_glyphs[num_type1_glyphs] = glyph;
+		    num_type1_glyphs++;
+		    if (font_change){
+			subfont = subfont0;
+			subfont0 = 0;
+		    }
+		    break;
+		}
 		case ft_CID_encrypted:
 		case ft_CID_TrueType: {
 		    p.s[0].glyph = glyph;
@@ -428,8 +459,12 @@
 	    }
 	    code = pdf_attached_font_resource(pdev, (gs_font *)subfont, &pdsubf, 
 				       &glyph_usage, &real_widths, &char_cache_size, &width_cache_size);
-	    if (code < 0)
+	    if (code < 0) {
+		if(type1_glyphs)
+		    gs_free_object(pdev->pdf_memory, type1_glyphs, 
+				    "Temporary storage for CFF descendant glyphs");
 		return code;
+	    }
 	    if (break_index > start_index && pdev->charproc_just_accumulated)
 		break;
 	    if (subfont->FontType == ft_user_defined &&
@@ -438,75 +473,89 @@
 		pte->current_font = subfont;
 		return gs_error_undefined;
 	    }
-	    font_change = (pdsubf != pdsubf0 && pdsubf0 != NULL);
+	    if (subfont->FontType == ft_encrypted || subfont->FontType == ft_encrypted2) {
+		font_change = (subfont != subfont0 && subfont0 != NULL);
+		if (font_change) {
+		    saved_subfont = subfont;
+		    subfont = subfont0;
+		    num_type1_glyphs--;
+		}
+    	    }else
+		font_change = (pdsubf != pdsubf0 && pdsubf0 != NULL);
 	    if (!font_change) {
 		pdsubf0 = pdsubf;
 		font_index0 = font_index;
 		subfont0 = subfont;
 	    }
-	    pfd = pdsubf->FontDescriptor;
-	    code = pdf_resize_resource_arrays(pdev, pdsubf, cid + 1);
-	    if (code < 0)
-		return code;
-	    if (subfont->FontType == ft_CID_encrypted || subfont->FontType == ft_CID_TrueType) {
-		if (cid >=width_cache_size) {
-		    /* fixme: we add the CID=0 glyph as CID=cid glyph to the output font.
-		       Really it must not add and leave the CID undefined. */
-		    cid = 0; /* notdef. */
-		}
-	    } 
-	    if (cid >= char_cache_size || cid >= width_cache_size)
-		return_error(gs_error_unregistered); /* Must not happen */
-	    if (pdsubf->FontType == ft_user_defined) {
-		code += 0; /* A good place for a breakpoint. */
-	    } else {
-		pdf_font_resource_t *pdfont;
-
-		code = pdf_obtain_cidfont_widths_arrays(pdev, pdsubf, wmode, &w, &w0, &v);
+	    if (subfont->FontType != ft_encrypted && subfont->FontType != ft_encrypted2) {
+		pfd = pdsubf->FontDescriptor;
+		code = pdf_resize_resource_arrays(pdev, pdsubf, cid + 1);
 		if (code < 0)
 		    return code;
-		code = pdf_obtain_parent_type0_font_resource(pdev, pdsubf, font_index,
-				&font->data.CMap->CMapName, &pdfont);
-		if (code < 0)
-		    return code;
-		if (pdf_is_CID_font(subfont)) {
-		    if (subfont->procs.decode_glyph((gs_font *)subfont, glyph) != GS_NO_CHAR) {
-			/* Since PScript5.dll creates GlyphNames2Unicode with character codes
-			   instead CIDs, and with the WinCharSetFFFF-H2 CMap
-			   character codes appears different than CIDs (Bug 687954),
-			   pass the character code intead the CID. */
-			code = pdf_add_ToUnicode(pdev, subfont, pdfont, chr + GS_MIN_CID_GLYPH, chr, NULL);
-		    } else {
-			/* If we interpret a PDF document, ToUnicode CMap may be attached to the Type 0 font. */
-			code = pdf_add_ToUnicode(pdev, pte->orig_font, pdfont, chr + GS_MIN_CID_GLYPH, chr, NULL);
+		if (subfont->FontType == ft_CID_encrypted || subfont->FontType == ft_CID_TrueType) {
+		    if (cid >=width_cache_size) {
+			/* fixme: we add the CID=0 glyph as CID=cid glyph to the output font.    
+		           Really it must not add and leave the CID undefined. */
+			cid = 0; /* notdef. */
 		    }
-		} else
-		    code = pdf_add_ToUnicode(pdev, subfont, pdfont, glyph, cid, NULL);
-		if (code < 0)
-		    return code;
-		/*  We can't check pdsubf->used[cid >> 3] here,
-		    because it mixed data for different values of WMode. 
-		    Perhaps pdf_font_used_glyph returns fast with reused glyphs.
-		*/
-		code = pdf_font_used_glyph(pfd, glyph, (gs_font_base *)subfont);
-		if (code == gs_error_rangecheck) {
-		    if (!(pdsubf->used[cid >> 3] & (0x80 >> (cid & 7)))) {
-			char buf[gs_font_name_max + 1];
-			int l = min(sizeof(buf) - 1, subfont->font_name.size);
+		} 
+		if (cid >= char_cache_size || cid >= width_cache_size)
+		    return_error(gs_error_unregistered); /* Must not happen */
+		if (pdsubf->FontType == ft_user_defined  || pdsubf->FontType == ft_encrypted || 
+				pdsubf->FontType == ft_encrypted2) {
+		    code += 0; /* A good place for a breakpoint. */
+		} else {
+		    pdf_font_resource_t *pdfont;
 
-			memcpy(buf, subfont->font_name.chars, l);
-			buf[l] = 0;
-			eprintf2("Missing glyph CID=%d in the font %s . The output PDF may fail with some viewers.\n", (int)cid, buf);
-			pdsubf->used[cid >> 3] |= 0x80 >> (cid & 7);
-		    }
-		    cid = 0, code = 1;  /* undefined glyph. */
-		} else if (code < 0)
-		    return code;
-		if (code == 0 /* just copied */ || pdsubf->Widths[cid] == 0) {
-		    pdf_glyph_widths_t widths;
+		    code = pdf_obtain_cidfont_widths_arrays(pdev, pdsubf, wmode, &w, &w0, &v);
+		    if (code < 0)
+			return code;
+		    code = pdf_obtain_parent_type0_font_resource(pdev, pdsubf, font_index,
+			&font->data.CMap->CMapName, &pdfont);
+		    if (code < 0)
+			return code;
+		    if (pdf_is_CID_font(subfont)) {
+			if (subfont->procs.decode_glyph((gs_font *)subfont, glyph) != GS_NO_CHAR) {
+			    /* Since PScript5.dll creates GlyphNames2Unicode with character codes
+			       instead CIDs, and with the WinCharSetFFFF-H2 CMap
+		               character codes appears different than CIDs (Bug 687954),
+		               pass the character code intead the CID. */
+			    code = pdf_add_ToUnicode(pdev, subfont, pdfont, 
+				chr + GS_MIN_CID_GLYPH, chr, NULL);
+			} else {
+			    /* If we interpret a PDF document, ToUnicode 
+			       CMap may be attached to the Type 0 font. */
+			    code = pdf_add_ToUnicode(pdev, pte->orig_font, pdfont, 
+				chr + GS_MIN_CID_GLYPH, chr, NULL);
+			}
+		    } else
+			code = pdf_add_ToUnicode(pdev, subfont, pdfont, glyph, cid, NULL);
+		    if (code < 0)
+			return code;
+		    /*  We can't check pdsubf->used[cid >> 3] here,
+			because it mixed data for different values of WMode. 
+			Perhaps pdf_font_used_glyph returns fast with reused glyphs.
+		     */
+		    code = pdf_font_used_glyph(pfd, glyph, (gs_font_base *)subfont);
+		    if (code == gs_error_rangecheck) {
+			if (!(pdsubf->used[cid >> 3] & (0x80 >> (cid & 7)))) {
+			    char buf[gs_font_name_max + 1];
+			    int l = min(sizeof(buf) - 1, subfont->font_name.size);
+    
+			    memcpy(buf, subfont->font_name.chars, l);
+			    buf[l] = 0;
+			    eprintf2("Missing glyph CID=%d in the font %s . The output PDF may fail with some viewers.\n", 
+				    (int)cid, buf);
+			    pdsubf->used[cid >> 3] |= 0x80 >> (cid & 7);
+			}
+			cid = 0, code = 1;  /* undefined glyph. */
+		    } else if (code < 0)
+			return code;
+		    if (code == 0 /* just copied */ || pdsubf->Widths[cid] == 0) {
+			pdf_glyph_widths_t widths;
 
 		    code = pdf_glyph_widths(pdsubf, wmode, glyph, (gs_font *)subfont, &widths,
-				pte->cdevproc_callout ? pte->cdevproc_result : NULL);
+			pte->cdevproc_callout ? pte->cdevproc_result : NULL);
 		    if (code < 0)
 			return code;
 		    if (code == TEXT_PROCESS_CDEVPROC) {
@@ -530,26 +579,27 @@
 			   v-vector, comupte and store the glyph width for WMode 0. */
 			/* fixme : skip computing real_width here. */
 			code = pdf_glyph_widths(pdsubf, 0, glyph, (gs_font *)subfont, &widths,
-				    pte->cdevproc_callout ? pte->cdevproc_result : NULL);
+			    pte->cdevproc_callout ? pte->cdevproc_result : NULL);
 			if (code < 0)
 			    return code;
 			w0[cid] = widths.Width.w;
 		    }
 		    if (pdsubf->u.cidfont.CIDToGIDMap != 0) {
 			gs_font_cid2 *subfont2 = (gs_font_cid2 *)subfont;
-
+    
 			pdsubf->u.cidfont.CIDToGIDMap[cid] =
-			    subfont2->cidata.CIDMap_proc(subfont2, glyph);
+			subfont2->cidata.CIDMap_proc(subfont2, glyph);
 		    }
 		}
 		if (wmode)
 		    pdsubf->u.cidfont.used2[cid >> 3] |= 0x80 >> (cid & 7);
+		}
+		pdsubf->used[cid >> 3] |= 0x80 >> (cid & 7);
 	    }
-	    pdsubf->used[cid >> 3] |= 0x80 >> (cid & 7);
 	    if (pte->cdevproc_callout) {
-		 /* Only handle a single character because its width is stored 
-		    into pte->cdevproc_result, and process_text_modify_width neds it. 
-		    fixme: next time take from w, v, real_widths. */
+		/* Only handle a single character because its width is stored 
+	          into pte->cdevproc_result, and process_text_modify_width neds it. 
+                  fixme: next time take from w, v, real_widths. */
 		break_index = scan.index;
 		break_xy_index = scan.xy_index;
 		break;
@@ -562,13 +612,59 @@
 				 pte->text.x_widths == pte->text.y_widths ? 2 : 1);
 	    gs_text_params_t save_text;
 
+        if (!subfont && num_type1_glyphs != 0)
+ 	    subfont = subfont0;
+	if (subfont && (subfont->FontType == ft_encrypted || subfont->FontType == ft_encrypted2)) {
+	    int save_op = pte->text.operation;
+
+	    pte->current_font = subfont;
+	    pte->text.operation |= TEXT_FROM_GLYPHS;
+	    pte->text.data.glyphs = type1_glyphs;
+	    /* initially this code reused scan.text.data.bytes directly, however it turns 
+	     * out that in the depths of pdf_obtain_font_resource_unencoded, we use the 
+	     * string we passed in to hold a list of glyph name indices. These are 4 bytes
+	     * in size, so if we reused that we would potentially run off the end of the 
+	     * buffer, as the incoming data stream may be encoded with as few as one byte
+	     * per glyph. Also, we can corrupt the input stream for the same reason. 
+	     * Because we are going to write these fonts out as straight type 1, we 
+	     * know its safe to reuse the data buffer to store the result, because 
+	     * that can't use more than one byte per glyph.
+	     */
+	    str.data = gs_alloc_bytes(pdev->pdf_memory, num_type1_glyphs * sizeof(gs_glyph), 
+		"working buffer for CFF fonts");
+	    str.size = num_type1_glyphs;
+	    code = pdf_obtain_font_resource_unencoded(pte, (const gs_string *)&str, &pdsubf0, 
+		type1_glyphs);
+	    if (code < 0) {
+		gs_free_object(pdev->pdf_memory, (void *)str.data, 
+		    "working buffer for CFF fonts");
+		if(type1_glyphs) {
+		    gs_free_object(pdev->pdf_memory, type1_glyphs, 
+			"Temporary storage for CFF descendant glyphs");
+		    num_type1_glyphs = 0;
+		    type1_glyphs = 0;
+		}
+		return(code);
+	    }	
+	    memcpy((void *)scan.text.data.bytes, (void *)str.data, str.size);
+	    gs_free_object(pdev->pdf_memory, (void *)str.data, 
+		"working buffer for CFF fonts");
+	    str.data = scan.text.data.bytes;
+	    pdsubf = pdsubf0;
+	    pte->text.operation = save_op;
+	}
 	    pte->current_font = subfont0;
 	    code = gs_matrix_multiply(&subfont0->FontMatrix, &font->FontMatrix, &m3); 
 	    /* We thought that it should be gs_matrix_multiply(&font->FontMatrix, &subfont0->FontMatrix, &m3); */
-	    if (code < 0)
-		return code;
-	    if (pdsubf0->FontType == ft_user_defined)
-		pdfont = pdsubf0;
+		if (code < 0) {
+		    if(type1_glyphs)
+		gs_free_object(pdev->pdf_memory, type1_glyphs, 
+		"Temporary storage for CFF descendant glyphs");
+			return code;
+		}
+	    if (pdsubf0->FontType == ft_user_defined  || pdsubf->FontType == ft_encrypted || 
+	    pdsubf->FontType == ft_encrypted2)
+		    pdfont = pdsubf0;
 	    else {
 		code = pdf_obtain_parent_type0_font_resource(pdev, pdsubf0, font_index0, 
 			    &font->data.CMap->CMapName, &pdfont);
@@ -587,14 +683,22 @@
 	    }
 	    pdf_set_text_wmode(pdev, font->WMode);
 	    code = pdf_update_text_state(&text_state, (pdf_text_enum_t *)pte, pdfont, &m3);
-	    if (code < 0)
-		return code;
+		if (code < 0) {
+	    if(type1_glyphs)
+		gs_free_object(pdev->pdf_memory, type1_glyphs, 
+		"Temporary storage for CFF descendant glyphs");
+	    return code;
+		}
 	    /* process_text_modify_width breaks text parameters. 
 	       We would like to improve it someday. 
 	       Now save them locally and restore after the call. */
 	    save_text = pte->text;
+	    if (subfont && (subfont->FontType != ft_encrypted && 
+	    subfont->FontType != ft_encrypted2)) {
+	    /* If we are a type 1 descendant, we already sorted this out above */
 	    str.data = scan.text.data.bytes + index;
 	    str.size = break_index - index;
+	}
 	    if (pte->text.operation & TEXT_REPLACE_WIDTHS) {
 		if (pte->text.x_widths != NULL)
 		    pte->text.x_widths += xy_index * xy_index_step;
@@ -602,8 +706,40 @@
 		    pte->text.y_widths += xy_index * xy_index_step;
 	    }
 	    pte->xy_index = 0;
+	if (subfont && (subfont->FontType == ft_encrypted || 
+	    subfont->FontType == ft_encrypted2)) {
+	    gs_font *f = pte->orig_font;
+
+	    adjust_first_last_char(pdfont, (byte *)str.data, 1);
+
+	    /* Make sure we use the descendant font, not the original type 0 ! */
+	    pte->orig_font = subfont;
+	    code = process_text_modify_width((pdf_text_enum_t *)pte, 
+		(gs_font *)subfont, &text_state, &str, &wxy, type1_glyphs, false);
+	    if (code < 0) {
+		if (type1_glyphs)
+		    gs_free_object(pdev->pdf_memory, type1_glyphs, 
+		    "Temporary storage for CFF descendant glyphs");
+		return(code);
+	    }
+	    if(type1_glyphs){
+		if(font_change){
+		    type1_glyphs[0] = type1_glyphs[num_type1_glyphs];
+		    num_type1_glyphs = 1;
+		    subfont = saved_subfont;
+		    font_change = 0;
+		}else{
+		    gs_free_object(pdev->pdf_memory, type1_glyphs, 
+			"Temporary storage for CFF descendant glyphs");
+		    num_type1_glyphs = 0;
+		    type1_glyphs = 0;
+		}
+	    }
+	    pte->orig_font = f;
+	}else{
 	    code = process_text_modify_width((pdf_text_enum_t *)pte, (gs_font *)font,
-				  &text_state, &str, &wxy, NULL, true);
+		  &text_state, &str, &wxy, NULL, true);
+	}
 	    if (pte->text.operation & TEXT_REPLACE_WIDTHS) {
 		if (pte->text.x_widths != NULL)
 		    pte->text.x_widths -= xy_index * xy_index_step;

Modified: trunk/gs/src/gdevpdte.c
===================================================================
--- trunk/gs/src/gdevpdte.c	2007-09-09 00:59:22 UTC (rev 8234)
+++ trunk/gs/src/gdevpdte.c	2007-09-10 08:31:42 UTC (rev 8235)
@@ -365,7 +365,7 @@
     return 0;
 }
 
-private void
+void
 adjust_first_last_char(pdf_font_resource_t *pdfont, byte *str, int size)
 {
     int i;

Modified: trunk/gs/src/gdevpdtt.c
===================================================================
--- trunk/gs/src/gdevpdtt.c	2007-09-09 00:59:22 UTC (rev 8234)
+++ trunk/gs/src/gdevpdtt.c	2007-09-10 08:31:42 UTC (rev 8235)
@@ -1348,10 +1348,11 @@
 	if (standard_glyph_code_for_notdef == GS_NO_GLYPH)
 	    standard_glyph_code_for_notdef = 
 		    gs_c_name_glyph((const byte *)".notdef", 7) - gs_c_min_std_encoding_glyph;
-	for (ch = 0; ch < 256; ch++) {
+	for (ch = *last_reserved_char + 1; ch < 256; ch++) {
 	    pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
 
 	    if (pet->glyph == GS_NO_GLYPH && enc[ch] == standard_glyph_code_for_notdef) {
+		*last_reserved_char = ch;
 		break;
 	    }
 	}
@@ -1472,6 +1473,7 @@
     }
 do_unknown:
     if (unknown) {
+	int last_reserved_char = -1;
 	 /* Using global glyph names. */
 
 	/* Try to find an existing font resource, which has necessary glyphs. 
@@ -1495,14 +1497,21 @@
 	/* Try to add glyphs to the current font resource. . */
 	cgp->num_unused_chars = 0;
 	cgp->num_all_chars = 0;
+
+	if(pdfont != NULL)
+		last_reserved_char = pdfont->u.simple.last_reserved_char;
+
 	for (i = 0; i < pstr->size; i++) {
+		
 	    if (pdfont == NULL)
 		ch = 256; /* Force new encoding. */
 	    else
-		ch = pdf_reserve_char_code_in_pdfont(pdfont, cgp, gdata[i], &pdfont->u.simple.last_reserved_char);
+		ch = pdf_reserve_char_code_in_pdfont(pdfont, cgp, gdata[i], &last_reserved_char);
 	    if (ch > 255) {
+		if(pdfont != NULL)
+			last_reserved_char = pdfont->u.simple.last_reserved_char;
 		/* Start a new font/encoding. */
-		int last_reserved_char = -1;
+		last_reserved_char = -1;
 
 		cgp->num_unused_chars = 0;
 		cgp->num_all_chars = 0;
@@ -1515,10 +1524,10 @@
 			return_error(gs_error_unregistered);
 		    }
 		}
-		if (pdfont != NULL)
-		    pdfont->u.simple.last_reserved_char = last_reserved_char;
-	    }
 	}
+    }
+	if (pdfont != NULL)
+	    pdfont->u.simple.last_reserved_char = last_reserved_char;
 	/* Change glyphs to char codes in the text : */
 	for (i = 0; i < pstr->size; i++) {
 	    /* A trick : pdf_reserve_char_code_in_pdfont here simply encodes with cgp. */

Modified: trunk/gs/src/gdevpdtt.h
===================================================================
--- trunk/gs/src/gdevpdtt.h	2007-09-09 00:59:22 UTC (rev 8234)
+++ trunk/gs/src/gdevpdtt.h	2007-09-10 08:31:42 UTC (rev 8235)
@@ -320,4 +320,6 @@
 
 int pdf_shift_text_currentpoint(pdf_text_enum_t *penum, gs_point *wpt);
 
+void adjust_first_last_char(pdf_font_resource_t *pdfont, byte *str, int size);
+
 #endif /* gdevpdtt_INCLUDED */



More information about the gs-cvs mailing list