Back to index

lightning-sunbird  0.9+nobinonly
nsCidMap.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Golden Hills Computer Services code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Brian Stell <bstell@ix.netcom.com>.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Brian Stell <bstell@ix.netcom.com>.
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 //
00040 // This file has routines to build Postscript CID maps
00041 //
00042 // For general information on Postscript see:
00043 //   Adobe Solutions Network: Technical Notes - Fonts
00044 //   http://partners.adobe.com/asn/developer/technotes/fonts.html
00045 //
00046 // For information on CID maps see:
00047 //
00048 //   CID-Keyed Font Technology Overview
00049 //   http://partners.adobe.com/asn/developer/pdfs/tn/5092.CID_Overview.pdf
00050 //
00051 //   Adobe CMap and CID Font Files Specification
00052 //   http://partners.adobe.com/asn/developer/pdfs/tn/5014.CMap_CIDFont_Spec.pdf
00053 //
00054 //   Building CMap Files for CID-Keyed Fonts
00055 //   http://partners.adobe.com/asn/developer/pdfs/tn/5099.CMapFiles.pdf
00056 //
00057 //
00058 
00059 #include "nsCidMap.h"
00060 
00061 CodeSpaceRangeElement UCS2_CodeSpaceRange[2] = {
00062   { 2, 0x0000, 0xD7FF },
00063   { 2, 0xE000, 0xFFFF },
00064 };
00065 
00066 int len_UCS2_CodeSpaceRange = 
00067              sizeof(UCS2_CodeSpaceRange)/sizeof(UCS2_CodeSpaceRange[0]);
00068 
00069 void
00070 WriteCidCharMap(const PRUnichar *aCharIDs, PRUint32 *aCIDs,
00071                 int aLen, FILE *aFile)
00072 {
00073   int i, j, blk_len;
00074   int fix_len = 0; // older versions of Ghostscript do not like a len of 2
00075 
00076   while (aLen) {
00077     /* determine the # of lines in this block */
00078     if (aLen >= 100)
00079       blk_len = 100;
00080     else
00081       blk_len = aLen;
00082 
00083     if (blk_len == 2) {
00084       fix_len = 1;
00085       fprintf(aFile, "%% add an extra dummy value to the end of this block "
00086               " since older versions of\n");
00087       fprintf(aFile, "%% Ghostscript do not like a block len of 2\n");
00088     }
00089 
00090     /* output the block */
00091     fprintf(aFile, "%d begincidchar\n", blk_len+fix_len);
00092     for (i=0; i<blk_len; i++)
00093       fprintf(aFile, "<%04X> %d\n", aCharIDs[i], aCIDs[i]);
00094     for (j=0; j<fix_len; j++) // repeat the old value
00095       fprintf(aFile, "<%04X> %d\n", aCharIDs[i-1], aCIDs[i-1]);
00096     fprintf(aFile, "endcidchar\n\n");
00097 
00098     /* setup for next block */
00099     aLen -= blk_len;
00100     aCharIDs += blk_len;
00101     aCIDs += blk_len;
00102   }
00103 }
00104 
00105 void
00106 WriteCidRangeMapUnicode(FILE *aFile)
00107 {
00108   int i;
00109 
00110   fprintf(aFile, "100 begincidrange\n");
00111   for (i=0; i<100; i++)
00112     fprintf(aFile, "<%04X> <%04X> %d\n", i*256, ((i+1)*256)-1, i*256);
00113   fprintf(aFile, "endcidrange\n\n");
00114 
00115   fprintf(aFile, "100 begincidrange\n");
00116   for (i=100; i<200; i++)
00117     fprintf(aFile, "<%04X> <%04X> %d\n", i*256, ((i+1)*256)-1, i*256);
00118   fprintf(aFile, "endcidrange\n\n");
00119 
00120   fprintf(aFile, "56 begincidrange\n");
00121   for (i=200; i<256; i++)
00122     fprintf(aFile, "<%04X> <%04X> %d\n", i*256, ((i+1)*256)-1, i*256);
00123   fprintf(aFile, "endcidrange\n\n");
00124 
00125 }
00126 
00127 void
00128 WriteCmapHeader(const char *aName, const char *aRegistry, 
00129                 const char *aEncoding, int aSupplement,
00130                 int aType, int aWmode, FILE *aFile)
00131 {
00132   fprintf(aFile, "%%%%DocumentNeededResources: procset CIDInit\n");
00133   fprintf(aFile, "%%%%IncludeResource: procset CIDInit\n");
00134   fprintf(aFile, "%%%%BeginResource: CMap %s\n", aName);
00135   fprintf(aFile, "%%%%Title: (%s %s %s %d)\n", aName, aRegistry, aEncoding,aSupplement);
00136   fprintf(aFile, "%%%%Version : 1\n");
00137   fprintf(aFile, "\n");
00138   fprintf(aFile, "/CIDInit /ProcSet findresource begin\n");
00139   // IMPROVMENT: to add support for Postlevel 1 interpreters
00140   // IMPROVMENT: add code to test if CIDInit is defined 
00141   // IMPROVMENT: if not defined then add code here to define it
00142   fprintf(aFile, "\n");
00143   fprintf(aFile, "12 dict begin\n");
00144   fprintf(aFile, "\n");
00145   fprintf(aFile, "begincmap\n");
00146   fprintf(aFile, "\n");
00147   fprintf(aFile, "/CIDSystemInfo 3 dict dup begin\n");
00148   fprintf(aFile, "  /Registry (%s) def\n", aRegistry);
00149   fprintf(aFile, "  /Ordering (%s) def\n", aEncoding);
00150   fprintf(aFile, "  /Supplement %d def\n", aSupplement);
00151   fprintf(aFile, "end def\n");
00152   fprintf(aFile, "\n");
00153   fprintf(aFile, "/CMapName /%s def\n", aName);
00154   fprintf(aFile, "\n");
00155   fprintf(aFile, "/CMapVersion 1 def\n");
00156   fprintf(aFile, "/CMapType %d def\n", aType);
00157   fprintf(aFile, "\n");
00158   fprintf(aFile, "/WMode %d def\n", aWmode);
00159   fprintf(aFile, "\n");
00160 }
00161 
00162 void
00163 WriteCmapFooter(FILE *aFile)
00164 {
00165   fprintf(aFile, "endcmap\n");
00166   fprintf(aFile, "\n");
00167   fprintf(aFile, "CMapName currentdict /CMap defineresource pop\n");
00168   fprintf(aFile, "\n");
00169   fprintf(aFile, "end\n");
00170   fprintf(aFile, "end\n");
00171   fprintf(aFile, "%%%%EndResource\n");
00172   fprintf(aFile, "\n");
00173 }
00174 
00175 PRBool
00176 WriteCodeSpaceRangeMap(CodeSpaceRangeElement *aElements, int aLen, FILE *aFile)
00177 {
00178   int i, blk_len;
00179 
00180   while (aLen) {
00181     /* determine the # of lines in this block */
00182     if (aLen >= 100)
00183       blk_len = 100;
00184     else
00185       blk_len = aLen;
00186 
00187     /* output the block */
00188     fprintf(aFile, "%d begincodespacerange\n", blk_len);
00189     for (i=0; i<blk_len; i++, aElements++) {
00190       if (aElements->num_bytes == 1)
00191         fprintf(aFile, "<%02X>   <%02X>\n", aElements->start, aElements->end);
00192       else if (aElements->num_bytes == 2)
00193         fprintf(aFile, "<%04X> <%04X>\n", aElements->start, aElements->end);
00194       else {
00195         fprintf(aFile, "codespacerange: invalid num_bytes (%d)\nexiting...\n", 
00196                 aElements->num_bytes);
00197         return PR_FALSE;
00198       }
00199     }
00200     fprintf(aFile, "endcodespacerange\n\n");
00201 
00202     /* setup for next block */
00203     aLen -= blk_len;
00204   }
00205   return PR_TRUE;
00206 }
00207 
00208 void
00209 WriteCodeSpaceRangeMapUCS2(FILE *aFile)
00210 {
00211   WriteCodeSpaceRangeMap(UCS2_CodeSpaceRange, len_UCS2_CodeSpaceRange, aFile);
00212 }
00213