Changeset 497 for trunk


Ignore:
Timestamp:
Dec 27, 2011, 10:39:53 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Lucide: updated fontconfig and poppler

Location:
trunk
Files:
8 added
91 edited

Legend:

Unmodified
Added
Removed
  • trunk/Lucide/plugins/lupoppler/lupoppler.cpp

    r470 r497  
    719719    PopplerPage *page = &( document->pages[ pagenum ] );
    720720
    721     Object obj;
    722     Links *links = new Links( page->page->getAnnots( &obj ),
    723                             document->doc->getCatalog()->getBaseURI() );
    724     obj.free();
     721    Links *links = new Links( page->page->getAnnots(document->doc->getCatalog()) );
    725722
    726723    if ( links == NULL ) {  // No links, return empty LuLinkMapSequence
     
    741738    for ( int i = 0; i < len; i++ )
    742739    {
    743         Link *link = links->getLink( i );
     740        AnnotLink *link = links->getLink( i );
    744741        LinkAction *link_action = link->getAction();
    745742        build_link( document->doc, &(mapping->_buffer[ i ].link), NULL, link_action );
     
    14391436    for (int i = 0; i < doc->doc->getNumPages(); ++i) {
    14401437        Page *page = doc->pages[ i ].page;
    1441         FormPageWidgets *widgets = page->getPageWidgets();
     1438        FormPageWidgets *widgets = page->getFormWidgets(doc->doc->getCatalog());
    14421439        if (widgets == NULL || widgets->getNumWidgets() > 0)
    14431440            return TRUE;
     
    14531450    LuPopplerDocumentData *somThis = LuPopplerDocumentGetData(somSelf);
    14541451
    1455     Page *page = ((PopplerDocument *)somThis->data)->pages[ pagenum ].page;
    1456 
    1457     FormPageWidgets *widgets = page->getPageWidgets();
     1452    PopplerDocument *doc = (PopplerDocument *)somThis->data;
     1453    Page *page = doc->pages[ pagenum ].page;
     1454
     1455    FormPageWidgets *widgets = page->getFormWidgets(doc->doc->getCatalog());
    14581456
    14591457    LuDocument_LuInputFieldSequence *fields = (LuDocument_LuInputFieldSequence *)
  • trunk/poppler/fc-emulate-os2/Makefile.kmk

    r483 r497  
    1919fontconfig_INCS          = . ../freetype2/include
    2020fontconfig_SOURCES       = \
    21         fontconfig/fontconfig.c
     21        fontconfig/fontconfig.c \
     22        fontconfig/fcpat.c \
     23        fontconfig/fclang.c
    2224
    2325include $(FILE_KBUILD_SUB_FOOTER)
  • trunk/poppler/fc-emulate-os2/fontconfig/fontconfig.c

    r484 r497  
    11/*
    22 * This code is (C) Netlabs.org
    3  * Author: Doodle <doodle@netlabs.org>
    4  *         Peter Weilbacher <mozilla@weilbacher.org>
    5  *         KO Myung-Hun
     3 * Authors:
     4 *    Doodle <doodle@netlabs.org>
     5 *    Peter Weilbacher <mozilla@weilbacher.org>
     6 *
     7 * Contributors:
     8 *    KO Myung-Hun <komh78@gmail.com>
     9 *    Alex Taylor <alex@altsan.org>
     10 *    Rich Walsh <rich@e-vertise.com>
     11 *    Silvan Scherrer <silvan.scherrer@aroa.ch>
    612 *
    713 */
    814
    9 #include <stdlib.h>
    10 #include <stdio.h>
    11 #include <sys/stat.h>
    12 #include <math.h> /* for fabs */
    13 #include <float.h> /* for DBL_EPSILON */
    14 #include <iconv.h>
    15 #define INCL_DOS
    16 #define INCL_WIN
    17 #define INCL_DOSERRORS
    18 #define INCL_SHLERRORS
    19 #include <os2.h>
    20 #include <fontconfig/fontconfig.h>
    21 #include <fontconfig/fcfreetype.h>
    22 #include <fontconfig/fcprivate.h>
    23 
    24 #include <ft2build.h>
    25 #include FT_FREETYPE_H
    26 #include FT_SFNT_NAMES_H
    27 #include FT_TRUETYPE_IDS_H
    28 
    29 #ifdef FC_CACHE_VERSION_STRING
    30 #undef FC_CACHE_VERSION_STRING
    31 #endif
    32 #define FC_CACHE_VERSION_STRING "v1.3_with_GCC"
    33 
    34 
    35 #ifdef FC_EXPORT_FUNCTIONS
    36 # define fcExport __declspec(dllexport)
    37 #else
    38 # define fcExport
    39 #endif
    40 
    41 // #define FONTCONFIG_DEBUG_PRINTF
    42 
    43 /* structure for the font cache in OS2.INI  */
    44 typedef struct FontDescriptionCache_s
    45 {
    46   char achFileName[CCHMAXPATH];
    47   struct stat FileStatus;
    48   char achFamilyName[128];
    49   char achStyleName[128];
    50   long lFontIndex;
    51 
    52   struct FontDescriptionCache_s *pNext;
    53 } FontDescriptionCache_t, *FontDescriptionCache_p;
    54 
    55 struct _FcPattern
    56 {
    57     char *family;
    58     int slant;
    59     int weight;
    60     double pixelsize;
    61     int spacing;
    62     FcBool hinting;
    63     FcBool antialias;
    64     FcBool embolden;
    65     FcBool verticallayout;
    66     int hintstyle;
    67     FcBool autohint;
    68     FcBool bitmap;
    69     int rgba;
    70     double size;
    71     char *style;
    72     FT_Face face;
    73     int ref;
    74     char *lang;
    75 
    76     FontDescriptionCache_p pFontDesc;
    77 };
    78 
     15#include "fcint.h"
    7916
    8017static FT_Library hFtLib;
     
    8421static time_t initTime;
    8522#define FC_TIMER_DEFAULT 30 // reinit after 30s by default, as in original FC
    86 static void *pConfig;
    8723
    8824fcExport void FcFini()
     
    11753}
    11854
    119 // #define LOOKUP_SFNT_NAME_DEBUG
    120 
    121 #define CP_UCS2BE   "UCS-2BE"   /* UCS-2BE */
    122 #define CP_UTF8     "UTF-8"     /* UTF-8   */
    123 
    124 #define CP_KOR      "IBM-949"   /* KSC5601 */
    125 #define CP_JPN      "IBM-943"   /* SJIS    */
    126 #define CP_PRC      "IBM-1381"  /* GB2312  */
    127 #define CP_ROC      "IBM-950"   /* Big5    */
    128 
    129 #define CP_SYSTEM   ""          /* System  */
     55static const char CP_UCS2BE[] = "UCS-2BE";  /* UCS-2BE */
     56static const char CP_UTF8[]   = "UTF-8";    /* UTF-8   */
     57static const char CP_KOR[]    = "IBM-949";  /* KSC5601 */
     58static const char CP_JPN[]    = "IBM-943";  /* SJIS    */
     59static const char CP_PRC[]    = "IBM-1381"; /* GB2312  */
     60static const char CP_ROC[]    = "IBM-950";  /* Big5    */
     61static const char CP_SYSTEM[] = "";         /* System  */
    13062
    13163enum {LANG_NONE, LANG_KOR, LANG_JPN, LANG_PRC, LANG_ROC};
     64
     65
     66/*
     67 * Employ a simple check to make sure a self-identified DBCS string isn't
     68 * actually a UCS-2 string.  (Workaround for some buggy Japanese system fonts
     69 * which stupidly have Unicode names under the Shift-JIS ID.)  This is far
     70 * from foolproof, but it should catch strings with either basic Latin or
     71 * halfwidth forms in them.
     72 */
     73static FcBool RealDBCSName( unsigned char *name, int len )
     74{
     75    int i;
     76    for ( i = 0; i < len; i++ ) {
     77       if ( name[i] == 0xFF || name[i] == 0 )
     78          return FcFalse;
     79    }
     80    return FcTrue;
     81}
     82
    13283
    13384/*
     
    225176    FT_Get_Sfnt_Name(ftface, found, &sfntName);
    226177
    227     name     = sfntName.string;
     178    name     = (char*)sfntName.string;
    228179    name_len = sfntName.string_len;
    229180
     
    296247      {
    297248        case TT_MS_ID_WANSUNG:
    298           fromCode = CP_KOR;
     249          if (!RealDBCSName(sfntName.string, sfntName.string_len))
     250             fromCode = CP_UCS2BE;
     251          else
     252             fromCode = CP_KOR;
    299253          break;
    300254
    301255        case TT_MS_ID_SJIS:
    302           fromCode = CP_JPN;
     256          if (!RealDBCSName(sfntName.string, sfntName.string_len))
     257             fromCode = CP_UCS2BE;
     258          else
     259             fromCode = CP_JPN;
    303260          break;
    304261
    305262        case TT_MS_ID_GB2312:
    306           fromCode = CP_PRC;
     263          if (!RealDBCSName(sfntName.string, sfntName.string_len))
     264             fromCode = CP_UCS2BE;
     265          else
     266             fromCode = CP_PRC;
    307267          break;
    308268
    309269        case TT_MS_ID_BIG_5:
    310           fromCode = CP_ROC;
     270          if (!RealDBCSName(sfntName.string, sfntName.string_len))
     271             fromCode = CP_UCS2BE;
     272          else
     273             fromCode = CP_ROC;
    311274          break;
    312275
     
    317280      }
    318281
    319       name = alloca(sfntName.string_len);
    320       name_len = 0;
    321 
    322       for (j = 0, name_len = 0; j < sfntName.string_len; j++)
    323         if (sfntName.string[j])
    324           name[name_len++] = sfntName.string[j];
     282      if (fromCode == CP_UCS2BE) {
     283          name     = (char*)sfntName.string;
     284          name_len = sfntName.string_len;
     285      } else {
     286         name = alloca(sfntName.string_len);
     287         name_len = 0;
     288         for (j = 0, name_len = 0; j < sfntName.string_len; j++)
     289            if (sfntName.string[j])
     290               name[name_len++] = sfntName.string[j];
     291      }
     292
    325293    }
    326294  }
     
    853821}
    854822
    855 fcExport FcPattern *FcPatternCreate(void)
    856 {
    857   FcPattern *pResult = malloc(sizeof(FcPattern));
    858   if (pResult)
    859   {
    860     memset(pResult, 0, sizeof(FcPattern));
    861   }
    862   pResult->hinting = FcTrue; // default to hinting on
    863   pResult->antialias = FcTrue; // default to antialias on
    864   pResult->embolden = FcFalse; // no emboldening by default
    865   pResult->verticallayout = FcFalse; // horizontal layout by default
    866   pResult->autohint = FcFalse; // off by default as recommended in fontconfig.h
    867   pResult->bitmap = FcTrue; // default to using embedded bitmaps
    868   /* set the strings to NULL for easy testing */
    869   pResult->family = NULL;
    870   pResult->style = NULL;
    871   pResult->lang = NULL;
    872   pResult->ref = 1;
    873   return pResult;
    874 }
    875 
    876 fcExport void FcPatternDestroy(FcPattern *p)
    877 {
    878   if (!p)
    879     return;
    880 
    881   if (--p->ref > 0)
    882     return;
    883   if (p->family)
    884     free(p->family);
    885   if (p->style)
    886     free(p->style);
    887   if (p->lang)
    888     free(p->lang);
    889   free(p);
    890 }
    891823
    892824fcExport FcBool FcConfigSubstitute(FcConfig *config, FcPattern *p, FcMatchKind kind)
     
    915847}
    916848
    917 fcExport FcResult FcPatternGetInteger(const FcPattern *p, const char *object, int id, int *i)
    918 {
    919   if (!p)
    920     return FcResultNoMatch;
    921 
    922   if (id) // we don't support more than one property of the same type
    923     return FcResultNoId;
    924 
    925   if (strcmp(object, FC_INDEX)==0)
    926   {
    927     *i = p->pFontDesc->lFontIndex;
    928     return FcResultMatch;
    929   }
    930   if (strcmp(object, FC_SLANT)==0)
    931   {
    932     *i = p->slant;
    933     return FcResultMatch;
    934   }
    935   if (strcmp(object, FC_WEIGHT)==0)
    936   {
    937     *i = p->weight;
    938     return FcResultMatch;
    939   }
    940   if (strcmp(object, FC_HINT_STYLE)==0)
    941   {
    942     *i = p->hintstyle;
    943     return FcResultMatch;
    944   }
    945   if (strcmp(object, FC_RGBA)==0)
    946   {
    947     *i = p->rgba;
    948     return FcResultMatch;
    949   }
    950   return FcResultNoMatch;
    951 }
    952 
    953 fcExport FcResult FcPatternGetString(const FcPattern *p, const char *object, int id, FcChar8 **s)
    954 {
    955   if (!p)
    956     return FcResultNoMatch;
    957 
    958   if (id) // we don't support more than one property of the same type
    959     return FcResultNoId;
    960 
    961   if (strcmp(object, FC_FILE)==0)
    962   {
    963     *s = (FcChar8 *)p->pFontDesc->achFileName;
    964     return FcResultMatch;
    965   }
    966 
    967   if (strcmp(object, FC_FAMILY)==0)
    968   {
    969     if (p->family)
    970     {
    971       *s = (FcChar8 *)p->family;
    972       return FcResultMatch;
    973     } else
    974     if (p->pFontDesc)
    975     {
    976       *s = (FcChar8 *)p->pFontDesc->achFamilyName;
    977       return FcResultMatch;
    978     }
    979   }
    980 
    981   if (strcmp(object, FC_STYLE)==0)
    982   {
    983     if (p->style)
    984     {
    985       *s = (FcChar8 *)p->style;
    986       return FcResultMatch;
    987     } else
    988     if (p->pFontDesc)
    989     {
    990       *s = (FcChar8 *)p->pFontDesc->achStyleName;
    991       return FcResultMatch;
    992     }
    993   }
    994 
    995   return FcResultNoMatch;
    996 }
    997 
    998 #ifndef FC_EMBEDDED_BITMAP
    999 #define FC_EMBEDDED_BITMAP "embeddedbitmap"
    1000 #endif
    1001 
    1002 fcExport FcResult FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
    1003 {
    1004   if (!p)
    1005     return FcResultNoMatch;
    1006 
    1007   if (id) // we don't support more than one property of the same type
    1008     return FcResultNoId;
    1009 
    1010   if (strcmp(object, FC_HINTING)==0)
    1011   {
    1012     *b = p->hinting;
    1013     return FcResultMatch;
    1014   }
    1015   if (strcmp(object, FC_ANTIALIAS)==0)
    1016   {
    1017     *b = p->antialias;
    1018     return FcResultMatch;
    1019   }
    1020   if (strcmp(object, FC_EMBOLDEN)==0)
    1021   {
    1022     *b = p->embolden;
    1023     return FcResultMatch;
    1024   }
    1025   if (strcmp(object, FC_VERTICAL_LAYOUT)==0)
    1026   {
    1027     *b = p->verticallayout;
    1028     return FcResultMatch;
    1029   }
    1030   if (strcmp(object, FC_AUTOHINT)==0)
    1031   {
    1032     *b = p->autohint;
    1033     return FcResultMatch;
    1034   }
    1035   if (strcmp(object, FC_EMBEDDED_BITMAP)==0)
    1036   {
    1037     *b = p->bitmap;
    1038     return FcResultMatch;
    1039   }
    1040   return FcResultNoMatch;
    1041 }
    1042 
    1043 fcExport FcResult FcPatternGet(const FcPattern *p, const char *object, int id, FcValue *v)
    1044 {
    1045   if (!v)
    1046     return FcResultNoMatch;
    1047 
    1048   if (id) // we don't support more than one property of the same type
    1049     return FcResultNoId;
    1050 
    1051   if (strcmp(object, FC_ANTIALIAS)==0)
    1052   {
    1053     v->type = FcTypeBool;
    1054     v->u.b  = FcTrue;
    1055     return FcResultMatch;
    1056   }
    1057   return FcResultNoMatch;
    1058 }
    1059 
    1060 
    1061 fcExport FcBool FcPatternAddInteger(FcPattern *p, const char *object, int i)
    1062 {
    1063   if (!p)
    1064     return FcFalse;
    1065 
    1066   if (strcmp(object, FC_INDEX)==0)
    1067   {
    1068     p->pFontDesc->lFontIndex = i;
    1069     return FcTrue;
    1070   }
    1071   if (strcmp(object, FC_SLANT)==0)
    1072   {
    1073     p->slant = i;
    1074     return FcTrue;
    1075   }
    1076   if (strcmp(object, FC_WEIGHT)==0)
    1077   {
    1078     p->weight = i;
    1079     return FcTrue;
    1080   }
    1081   if (strcmp(object, FC_HINT_STYLE)==0)
    1082   {
    1083     p->hintstyle = i;
    1084     return FcTrue;
    1085   }
    1086   if (strcmp(object, FC_RGBA)==0)
    1087   {
    1088     p->rgba = i;
    1089     return FcTrue;
    1090   }
    1091 
    1092   return FcFalse;
    1093 }
    1094 
    1095 fcExport FcBool FcPatternAddDouble(FcPattern *p, const char *object, double d)
    1096 {
    1097   if (!p)
    1098     return FcFalse;
    1099 
    1100   if (strcmp(object, FC_PIXEL_SIZE)==0)
    1101   {
    1102     p->pixelsize = d;
    1103     return FcTrue;
    1104   }
    1105   if (strcmp(object, FC_SIZE)==0)
    1106   {
    1107     p->size = d;
    1108     return FcTrue;
    1109   }
    1110 
    1111   return FcFalse;
    1112 }
    1113 
    1114 fcExport FcResult FcPatternGetDouble(const FcPattern *p, const char *object, int id, double *d)
    1115 {
    1116   if (!p)
    1117     return FcResultNoMatch;
    1118 
    1119   if (id) // we don't support more than one property of the same type
    1120     return FcResultNoId;
    1121 
    1122   if (strcmp(object, FC_PIXEL_SIZE)==0)
    1123   {
    1124     *d = p->pixelsize;
    1125     return FcResultMatch;
    1126   }
    1127   if (strcmp(object, FC_SIZE)==0)
    1128   {
    1129     *d = p->size;
    1130     return FcResultMatch;
    1131   }
    1132 
    1133   return FcResultNoMatch;
    1134 }
    1135 
    1136 fcExport FcBool FcPatternAddString(FcPattern *p, const char *object, const FcChar8 *s)
    1137 {
    1138   if (!p)
    1139     return FcFalse;
    1140 
    1141   if (strcmp(object, FC_FAMILY)==0)
    1142   {
    1143     if (p->family)
    1144     {
    1145       free(p->family); p->family = NULL;
    1146     }
    1147     p->family = strdup((const char *)s);
    1148     return FcTrue;
    1149   }
    1150 
    1151   if (strcmp(object, FC_STYLE)==0)
    1152   {
    1153     if (p->style)
    1154     {
    1155       free(p->style); p->style = NULL;
    1156     }
    1157     p->style = strdup((const char *)s);
    1158     return FcTrue;
    1159   }
    1160 
    1161   if (strcmp(object, FC_LANG)==0)
    1162   {
    1163     if (p->lang)
    1164     {
    1165       free(p->lang); p->lang = NULL;
    1166     }
    1167     p->lang = strdup((const char *)s);
    1168     return FcTrue;
    1169   }
    1170 
    1171   return FcFalse;
    1172 }
    1173 
    1174 fcExport FcBool FcPatternAddBool(FcPattern *p, const char *object, FcBool b)
    1175 {
    1176   if (!p)
    1177     return FcFalse;
    1178 
    1179   if (strcmp(object, FC_HINTING)==0)
    1180   {
    1181     p->hinting = b;
    1182     return FcTrue;
    1183   }
    1184   if (strcmp(object, FC_ANTIALIAS)==0)
    1185   {
    1186     p->antialias = b;
    1187     return FcTrue;
    1188   }
    1189   if (strcmp(object, FC_EMBOLDEN)==0)
    1190   {
    1191     p->embolden = b;
    1192     return FcTrue;
    1193   }
    1194   if (strcmp(object, FC_VERTICAL_LAYOUT)==0)
    1195   {
    1196     p->verticallayout = b;
    1197     return FcTrue;
    1198   }
    1199   if (strcmp(object, FC_AUTOHINT)==0)
    1200   {
    1201     p->autohint = b;
    1202     return FcTrue;
    1203   }
    1204   if (strcmp(object, FC_EMBEDDED_BITMAP)==0)
    1205   {
    1206     p->bitmap = b;
    1207     return FcTrue;
    1208   }
    1209 
    1210   return FcFalse;
    1211 }
    1212 
    1213 fcExport FcBool FcPatternAddFTFace(FcPattern *p, const char *object, const FT_Face f)
    1214 {
    1215   if (!p)
    1216     return FcFalse;
    1217 
    1218   if (strcmp(object, FC_FT_FACE)==0)
    1219   {
    1220     p->face = f;
    1221     return FcTrue;
    1222   }
    1223 
    1224   return FcFalse;
    1225 }
    1226 
    1227 fcExport FcResult FcPatternGetFTFace(const FcPattern *p, const char *object, int id, FT_Face *f)
    1228 {
    1229   if (!p)
    1230     return FcResultNoMatch;
    1231 
    1232   if (id) // we don't support more than one property of the same type
    1233     return FcResultNoId;
    1234 
    1235   if (strcmp(object, FC_FT_FACE)==0 && p && p->face)
    1236   {
    1237     *f = p->face;
    1238     return FcResultMatch;
    1239   }
    1240 
    1241   return FcResultNoMatch;
    1242 }
    1243 
    1244 
    1245 #define DEFAULT_SERIF_FONT          "Times New Roman"
    1246 #define DEFAULT_SERIF_FONTJA       "Times New Roman WT J"
    1247 #define DEFAULT_SANSSERIF_FONT      "Helvetica"
    1248 #define DEFAULT_MONOSPACED_FONT     "Courier"
    1249 #define DEFAULT_SYMBOL_FONT         "Symbol Set"
    1250849
    1251850fcExport FcPattern *FcFontMatch(FcConfig *config, FcPattern *p, FcResult *result)
     
    1279878         p->family, p->weight, p->slant, p->pixelsize);
    1280879#endif
     880
     881  if (!p->outline)
     882  {
     883#ifdef MATCH_DEBUG
     884    printf("Only outline fonts are supported!!!\n");
     885#endif
     886    if (result)
     887      *result = FcResultNoMatch;
     888    return NULL;
     889  }
    1281890
    1282891  // first try to match the font using an exact match of the family name
     
    1315924                     (stristr(pFont->achStyleName, "HEAVY")==NULL)    &&
    1316925                     (stristr(pFont->achStyleName, "BLACK")==NULL));
    1317       }
    1318 
    1319       if ( p->slant > FC_SLANT_ROMAN )
     926      }
     927
     928      if ( p->slant > FC_SLANT_ITALIC )
     929      {
     930        // Looking for an OBLIQUE font (fall back to ITALIC if necessary)
     931        bSlantOk = (stristr(pFont->achStyleName, "OBLIQUE")!=NULL);
     932        if (!bSlantOk)
     933           bSlantOk = (stristr(pFont->achStyleName, "ITALIC")!=NULL);
     934      } else if ( p->slant > FC_SLANT_ROMAN )
    1320935      {
    1321936        // Looking for an ITALIC font
    1322937        bSlantOk = (stristr(pFont->achStyleName, "ITALIC")!=NULL);
    1323       } else if ( p->slant > FC_SLANT_OBLIQUE )
    1324       {
    1325         // Looking for an OBLIQUE font
    1326         bSlantOk = (stristr(pFont->achStyleName, "OBLIQUE")!=NULL);
    1327938      } else
    1328939      {
     
    1388999      // we want to match Times New Roman which has an additional trailing
    13891000      // space in the name...
    1390       achKeySpace = malloc(strlen(achKey) +2);
     1001      achKeySpace = malloc(strlen(achKey) + 2);
    13911002      strcpy(achKeySpace, achKey);
    13921003      strcat(achKeySpace, " ");
     
    14011012         (stricmp( p->family, "ZAPF DINGBATS" ) == 0 )))
    14021013    {
    1403       strncpy(achKey, "DejaVu Sans", sizeof(achKey));
     1014      strncpy(achKey, DEFAULT_DINGBATS_FONT, sizeof(achKey));
    14041015    }
    14051016
     
    14251036        }
    14261037
    1427         if ( p->slant > FC_SLANT_ROMAN )
     1038        if ( p->slant > FC_SLANT_ITALIC )
     1039        {
     1040          // Looking for an OBLIQUE font (fall back to ITALIC if necessary)
     1041          bSlantOk = (stristr(pFont->achStyleName, "OBLIQUE")!=NULL);
     1042          if (!bSlantOk)
     1043             bSlantOk = (stristr(pFont->achStyleName, "ITALIC")!=NULL);
     1044        } else if ( p->slant > FC_SLANT_ROMAN )
    14281045        {
    14291046          // Looking for an ITALIC font
    14301047          bSlantOk = (stristr(pFont->achStyleName, "ITALIC")!=NULL);
    1431         } else if ( p->slant > FC_SLANT_OBLIQUE )
    1432         {
    1433           // Looking for an OBLIQUE font
    1434           bSlantOk = (stristr(pFont->achStyleName, "OBLIQUE")!=NULL);
    14351048        } else
    14361049        {
     
    14851098        }
    14861099
    1487         if ( p->slant > FC_SLANT_ROMAN )
     1100        if ( p->slant > FC_SLANT_ITALIC )
     1101        {
     1102          // Looking for an OBLIQUE font (fall back to ITALIC if necessary)
     1103          bSlantOk = (stristr(pFont->achStyleName, "OBLIQUE")!=NULL);
     1104          if (!bSlantOk)
     1105             bSlantOk = (stristr(pFont->achStyleName, "ITALIC")!=NULL);
     1106        } else if ( p->slant > FC_SLANT_ROMAN )
    14881107        {
    14891108          // Looking for an ITALIC font
    14901109          bSlantOk = (stristr(pFont->achStyleName, "ITALIC")!=NULL);
    1491         } else if ( p->slant > FC_SLANT_OBLIQUE )
    1492         {
    1493           // Looking for an OBLIQUE font
    1494           bSlantOk = (stristr(pFont->achStyleName, "OBLIQUE")!=NULL);
    14951110        } else
    14961111        {
     
    15681183}
    15691184
    1570 fcExport FcBool FcPatternDel(FcPattern *p, const char *object)
    1571 {
    1572   // This is a stub.
    1573   return FcTrue;
    1574 }
    15751185
    15761186fcExport FcObjectSet *FcObjectSetBuild(const char *first, ...)
     
    17071317}
    17081318
    1709 fcExport FcFontSet *FcFontSort(FcConfig *config, FcPattern *p, FcBool trim, FcCharSet **csp, FcResult *result)
    1710 {
    1711   // This is a stub.
    1712 
    1713   // I currently have no idea what kind of sorting to do here,
    1714   // what would be the best for Mozilla, so I simply won't sort it. :)
    1715   // Use the same code as for FcFontList().
    1716   // enhanced for poppler usage.
    1717   // according to docs fcfontsort brings back the fonts matching the pattern. so we use FcFontMatch
    1718   // if FcFontMatch has no font found we try the default ones
     1319fcExport FcFontSet *FcFontSort(FcConfig *config, FcPattern *p, FcBool trim,
     1320                               FcCharSet **csp, FcResult *result)
     1321{
     1322  // Enhanced for poppler usage.  According to docs fcfontsort brings back
     1323  // the fonts matching the pattern, so we use FcFontMatch  if FcFontMatch
     1324  // has no font found we try the default ones
    17191325
    17201326  *result = FcResultMatch;
     
    17301336     if (p->lang && (stristr(p->lang, "JA") != NULL))
    17311337        {
    1732            FcPatternAddString(pDup, FC_FAMILY, DEFAULT_SERIF_FONTJA);
     1338           FcPatternAddString(pDup, FC_FAMILY, (const FcChar8 *)DEFAULT_SERIF_FONTJA);
    17331339        }
    17341340        else
    17351341        {
    1736            FcPatternAddString(pDup, FC_FAMILY, DEFAULT_SERIF_FONT);
     1342           FcPatternAddString(pDup, FC_FAMILY, (const FcChar8 *)DEFAULT_SERIF_FONT);
    17371343        }
    17381344     newPattern = FcFontMatch(config, pDup, result);
     
    17421348  if (newPattern && fs)
    17431349  {
    1744     FcFontSetAdd(fs, newPattern); 
     1350    FcFontSetAdd(fs, newPattern);
    17451351  }
    17461352  return fs;
     
    17891395}
    17901396
    1791 fcExport FcBool FcPatternEqual(const FcPattern *pa, const FcPattern *pb)
    1792 {
    1793   /* point to the same pattern */
    1794   if (pa == pb) {
    1795     return FcTrue;
    1796   }
    1797 
    1798   /* one of the patterns is invalid */
    1799   if (!pa || !pb) {
    1800     return FcFalse;
    1801   }
    1802 
    1803   /* check string properties */
    1804   /* If the string have the same address or they are both NULL it would mean
    1805    * we had equal strings. If that is not the case we have to test if only
    1806    * one of them is NULL and finally how they compare.
    1807    */
    1808   if (!(pa->family == pb->family || (!pa->family && !pb->family))
    1809       && (!pa->family || !pb->family || stricmp(pa->family, pb->family) != 0))
    1810   {
    1811     return FcFalse;
    1812   }
    1813 
    1814   if (!(pa->style == pb->style || (!pa->style && !pb->style))
    1815       && (!pa->style || !pb->style || stricmp(pa->style, pb->style) != 0))
    1816   {
    1817     return FcFalse;
    1818   }
    1819 
    1820   /* check int properties */
    1821   if (pa->weight != pb->weight ||
    1822       pa->slant != pb->slant ||
    1823       pa->spacing != pb->spacing ||
    1824       pa->hintstyle != pb->hintstyle ||
    1825       pa->rgba != pb->rgba)
    1826   {
    1827     return FcFalse;
    1828   }
    1829 
    1830   /* check double properties, better not compare directly */
    1831   if (fabs(pa->pixelsize-pb->pixelsize) > DBL_EPSILON ||
    1832       fabs(pa->size-pb->size) > DBL_EPSILON)
    1833   {
    1834     return FcFalse;
    1835   }
    1836 
    1837   /* check bool properties, just direct comparison as for ints */
    1838   if (pa->hinting != pb->hinting ||
    1839       pa->antialias != pb->antialias ||
    1840       pa->embolden != pb->embolden ||
    1841       pa->verticallayout != pb->verticallayout ||
    1842       pa->autohint != pb->autohint ||
    1843       pa->bitmap != pb->bitmap)
    1844   {
    1845     return FcFalse;
    1846   }
    1847 
    1848   /* if we haven't returned by now then everything is equal */
    1849   return FcTrue;
    1850 }
    18511397
    18521398fcExport FcBool FcInitReinitialize(void)
     
    19021448}
    19031449
    1904 /*
    1905  * test langset for language support
    1906  * FcLangSetHasLang checks whether ls supports lang. If ls has a matching
    1907  * language and territory pair, this function returns FcLangEqual. If ls has
    1908  * a matching language but differs in which territory that language is for,
    1909  * this function returns FcLangDiffentTerritory. If ls has no matching
    1910  * language, this function returns FcLangDifferentLang.
    1911  */
    1912 fcExport FcLangResult FcLangSetHasLang(const FcLangSet *ls, const FcChar8 *lang)
    1913 {
    1914   // Stub
    1915   return FcLangEqual;
    1916 }
    19171450
    19181451/*
     
    19481481}
    19491482
    1950 /*
    1951  * Increment pattern reference count
    1952  * Add another reference to p. Patterns are freed only when the reference
    1953  * count reaches zero.
    1954  */
    1955 fcExport void FcPatternReference(FcPattern *p)
    1956 {
    1957   if (!p)
    1958     return;
    1959 
    1960   p->ref++;
    1961 }
    1962 
    1963 /*
    1964  * Copy a pattern
    1965  * Copy a pattern, returning a new pattern that matches p. Each pattern may be
    1966  * modified without affecting the other.
    1967  */
    1968 fcExport FcPattern *FcPatternDuplicate(const FcPattern *p)
    1969 {
    1970   FcPattern *pResult = malloc(sizeof(FcPattern));
    1971   if (pResult)
    1972   {
    1973     /* for a start, copy all entries */
    1974     memcpy(pResult, p, sizeof(FcPattern));
    1975 
    1976     /* now correct the pointers */
    1977     if (p->family)
    1978       pResult->family = strdup(p->family);
    1979     if (p->style)
    1980       pResult->style = strdup(p->style);
    1981     if (p->lang)
    1982       pResult->lang = strdup(p->lang);
    1983 
    1984     /* this is doubtful, but for now set the reference to 1,
    1985      * so that the duplicate pattern is treated like a new one
    1986      */
    1987     pResult->ref = 1;
    1988   }
    1989   return pResult;
    1990 }
    1991 
    1992 FcPattern *
    1993 FcPatternBuild (FcPattern *p, ...)
    1994 {
    1995     va_list     va;
    1996 
    1997     // according to fontconfig FcInit() is not needed in a app, so make sure its called
    1998     if (!pConfig)
    1999     {
    2000        FcInit();
    2001     }
    2002 
    2003     va_start (va, p);
    2004     FcPatternVapBuild (p, p, va);
    2005     va_end (va);
    2006     return p;
    2007 }
    2008 
    2009 FcBool
    2010 FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append)
    2011 {
    2012    FcBool rc = FcTrue;
    2013                            
    2014    switch (value.type)
    2015    {
    2016         case FcTypeInteger:
    2017             rc = FcPatternAddInteger(p,  object, value.u.i);
    2018             break;
    2019         case FcTypeDouble:
    2020             rc = FcPatternAddDouble(p,  object, value.u.d);
    2021             break;
    2022         case FcTypeString:
    2023             rc = FcPatternAddString(p,  object, value.u.s);
    2024             break;
    2025         case FcTypeBool:
    2026             rc = FcPatternAddBool(p,  object, value.u.b);
    2027             break;
    2028         case FcTypeFTFace:
    2029             rc = FcPatternAddFTFace(p,  object, value.u.f);
    2030             break;
    2031     }
    2032         return rc;     
    2033 
    2034 }
  • trunk/poppler/fc-emulate-os2/fontconfig/fontconfig.h

    r484 r497  
    4040
    4141#define FC_MAJOR        2
    42 #define FC_MINOR        3
    43 #define FC_REVISION     2
     42#define FC_MINOR        8
     43#define FC_REVISION     0
    4444
    4545#define FC_VERSION      ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION))
     
    5555 */
    5656
    57 #define FC_CACHE_VERSION    "1"
     57#define FC_CACHE_VERSION    "3"
    5858
    5959#define FcTrue          1
     
    9797#define FC_FONTFORMAT       "fontformat"        /* String */
    9898#define FC_EMBOLDEN         "embolden"          /* Bool - true if emboldening needed*/
    99 
     99#define FC_EMBEDDED_BITMAP  "embeddedbitmap"    /* Bool - true to enable embedded bitmaps */
     100#define FC_DECORATIVE       "decorative"        /* Bool - true if style is a decorative variant */
     101#define FC_LCD_FILTER       "lcdfilter"         /* Int */
     102
     103#define FC_CACHE_SUFFIX             ".cache-"FC_CACHE_VERSION
    100104#define FC_DIR_CACHE_FILE           "fonts.cache-"FC_CACHE_VERSION
    101105#define FC_USER_CACHE_FILE          ".fonts.cache-"FC_CACHE_VERSION
     
    121125#define FC_WEIGHT_BLACK             210
    122126#define FC_WEIGHT_HEAVY             FC_WEIGHT_BLACK
     127#define FC_WEIGHT_EXTRABLACK        215
     128#define FC_WEIGHT_ULTRABLACK        FC_WEIGHT_EXTRABLACK
    123129
    124130#define FC_SLANT_ROMAN              0
     
    154160#define FC_HINT_MEDIUM      2
    155161#define FC_HINT_FULL        3
     162
     163/* LCD filter */
     164#define FC_LCD_NONE         0
     165#define FC_LCD_DEFAULT      1
     166#define FC_LCD_LIGHT        2
     167#define FC_LCD_LEGACY       3
    156168 
    157169typedef enum _FcType {
     
    233245
    234246typedef enum _FcLangResult {
    235     FcLangEqual, FcLangDifferentCountry, FcLangDifferentLang
     247    FcLangEqual = 0,
     248    FcLangDifferentCountry = 1,
     249    FcLangDifferentTerritory = 1,
     250    FcLangDifferentLang = 2
    236251} FcLangResult;
    237252
     
    265280_FCFUNCPROTOBEGIN
    266281
    267 FcBool
    268 FcDirCacheValid (const FcChar8 *cache_file);
    269 
    270282/* fcblanks.c */
    271283FcBlanks *
     
    280292FcBool
    281293FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4);
     294
     295/* fccache.c */
     296
     297FcBool
     298FcDirCacheValid (const FcChar8 *cache_file);
    282299
    283300/* fccfg.c */
  • trunk/poppler/mypoppler/config.h

    r477 r497  
    1717/* #undef ENABLE_LIBPNG */
    1818
     19/* Build against libtiff. */
     20/* #undef ENABLE_LIBTIFF */
     21
    1922/* Do not hardcode the library location */
    2023/* #undef ENABLE_RELOCATABLE */
     
    6366/* #undef HAVE_LIBOPENJPEG */
    6467
     68/* Define to 1 if you have the `tiff' library (-ltiff). */
     69/* #undef HAVE_LIBTIFF */
     70
    6571/* Define to 1 if you have the `z' library (-lz). */
    6672/* #undef HAVE_LIBZ */
     
    122128#define HAVE_SYS_TYPES_H 1
    123129
     130/* Define to 1 if you have the <tiffio.h> header file. */
     131/* #undef HAVE_TIFFIO_H */
     132
    124133/* Define to 1 if you have the <unistd.h> header file. */
    125134#define HAVE_UNISTD_H 1
     
    151160
    152161/* Define to the full name and version of this package. */
    153 #define PACKAGE_STRING "poppler 0.16.3"
     162#define PACKAGE_STRING "poppler 0.18.1"
    154163
    155164/* Define to the one symbol short name of this package. */
     
    160169
    161170/* Define to the version of this package. */
    162 #define PACKAGE_VERSION "0.16.3"
     171#define PACKAGE_VERSION "0.18.1"
    163172
    164173/* Poppler data dir */
     
    167176/* Support for curl based doc builder is compiled in. */
    168177/* #undef POPPLER_HAS_CURL_SUPPORT */
    169 
    170 /* Have GDK */
    171 /* #undef POPPLER_WITH_GDK */
    172178
    173179/* Define to necessary symbol if this constant uses a non-standard name on
     
    191197
    192198/* Version number of package */
    193 #define VERSION "0.16.3"
     199#define VERSION "0.18.1"
    194200
    195201/* Use fontconfig font configuration backend */
  • trunk/poppler/mypoppler/fofi/FoFiBase.cc

    r257 r497  
    1515//
    1616// Copyright (C) 2008 Ed Avis <eda@waniasset.com>
     17// Copyright (C) 2011 Jim Meyering <jim@meyering.net>
    1718//
    1819// To see a description of the changes please see the Changelog file that
     
    6364  }
    6465  n = (int)ftell(f);
     66  if (n < 0) {
     67    error(-1, "Cannot determine length of '%s'", fileName);
     68    fclose(f);
     69    return NULL;
     70  }
    6571  if (fseek(f, 0, SEEK_SET) != 0) {
    6672    error(-1, "Cannot seek to start of '%s'", fileName);
  • trunk/poppler/mypoppler/fofi/FoFiTrueType.h

    r257 r497  
    1616// Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
    1717// Copyright (C) 2007 Koji Otani <sho@bbr.jp>
     18// Copyright (C) 2011 Albert Astals Cid <aacid@kde.org>
    1819//
    1920// To see a description of the changes please see the Changelog file that
     
    2930#endif
    3031
     32#include "stddef.h"
    3133#include "goo/gtypes.h"
    3234#include "FoFiBase.h"
  • trunk/poppler/mypoppler/goo/GooTimer.h

    r461 r497  
    88// Copyright 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
    99// Copyright 2010 Hib Eris <hib@hiberis.nl>
     10// Copyright 2011 Albert Astals cid <aacid@kde.org>
    1011// Inspired by gtimer.c in glib, which is Copyright 2000 by the GLib Team
    1112//
     
    1920#endif
    2021
     22#include "poppler/poppler-config.h"
    2123#include "gtypes.h"
    2224#ifdef HAVE_GETTIMEOFDAY
  • trunk/poppler/mypoppler/goo/ImgWriter.h

    r461 r497  
    66//
    77// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
    8 // Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
     8// Copyright (C) 2009, 2011 Albert Astals Cid <aacid@kde.org>
    99// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
    1010// Copyright (C) 2010 Brian Cameron <brian.cameron@oracle.com>
     11// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
    1112//
    1213//========================================================================
     
    1516#define IMGWRITER_H
    1617
    17 #include <config.h>
    1818#include <stdio.h>
    1919       
     
    2828               
    2929                virtual bool close() = 0;
     30                virtual bool supportCMYK() { return false; }
    3031};
    3132
  • trunk/poppler/mypoppler/goo/JpegWriter.cc

    r461 r497  
    88// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
    99// Copyright (C) 2010 Harry Roberts <harry.roberts@midnight-labs.org>
     10// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
    1011//
    1112//========================================================================
     
    2829}
    2930
    30 JpegWriter::JpegWriter(int q, bool p)
    31 : progressive(p), quality(q)
     31JpegWriter::JpegWriter(int q, bool p, J_COLOR_SPACE cm)
     32: progressive(p), quality(q), colorMode(cm)
    3233{
    3334}
    3435
    35 JpegWriter::JpegWriter()
    36 : progressive(false), quality(-1)
     36JpegWriter::JpegWriter(J_COLOR_SPACE cm)
     37: progressive(false), quality(-1), colorMode(cm)
    3738{
    3839}
     
    6263        cinfo.X_density = hDPI;
    6364        cinfo.Y_density = vDPI;
    64         cinfo.input_components = 3;     /* # of color components per pixel */
    65         cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
     65        cinfo.in_color_space = colorMode; /* colorspace of input image */
     66        /* # of color components per pixel */
     67        switch (colorMode) {
     68                case JCS_GRAYSCALE:
     69                        cinfo.input_components = 1;     
     70                        break;
     71                case JCS_RGB:
     72                        cinfo.input_components = 3;     
     73                        break;
     74                case JCS_CMYK:
     75                        cinfo.input_components = 4;     
     76                        break;
     77                default:
     78                        return false;
     79        }
    6680        jpeg_set_defaults(&cinfo);
     81        if (cinfo.in_color_space == JCS_CMYK) {
     82                jpeg_set_colorspace(&cinfo, JCS_YCCK);
     83                cinfo.write_JFIF_header = TRUE;
     84        }
    6785       
    6886        // Set quality
     
    84102bool JpegWriter::writePointers(unsigned char **rowPointers, int rowCount)
    85103{
     104        if (colorMode == JCS_CMYK) {
     105                for (int y = 0; y < rowCount; y++) {
     106                        unsigned char *row = rowPointers[y];
     107                        for (unsigned int x = 0; x < cinfo.image_width; x++) {
     108                                for (int n = 0; n < 4; n++) {
     109                                        *row = 0xff - *row;
     110                                        row++;
     111                                }
     112                        }
     113                }
     114        }
    86115        // Write all rows to the file
    87116        jpeg_write_scanlines(&cinfo, rowPointers, rowCount);
     
    90119}
    91120
    92 bool JpegWriter::writeRow(unsigned char **row)
     121bool JpegWriter::writeRow(unsigned char **rowPointer)
    93122{
     123        if (colorMode == JCS_CMYK) {
     124                unsigned char *row = rowPointer[0];
     125                for (unsigned int x = 0; x < cinfo.image_width; x++) {
     126                        for (int n = 0; n < 4; n++) {
     127                                *row = 0xff - *row;
     128                                row++;
     129                        }
     130                }
     131        }
    94132        // Write the row to the file
    95         jpeg_write_scanlines(&cinfo, row, 1);
     133        jpeg_write_scanlines(&cinfo, rowPointer, 1);
    96134       
    97135        return true;
  • trunk/poppler/mypoppler/goo/JpegWriter.h

    r461 r497  
    1010// Copyright (C) 2010 Harry Roberts <harry.roberts@midnight-labs.org>
    1111// Copyright (C) 2010 Brian Cameron <brian.cameron@oracle.com>
     12// Copyright (C) 2011 Albert Astals Cid <aacid@kde.org>
     13// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
    1214//
    1315//========================================================================
     
    1618#define JPEGWRITER_H
    1719
    18 #include <config.h>
     20#include "poppler/poppler-config.h"
    1921
    2022#ifdef ENABLE_LIBJPEG
     
    3032{
    3133        public:
    32                 JpegWriter(int quality, bool progressive);
    33                 JpegWriter();
     34                JpegWriter(int quality, bool progressive, J_COLOR_SPACE colorMode = JCS_RGB);
     35                JpegWriter(J_COLOR_SPACE colorMode = JCS_RGB);
    3436                ~JpegWriter();
    3537               
     
    4042               
    4143                bool close();
     44                bool supportCMYK() { return colorMode == JCS_CMYK; }
    4245       
    4346        private:
    4447                bool progressive;
    4548                int quality;
     49                J_COLOR_SPACE colorMode;
    4650                struct jpeg_compress_struct cinfo;
    4751                struct jpeg_error_mgr jerr;
  • trunk/poppler/mypoppler/goo/PNGWriter.cc

    r470 r497  
    99// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
    1010// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
    11 // Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
     11// Copyright (C) 2010, 2011 Adrian Johnson <ajohnson@redneon.com>
    1212// Copyright (C) 2011 Thomas Klausner <wiz@danbala.tuwien.ac.at>
    1313//
     
    1919
    2020#include <zlib.h>
     21#include <stdlib.h>
    2122
    2223#include "poppler/Error.h"
     24#include "goo/gmem.h"
    2325
    24 PNGWriter::PNGWriter()
     26PNGWriter::PNGWriter(Format formatA) : format(formatA)
    2527{
     28        icc_data = NULL;
     29        icc_data_size = 0;
     30        icc_name = NULL;
     31        sRGB_profile = false;
    2632}
    2733
     
    3036        /* cleanup heap allocation */
    3137        png_destroy_write_struct(&png_ptr, &info_ptr);
     38        if (icc_data) {
     39                gfree(icc_data);
     40                free(icc_name);
     41        }
     42}
     43
     44void PNGWriter::setICCProfile(const char *name, unsigned char *data, int size)
     45{
     46        icc_data = (unsigned char *)gmalloc(size);
     47        memcpy(icc_data, data, size);
     48        icc_data_size = size;
     49        icc_name = strdup(name);
     50}
     51
     52void PNGWriter::setSRGBProfile()
     53{
     54        sRGB_profile = true;
    3255}
    3356
    3457bool PNGWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
    3558{
     59  /* libpng changed the png_set_iCCP() prototype in 1.5.0 */
     60#if PNG_LIBPNG_VER < 10500
     61        png_charp icc_data_ptr = (png_charp)icc_data;
     62#else
     63        png_const_bytep icc_data_ptr = (png_const_bytep)icc_data;
     64#endif
     65
    3666        /* initialize stuff */
    3767        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
     
    6292        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
    6393
    64         png_byte bit_depth = 8;
    65         png_byte color_type = PNG_COLOR_TYPE_RGB;
     94        // Silence silly gcc
     95        png_byte bit_depth = -1;
     96        png_byte color_type = -1;
     97        switch (format) {
     98                case RGB:
     99                        bit_depth = 8;
     100                        color_type = PNG_COLOR_TYPE_RGB;
     101                        break;
     102                case RGBA:
     103                        bit_depth = 8;
     104                        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
     105                        break;
     106                case GRAY:
     107                        bit_depth = 8;
     108                        color_type = PNG_COLOR_TYPE_GRAY;
     109                        break;
     110                case MONOCHROME:
     111                        bit_depth = 1;
     112                        color_type = PNG_COLOR_TYPE_GRAY;
     113                        break;
     114        }
    66115        png_byte interlace_type = PNG_INTERLACE_NONE;
    67116
    68117        png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    69118
    70         // PNG_RESOLUTION_UNKNOWN means dots per inch
    71         png_set_pHYs(png_ptr, info_ptr, hDPI, vDPI, PNG_RESOLUTION_UNKNOWN);
     119        png_set_pHYs(png_ptr, info_ptr, hDPI/0.0254, vDPI/0.0254, PNG_RESOLUTION_METER);
     120
     121        if (icc_data)
     122                png_set_iCCP(png_ptr, info_ptr, icc_name, PNG_COMPRESSION_TYPE_BASE, icc_data_ptr, icc_data_size);
     123        else if (sRGB_profile)
     124                png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_RELATIVE);
    72125
    73126        png_write_info(png_ptr, info_ptr);
     
    76129                return false;
    77130        }
    78        
     131
     132        // pack 1 pixel/byte rows into 8 pixels/byte
     133        if (format == MONOCHROME)
     134                png_set_packing(png_ptr);
     135
    79136        return true;
    80137}
  • trunk/poppler/mypoppler/goo/PNGWriter.h

    r461 r497  
    77// Copyright (C) 2009 Warren Toomey <wkt@tuhs.org>
    88// Copyright (C) 2009 Shen Liang <shenzhuxi@gmail.com>
    9 // Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
     9// Copyright (C) 2009, 2011 Albert Astals Cid <aacid@kde.org>
    1010// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
    11 // Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
     11// Copyright (C) 2010, 2011 Adrian Johnson <ajohnson@redneon.com>
    1212//
    1313//========================================================================
     
    1616#define PNGWRITER_H
    1717
    18 #include <config.h>
     18#include "poppler/poppler-config.h"
    1919
    2020#ifdef ENABLE_LIBPNG
     
    2727{
    2828        public:
    29                 PNGWriter();
     29
     30                /* RGB        - 3 bytes/pixel
     31                 * RGBA       - 4 bytes/pixel
     32                 * GRAY       - 1 byte/pixel
     33                 * MONOCHROME - 1 byte/pixel. PNGWriter will bitpack to 8 pixels/byte
     34                 */
     35                enum Format { RGB, RGBA, GRAY, MONOCHROME };
     36
     37                PNGWriter(Format format = RGB);
    3038                ~PNGWriter();
     39
     40                void setICCProfile(const char *name, unsigned char *data, int size);
     41                void setSRGBProfile();
     42
    3143               
    3244                bool init(FILE *f, int width, int height, int hDPI, int vDPI);
     
    3850       
    3951        private:
     52                Format format;
    4053                png_structp png_ptr;
    4154                png_infop info_ptr;
     55                unsigned char *icc_data;
     56                int icc_data_size;
     57                char *icc_name;
     58                bool sRGB_profile;
    4259};
    4360
  • trunk/poppler/mypoppler/goo/gfile.h

    r461 r497  
    1717//
    1818// Copyright (C) 2006 Kristian HÞgsberg <krh@redhat.com>
    19 // Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
     19// Copyright (C) 2009, 2011 Albert Astals Cid <aacid@kde.org>
    2020// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
    2121//
     
    2828#define GFILE_H
    2929
     30#include "poppler/poppler-config.h"
    3031#include <stdio.h>
    3132#include <stdlib.h>
  • trunk/poppler/mypoppler/poppler/Annot.cc

    r470 r497  
    2020// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
    2121// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
    22 // Copyright (C) 2008 Pino Toscano <pino@kde.org>
     22// Copyright (C) 2008, 2011 Pino Toscano <pino@kde.org>
    2323// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
    2424// Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
    2525// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
     26// Copyright (C) 2011 José Aliste <jaliste@src.gnome.org>
    2627//
    2728// To see a description of the changes please see the Changelog file that
     
    4748#include "Gfx.h"
    4849#include "Lexer.h"
     50#include "Page.h"
    4951#include "Annot.h"
    5052#include "GfxFont.h"
     
    5355#include "Form.h"
    5456#include "Error.h"
    55 #include "Page.h"
    5657#include "XRef.h"
    5758#include "Movie.h"
     
    128129
    129130  if (dict->lookup("Subtype", &obj1)->isName()) {
    130     GooString *typeName = new GooString(obj1.getName());
    131 
    132     if (!typeName->cmp("Markup3D")) {
     131    const char *typeName = obj1.getName();
     132
     133    if (!strcmp(typeName, "Markup3D")) {
    133134      type = annotExternalDataMarkup3D;
    134135    } else {
    135136      type = annotExternalDataMarkupUnknown;
    136137    }
    137     delete typeName;
    138138  } else {
    139139    type = annotExternalDataMarkupUnknown;
     
    181181
    182182  if (dict->lookup("S", &obj1)->isName()) {
    183     GooString *effectName = new GooString(obj1.getName());
    184 
    185     if (!effectName->cmp("C"))
     183    const char *effectName = obj1.getName();
     184
     185    if (!strcmp(effectName, "C"))
    186186      effectType = borderEffectCloudy;
    187187    else
    188188      effectType = borderEffectNoEffect;
    189     delete effectName;
    190189  } else {
    191190    effectType = borderEffectNoEffect;
     
    442441}
    443442
     443GBool AnnotBorder::parseDashArray(Object *dashObj) {
     444  GBool correct = gTrue;
     445  int tempLength = dashObj->arrayGetLength();
     446  double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
     447
     448  // TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
     449  for (int i = 0; i < tempLength && i < DASH_LIMIT && correct; i++) {
     450    Object obj1;
     451
     452    if (dashObj->arrayGet(i, &obj1)->isNum()) {
     453      tempDash[i] = obj1.getNum();
     454
     455      correct = tempDash[i] >= 0;
     456      obj1.free();
     457    }
     458  }
     459
     460  if (correct) {
     461    dashLength = tempLength;
     462    dash = tempDash;
     463    style = borderDashed;
     464  } else {
     465    gfree (tempDash);
     466  }
     467
     468  return correct;
     469}
     470
    444471AnnotBorder::~AnnotBorder() {
    445472  if (dash)
     
    483510    obj1.free();
    484511
    485     // TODO: check not all zero ? (Line Dash Pattern Page 217 PDF 8.1)
    486512    if (arrayLength == 4) {
    487       if (array->get(3, &obj1)->isArray()) {
    488         Array *dashPattern = obj1.getArray();
    489         int tempLength = dashPattern->getLength();
    490         double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
    491 
    492         for(int i = 0; i < tempLength && i < DASH_LIMIT && correct; i++) {
    493 
    494           if (dashPattern->get(i, &obj1)->isNum()) {
    495             tempDash[i] = obj1.getNum();
    496 
    497             if (tempDash[i] < 0)
    498               correct = gFalse;
    499 
    500           } else {
    501             correct = gFalse;
    502           }
    503           obj1.free();
    504         }
    505 
    506         if (correct) {
    507           dashLength = tempLength;
    508           dash = tempDash;
    509           style = borderDashed;
    510         } else {
    511           gfree (tempDash);
    512         }
    513       } else {
     513      if (array->get(3, &obj1)->isArray())
     514        correct = parseDashArray(&obj1);
     515      else
    514516        correct = gFalse;
    515       }
    516517      obj1.free();
    517518    }
     
    545546  dict->lookup("S", &obj2);
    546547  if (obj1.isNum() && obj2.isName()) {
    547     GooString *styleName = new GooString(obj2.getName());
     548    const char *styleName = obj2.getName();
    548549
    549550    width = obj1.getNum();
    550551
    551     if (!styleName->cmp("S")) {
     552    if (!strcmp(styleName, "S")) {
    552553      style = borderSolid;
    553     } else if (!styleName->cmp("D")) {
     554    } else if (!strcmp(styleName, "D")) {
    554555      style = borderDashed;
    555     } else if (!styleName->cmp("B")) {
     556    } else if (!strcmp(styleName, "B")) {
    556557      style = borderBeveled;
    557     } else if (!styleName->cmp("I")) {
     558    } else if (!strcmp(styleName, "I")) {
    558559      style = borderInset;
    559     } else if (!styleName->cmp("U")) {
     560    } else if (!strcmp(styleName, "U")) {
    560561      style = borderUnderlined;
    561562    } else {
    562563      style = borderSolid;
    563564    }
    564     delete styleName;
    565565  } else {
    566566    width = 0;
     
    569569  obj1.free();
    570570
    571   // TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
    572   if (dict->lookup("D", &obj1)->isArray()) {
    573     GBool correct = gTrue;
    574     int tempLength = obj1.arrayGetLength();
    575     double *tempDash = (double *) gmallocn (tempLength, sizeof (double));
    576 
    577     for(int i = 0; i < tempLength && correct; i++) {
    578       Object obj2;
    579 
    580       if (obj1.arrayGet(i, &obj2)->isNum()) {
    581         tempDash[i] = obj2.getNum();
    582 
    583         if (tempDash[i] < 0)
    584           correct = gFalse;
    585       } else {
    586         correct = gFalse;
    587       }
    588       obj2.free();
    589     }
    590 
    591     if (correct) {
    592       dashLength = tempLength;
    593       dash = tempDash;
    594       style = borderDashed;
    595     } else {
    596       gfree (tempDash);
    597     }
    598 
    599   }
    600 
    601   if (!dash) {
    602     dashLength = 1;
    603     dash = (double *) gmallocn (dashLength, sizeof (double));
    604     dash[0] = 3;
    605   }
    606   obj1.free();
     571  if (style == borderDashed) {
     572    if (dict->lookup("D", &obj1)->isArray())
     573      parseDashArray(&obj1);
     574    obj1.free();
     575
     576    if (!dash) {
     577      dashLength = 1;
     578      dash = (double *) gmallocn (dashLength, sizeof (double));
     579      dash[0] = 3;
     580    }
     581  }
    607582}
    608583
     
    662637  }
    663638
     639  if (adjust != 0)
     640    adjustColor(adjust);
     641}
     642
     643void AnnotColor::adjustColor(int adjust) {
     644  int i;
     645
    664646  if (length == 4) {
    665647    adjust = -adjust;
     
    677659
    678660//------------------------------------------------------------------------
    679 // AnnotBorderStyle
    680 //------------------------------------------------------------------------
    681 
    682 AnnotBorderStyle::AnnotBorderStyle(AnnotBorderType typeA, double widthA,
    683                                    double *dashA, int dashLengthA,
    684                                    double rA, double gA, double bA) {
    685   type = typeA;
    686   width = widthA;
    687   dash = dashA;
    688   dashLength = dashLengthA;
    689   r = rA;
    690   g = gA;
    691   b = bA;
    692 }
    693 
    694 AnnotBorderStyle::~AnnotBorderStyle() {
    695   if (dash) {
    696     gfree(dash);
    697   }
    698 }
    699 
    700 //------------------------------------------------------------------------
    701661// AnnotIconFit
    702662//------------------------------------------------------------------------
     
    706666
    707667  if (dict->lookup("SW", &obj1)->isName()) {
    708     GooString *scaleName = new GooString(obj1.getName());
    709 
    710     if(!scaleName->cmp("B")) {
     668    const char *scaleName = obj1.getName();
     669
     670    if(!strcmp(scaleName, "B")) {
    711671      scaleWhen = scaleBigger;
    712     } else if(!scaleName->cmp("S")) {
     672    } else if(!strcmp(scaleName, "S")) {
    713673      scaleWhen = scaleSmaller;
    714     } else if(!scaleName->cmp("N")) {
     674    } else if(!strcmp(scaleName, "N")) {
    715675      scaleWhen = scaleNever;
    716676    } else {
    717677      scaleWhen = scaleAlways;
    718678    }
    719     delete scaleName;
    720679  } else {
    721680    scaleWhen = scaleAlways;
     
    724683
    725684  if (dict->lookup("S", &obj1)->isName()) {
    726     GooString *scaleName = new GooString(obj1.getName());
    727 
    728     if(!scaleName->cmp("A")) {
     685    const char *scaleName = obj1.getName();
     686
     687    if(!strcmp(scaleName, "A")) {
    729688      scale = scaleAnamorphic;
    730689    } else {
    731690      scale = scaleProportional;
    732691    }
    733     delete scaleName;
    734692  } else {
    735693    scale = scaleProportional;
     
    791749  obj1.free();
    792750
    793   if (dict->lookup("CA", &obj1)->isName()) {
    794     normalCaption = new GooString(obj1.getName());
     751  if (dict->lookup("CA", &obj1)->isString()) {
     752    normalCaption = new GooString(obj1.getString());
    795753  } else {
    796754    normalCaption = NULL;
     
    798756  obj1.free();
    799757
    800   if (dict->lookup("RC", &obj1)->isName()) {
    801     rolloverCaption = new GooString(obj1.getName());
     758  if (dict->lookup("RC", &obj1)->isString()) {
     759    rolloverCaption = new GooString(obj1.getString());
    802760  } else {
    803761    rolloverCaption = NULL;
     
    805763  obj1.free();
    806764
    807   if (dict->lookup("AC", &obj1)->isName()) {
    808     alternateCaption = new GooString(obj1.getName());
     765  if (dict->lookup("AC", &obj1)->isString()) {
     766    alternateCaption = new GooString(obj1.getString());
    809767  } else {
    810768    alternateCaption = NULL;
     
    854812  Object obj1;
    855813
     814  refCnt = 1;
    856815  flags = flagUnknown;
    857816  type = typeUnknown;
     
    876835
    877836Annot::Annot(XRef *xrefA, Dict *dict, Catalog* catalog) {
     837  refCnt = 1;
    878838  hasRef = false;
    879839  flags = flagUnknown;
     
    884844
    885845Annot::Annot(XRef *xrefA, Dict *dict, Catalog* catalog, Object *obj) {
     846  refCnt = 1;
    886847  if (obj->isRef()) {
    887848    hasRef = gTrue;
     
    10491010}
    10501011
     1012void Annot::getRect(double *x1, double *y1, double *x2, double *y2) const {
     1013  *x1 = rect->x1;
     1014  *y1 = rect->y1;
     1015  *x2 = rect->x2;
     1016  *y2 = rect->y2;
     1017}
     1018
     1019GBool Annot::inRect(double x, double y) const {
     1020  return rect->contains(x, y);
     1021}
     1022
    10511023void Annot::update(const char *key, Object *value) {
    10521024  /* Set M to current time */
     
    11081080}
    11091081
     1082void Annot::setAppearanceState(char *state) {
     1083  if (!state)
     1084    return;
     1085
     1086  if (appearState && appearState->cmp(state) == 0)
     1087    return;
     1088
     1089  delete appearState;
     1090  appearState = new GooString(state);
     1091
     1092  Object obj1;
     1093  obj1.initName(state);
     1094  update ("AS", &obj1);
     1095
     1096  // The appearance state determines the current appearance stream
     1097  Object obj2;
     1098  if (annotObj.dictLookup("AP", &obj2)->isDict()) {
     1099    Object obj3;
     1100
     1101    if (obj2.dictLookup("N", &obj3)->isDict()) {
     1102      Object obj4;
     1103
     1104      appearance.free();
     1105      if (obj3.dictLookupNF(state, &obj4)->isRef())
     1106        obj4.copy(&appearance);
     1107      else
     1108        appearance.initNull();
     1109      obj4.free();
     1110    }
     1111    obj3.free();
     1112  }
     1113  obj2.free();
     1114}
     1115
    11101116double Annot::getXMin() {
    11111117  return rect->x1;
     
    11271133  }
    11281134  valueObject.free();
     1135}
     1136
     1137void Annot::incRefCnt() {
     1138  refCnt++;
     1139}
     1140
     1141void Annot::decRefCnt() {
     1142  if (--refCnt == 0)
     1143    delete this;
    11291144}
    11301145
     
    14691484
    14701485  if (dict->lookup("RT", &obj1)->isName()) {
    1471     GooString *replyName = new GooString(obj1.getName());
    1472 
    1473     if (!replyName->cmp("R")) {
     1486    const char *replyName = obj1.getName();
     1487
     1488    if (!strcmp(replyName, "R")) {
    14741489      replyTo = replyTypeR;
    1475     } else if (!replyName->cmp("Group")) {
     1490    } else if (!strcmp(replyName, "Group")) {
    14761491      replyTo = replyTypeGroup;
    14771492    } else {
    14781493      replyTo = replyTypeR;
    14791494    }
    1480     delete replyName;
    14811495  } else {
    14821496    replyTo = replyTypeR;
     
    20002014
    20012015AnnotLink::~AnnotLink() {
    2002   /*
    2003   if (actionDict)
    2004     delete actionDict;
    2005   */
    2006   dest.free();
     2016  delete action;
    20072017  /*
    20082018  if (uriAction)
     
    20152025void AnnotLink::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
    20162026  Object obj1;
    2017   /*
    2018   if (dict->lookup("A", &obj1)->isDict()) {
    2019     actionDict = NULL;
    2020   } else {
    2021     actionDict = NULL;
    2022   }
    2023   obj1.free();
    2024   */
    2025   dict->lookup("Dest", &dest);
     2027
     2028  action = NULL;
     2029
     2030  // look for destination
     2031  if (!dict->lookup("Dest", &obj1)->isNull()) {
     2032    action = LinkAction::parseDest(&obj1);
     2033  // look for action
     2034  } else {
     2035    obj1.free();
     2036    if (dict->lookup("A", &obj1)->isDict()) {
     2037      action = LinkAction::parseAction(&obj1, catalog->getBaseURI());
     2038    }
     2039  }
     2040  obj1.free();
     2041
    20262042  if (dict->lookup("H", &obj1)->isName()) {
    2027     GooString *effect = new GooString(obj1.getName());
    2028 
    2029     if (!effect->cmp("N")) {
     2043    const char *effect = obj1.getName();
     2044
     2045    if (!strcmp(effect, "N")) {
    20302046      linkEffect = effectNone;
    2031     } else if (!effect->cmp("I")) {
     2047    } else if (!strcmp(effect, "I")) {
    20322048      linkEffect = effectInvert;
    2033     } else if (!effect->cmp("O")) {
     2049    } else if (!strcmp(effect, "O")) {
    20342050      linkEffect = effectOutline;
    2035     } else if (!effect->cmp("P")) {
     2051    } else if (!strcmp(effect, "P")) {
    20362052      linkEffect = effectPush;
    20372053    } else {
    20382054      linkEffect = effectInvert;
    20392055    }
    2040     delete effect;
    20412056  } else {
    20422057    linkEffect = effectInvert;
     
    21672182
    21682183  if (dict->lookup("IT", &obj1)->isName()) {
    2169     GooString *intentName = new GooString(obj1.getName());
    2170 
    2171     if (!intentName->cmp("FreeText")) {
     2184    const char *intentName = obj1.getName();
     2185
     2186    if (!strcmp(intentName, "FreeText")) {
    21722187      intent = intentFreeText;
    2173     } else if (!intentName->cmp("FreeTextCallout")) {
     2188    } else if (!strcmp(intentName, "FreeTextCallout")) {
    21742189      intent = intentFreeTextCallout;
    2175     } else if (!intentName->cmp("FreeTextTypeWriter")) {
     2190    } else if (!strcmp(intentName, "FreeTextTypeWriter")) {
    21762191      intent = intentFreeTextTypeWriter;
    21772192    } else {
    21782193      intent = intentFreeText;
    21792194    }
    2180     delete intentName;
    21812195  } else {
    21822196    intent = intentFreeText;
     
    21992213
    22002214  if (dict->lookup("LE", &obj1)->isName()) {
    2201     GooString *styleName = new GooString(obj1.getName());
    2202     endStyle = parseAnnotLineEndingStyle(styleName);
    2203     delete styleName;
     2215    GooString styleName(obj1.getName());
     2216    endStyle = parseAnnotLineEndingStyle(&styleName);
    22042217  } else {
    22052218    endStyle = annotLineEndingNone;
     
    23232336
    23242337  if (dict->lookup("IT", &obj1)->isName()) {
    2325     GooString *intentName = new GooString(obj1.getName());
    2326 
    2327     if(!intentName->cmp("LineArrow")) {
     2338    const char *intentName = obj1.getName();
     2339
     2340    if(!strcmp(intentName, "LineArrow")) {
    23282341      intent = intentLineArrow;
    2329     } else if(!intentName->cmp("LineDimension")) {
     2342    } else if(!strcmp(intentName, "LineDimension")) {
    23302343      intent = intentLineDimension;
    23312344    } else {
    23322345      intent = intentLineArrow;
    23332346    }
    2334     delete intentName;
    23352347  } else {
    23362348    intent = intentLineArrow;
     
    23492361
    23502362  if (dict->lookup("CP", &obj1)->isName()) {
    2351     GooString *captionName = new GooString(obj1.getName());
    2352 
    2353     if(!captionName->cmp("Inline")) {
     2363    const char *captionName = obj1.getName();
     2364
     2365    if(!strcmp(captionName, "Inline")) {
    23542366      captionPos = captionPosInline;
    2355     } else if(!captionName->cmp("Top")) {
     2367    } else if(!strcmp(captionName, "Top")) {
    23562368      captionPos = captionPosTop;
    23572369    } else {
    23582370      captionPos = captionPosInline;
    23592371    }
    2360     delete captionName;
    23612372  } else {
    23622373    captionPos = captionPosInline;
     
    25722583
    25732584      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
    2574         double x1, y1, x2, y2, x3, y3;
     2585        double x1, x2, y3;
    25752586        double x, y;
    25762587
    25772588        x1 = quadrilaterals->getX1(i);
    2578         y1 = quadrilaterals->getY1(i);
    25792589        x2 = quadrilaterals->getX2(i);
    2580         y2 = quadrilaterals->getY2(i);
    2581         x3 = quadrilaterals->getX3(i);
    25822590        y3 = quadrilaterals->getY3(i);
    25832591
     
    25972605
    25982606      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
    2599         double x1, y1, x2, y2, x3, y3;
     2607        double x1, y1, x2, y3;
    26002608        double x, y;
    26012609        double h2;
     
    26042612        y1 = quadrilaterals->getY1(i);
    26052613        x2 = quadrilaterals->getX2(i);
    2606         y2 = quadrilaterals->getY2(i);
    2607         x3 = quadrilaterals->getX3(i);
    26082614        y3 = quadrilaterals->getY3(i);
    26092615        h2 = (y1 - y3) / 2.0;
     
    26892695    Annot(xrefA, dict, catalog, obj) {
    26902696  type = typeWidget;
    2691   widget = NULL;
     2697  field = NULL;
     2698  initialize(xrefA, catalog, dict);
     2699}
     2700
     2701AnnotWidget::AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj, FormField *fieldA) :
     2702    Annot(xrefA, dict, catalog, obj) {
     2703  type = typeWidget;
     2704  field = fieldA;
    26922705  initialize(xrefA, catalog, dict);
    26932706}
     
    27102723  Object obj1;
    27112724
    2712   if ((form = catalog->getForm ())) {
    2713     widget = form->findWidgetByRef (ref);
    2714 
    2715     // check if field apperances need to be regenerated
    2716     // Only text or choice fields needs to have appearance regenerated
    2717     // see section 8.6.2 "Variable Text" of PDFReference
    2718     regen = gFalse;
    2719     if (widget != NULL && (widget->getType () == formText || widget->getType () == formChoice)) {
    2720       regen = form->getNeedAppearances ();
    2721     }
    2722   }
    2723 
    2724   // If field doesn't have an AP we'll have to generate it
    2725   if (appearance.isNone () || appearance.isNull ())
    2726     regen = gTrue;
     2725  form = catalog->getForm();
    27272726
    27282727  if(dict->lookup("H", &obj1)->isName()) {
    2729     GooString *modeName = new GooString(obj1.getName());
    2730 
    2731     if(!modeName->cmp("N")) {
     2728    const char *modeName = obj1.getName();
     2729
     2730    if(!strcmp(modeName, "N")) {
    27322731      mode = highlightModeNone;
    2733     } else if(!modeName->cmp("O")) {
     2732    } else if(!strcmp(modeName, "O")) {
    27342733      mode = highlightModeOutline;
    2735     } else if(!modeName->cmp("P") || !modeName->cmp("T")) {
     2734    } else if(!strcmp(modeName, "P") || !strcmp(modeName, "T")) {
    27362735      mode = highlightModePush;
    27372736    } else {
    27382737      mode = highlightModeInvert;
    27392738    }
    2740     delete modeName;
    27412739  } else {
    27422740    mode = highlightModeInvert;
     
    27512749  obj1.free();
    27522750
     2751  action = NULL;
    27532752  if(dict->lookup("A", &obj1)->isDict()) {
    2754     action = NULL;
    2755   } else {
    2756     action = NULL;
     2753    action = LinkAction::parseAction(&obj1, catalog->getBaseURI());
    27572754  }
    27582755  obj1.free();
     
    30143011
    30153012// Draw the variable text or caption for a field.
    3016 void AnnotWidget::drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
     3013void AnnotWidget::drawText(GooString *text, GooString *da, GfxResources *resources,
    30173014    GBool multiline, int comb, int quadding,
    30183015    GBool txField, GBool forceZapfDingbats,
     
    30743071    tok = (GooString *)daToks->get(tfPos);
    30753072    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
    3076       if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {
     3073      if (!resources || !(font = resources->lookupFont(tok->getCString() + 1))) {
    30773074        if (forceZapfDingbats) {
    30783075          // We are forcing ZaDb but the font does not exist
     
    31953192      // compute text start position
    31963193      switch (quadding) {
    3197         case fieldQuadLeft:
    3198         default:
    3199           x = borderWidth + 2;
    3200           break;
    3201         case fieldQuadCenter:
    3202           x = (rect->x2 - rect->x1 - w) / 2;
    3203           break;
    3204         case fieldQuadRight:
    3205           x = rect->x2 - rect->x1 - borderWidth - 2 - w;
    3206           break;
     3194      case quaddingLeftJustified:
     3195      default:
     3196        x = borderWidth + 2;
     3197        break;
     3198      case quaddingCentered:
     3199        x = (rect->x2 - rect->x1 - w) / 2;
     3200        break;
     3201      case quaddingRightJustified:
     3202        x = rect->x2 - rect->x1 - borderWidth - 2 - w;
     3203        break;
    32073204      }
    32083205
     
    32493246      // compute starting text cell
    32503247      switch (quadding) {
    3251         case fieldQuadLeft:
    3252         default:
     3248      case quaddingLeftJustified:
     3249      default:
    32533250          x = borderWidth;
    3254           break;
    3255         case fieldQuadCenter:
    3256           x = borderWidth + (comb - charCount) / 2 * w;
    3257           break;
    3258         case fieldQuadRight:
    3259           x = borderWidth + (comb - charCount) * w;
    3260           break;
     3251        break;
     3252      case quaddingCentered:
     3253        x = borderWidth + (comb - charCount) / 2 * w;
     3254        break;
     3255      case quaddingRightJustified:
     3256        x = borderWidth + (comb - charCount) * w;
     3257        break;
    32613258      }
    32623259      y = 0.5 * (rect->y2 - rect->y1) - 0.4 * fontSize;
     
    33403337      w *= fontSize;
    33413338      switch (quadding) {
    3342         case fieldQuadLeft:
    3343         default:
    3344           x = borderWidth + 2;
    3345           break;
    3346         case fieldQuadCenter:
    3347           x = (rect->x2 - rect->x1 - w) / 2;
    3348           break;
    3349         case fieldQuadRight:
    3350           x = rect->x2 - rect->x1 - borderWidth - 2 - w;
    3351           break;
     3339      case quaddingLeftJustified:
     3340      default:
     3341        x = borderWidth + 2;
     3342        break;
     3343      case quaddingCentered:
     3344        x = (rect->x2 - rect->x1 - w) / 2;
     3345        break;
     3346      case quaddingRightJustified:
     3347        x = rect->x2 - rect->x1 - borderWidth - 2 - w;
     3348        break;
    33523349      }
    33533350      y = 0.5 * (rect->y2 - rect->y1) - 0.4 * fontSize;
     
    33993396
    34003397// Draw the variable text or caption for a field.
    3401 void AnnotWidget::drawListBox(GooString **text, GBool *selection,
    3402                               int nOptions, int topIdx,
    3403                               GooString *da, GfxFontDict *fontDict, int quadding) {
     3398void AnnotWidget::drawListBox(FormFieldChoice *fieldChoice,
     3399                              GooString *da, GfxResources *resources, int quadding) {
    34043400  GooList *daToks;
    34053401  GooString *tok, *convertedText;
     
    34463442    tok = (GooString *)daToks->get(tfPos);
    34473443    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
    3448       if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {
     3444      if (!resources || !(font = resources->lookupFont(tok->getCString() + 1))) {
    34493445        error(-1, "Unknown font in field's DA string");
    34503446      }
     
    34723468  if (fontSize == 0) {
    34733469    wMax = 0;
    3474     for (i = 0; i < nOptions; ++i) {
     3470    for (i = 0; i < fieldChoice->getNumChoices(); ++i) {
    34753471      j = 0;
    3476       layoutText(text[i], convertedText, &j, font, &w, 0.0, NULL, gFalse);
     3472      layoutText(fieldChoice->getChoice(i), convertedText, &j, font, &w, 0.0, NULL, gFalse);
    34773473      if (w > wMax) {
    34783474        wMax = w;
     
    34933489  // draw the text
    34943490  y = rect->y2 - rect->y1 - 1.1 * fontSize;
    3495   for (i = topIdx; i < nOptions; ++i) {
     3491  for (i = fieldChoice->getTopIndex(); i < fieldChoice->getNumChoices(); ++i) {
    34963492    // setup
    34973493    appearBuf->append("q\n");
    34983494
    34993495    // draw the background if selected
    3500     if (selection[i]) {
     3496    if (fieldChoice->isSelected(i)) {
    35013497      appearBuf->append("0 g f\n");
    35023498      appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re f\n",
     
    35123508    // compute text width and start position
    35133509    j = 0;
    3514     layoutText(text[i], convertedText, &j, font, &w, 0.0, NULL, gFalse);
     3510    layoutText(fieldChoice->getChoice(i), convertedText, &j, font, &w, 0.0, NULL, gFalse);
    35153511    w *= fontSize;
    35163512    switch (quadding) {
    3517       case fieldQuadLeft:
    3518       default:
    3519         x = borderWidth + 2;
    3520         break;
    3521       case fieldQuadCenter:
    3522         x = (rect->x2 - rect->x1 - w) / 2;
    3523         break;
    3524       case fieldQuadRight:
    3525         x = rect->x2 - rect->x1 - borderWidth - 2 - w;
    3526         break;
     3513    case quaddingLeftJustified:
     3514    default:
     3515      x = borderWidth + 2;
     3516      break;
     3517    case quaddingCentered:
     3518      x = (rect->x2 - rect->x1 - w) / 2;
     3519      break;
     3520    case quaddingRightJustified:
     3521      x = rect->x2 - rect->x1 - borderWidth - 2 - w;
     3522      break;
    35273523    }
    35283524
     
    35503546
    35513547    // change the text color if selected
    3552     if (selection[i]) {
     3548    if (fieldChoice->isSelected(i)) {
    35533549      appearBuf->append("1 g\n");
    35543550    }
     
    35733569}
    35743570
    3575 void AnnotWidget::generateFieldAppearance() {
    3576   Object mkObj, ftObj, appearDict, drObj, obj1, obj2, obj3;
    3577   Dict *field;
    3578   Dict *annot;
    3579   Dict *acroForm;
    3580   Dict *mkDict;
    3581   MemStream *appearStream;
    3582   GfxFontDict *fontDict;
    3583   GBool hasCaption;
    3584   double w, dx, dy, r;
     3571void AnnotWidget::drawBorder() {
     3572  int dashLength;
    35853573  double *dash;
    3586   GooString *caption, *da;
    3587   GooString **text;
    3588   GBool *selection;
    3589   int dashLength, ff, quadding, comb, nOptions, topIdx, i, j;
    3590   GBool modified;
    3591   AnnotColor aColor;
    3592 
    3593   if (widget == NULL || !widget->getField () || !widget->getField ()->getObj ()->isDict ())
     3574  AnnotColor adjustedColor;
     3575  double w = border->getWidth();
     3576
     3577  AnnotColor *aColor = appearCharacs->getBorderColor();
     3578  if (!aColor)
     3579    aColor = appearCharacs->getBackColor();
     3580  if (!aColor)
    35943581    return;
    35953582
    3596   field = widget->getField ()->getObj ()->getDict ();
    3597   annot = widget->getObj ()->getDict ();
    3598   acroForm = form->getObj ()->getDict ();
    3599  
    3600   // do not regenerate appearence if widget has not changed
    3601   modified = widget->isModified ();
    3602 
    3603   // only regenerate when it doesn't have an AP or
    3604   // it already has an AP but widget has been modified
    3605   if (!regen && !modified) {
    3606     return;
    3607   }
    3608 
    3609   appearBuf = new GooString ();
    3610   // get the appearance characteristics (MK) dictionary
    3611   if (annot->lookup("MK", &mkObj)->isDict()) {
    3612     mkDict = mkObj.getDict();
    3613   } else {
    3614     mkDict = NULL;
    3615   }
    3616   // draw the background
    3617   if (mkDict) {
    3618     if (mkDict->lookup("BG", &obj1)->isArray() &&
    3619         obj1.arrayGetLength() > 0) {
    3620       AnnotColor aColor = AnnotColor (obj1.getArray());
    3621       setColor(&aColor, gTrue);
    3622       appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n",
    3623           rect->x2 - rect->x1, rect->y2 - rect->y1);
    3624     }
    3625     obj1.free();
    3626   }
    3627 
    3628   // get the field type
    3629   Form::fieldLookup(field, "FT", &ftObj);
    3630 
    3631   // get the field flags (Ff) value
    3632   if (Form::fieldLookup(field, "Ff", &obj1)->isInt()) {
    3633     ff = obj1.getInt();
    3634   } else {
    3635     ff = 0;
    3636   }
    3637   obj1.free();
    3638 
    3639   // draw the border
    3640   if (mkDict && border) {
    3641     w = border->getWidth();
    3642     if (w > 0) {
    3643       mkDict->lookup("BC", &obj1);
    3644       if (!(obj1.isArray() && obj1.arrayGetLength() > 0)) {
    3645         mkDict->lookup("BG", &obj1);
     3583  double dx = rect->x2 - rect->x1;
     3584  double dy = rect->y2 - rect->y1;
     3585
     3586  // radio buttons with no caption have a round border
     3587  GBool hasCaption = appearCharacs->getNormalCaption() != NULL;
     3588  if (field->getType() == formButton &&
     3589      static_cast<FormFieldButton*>(field)->getButtonType() == formButtonRadio && !hasCaption) {
     3590    double r = 0.5 * (dx < dy ? dx : dy);
     3591    switch (border->getStyle()) {
     3592    case AnnotBorder::borderDashed:
     3593      appearBuf->append("[");
     3594      dashLength = border->getDashLength();
     3595      dash = border->getDash();
     3596      for (int i = 0; i < dashLength; ++i) {
     3597        appearBuf->appendf(" {0:.2f}", dash[i]);
    36463598      }
    3647       if (obj1.isArray() && obj1.arrayGetLength() > 0) {
    3648         dx = rect->x2 - rect->x1;
    3649         dy = rect->y2 - rect->y1;
    3650 
    3651         // radio buttons with no caption have a round border
    3652         hasCaption = mkDict->lookup("CA", &obj2)->isString();
    3653         obj2.free();
    3654         if (ftObj.isName("Btn") && (ff & fieldFlagRadio) && !hasCaption) {
    3655           r = 0.5 * (dx < dy ? dx : dy);
    3656           switch (border->getStyle()) {
    3657             case AnnotBorder::borderDashed:
    3658               appearBuf->append("[");
    3659               dashLength = border->getDashLength();
    3660               dash = border->getDash();
    3661               for (i = 0; i < dashLength; ++i) {
    3662                 appearBuf->appendf(" {0:.2f}", dash[i]);
    3663               }
    3664               appearBuf->append("] 0 d\n");
    3665               // fall through to the solid case
    3666             case AnnotBorder::borderSolid:
    3667             case AnnotBorder::borderUnderlined:
    3668               appearBuf->appendf("{0:.2f} w\n", w);
    3669               aColor = AnnotColor (obj1.getArray());
    3670               setColor(&aColor, gFalse);
    3671               drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse);
    3672               break;
    3673             case AnnotBorder::borderBeveled:
    3674             case AnnotBorder::borderInset:
    3675               appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
    3676               aColor = AnnotColor (obj1.getArray());
    3677               setColor(&aColor, gFalse);
    3678               drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse);
    3679               aColor = AnnotColor (obj1.getArray(),
    3680                                    border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
    3681               setColor(&aColor, gFalse);
    3682               drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
    3683               aColor = AnnotColor (obj1.getArray(),
    3684                                    border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
    3685               setColor(&aColor, gFalse);
    3686               drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w);
    3687               break;
    3688           }
    3689 
    3690         } else {
    3691           switch (border->getStyle()) {
    3692             case AnnotBorder::borderDashed:
    3693               appearBuf->append("[");
    3694               dashLength = border->getDashLength();
    3695               dash = border->getDash();
    3696               for (i = 0; i < dashLength; ++i) {
    3697                 appearBuf->appendf(" {0:.2f}", dash[i]);
    3698               }
    3699               appearBuf->append("] 0 d\n");
    3700               // fall through to the solid case
    3701             case AnnotBorder::borderSolid:
    3702               appearBuf->appendf("{0:.2f} w\n", w);
    3703               aColor = AnnotColor (obj1.getArray());
    3704               setColor(&aColor, gFalse);
    3705               appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n",
    3706                   0.5 * w, dx - w, dy - w);
    3707               break;
    3708             case AnnotBorder::borderBeveled:
    3709             case AnnotBorder::borderInset:
    3710               aColor = AnnotColor (obj1.getArray(),
    3711                                    border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
    3712               setColor(&aColor, gTrue);
    3713               appearBuf->append("0 0 m\n");
    3714               appearBuf->appendf("0 {0:.2f} l\n", dy);
    3715               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
    3716               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
    3717               appearBuf->appendf("{0:.2f} {1:.2f} l\n", w, dy - w);
    3718               appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
    3719               appearBuf->append("f\n");
    3720               aColor = AnnotColor (obj1.getArray(),
    3721                                    border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
    3722               setColor(&aColor, gTrue);
    3723               appearBuf->append("0 0 m\n");
    3724               appearBuf->appendf("{0:.2f} 0 l\n", dx);
    3725               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
    3726               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
    3727               appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, w);
    3728               appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
    3729               appearBuf->append("f\n");
    3730               break;
    3731             case AnnotBorder::borderUnderlined:
    3732               appearBuf->appendf("{0:.2f} w\n", w);
    3733               aColor = AnnotColor (obj1.getArray());
    3734               setColor(&aColor, gFalse);
    3735               appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx);
    3736               break;
    3737           }
    3738 
    3739           // clip to the inside of the border
    3740           appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n",
    3741               w, dx - 2 * w, dy - 2 * w);
     3599      appearBuf->append("] 0 d\n");
     3600      // fall through to the solid case
     3601    case AnnotBorder::borderSolid:
     3602    case AnnotBorder::borderUnderlined:
     3603      appearBuf->appendf("{0:.2f} w\n", w);
     3604      setColor(aColor, gFalse);
     3605      drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse);
     3606      break;
     3607    case AnnotBorder::borderBeveled:
     3608    case AnnotBorder::borderInset:
     3609      appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
     3610      setColor(aColor, gFalse);
     3611      drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse);
     3612      adjustedColor = AnnotColor(*aColor);
     3613      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
     3614      setColor(&adjustedColor, gFalse);
     3615      drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
     3616      adjustedColor = AnnotColor(*aColor);
     3617      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
     3618      setColor(&adjustedColor, gFalse);
     3619      drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w);
     3620      break;
     3621    }
     3622  } else {
     3623    switch (border->getStyle()) {
     3624    case AnnotBorder::borderDashed:
     3625      appearBuf->append("[");
     3626      dashLength = border->getDashLength();
     3627      dash = border->getDash();
     3628      for (int i = 0; i < dashLength; ++i) {
     3629        appearBuf->appendf(" {0:.2f}", dash[i]);
     3630      }
     3631      appearBuf->append("] 0 d\n");
     3632      // fall through to the solid case
     3633    case AnnotBorder::borderSolid:
     3634      appearBuf->appendf("{0:.2f} w\n", w);
     3635      setColor(aColor, gFalse);
     3636      appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n",
     3637                         0.5 * w, dx - w, dy - w);
     3638      break;
     3639    case AnnotBorder::borderBeveled:
     3640    case AnnotBorder::borderInset:
     3641      adjustedColor = AnnotColor(*aColor);
     3642      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
     3643      setColor(&adjustedColor, gTrue);
     3644      appearBuf->append("0 0 m\n");
     3645      appearBuf->appendf("0 {0:.2f} l\n", dy);
     3646      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
     3647      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
     3648      appearBuf->appendf("{0:.2f} {1:.2f} l\n", w, dy - w);
     3649      appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
     3650      appearBuf->append("f\n");
     3651      adjustedColor = AnnotColor(*aColor);
     3652      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
     3653      setColor(&adjustedColor, gTrue);
     3654      appearBuf->append("0 0 m\n");
     3655      appearBuf->appendf("{0:.2f} 0 l\n", dx);
     3656      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
     3657      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
     3658      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, w);
     3659      appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
     3660      appearBuf->append("f\n");
     3661      break;
     3662    case AnnotBorder::borderUnderlined:
     3663      appearBuf->appendf("{0:.2f} w\n", w);
     3664      setColor(aColor, gFalse);
     3665      appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx);
     3666      break;
     3667    }
     3668
     3669    // clip to the inside of the border
     3670    appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n",
     3671                       w, dx - 2 * w, dy - 2 * w);
     3672  }
     3673}
     3674
     3675void AnnotWidget::drawFormFieldButton(GfxResources *resources, GooString *da) {
     3676  GooString *caption = NULL;
     3677  if (appearCharacs)
     3678    caption = appearCharacs->getNormalCaption();
     3679
     3680  switch (static_cast<FormFieldButton *>(field)->getButtonType()) {
     3681  case formButtonRadio: {
     3682    //~ Acrobat doesn't draw a caption if there is no AP dict (?)
     3683    if (appearState && appearState->cmp("Off") != 0) {
     3684      if (caption) {
     3685        drawText(caption, da, resources, gFalse, 0, fieldQuadCenter,
     3686                 gFalse, gTrue);
     3687      } else if (appearCharacs) {
     3688        AnnotColor *aColor = appearCharacs->getBorderColor();
     3689        if (aColor) {
     3690          double dx = rect->x2 - rect->x1;
     3691          double dy = rect->y2 - rect->y1;
     3692          setColor(aColor, gTrue);
     3693          drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy), gTrue);
    37423694        }
    37433695      }
    3744       obj1.free();
    3745     }
    3746   }
    3747 
    3748   // get the resource dictionary
    3749   acroForm->lookup("DR", &drObj);
    3750 
    3751   // build the font dictionary
    3752   if (drObj.isDict() && drObj.dictLookup("Font", &obj1)->isDict()) {
    3753     fontDict = new GfxFontDict(xref, NULL, obj1.getDict());
    3754   } else {
    3755     fontDict = NULL;
    3756   }
    3757   obj1.free();
    3758 
    3759   // get the default appearance string
    3760   if (Form::fieldLookup(field, "DA", &obj1)->isNull()) {
    3761     obj1.free();
    3762     acroForm->lookup("DA", &obj1);
    3763   }
    3764   if (obj1.isString()) {
    3765     da = obj1.getString()->copy();
    3766     //TODO: look for a font size / name HERE
    3767     // => create a function
    3768   } else {
    3769     da = NULL;
    3770   }
    3771   obj1.free();
     3696    }
     3697  }
     3698    break;
     3699  case formButtonPush:
     3700    if (caption)
     3701      drawText(caption, da, resources, gFalse, 0, fieldQuadCenter, gFalse, gFalse);
     3702    break;
     3703  case formButtonCheck:
     3704    if (appearState && appearState->cmp("Off") != 0) {
     3705      if (!caption) {
     3706        GooString checkMark("3");
     3707        drawText(&checkMark, da, resources, gFalse, 0, fieldQuadCenter, gFalse, gTrue);
     3708      } else {
     3709        drawText(caption, da, resources, gFalse, 0, fieldQuadCenter, gFalse, gTrue);
     3710      }
     3711    }
     3712    break;
     3713  }
     3714}
     3715
     3716void AnnotWidget::drawFormFieldText(GfxResources *resources, GooString *da) {
     3717  VariableTextQuadding quadding;
     3718  GooString *contents;
     3719  FormFieldText *fieldText = static_cast<FormFieldText *>(field);
     3720
     3721  contents = fieldText->getContent();
     3722  if (contents) {
     3723    quadding = field->hasTextQuadding() ? field->getTextQuadding() : form->getTextQuadding();
     3724
     3725    int comb = 0;
     3726    if (fieldText->isComb())
     3727      comb = fieldText->getMaxLen();
     3728
     3729    drawText(contents, da, resources,
     3730             fieldText->isMultiline(), comb, quadding, gTrue, gFalse, fieldText->isPassword());
     3731  }
     3732}
     3733
     3734void AnnotWidget::drawFormFieldChoice(GfxResources *resources, GooString *da) {
     3735  GooString *selected;
     3736  VariableTextQuadding quadding;
     3737  FormFieldChoice *fieldChoice = static_cast<FormFieldChoice *>(field);
     3738
     3739  quadding = field->hasTextQuadding() ? field->getTextQuadding() : form->getTextQuadding();
     3740
     3741  if (fieldChoice->isCombo()) {
     3742    selected = fieldChoice->getSelectedChoice();
     3743    if (selected) {
     3744      drawText(selected, da, resources, gFalse, 0, quadding, gTrue, gFalse);
     3745      //~ Acrobat draws a popup icon on the right side
     3746    }
     3747  // list box
     3748  } else {
     3749    drawListBox(fieldChoice, da, resources, quadding);
     3750  }
     3751}
     3752
     3753void AnnotWidget::generateFieldAppearance() {
     3754  Object appearDict, obj1, obj2;
     3755  GfxResources *resources;
     3756  MemStream *appearStream;
     3757  GooString *da;
     3758
     3759  appearBuf = new GooString ();
     3760
     3761  // draw the background
     3762  if (appearCharacs) {
     3763    AnnotColor *aColor = appearCharacs->getBackColor();
     3764    if (aColor) {
     3765      setColor(aColor, gTrue);
     3766      appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n",
     3767                         rect->x2 - rect->x1, rect->y2 - rect->y1);
     3768    }
     3769  }
     3770
     3771  // draw the border
     3772  if (appearCharacs && border && border->getWidth() > 0)
     3773    drawBorder();
     3774
     3775  da = field->getDefaultAppearance();
     3776  if (!da)
     3777    da = form->getDefaultAppearance();
     3778
     3779  resources = form->getDefaultResources();
    37723780
    37733781  // draw the field contents
    3774   if (ftObj.isName("Btn")) {
    3775     caption = NULL;
    3776     if (mkDict) {
    3777       if (mkDict->lookup("CA", &obj1)->isString()) {
    3778         caption = obj1.getString()->copy();
    3779       }
    3780       obj1.free();
    3781     }
    3782     // radio button
    3783     if (ff & fieldFlagRadio) {
    3784       //~ Acrobat doesn't draw a caption if there is no AP dict (?)
    3785       if (Form::fieldLookup(field, "V", &obj1)->isName()) {
    3786         if (annot->lookup("AS", &obj2)->isName(obj1.getName()) &&
    3787             strcmp (obj1.getName(), "Off") != 0) {
    3788           if (caption) {
    3789             drawText(caption, da, fontDict, gFalse, 0, fieldQuadCenter,
    3790                 gFalse, gTrue);
    3791           } else {
    3792             if (mkDict) {
    3793               if (mkDict->lookup("BC", &obj3)->isArray() &&
    3794                   obj3.arrayGetLength() > 0) {
    3795                 dx = rect->x2 - rect->x1;
    3796                 dy = rect->y2 - rect->y1;
    3797                 aColor = AnnotColor (obj3.getArray());
    3798                 setColor(&aColor, gTrue);
    3799                 drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy),
    3800                     gTrue);
    3801               }
    3802               obj3.free();
    3803             }
    3804           }
    3805         }
    3806         obj2.free();
    3807       }
    3808       obj1.free();
    3809       // pushbutton
    3810     } else if (ff & fieldFlagPushbutton) {
    3811       if (caption) {
    3812         drawText(caption, da, fontDict, gFalse, 0, fieldQuadCenter,
    3813             gFalse, gFalse);
    3814       }
    3815       // checkbox
    3816     } else {
    3817       if (annot->lookup("AS", &obj1)->isName() &&
    3818           strcmp(obj1.getName(), "Off") != 0) {
    3819         if (!caption) {
    3820           caption = new GooString("3"); // ZapfDingbats checkmark
    3821         }
    3822         drawText(caption, da, fontDict, gFalse, 0, fieldQuadCenter,
    3823             gFalse, gTrue);
    3824       }
    3825       obj1.free();
    3826     }
    3827     if (caption) {
    3828       delete caption;
    3829     }
    3830   } else if (ftObj.isName("Tx")) {
    3831     if (Form::fieldLookup(field, "V", &obj1)->isString()) {
    3832       if (Form::fieldLookup(field, "Q", &obj2)->isInt()) {
    3833         quadding = obj2.getInt();
    3834       } else {
    3835         quadding = fieldQuadLeft;
    3836       }
    3837       obj2.free();
    3838       comb = 0;
    3839       if (ff & fieldFlagComb) {
    3840         if (Form::fieldLookup(field, "MaxLen", &obj2)->isInt()) {
    3841           comb = obj2.getInt();
    3842         }
    3843         obj2.free();
    3844       }
    3845       drawText(obj1.getString(), da, fontDict,
    3846           ff & fieldFlagMultiline, comb, quadding, gTrue, gFalse, ff & fieldFlagPassword);
    3847     }
    3848     obj1.free();
    3849   } else if (ftObj.isName("Ch")) {
    3850     if (Form::fieldLookup(field, "Q", &obj1)->isInt()) {
    3851       quadding = obj1.getInt();
    3852     } else {
    3853       quadding = fieldQuadLeft;
    3854     }
    3855     obj1.free();
    3856     // combo box
    3857     if (ff & fieldFlagCombo) {
    3858       if (Form::fieldLookup(field, "V", &obj1)->isString()) {
    3859         drawText(obj1.getString(), da, fontDict,
    3860             gFalse, 0, quadding, gTrue, gFalse);
    3861         //~ Acrobat draws a popup icon on the right side
    3862       }
    3863       obj1.free();
    3864       // list box
    3865     } else {
    3866       if (field->lookup("Opt", &obj1)->isArray()) {
    3867         nOptions = obj1.arrayGetLength();
    3868         // get the option text
    3869         text = (GooString **)gmallocn(nOptions, sizeof(GooString *));
    3870         for (i = 0; i < nOptions; ++i) {
    3871           text[i] = NULL;
    3872           obj1.arrayGet(i, &obj2);
    3873           if (obj2.isString()) {
    3874             text[i] = obj2.getString()->copy();
    3875           } else if (obj2.isArray() && obj2.arrayGetLength() == 2) {
    3876             if (obj2.arrayGet(1, &obj3)->isString()) {
    3877               text[i] = obj3.getString()->copy();
    3878             }
    3879             obj3.free();
    3880           }
    3881           obj2.free();
    3882           if (!text[i]) {
    3883             text[i] = new GooString();
    3884           }
    3885         }
    3886         // get the selected option(s)
    3887         selection = (GBool *)gmallocn(nOptions, sizeof(GBool));
    3888         //~ need to use the I field in addition to the V field
    3889         Form::fieldLookup(field, "V", &obj2);
    3890         for (i = 0; i < nOptions; ++i) {
    3891           selection[i] = gFalse;
    3892           if (obj2.isString()) {
    3893             if (!obj2.getString()->cmp(text[i])) {
    3894               selection[i] = gTrue;
    3895             }
    3896           } else if (obj2.isArray()) {
    3897             for (j = 0; j < obj2.arrayGetLength(); ++j) {
    3898               if (obj2.arrayGet(j, &obj3)->isString() &&
    3899                   !obj3.getString()->cmp(text[i])) {
    3900                 selection[i] = gTrue;
    3901               }
    3902               obj3.free();
    3903             }
    3904           }
    3905         }
    3906         obj2.free();
    3907         // get the top index
    3908         if (field->lookup("TI", &obj2)->isInt()) {
    3909           topIdx = obj2.getInt();
    3910         } else {
    3911           topIdx = 0;
    3912         }
    3913         obj2.free();
    3914         // draw the text
    3915         drawListBox(text, selection, nOptions, topIdx, da, fontDict, quadding);
    3916         for (i = 0; i < nOptions; ++i) {
    3917           delete text[i];
    3918         }
    3919         gfree(text);
    3920         gfree(selection);
    3921       }
    3922       obj1.free();
    3923     }
    3924   } else if (ftObj.isName("Sig")) {
     3782  switch (field->getType()) {
     3783  case formButton:
     3784    drawFormFieldButton(resources, da);
     3785    break;
     3786  case formText:
     3787    drawFormFieldText(resources, da);
     3788    break;
     3789  case formChoice:
     3790    drawFormFieldChoice(resources, da);
     3791    break;
     3792  case formSignature:
    39253793    //~unimp
    3926   } else {
     3794    break;
     3795  case formUndef:
     3796  default:
    39273797    error(-1, "Unknown field type");
    3928   }
    3929 
    3930   if (da) {
    3931     delete da;
    39323798  }
    39333799
     
    39453811
    39463812  // set the resource dictionary
    3947   if (drObj.isDict()) {
    3948     appearDict.dictAdd(copyString("Resources"), drObj.copy(&obj1));
    3949   }
    3950   drObj.free();
     3813  Object *resDict = form->getDefaultResourcesObj();
     3814  if (resDict->isDict()) {
     3815    appearDict.dictAdd(copyString("Resources"), resDict->copy(&obj1));
     3816  }
    39513817
    39523818  // build the appearance stream
     
    39583824
    39593825  appearStream->setNeedFree(gTrue);
    3960 
    3961   if (widget->isModified()) {
    3962     //create a new object that will contains the new appearance
    3963    
    3964     //if we already have a N entry in our AP dict, reuse it
    3965     if (annot->lookup("AP", &obj1)->isDict() &&
    3966         obj1.dictLookupNF("N", &obj2)->isRef()) {
    3967       appRef = obj2.getRef();
    3968     }
    3969 
    3970     obj2.free();
    3971     obj1.free();
    3972 
    3973     // this annot doesn't have an AP yet, create one
    3974     if (appRef.num == 0)
    3975       appRef = xref->addIndirectObject(&appearance);
    3976     else // since we reuse the already existing AP, we have to notify the xref about this update
    3977       xref->setModifiedObject(&appearance, appRef);
    3978 
    3979     // update object's AP and AS
    3980     Object apObj;
    3981     apObj.initDict(xref);
    3982 
    3983     Object oaRef;
    3984     oaRef.initRef(appRef.num, appRef.gen);
    3985 
    3986     apObj.dictSet("N", &oaRef);
    3987     annot->set("AP", &apObj);
    3988     Dict* d = new Dict(annot);
    3989     d->decRef();
    3990     Object dictObj;
    3991     dictObj.initDict(d);
    3992 
    3993     xref->setModifiedObject(&dictObj, ref);
    3994     dictObj.free();
    3995   }
    3996 
    3997   if (fontDict) {
    3998     delete fontDict;
    3999   }
    4000   ftObj.free();
    4001   mkObj.free();
    40023826}
    40033827
     
    40103834
    40113835  addDingbatsResource = gFalse;
    4012   generateFieldAppearance ();
     3836
     3837  // Only construct the appearance stream when
     3838  // - annot doesn't have an AP or
     3839  // - it's a field containing text (text and choices) and
     3840  // - NeedAppearances is true or
     3841  // - widget has been modified or
     3842  if (field) {
     3843    if (appearance.isNull() || (form && form->getNeedAppearances()) ||
     3844        ((field->getType() == formText || field->getType() == formChoice) &&
     3845         field->isModified()))
     3846      generateFieldAppearance();
     3847  }
    40133848
    40143849  // draw the appearance stream
     
    42484083    }
    42494084  }
     4085  obj1.free();
    42504086
    42514087  dict->lookup("AA", &additionAction);
     
    45964432
    45974433  if (dict->lookup("IT", &obj1)->isName()) {
    4598     GooString *intentName = new GooString(obj1.getName());
    4599 
    4600     if(!intentName->cmp("PolygonCloud")) {
     4434    const char *intentName = obj1.getName();
     4435
     4436    if(!strcmp(intentName, "PolygonCloud")) {
    46014437      intent = polygonCloud;
    4602     } else if(!intentName->cmp("PolyLineDimension")) {
     4438    } else if(!strcmp(intentName, "PolyLineDimension")) {
    46034439      intent = polylineDimension;
    46044440    } else {
    46054441      intent = polygonDimension;
    46064442    }
    4607     delete intentName;
    46084443  } else {
    46094444    intent = polygonCloud;
     
    51454980
    51464981  if (dict->lookup("A", &obj1)->isName()) {
    5147     GooString *name = new GooString(obj1.getName());
    5148 
    5149     if(!name->cmp("PO")) {
     4982    const char *name = obj1.getName();
     4983
     4984    if(!strcmp(name, "PO")) {
    51504985      aTrigger = aTriggerPageOpened;
    5151     } else if(!name->cmp("PV")) {
     4986    } else if(!strcmp(name, "PV")) {
    51524987      aTrigger = aTriggerPageVisible;
    5153     } else if(!name->cmp("XA")) {
     4988    } else if(!strcmp(name, "XA")) {
    51544989      aTrigger = aTriggerUserAction;
    51554990    } else {
    51564991      aTrigger = aTriggerUnknown;
    51574992    }
    5158     delete name;
    51594993  } else {
    51604994    aTrigger = aTriggerUnknown;
     
    51634997
    51644998  if(dict->lookup("AIS", &obj1)->isName()) {
    5165     GooString *name = new GooString(obj1.getName());
    5166 
    5167     if(!name->cmp("I")) {
     4999    const char *name = obj1.getName();
     5000
     5001    if(!strcmp(name, "I")) {
    51685002      aState = aStateEnabled;
    5169     } else if(!name->cmp("L")) {
     5003    } else if(!strcmp(name, "L")) {
    51705004      aState = aStateDisabled;
    51715005    } else {
    51725006      aState = aStateUnknown;
    51735007    }
    5174     delete name;
    51755008  } else {
    51765009    aState = aStateUnknown;
     
    51795012
    51805013  if(dict->lookup("D", &obj1)->isName()) {
    5181     GooString *name = new GooString(obj1.getName());
    5182 
    5183     if(!name->cmp("PC")) {
     5014    const char *name = obj1.getName();
     5015
     5016    if(!strcmp(name, "PC")) {
    51845017      dTrigger = dTriggerPageClosed;
    5185     } else if(!name->cmp("PI")) {
     5018    } else if(!strcmp(name, "PI")) {
    51865019      dTrigger = dTriggerPageInvisible;
    5187     } else if(!name->cmp("XD")) {
     5020    } else if(!strcmp(name, "XD")) {
    51885021      dTrigger = dTriggerUserAction;
    51895022    } else {
    51905023      dTrigger = dTriggerUnknown;
    51915024    }
    5192     delete name;
    51935025  } else {
    51945026    dTrigger = dTriggerUnknown;
     
    51975029
    51985030  if(dict->lookup("DIS", &obj1)->isName()) {
    5199     GooString *name = new GooString(obj1.getName());
    5200 
    5201     if(!name->cmp("U")) {
     5031    const char *name = obj1.getName();
     5032
     5033    if(!strcmp(name, "U")) {
    52025034      dState = dStateUninstantiaded;
    5203     } else if(!name->cmp("I")) {
     5035    } else if(!strcmp(name, "I")) {
    52045036      dState = dStateInstantiated;
    5205     } else if(!name->cmp("L")) {
     5037    } else if(!strcmp(name, "L")) {
    52065038      dState = dStateLive;
    52075039    } else {
    52085040      dState = dStateUnknown;
    52095041    }
    5210     delete name;
    52115042  } else {
    52125043    dState = dStateUnknown;
     
    52365067  Annot *annot;
    52375068  Object obj1;
    5238   int size;
    52395069  int i;
    52405070
     
    52525082        annotsObj->arrayGetNF(i, &obj2);
    52535083        annot = createAnnot (xref, obj1.getDict(), catalog, &obj2);
    5254         if (annot && annot->isOk()) {
    5255           if (nAnnots >= size) {
    5256             size += 16;
    5257             annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
     5084        if (annot) {
     5085          if (annot->isOk()) {
     5086            appendAnnot(annot);
    52585087          }
    5259           annots[nAnnots++] = annot;
    5260         } else {
    5261           delete annot;
     5088          annot->decRefCnt();
    52625089        }
    52635090      }
     
    52685095}
    52695096
     5097void Annots::appendAnnot(Annot *annot) {
     5098  if (annot && annot->isOk()) {
     5099    if (nAnnots >= size) {
     5100      size += 16;
     5101      annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
     5102    }
     5103    annots[nAnnots++] = annot;
     5104    annot->incRefCnt();
     5105  }
     5106}
     5107
    52705108Annot *Annots::createAnnot(XRef *xref, Dict* dict, Catalog *catalog, Object *obj) {
    5271   Annot *annot;
     5109  Annot *annot = NULL;
    52725110  Object obj1;
    52735111
    52745112  if (dict->lookup("Subtype", &obj1)->isName()) {
    5275     GooString *typeName = new GooString(obj1.getName());
    5276 
    5277     if (!typeName->cmp("Text")) {
     5113    const char *typeName = obj1.getName();
     5114
     5115    if (!strcmp(typeName, "Text")) {
    52785116      annot = new AnnotText(xref, dict, catalog, obj);
    5279     } else if (!typeName->cmp("Link")) {
     5117    } else if (!strcmp(typeName, "Link")) {
    52805118      annot = new AnnotLink(xref, dict, catalog, obj);
    5281     } else if (!typeName->cmp("FreeText")) {
     5119    } else if (!strcmp(typeName, "FreeText")) {
    52825120      annot = new AnnotFreeText(xref, dict, catalog, obj);
    5283     } else if (!typeName->cmp("Line")) {
     5121    } else if (!strcmp(typeName, "Line")) {
    52845122      annot = new AnnotLine(xref, dict, catalog, obj);
    5285     } else if (!typeName->cmp("Square")) {
     5123    } else if (!strcmp(typeName, "Square")) {
    52865124      annot = new AnnotGeometry(xref, dict, catalog, obj);
    5287     } else if (!typeName->cmp("Circle")) {
     5125    } else if (!strcmp(typeName, "Circle")) {
    52885126      annot = new AnnotGeometry(xref, dict, catalog, obj);
    5289     } else if (!typeName->cmp("Polygon")) {
     5127    } else if (!strcmp(typeName, "Polygon")) {
    52905128      annot = new AnnotPolygon(xref, dict, catalog, obj);
    5291     } else if (!typeName->cmp("PolyLine")) {
     5129    } else if (!strcmp(typeName, "PolyLine")) {
    52925130      annot = new AnnotPolygon(xref, dict, catalog, obj);
    5293     } else if (!typeName->cmp("Highlight")) {
     5131    } else if (!strcmp(typeName, "Highlight")) {
    52945132      annot = new AnnotTextMarkup(xref, dict, catalog, obj);
    5295     } else if (!typeName->cmp("Underline")) {
     5133    } else if (!strcmp(typeName, "Underline")) {
    52965134      annot = new AnnotTextMarkup(xref, dict, catalog, obj);
    5297     } else if (!typeName->cmp("Squiggly")) {
     5135    } else if (!strcmp(typeName, "Squiggly")) {
    52985136      annot = new AnnotTextMarkup(xref, dict, catalog, obj);
    5299     } else if (!typeName->cmp("StrikeOut")) {
     5137    } else if (!strcmp(typeName, "StrikeOut")) {
    53005138      annot = new AnnotTextMarkup(xref, dict, catalog, obj);
    5301     } else if (!typeName->cmp("Stamp")) {
     5139    } else if (!strcmp(typeName, "Stamp")) {
    53025140      annot = new AnnotStamp(xref, dict, catalog, obj);
    5303     } else if (!typeName->cmp("Caret")) {
     5141    } else if (!strcmp(typeName, "Caret")) {
    53045142      annot = new AnnotCaret(xref, dict, catalog, obj);
    5305     } else if (!typeName->cmp("Ink")) {
     5143    } else if (!strcmp(typeName, "Ink")) {
    53065144      annot = new AnnotInk(xref, dict, catalog, obj);
    5307     } else if (!typeName->cmp("FileAttachment")) {
     5145    } else if (!strcmp(typeName, "FileAttachment")) {
    53085146      annot = new AnnotFileAttachment(xref, dict, catalog, obj);
    5309     } else if (!typeName->cmp("Sound")) {
     5147    } else if (!strcmp(typeName, "Sound")) {
    53105148      annot = new AnnotSound(xref, dict, catalog, obj);
    5311     } else if(!typeName->cmp("Movie")) {
     5149    } else if(!strcmp(typeName, "Movie")) {
    53125150      annot = new AnnotMovie(xref, dict, catalog, obj);
    5313     } else if(!typeName->cmp("Widget")) {
    5314       annot = new AnnotWidget(xref, dict, catalog, obj);
    5315     } else if(!typeName->cmp("Screen")) {
     5151    } else if(!strcmp(typeName, "Widget")) {
     5152      // Find the annot in forms
     5153      if (obj->isRef()) {
     5154        Form *form = catalog->getForm();
     5155        if (form) {
     5156          FormWidget *widget = form->findWidgetByRef(obj->getRef());
     5157          if (widget) {
     5158            annot = widget->getWidgetAnnotation();
     5159            annot->incRefCnt();
     5160          }
     5161        }
     5162      }
     5163      if (!annot)
     5164        annot = new AnnotWidget(xref, dict, catalog, obj);
     5165    } else if(!strcmp(typeName, "Screen")) {
    53165166      annot = new AnnotScreen(xref, dict, catalog, obj);
    5317     } else if(!typeName->cmp("PrinterMark")) {
     5167    } else if(!strcmp(typeName, "PrinterMark")) {
    53185168      annot = new Annot(xref, dict, catalog, obj);
    5319     } else if (!typeName->cmp("TrapNet")) {
     5169    } else if (!strcmp(typeName, "TrapNet")) {
    53205170      annot = new Annot(xref, dict, catalog, obj);
    5321     } else if (!typeName->cmp("Watermark")) {
     5171    } else if (!strcmp(typeName, "Watermark")) {
    53225172      annot = new Annot(xref, dict, catalog, obj);
    5323     } else if (!typeName->cmp("3D")) {
     5173    } else if (!strcmp(typeName, "3D")) {
    53245174      annot = new Annot3D(xref, dict, catalog, obj);
    5325     } else if (!typeName->cmp("Popup")) {
     5175    } else if (!strcmp(typeName, "Popup")) {
    53265176      /* Popup annots are already handled by markup annots
    53275177       * Here we only care about popup annots without a
     
    53395189      annot = new Annot(xref, dict, catalog, obj);
    53405190    }
    5341 
    5342     delete typeName;
    5343   } else {
    5344     annot = NULL;
    53455191  }
    53465192  obj1.free();
     
    53655211
    53665212  for (i = 0; i < nAnnots; ++i) {
    5367     delete annots[i];
     5213    annots[i]->decRefCnt();
    53685214  }
    53695215  gfree(annots);
  • trunk/poppler/mypoppler/poppler/Annot.h

    r470 r497  
    1616// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
    1717// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
    18 // Copyright (C) 2007-2010 Carlos Garcia Campos <carlosgc@gnome.org>
     18// Copyright (C) 2007-2011 Carlos Garcia Campos <carlosgc@gnome.org>
    1919// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
    2020// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
     
    2222// Copyright (C) 2008 Pino Toscano <pino@kde.org>
    2323// Copyright (C) 2008 Tomas Are Haavet <tomasare@gmail.com>
    24 // Copyright (C) 2009, 2010 Albert Astals Cid <aacid@kde.org>
     24// Copyright (C) 2009-2011 Albert Astals Cid <aacid@kde.org>
    2525//
    2626// To see a description of the changes please see the Changelog file that
     
    3636#endif
    3737
     38#include "Object.h"
     39
    3840class XRef;
    3941class Gfx;
     
    4143class CharCodeToUnicode;
    4244class GfxFont;
    43 class GfxFontDict;
     45class GfxResources;
    4446class Form;
    4547class FormWidget;
     48class FormField;
     49class FormFieldChoice;
    4650class PDFRectangle;
    4751class Movie;
     
    232236
    233237protected:
     238  GBool parseDashArray(Object *dashObj);
     239
    234240  AnnotBorderType type;
    235241  double width;
     242  static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
    236243  int dashLength;
    237244  double *dash;
     
    252259
    253260protected:
    254   static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
    255261  double horizontalCorner;          // (Default 0)
    256262  double verticalCorner;            // (Default 0)
     
    294300  AnnotColor(Array *array, int adjust = 0);
    295301
     302  void adjustColor(int adjust);
     303
    296304  AnnotColorSpace getSpace() const { return (AnnotColorSpace) length; }
    297305  const double *getValues() const { return values; }
     
    301309  double values[4];
    302310  int length;
    303 };
    304 
    305 //------------------------------------------------------------------------
    306 // AnnotBorderStyle
    307 //------------------------------------------------------------------------
    308 
    309 enum AnnotBorderType {
    310   annotBorderSolid,
    311   annotBorderDashed,
    312   annotBorderBeveled,
    313   annotBorderInset,
    314   annotBorderUnderlined
    315 };
    316 
    317 class AnnotBorderStyle {
    318 public:
    319 
    320   AnnotBorderStyle(AnnotBorderType typeA, double widthA,
    321                    double *dashA, int dashLengthA,
    322                    double rA, double gA, double bA);
    323   ~AnnotBorderStyle();
    324 
    325   AnnotBorderType getType() { return type; }
    326   double getWidth() { return width; }
    327   void getDash(double **dashA, int *dashLengthA)
    328     { *dashA = dash; *dashLengthA = dashLength; }
    329   void getColor(double *rA, double *gA, double *bA)
    330     { *rA = r; *gA = g; *bA = b; }
    331 
    332 private:
    333 
    334   AnnotBorderType type;
    335   double width;
    336   double *dash;
    337   int dashLength;
    338   double r, g, b;
    339311};
    340312
     
    487459  Annot(XRef *xrefA, Dict *dict, Catalog *catalog);
    488460  Annot(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
    489   virtual ~Annot();
    490461  GBool isOk() { return ok; }
     462
     463  void incRefCnt();
     464  void decRefCnt();
    491465
    492466  virtual void draw(Gfx *gfx, GBool printing);
     
    512486  void setPage(Ref *pageRef, int pageIndex);
    513487
     488  void setAppearanceState(char *state);
     489
    514490  // getters
    515491  XRef *getXRef() const { return xref; }
     492  GBool getHasRef() const { return hasRef; }
    516493  Ref getRef() const { return ref; }
    517494  AnnotSubtype getType() const { return type; }
    518495  PDFRectangle *getRect() const { return rect; }
     496  void getRect(double *x1, double *y1, double *x2, double *y2) const;
    519497  GooString *getContents() const { return contents; }
    520498  int getPageNum() const { return page; }
     
    530508  int getId() { return ref.num; }
    531509
     510  // Check if point is inside the annot rectangle.
     511  GBool inRect(double x, double y) const;
     512
    532513private:
    533514  void readArrayNum(Object *pdfArray, int key, double *value);
     
    538519
    539520protected:
     521  virtual ~Annot();
    540522  void setColor(AnnotColor *color, GBool fill);
    541523  void drawCircle(double cx, double cy, double r, GBool fill);
     
    550532  // and sets M to the current time
    551533  void update(const char *key, Object *value);
     534
     535  int refCnt;
    552536
    553537  Object annotObj;
     
    775759
    776760  // getters
    777   Dict *getActionDict() const { return actionDict; }
    778   Object *getDest() { return &dest; }
     761  LinkAction *getAction() const { return action; }
    779762  AnnotLinkEffect getLinkEffect() const { return linkEffect; }
    780763  Dict *getUriAction() const { return uriAction; }
     
    785768  void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
    786769
    787   Dict *actionDict;                    // A
    788   Object dest;                         // Dest
     770  LinkAction *action;                  // A, Dest
    789771  AnnotLinkEffect linkEffect;          // H          (Default I)
    790772  Dict *uriAction;                     // PA
     
    11541136
    11551137  AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
     1138  AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj, FormField *fieldA);
    11561139  virtual ~AnnotWidget();
    11571140
    11581141  virtual void draw(Gfx *gfx, GBool printing);
    11591142
     1143  void drawBorder();
     1144  void drawFormFieldButton(GfxResources *resources, GooString *da);
     1145  void drawFormFieldText(GfxResources *resources, GooString *da);
     1146  void drawFormFieldChoice(GfxResources *resources, GooString *da);
    11601147  void generateFieldAppearance ();
    11611148
    11621149  AnnotWidgetHighlightMode getMode() { return mode; }
    11631150  AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; }
    1164   Dict *getAction() { return action; }
     1151  LinkAction *getAction() { return action; }
    11651152  Dict *getAdditionActions() { return additionActions; }
    11661153  Dict *getParent() { return parent; }
     
    11701157  void initialize(XRef *xrefA, Catalog *catalog, Dict *dict);
    11711158
    1172   void drawText(GooString *text, GooString *da, GfxFontDict *fontDict,
     1159  void drawText(GooString *text, GooString *da, GfxResources *resources,
    11731160                GBool multiline, int comb, int quadding,
    11741161                GBool txField, GBool forceZapfDingbats,
    11751162                GBool password=false);
    1176   void drawListBox(GooString **text, GBool *selection,
    1177                    int nOptions, int topIdx,
    1178                    GooString *da, GfxFontDict *fontDict, int quadding);
     1163  void drawListBox(FormFieldChoice *fieldChoice,
     1164                   GooString *da, GfxResources *resources, int quadding);
    11791165  void layoutText(GooString *text, GooString *outBuf, int *i, GfxFont *font,
    11801166                  double *width, double widthLimit, int *charCount,
     
    11831169
    11841170  Form *form;
    1185   FormWidget *widget;                     // FormWidget object for this annotation
     1171  FormField *field;                       // FormField object for this annotation
    11861172  AnnotWidgetHighlightMode mode;          // H  (Default I)
    11871173  AnnotAppearanceCharacs *appearCharacs;  // MK
    1188   Dict *action;                           // A
     1174  LinkAction *action;                     // A
    11891175  Dict *additionActions;                  // AA
    11901176  // inherited  from Annot
    11911177  // AnnotBorderBS border;                // BS
    11921178  Dict *parent;                           // Parent
    1193   GBool regen;
    11941179  GBool addDingbatsResource;
    11951180};
     
    12691254  int getNumAnnots() { return nAnnots; }
    12701255  Annot *getAnnot(int i) { return annots[i]; }
     1256  void appendAnnot(Annot *annot);
    12711257
    12721258private:
     
    12761262  Annot **annots;
    12771263  int nAnnots;
     1264  int size;
    12781265};
    12791266
  • trunk/poppler/mypoppler/poppler/ArthurOutputDev.cc

    r470 r497  
    1515//
    1616// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
    17 // Copyright (C) 2005-2009 Albert Astals Cid <aacid@kde.org>
     17// Copyright (C) 2005-2009, 2011 Albert Astals Cid <aacid@kde.org>
    1818// Copyright (C) 2008, 2010 Pino Toscano <pino@kde.org>
    19 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
     19// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
    2020// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
    2121// Copyright (C) 2010 Matthias Fauconneau <matthias.fauconneau@gmail.com>
     22// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
    2223//
    2324// To see a description of the changes please see the Changelog file that
     
    8788
    8889ArthurOutputDev::ArthurOutputDev(QPainter *painter):
    89   m_painter(painter)
     90  m_painter(painter),
     91  m_fontHinting(NoHinting)
    9092{
    9193  m_currentBrush = QBrush(Qt::SolidPattern);
     
    105107#ifdef HAVE_SPLASH
    106108  delete m_fontEngine;
     109
     110  const bool isHintingEnabled = m_fontHinting != NoHinting;
     111  const bool isSlightHinting = m_fontHinting == SlightHinting;
     112
    107113  m_fontEngine = new SplashFontEngine(
    108114#if HAVE_T1LIB_H
     
    111117#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
    112118  globalParams->getEnableFreeType(),
    113   gFalse,
     119  isHintingEnabled,
     120  isSlightHinting,
    114121#endif
    115122  m_painter->testRenderHint(QPainter::TextAntialiasing));
     
    132139
    133140void ArthurOutputDev::endPage() {
    134 }
    135 
    136 void ArthurOutputDev::drawLink(Link *link, Catalog *catalog)
    137 {
    138141}
    139142
     
    282285  double m11, m12, m21, m22, fontSize;
    283286  SplashCoord mat[4];
    284   int substIdx, n;
     287  int n;
    285288  int faceIndex = 0;
    286289  SplashCoord matrix[6];
     
    290293  fileName = NULL;
    291294  tmpBuf = NULL;
    292   substIdx = -1;
    293295
    294296  if (!(gfxFont = state->getFont())) {
     
    771773  double *ctm;
    772774  QMatrix matrix;
    773   int is_identity_transform;
    774775  QImage image;
    775776  int stride;
     
    781782  imgStr->reset();
    782783 
    783   /* ICCBased color space doesn't do any color correction
    784    * so check its underlying color space as well */
    785   is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB ||
    786                   (colorMap->getColorSpace()->getMode() == csICCBased &&
    787                   ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB);
    788 
    789784  image = QImage(width, height, QImage::Format_ARGB32);
    790785  data = (unsigned int *)image.bits();
  • trunk/poppler/mypoppler/poppler/ArthurOutputDev.h

    r470 r497  
    1616// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
    1717// Copyright (C) 2005 Albert Astals Cid <aacid@kde.org>
    18 // Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
    19 // Copyright (C) 2010, 2010 Pino Toscano <pino@kde.org>
     18// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
     19// Copyright (C) 2010 Pino Toscano <pino@kde.org>
     20// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
    2021//
    2122// To see a description of the changes please see the Changelog file that
     
    5253class ArthurOutputDev: public OutputDev {
    5354public:
     55  /**
     56   * Describes how fonts are distorted (aka hinted) to fit the pixel grid.
     57   * More hinting means sharper edges and less adherence to the true letter shapes.
     58   */
     59  enum FontHinting {
     60    NoHinting = 0, ///< Font shapes are left unchanged
     61    SlightHinting, ///< Font shapes are distorted vertically only
     62    FullHinting ///< Font shapes are distorted horizontally and vertically
     63  };
    5464
    5565  // Constructor.
     
    5868  // Destructor.
    5969  virtual ~ArthurOutputDev();
     70
     71  void setFontHinting(FontHinting hinting) { m_fontHinting = hinting; }
    6072
    6173  //----- get info about output device
     
    7991  // End a page.
    8092  virtual void endPage();
    81 
    82   //----- link borders
    83   virtual void drawLink(Link *link, Catalog *catalog);
    8493
    8594  //----- save/restore graphics state
     
    148157private:
    149158  QPainter *m_painter;
     159  FontHinting m_fontHinting;
    150160  QFont m_currentFont;
    151161  QPen m_currentPen;
  • trunk/poppler/mypoppler/poppler/CachedFile.cc

    r470 r497  
    66//
    77// Copyright 2009 Stefan Thomas <thomas@eload24.com>
    8 // Copyright 2010 Hib Eris <hib@hiberis.nl>
     8// Copyright 2010, 2011 Hib Eris <hib@hiberis.nl>
    99// Copyright 2010 Albert Astals Cid <aacid@kde.org>
    1010//
     
    3030  refCnt = 1;
    3131
    32   chunks->resize(length/CachedFileChunkSize + 1);
     32  if (length != ((size_t) -1)) {
     33    chunks->resize(length/CachedFileChunkSize + 1);
     34  }
     35  else {
     36    error(-1, "Failed to initialize file cache for '%s'.", uri->getCString());
     37    chunks->resize(0);
     38  }
    3339}
    3440
  • trunk/poppler/mypoppler/poppler/CairoFontEngine.cc

    r470 r497  
    708708CairoType3Font::CairoType3Font(Ref ref,
    709709                               XRef *xref,
    710                                Catalog *cat,
     710                               Catalog *catalog,
    711711                               cairo_font_face_t *cairo_font_face,
    712712                               Gushort *codeToGID,
  • trunk/poppler/mypoppler/poppler/CairoOutputDev.cc

    r470 r497  
    1919// Copyright (C) 2005, 2009 Albert Astals Cid <aacid@kde.org>
    2020// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
    21 // Copyright (C) 2006-2010 Carlos Garcia Campos <carlosgc@gnome.org>
     21// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org>
    2222// Copyright (C) 2008 Carl Worth <cworth@cworth.org>
    2323// Copyright (C) 2008-2011 Adrian Johnson <ajohnson@redneon.com>
     
    2626// Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
    2727// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
     28// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
    2829//
    2930// To see a description of the changes please see the Changelog file that
     
    4445
    4546#include "goo/gfile.h"
     47#include "goo/gtypes_p.h"
    4648#include "GlobalParams.h"
    4749#include "Error.h"
     
    6062#include "CairoFontEngine.h"
    6163#include "CairoRescaleBox.h"
     64#include "UTF8.h"
    6265//------------------------------------------------------------------------
    6366
     
    7578                        matrix->x0, matrix->y0);
    7679}
     80
     81
     82#define MIN(a,b) (((a) < (b)) ? (a) : (b))
     83#define MAX(a,b) (((a) > (b)) ? (a) : (b))
     84
    7785
    7886//------------------------------------------------------------------------
     
    131139  fill_opacity = 1.0;
    132140  textClipPath = NULL;
     141  strokePathClip = NULL;
    133142  haveCSPattern = gFalse;
    134143  cairo = NULL;
     
    136145  prescaleImages = gTrue;
    137146  printing = gTrue;
     147  use_show_text_glyphs = gFalse;
    138148  inType3Char = gFalse;
    139149  t3_glyph_has_bbox = gFalse;
     
    149159  text = NULL;
    150160  actualText = NULL;
     161
     162  // the SA parameter supposedly defaults to false, but Acrobat
     163  // apparently hardwires it to true
     164  stroke_adjust = globalParams->getStrokeAdjust();
     165  align_stroke_coords = gFalse;
     166  adjusted_stroke_width = gFalse;
    151167}
    152168
     
    243259}
    244260
    245 void CairoOutputDev::drawLink(Link *link, Catalog *catalog) {
    246 }
    247 
    248261void CairoOutputDev::saveState(GfxState *state) {
    249262  LOG(printf ("save\n"));
     
    254267  MaskStack *ms = new MaskStack;
    255268  ms->mask = cairo_pattern_reference(mask);
     269  ms->mask_matrix = mask_matrix;
    256270  ms->next = maskStack;
    257271  maskStack = ms;
     
    277291      cairo_pattern_destroy(mask);
    278292    mask = ms->mask;
     293    mask_matrix = ms->mask_matrix;
    279294    maskStack = ms->next;
    280295    delete ms;
     
    403418}
    404419
    405 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
    406 
    407420void CairoOutputDev::updateLineWidth(GfxState *state) {
    408421  LOG(printf ("line width: %f\n", state->getLineWidth()));
     422  adjusted_stroke_width = gFalse;
    409423  if (state->getLineWidth() == 0.0) {
    410424    /* find out how big pixels (device unit) are in the x and y directions
    411425     * choose the smaller of the two as our line width */
    412426    double x = 1.0, y = 1.0;
     427    if (printing) {
     428      // assume printer pixel size is 1/600 inch
     429      x = 72.0/600;
     430      y = 72.0/600;
     431    }
    413432    cairo_device_to_user_distance(cairo, &x, &y);
    414433    cairo_set_line_width (cairo, MIN(fabs(x),fabs(y)));
    415434  } else {
    416     cairo_set_line_width (cairo, state->getLineWidth());
     435    double width = state->getLineWidth();
     436    if (stroke_adjust && !printing) {
     437      double x, y;
     438      x = y = width;
     439
     440      /* find out line width in device units */
     441      cairo_user_to_device_distance(cairo, &x, &y);
     442      if (x <= 1.0 && y <= 1.0) {
     443        /* adjust width to at least one device pixel */
     444        x = y = 1.0;
     445        cairo_device_to_user_distance(cairo, &x, &y);
     446        width = MIN(fabs(x),fabs(y));
     447        adjusted_stroke_width = gTrue;
     448      }
     449    }
     450    cairo_set_line_width (cairo, width);
    417451  }
    418452  if (cairo_shape)
     
    574608  font_face = currentFont->getFontFace();
    575609  cairo_set_font_face (cairo, font_face);
     610
     611  use_show_text_glyphs = state->getFont()->hasToUnicodeCMap() &&
     612    cairo_surface_has_show_text_glyphs (cairo_get_target (cairo));
    576613 
    577614  double fontSize = state->getFontSize();
     
    605642}
    606643
     644void CairoOutputDev::alignStrokeCoords(double *x, double *y)
     645{
     646  /* see http://www.cairographics.org/FAQ/#sharp_lines */
     647  cairo_user_to_device (cairo, x, y);
     648  *x = floor(*x) + 0.5;
     649  *y = floor(*y) + 0.5;
     650  cairo_device_to_user (cairo, x, y);
     651}
     652
    607653void CairoOutputDev::doPath(cairo_t *cairo, GfxState *state, GfxPath *path) {
    608654  GfxSubpath *subpath;
     
    612658    subpath = path->getSubpath(i);
    613659    if (subpath->getNumPoints() > 0) {
    614       cairo_move_to (cairo, subpath->getX(0), subpath->getY(0));
    615          j = 1;
     660      if (align_stroke_coords) {
     661        double x = subpath->getX(0);
     662        double y = subpath->getY(0);
     663        alignStrokeCoords(&x, &y);
     664        cairo_move_to (cairo, x, y);
     665      } else {
     666        cairo_move_to (cairo, subpath->getX(0), subpath->getY(0));
     667      }
     668      j = 1;
    616669      while (j < subpath->getNumPoints()) {
    617670        if (subpath->getCurve(j)) {
     
    623676          j += 3;
    624677        } else {
    625           cairo_line_to (cairo, subpath->getX(j), subpath->getY(j));
     678          if (align_stroke_coords) {
     679            double x = subpath->getX(j);
     680            double y = subpath->getY(j);
     681            alignStrokeCoords(&x, &y);
     682            cairo_line_to (cairo, x, y);
     683          } else {
     684            cairo_line_to (cairo, subpath->getX(j), subpath->getY(j));
     685          }
    626686          ++j;
    627687        }
     
    643703  }
    644704
     705  if (adjusted_stroke_width)
     706    align_stroke_coords = gTrue;
    645707  doPath (cairo, state, state->getPath());
     708  align_stroke_coords = gFalse;
    646709  cairo_set_source (cairo, stroke_pattern);
    647710  LOG(printf ("stroke\n"));
     
    668731  if (mask) {
    669732    cairo_clip (cairo);
     733    cairo_save (cairo);
     734    cairo_set_matrix (cairo, &mask_matrix);
    670735    cairo_mask (cairo, mask);
     736    cairo_restore (cairo);
     737  } else if (strokePathClip) {
     738    fillToStrokePathClip();
    671739  } else {
    672740    cairo_fill (cairo);
     
    694762}
    695763
    696 GBool CairoOutputDev::tilingPatternFill(GfxState *state, Object *str,
    697                                         int paintType, Dict *resDict,
     764GBool CairoOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str,
     765                                        double *pmat, int paintType, int /*tilingType*/, Dict *resDict,
    698766                                        double *mat, double *bbox,
    699767                                        int x0, int y0, int x1, int y1,
     
    709777  double width, height;
    710778  int surface_width, surface_height;
     779  StrokePathClip *strokePathTmp;
    711780
    712781  width = bbox[2] - bbox[0];
     
    732801  box.x1 = bbox[0]; box.y1 = bbox[1];
    733802  box.x2 = bbox[2]; box.y2 = bbox[3];
     803  strokePathTmp = strokePathClip;
     804  strokePathClip = NULL;
    734805  gfx = new Gfx(xref, this, resDict, catalog, &box, NULL);
    735806  gfx->display(str);
    736807  delete gfx;
     808  strokePathClip = strokePathTmp;
    737809
    738810  pattern = cairo_pattern_create_for_surface (cairo_get_target (cairo));
     
    752824  cairo_set_source (cairo, pattern);
    753825  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
    754   cairo_fill (cairo);
     826  if (strokePathClip) {
     827    fillToStrokePathClip();
     828  } else {
     829    cairo_fill (cairo);
     830  }
    755831
    756832  cairo_pattern_destroy (pattern);
     
    817893}
    818894
     895#if CAIRO_VERSION == CAIRO_VERSION_ENCODE(1, 11, 2)
     896GBool CairoOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading)
     897{
     898  double x0, y0, x1, y1, x2, y2;
     899  GfxColor color[3];
     900  int i, j;
     901  GfxRGB rgb;
     902
     903  cairo_pattern_destroy(fill_pattern);
     904  fill_pattern = cairo_pattern_create_mesh ();
     905
     906  for (i = 0; i < shading->getNTriangles(); i++) {
     907    shading->getTriangle(i,
     908                         &x0, &y0, &color[0],
     909                         &x1, &y1, &color[1],
     910                         &x2, &y2, &color[2]);
     911
     912    cairo_pattern_mesh_begin_patch (fill_pattern);
     913
     914    cairo_pattern_mesh_move_to (fill_pattern, x0, y0);
     915    cairo_pattern_mesh_line_to (fill_pattern, x1, y1);
     916    cairo_pattern_mesh_line_to (fill_pattern, x2, y2);
     917
     918    for (j = 0; j < 3; j++) {
     919        shading->getColorSpace()->getRGB(&color[j], &rgb);
     920        cairo_pattern_mesh_set_corner_color_rgb (fill_pattern, j,
     921                                                 colToDbl(rgb.r),
     922                                                 colToDbl(rgb.g),
     923                                                 colToDbl(rgb.b));
     924    }
     925
     926    cairo_pattern_mesh_end_patch (fill_pattern);
     927  }
     928
     929  double xMin, yMin, xMax, yMax;
     930  // get the clip region bbox
     931  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
     932  state->moveTo(xMin, yMin);
     933  state->lineTo(xMin, yMax);
     934  state->lineTo(xMax, yMax);
     935  state->lineTo(xMax, yMin);
     936  state->closePath();
     937  fill(state);
     938  state->clearPath();
     939
     940  return gTrue;
     941}
     942
     943GBool CairoOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading)
     944{
     945  int i, j, k;
     946
     947  cairo_pattern_destroy(fill_pattern);
     948  fill_pattern = cairo_pattern_create_mesh ();
     949
     950  for (i = 0; i < shading->getNPatches(); i++) {
     951    GfxPatch *patch = shading->getPatch(i);
     952    GfxColor color;
     953    GfxRGB rgb;
     954
     955    cairo_pattern_mesh_begin_patch (fill_pattern);
     956
     957    cairo_pattern_mesh_move_to (fill_pattern, patch->x[0][0], patch->y[0][0]);
     958    cairo_pattern_mesh_curve_to (fill_pattern,
     959                            patch->x[0][1], patch->y[0][1],
     960                            patch->x[0][2], patch->y[0][2],
     961                            patch->x[0][3], patch->y[0][3]);
     962
     963    cairo_pattern_mesh_curve_to (fill_pattern,
     964                            patch->x[1][3], patch->y[1][3],
     965                            patch->x[2][3], patch->y[2][3],
     966                            patch->x[3][3], patch->y[3][3]);
     967
     968    cairo_pattern_mesh_curve_to (fill_pattern,
     969                            patch->x[3][2], patch->y[3][2],
     970                            patch->x[3][1], patch->y[3][1],
     971                            patch->x[3][0], patch->y[3][0]);
     972
     973    cairo_pattern_mesh_curve_to (fill_pattern,
     974                            patch->x[2][0], patch->y[2][0],
     975                            patch->x[1][0], patch->y[1][0],
     976                            patch->x[0][0], patch->y[0][0]);
     977
     978    cairo_pattern_mesh_set_control_point (fill_pattern, 0, patch->x[1][1], patch->y[1][1]);
     979    cairo_pattern_mesh_set_control_point (fill_pattern, 1, patch->x[1][2], patch->y[1][2]);
     980    cairo_pattern_mesh_set_control_point (fill_pattern, 2, patch->x[2][2], patch->y[2][2]);
     981    cairo_pattern_mesh_set_control_point (fill_pattern, 3, patch->x[2][1], patch->y[2][1]);
     982
     983    for (j = 0; j < 4; j++) {
     984      int u, v;
     985
     986      switch (j) {
     987        case 0:
     988          u = 0; v = 0;
     989          break;
     990        case 1:
     991          u = 0; v = 1;
     992          break;
     993        case 2:
     994          u = 1; v = 1;
     995          break;
     996        case 3:
     997          u = 1; v = 0;
     998          break;
     999      }
     1000
     1001      if (shading->isParameterized()) {
     1002        shading->getParameterizedColor (patch->color[u][v].c[0], &color);
     1003      } else {
     1004        for (k = 0; k < shading->getColorSpace()->getNComps(); k++) {
     1005          // simply cast to the desired type; that's all what is needed.
     1006          color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
     1007        }
     1008      }
     1009
     1010      shading->getColorSpace()->getRGB(&color, &rgb);
     1011      cairo_pattern_mesh_set_corner_color_rgb (fill_pattern, j,
     1012                                               colToDbl(rgb.r),
     1013                                               colToDbl(rgb.g),
     1014                                               colToDbl(rgb.b));
     1015    }
     1016    cairo_pattern_mesh_end_patch (fill_pattern);
     1017  }
     1018
     1019  double xMin, yMin, xMax, yMax;
     1020  // get the clip region bbox
     1021  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
     1022  state->moveTo(xMin, yMin);
     1023  state->lineTo(xMin, yMax);
     1024  state->lineTo(xMax, yMax);
     1025  state->lineTo(xMax, yMin);
     1026  state->closePath();
     1027  fill(state);
     1028  state->clearPath();
     1029
     1030  return gTrue;
     1031}
     1032#endif /* CAIRO_VERSION == CAIRO_VERSION_ENCODE(1, 11, 2) */
     1033
    8191034void CairoOutputDev::clip(GfxState *state) {
    8201035  doPath (cairo, state, state->getPath());
     
    8441059void CairoOutputDev::clipToStrokePath(GfxState *state) {
    8451060  LOG(printf("clip-to-stroke-path\n"));
     1061  strokePathClip = (StrokePathClip*)gmalloc (sizeof(*strokePathClip));
     1062  doPath (cairo, state, state->getPath());
     1063  strokePathClip->path = cairo_copy_path (cairo);
     1064  cairo_get_matrix (cairo, &strokePathClip->ctm);
     1065  strokePathClip->line_width = cairo_get_line_width (cairo);
     1066  strokePathClip->dash_count = cairo_get_dash_count (cairo);
     1067  if (strokePathClip->dash_count) {
     1068    strokePathClip->dashes = (double*) gmallocn (sizeof(double), strokePathClip->dash_count);
     1069    cairo_get_dash (cairo, strokePathClip->dashes, &strokePathClip->dash_offset);
     1070  } else {
     1071    strokePathClip->dashes = NULL;
     1072  }
     1073  strokePathClip->cap = cairo_get_line_cap (cairo);
     1074  strokePathClip->join = cairo_get_line_join (cairo);
     1075  strokePathClip->miter = cairo_get_miter_limit (cairo);
     1076}
     1077
     1078void CairoOutputDev::fillToStrokePathClip() {
     1079  cairo_save (cairo);
     1080
     1081  cairo_set_matrix (cairo, &strokePathClip->ctm);
     1082  cairo_set_line_width (cairo, strokePathClip->line_width);
     1083  strokePathClip->dash_count = cairo_get_dash_count (cairo);
     1084  cairo_set_dash (cairo, strokePathClip->dashes, strokePathClip->dash_count, strokePathClip->dash_offset);
     1085  cairo_set_line_cap (cairo, strokePathClip->cap);
     1086  cairo_set_line_join (cairo, strokePathClip->join);
     1087  cairo_set_miter_limit (cairo, strokePathClip->miter);
     1088
     1089  cairo_new_path (cairo);
     1090  cairo_append_path (cairo, strokePathClip->path);
     1091  cairo_stroke (cairo);
     1092
     1093  cairo_restore (cairo);
     1094
     1095  cairo_path_destroy (strokePathClip->path);
     1096  if (strokePathClip->dashes)
     1097    gfree (strokePathClip->dashes);
     1098  gfree (strokePathClip);
     1099  strokePathClip = NULL;
    8461100}
    8471101
     
    8581112  glyphs = (cairo_glyph_t *) gmallocn (len, sizeof (cairo_glyph_t));
    8591113  glyphCount = 0;
     1114  if (use_show_text_glyphs) {
     1115    clusters = (cairo_text_cluster_t *) gmallocn (len, sizeof (cairo_text_cluster_t));
     1116    clusterCount = 0;
     1117    utf8Max = len*2; // start with twice the number of glyphs. we will realloc if we need more.
     1118    utf8 = (char *) gmalloc (utf8Max);
     1119    utf8Count = 0;
     1120  }
    8601121}
    8611122
     
    8701131    glyphs[glyphCount].y = y - originY;
    8711132    glyphCount++;
     1133    if (use_show_text_glyphs) {
     1134      if (utf8Max - utf8Count < uLen*6) {
     1135        // utf8 encoded characters can be up to 6 bytes
     1136        if (utf8Max > uLen*6)
     1137          utf8Max *= 2;
     1138        else
     1139          utf8Max += 2*uLen*6;
     1140        utf8 = (char *) grealloc (utf8, utf8Max);
     1141      }
     1142      clusters[clusterCount].num_bytes = 0;
     1143      for (int i = 0; i < uLen; i++) {
     1144        int size = mapUTF8 (u[i], utf8 + utf8Count, utf8Max - utf8Count);
     1145        utf8Count += size;
     1146        clusters[clusterCount].num_bytes += size;
     1147      }
     1148      clusters[clusterCount].num_glyphs = 1;
     1149      clusterCount++;
     1150    }
    8721151  }
    8731152
     
    8981177    return;
    8991178  }
    900  
     1179
    9011180  if (!(render & 1) && !haveCSPattern) {
    9021181    LOG (printf ("fill string\n"));
    9031182    cairo_set_source (cairo, fill_pattern);
    904     cairo_show_glyphs (cairo, glyphs, glyphCount);
     1183    if (use_show_text_glyphs)
     1184      cairo_show_text_glyphs (cairo, utf8, utf8Count, glyphs, glyphCount, clusters, clusterCount, (cairo_text_cluster_flags_t)0);
     1185    else
     1186        cairo_show_glyphs (cairo, glyphs, glyphCount);
    9051187    if (cairo_shape)
    9061188      cairo_show_glyphs (cairo_shape, glyphs, glyphCount);
    9071189  }
    908  
     1190
    9091191  // stroke
    9101192  if ((render & 3) == 1 || (render & 3) == 2) {
     
    9471229  gfree (glyphs);
    9481230  glyphs = NULL;
     1231  if (use_show_text_glyphs) {
     1232    gfree (clusters);
     1233    clusters = NULL;
     1234    gfree (utf8);
     1235    utf8 = NULL;
     1236  }
    9491237}
    9501238
     
    11981486      printf("BAD status: %s\n", cairo_status_to_string(status));
    11991487  } else {
     1488    cairo_save(cairo);
     1489    cairo_set_matrix(cairo, &mask_matrix);
    12001490    cairo_mask(cairo, mask);
     1491    cairo_restore(cairo);
    12011492
    12021493    cairo_pattern_destroy(mask);
     
    12071498}
    12081499
    1209 typedef unsigned int uint32_t;
    1210 
    1211 static uint32_t luminocity(uint32_t x)
     1500static int luminocity(uint32_t x)
    12121501{
    12131502  int r = (x >> 16) & 0xff;
     
    12161505  // an arbitrary integer approximation of .3*r + .59*g + .11*b
    12171506  int y = (r*19661+g*38666+b*7209 + 32829)>>16;
    1218   return y << 24;
     1507  return y;
    12191508}
    12201509
     
    12321521     * and then use that as the mask. */
    12331522
    1234     double x1, y1, x2, y2, tmp;
     1523    /* Get clip extents in device space */
     1524    double x1, y1, x2, y2, x_min, y_min, x_max, y_max;
    12351525    cairo_clip_extents(cairo, &x1, &y1, &x2, &y2);
    12361526    cairo_user_to_device(cairo, &x1, &y1);
    12371527    cairo_user_to_device(cairo, &x2, &y2);
    1238     if (x1 > x2) {
    1239       tmp = x1;
    1240       x1 = x2;
    1241       x2 = tmp;
    1242     }
    1243 
    1244     if (y1 > y2) {
    1245       tmp = y1;
    1246       y1 = y2;
    1247       y2 = tmp;
    1248     }
    1249 
    1250     int width = (int)(ceil(x2) - floor(x1));
    1251     int height = (int)(ceil(y2) - floor(y1));
     1528    x_min = MIN(x1, x2);
     1529    y_min = MIN(y1, y2);
     1530    x_max = MAX(x1, x2);
     1531    y_max = MAX(y1, y2);
     1532    cairo_clip_extents(cairo, &x1, &y1, &x2, &y2);
     1533    cairo_user_to_device(cairo, &x1, &y2);
     1534    cairo_user_to_device(cairo, &x2, &y1);
     1535    x_min = MIN(x_min,MIN(x1, x2));
     1536    y_min = MIN(y_min,MIN(y1, y2));
     1537    x_max = MAX(x_max,MAX(x1, x2));
     1538    y_max = MAX(y_max,MAX(y1, y2));
     1539
     1540    int width = (int)(ceil(x_max) - floor(x_min));
     1541    int height = (int)(ceil(y_max) - floor(y_min));
     1542
     1543    /* Get group device offset */
     1544    double x_offset, y_offset;
     1545    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
     1546      cairo_surface_get_device_offset(cairo_get_group_target(cairo), &x_offset, &y_offset);
     1547    } else {
     1548      cairo_surface_t *pats;
     1549      cairo_pattern_get_surface(group, &pats);
     1550      cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
     1551    }
     1552
     1553    /* Adjust extents by group offset */
     1554    x_min += x_offset;
     1555    y_min += y_offset;
    12521556
    12531557    cairo_surface_t *source = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
     
    12641568    cairo_paint(maskCtx);
    12651569
    1266     cairo_matrix_t mat;
     1570    /* Copy source ctm to mask ctm and translate origin so that the
     1571     * mask appears it the same location on the source surface.  */
     1572    cairo_matrix_t mat, tmat;
     1573    cairo_matrix_init_translate(&tmat, -x_min, -y_min);
    12671574    cairo_get_matrix(cairo, &mat);
     1575    cairo_matrix_multiply(&mat, &mat, &tmat);
    12681576    cairo_set_matrix(maskCtx, &mat);
    12691577
    12701578    /* make the device offset of the new mask match that of the group */
    1271     double x_offset, y_offset;
    1272     if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
    1273       cairo_surface_get_device_offset(cairo_get_group_target(cairo), &x_offset, &y_offset);
    1274     } else {
    1275       cairo_surface_t *pats;
    1276       cairo_pattern_get_surface(group, &pats);
    1277       cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
    1278     }
    12791579    cairo_surface_set_device_offset(source, x_offset, y_offset);
    12801580
     
    12921592    for (int y=0; y<height; y++) {
    12931593      for (int x=0; x<width; x++) {
    1294         source_data[y*stride + x] = luminocity(source_data[y*stride + x]);
    1295 
    1296 #if 0
    1297         here is how splash deals with the transferfunction we should deal with this
    1298           at some point
     1594        int lum;
     1595        lum = luminocity(source_data[y*stride + x]);
    12991596        if (transferFunc) {
    1300           transferFunc->transform(&lum, &lum2);
    1301         } else {
    1302           lum2 = lum;
     1597          double lum_in, lum_out;
     1598          lum_in = lum/256.0;
     1599          transferFunc->transform(&lum_in, &lum_out);
     1600          lum = (int)(lum_out * 255.0 + 0.5);
    13031601        }
    1304         p[x] = (int)(lum2 * 255.0 + 0.5);
    1305 #endif
    1306 
     1602        source_data[y*stride + x] = lum << 24;
    13071603      }
    13081604    }
     
    13111607    /* setup the new mask pattern */
    13121608    mask = cairo_pattern_create_for_surface(source);
     1609    cairo_get_matrix(cairo, &mask_matrix);
    13131610
    13141611    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
     
    13171614      cairo_matrix_t patMatrix;
    13181615      cairo_pattern_get_matrix(group, &patMatrix);
     1616      /* Apply x_min, y_min offset to it appears in the same location as source. */
     1617      cairo_matrix_multiply(&patMatrix, &patMatrix, &tmat);
    13191618      cairo_pattern_set_matrix(mask, &patMatrix);
    13201619    }
     
    13231622  } else {
    13241623    mask = cairo_pattern_reference(group);
     1624    cairo_get_matrix(cairo, &mask_matrix);
    13251625  }
    13261626
     
    15411841      cairo_pattern_destroy (mask);
    15421842    mask = cairo_pop_group (cairo);
     1843    cairo_get_matrix (cairo, &mask_matrix);
    15431844  }
    15441845}
     
    16201921  if (state->getFillColorSpace()->getMode() == csPattern) {
    16211922    mask = cairo_pattern_reference (pattern);
     1923    cairo_get_matrix (cairo, &mask_matrix);
    16221924  } else if (!printing) {
    16231925    cairo_save (cairo);
     
    18922194
    18932195    mask = cairo_pattern_reference (pattern);
     2196    cairo_get_matrix (cairo, &mask_matrix);
    18942197  } else {
    18952198    cairo_save (cairo);
     
    21772480
    21782481  cairo_surface_mark_dirty (image);
     2482
     2483  setMimeData(str, ref, image);
     2484
    21792485  pattern = cairo_pattern_create_for_surface (image);
    21802486  cairo_surface_destroy (image);
     
    22842590}
    22852591
    2286 void CairoOutputDev::setMimeData(Stream *str, cairo_surface_t *image)
     2592void CairoOutputDev::setMimeData(Stream *str, Object *ref, cairo_surface_t *image)
    22872593{
    22882594  char *strBuffer;
     
    23042610  if (getStreamData (str->getNextStream(), &strBuffer, &len)) {
    23052611    cairo_status_t st;
     2612
     2613#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
     2614    if (ref && ref->isRef()) {
     2615      Ref imgRef = ref->getRef();
     2616      GooString *surfaceId = new GooString("poppler-surface-");
     2617      surfaceId->appendf("{0:d}-{1:d}", imgRef.gen, imgRef.num);
     2618      char *idBuffer = copyString(surfaceId->getCString());
     2619      st = cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_UNIQUE_ID,
     2620                                        (const unsigned char *)idBuffer,
     2621                                        surfaceId->getLength(),
     2622                                        gfree, idBuffer);
     2623      if (st)
     2624        gfree(idBuffer);
     2625      delete surfaceId;
     2626    }
     2627#endif
     2628
    23062629    st = cairo_surface_set_mime_data (image,
    23072630                                      str->getKind() == strDCT ?
     
    24272750  cairo_surface_mark_dirty (image);
    24282751
    2429   setMimeData(str, image);
     2752  setMimeData(str, ref, image);
    24302753
    24312754  pattern = cairo_pattern_create_for_surface (image);
  • trunk/poppler/mypoppler/poppler/CairoOutputDev.h

    r470 r497  
    1818// Copyright (C) 2005, 2006 Kristian HÞgsberg <krh@redhat.com>
    1919// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
    20 // Copyright (C) 2006-2010 Carlos Garcia Campos <carlosgc@gnome.org>
     20// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org>
    2121// Copyright (C) 2008, 2009, 2011 Adrian Johnson <ajohnson@redneon.com>
    2222// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
    23 // Copyright (C) 2010 Thomas Freitag <Thomas.Freitag@alfa.de>
     23// Copyright (C) 2010, 2011 Thomas Freitag <Thomas.Freitag@alfa.de>
    2424//
    2525// To see a description of the changes please see the Changelog file that
     
    108108  // radialShadedFill()?  If this returns false, these shaded fills
    109109  // will be reduced to a series of other drawing operations.
     110#if CAIRO_VERSION == CAIRO_VERSION_ENCODE(1, 11, 2)
     111  virtual GBool useShadedFills(int type) { return type <= 7; }
     112#else
    110113  virtual GBool useShadedFills(int type) { return type < 4; }
     114#endif
    111115
    112116  // Does this device use FillColorStop()?
     
    124128  // End a page.
    125129  virtual void endPage();
    126 
    127   //----- link borders
    128   virtual void drawLink(Link *link, Catalog *catalog);
    129130
    130131  //----- save/restore graphics state
     
    158159  virtual void eoFill(GfxState *state);
    159160  virtual void clipToStrokePath(GfxState *state);
    160   virtual GBool tilingPatternFill(GfxState *state, Object *str,
    161                                   int paintType, Dict *resDict,
     161  virtual GBool tilingPatternFill(GfxState *state, Catalog *cat, Object *str,
     162                                  double *pmat, int paintType, int tilingType, Dict *resDict,
    162163                                  double *mat, double *bbox,
    163164                                  int x0, int y0, int x1, int y1,
     
    167168  virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax);
    168169  virtual GBool radialShadedSupportExtend(GfxState *state, GfxRadialShading *shading);
     170#if CAIRO_VERSION == CAIRO_VERSION_ENCODE(1, 11, 2)
     171  virtual GBool gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading);
     172  virtual GBool patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading);
     173#endif
    169174
    170175  //----- path clipping
     
    276281                                     GBool interpolate);
    277282  GBool getStreamData (Stream *str, char **buffer, int *length);
    278   void setMimeData(Stream *str, cairo_surface_t *image);
    279  
     283  void setMimeData(Stream *str, Object *ref, cairo_surface_t *image);
     284  void fillToStrokePathClip();
     285  void alignStrokeCoords(double *x, double *y);
     286
    280287  GfxRGB fill_color, stroke_color;
    281288  cairo_pattern_t *fill_pattern, *stroke_pattern;
    282289  double fill_opacity;
    283290  double stroke_opacity;
     291  GBool stroke_adjust;
     292  GBool adjusted_stroke_width;
     293  GBool align_stroke_coords;
    284294  CairoFont *currentFont;
    285  
     295
     296  struct StrokePathClip {
     297    cairo_path_t *path;
     298    cairo_matrix_t ctm;
     299    double line_width;
     300    double *dashes;
     301    int dash_count;
     302    double dash_offset;
     303    cairo_line_cap_t cap;
     304    cairo_line_join_t join;
     305    double miter;
     306  } *strokePathClip;
     307
    286308  XRef *xref;                   // xref table for current document
    287309  Catalog *catalog;
     
    297319  GBool needFontUpdate;                // set when the font needs to be updated
    298320  GBool printing;
     321  GBool use_show_text_glyphs;
    299322  cairo_surface_t *surface;
    300323  cairo_glyph_t *glyphs;
    301324  int glyphCount;
     325  cairo_text_cluster_t *clusters;
     326  int clusterCount;
     327  char *utf8;
     328  int utf8Count;
     329  int utf8Max;
    302330  cairo_path_t *textClipPath;
    303331  GBool inType3Char;            // inside a Type 3 CharProc
     
    314342  cairo_pattern_t *shape;
    315343  cairo_pattern_t *mask;
     344  cairo_matrix_t mask_matrix;
    316345  cairo_surface_t *cairo_shape_surface;
    317346  cairo_t *cairo_shape;
     
    324353
    325354  struct MaskStack {
    326       cairo_pattern_t *mask;
    327       struct MaskStack *next;
     355    cairo_pattern_t *mask;
     356    cairo_matrix_t mask_matrix;
     357    struct MaskStack *next;
    328358  } *maskStack;
    329359
     
    363393  // radialShadedFill()?  If this returns false, these shaded fills
    364394  // will be reduced to a series of other drawing operations.
     395#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)
     396  virtual GBool useShadedFills(int type) { return type <= 7; }
     397#else
    365398  virtual GBool useShadedFills(int type) { return type < 4; }
     399#endif
    366400
    367401  // Does this device use FillColorStop()?
     
    374408  // Does this device need non-text content?
    375409  virtual GBool needNonText() { return gTrue; }
    376 
    377     //----- link borders
    378   virtual void drawLink(Link *link, Catalog *catalog) { }
    379410
    380411  //----- save/restore graphics state
     
    406437  virtual void fill(GfxState *state) { }
    407438  virtual void eoFill(GfxState *state) { }
    408   virtual GBool tilingPatternFill(GfxState *state, Object *str,
    409                                   int paintType, Dict *resDict,
     439  virtual void clipToStrokePath(GfxState *state) { }
     440  virtual GBool tilingPatternFill(GfxState *state, Catalog *cat, Object *str,
     441                                  double *pmat, int paintType, int tilingType, Dict *resDict,
    410442                                  double *mat, double *bbox,
    411443                                  int x0, int y0, int x1, int y1,
  • trunk/poppler/mypoppler/poppler/CairoRescaleBox.cc

    r461 r497  
    3636#include <math.h>
    3737#include "goo/gmem.h"
     38#include "goo/gtypes_p.h"
    3839#include "CairoRescaleBox.h"
    3940
    40 typedef unsigned short int      uint16_t;
    41 typedef unsigned int            uint32_t;
    4241
    4342/* we work in fixed point where 1. == 1 << 24 */
  • trunk/poppler/mypoppler/poppler/Catalog.cc

    r470 r497  
    1515//
    1616// Copyright (C) 2005 Kristian HÞgsberg <krh@redhat.com>
    17 // Copyright (C) 2005-2010 Albert Astals Cid <aacid@kde.org>
     17// Copyright (C) 2005-2011 Albert Astals Cid <aacid@kde.org>
    1818// Copyright (C) 2005 Jeff Muizelaar <jrmuizel@nit.ca>
    1919// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
    2020// Copyright (C) 2005 Marco Pesenti Gritti <mpg@redhat.com>
    2121// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
    22 // Copyright (C) 2006, 2008 Carlos Garcia Campos <carlosgc@gnome.org>
     22// Copyright (C) 2006, 2008, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
    2323// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
    24 // Copyright (C) 2008 Pino Toscano <pino@kde.org>
     24// Copyright (C) 2008, 2011 Pino Toscano <pino@kde.org>
    2525// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
    2626// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
     
    5151#include "Form.h"
    5252#include "OptionalContent.h"
     53#include "ViewerPreferences.h"
     54#include "FileSpec.h"
    5355
    5456//------------------------------------------------------------------------
     
    7678  embeddedFileNameTree = NULL;
    7779  jsNameTree = NULL;
     80  viewerPrefs = NULL;
    7881
    7982  pagesList = NULL;
     
    110113  optContentProps.free();
    111114
     115  // get the ViewerPreferences dictionary
     116  catDict.dictLookup("ViewerPreferences", &viewerPreferences);
     117
    112118  // perform form-related loading after all widgets have been loaded
    113119  if (getForm())
    114     getForm()->postWidgetsLoad();
     120    getForm()->postWidgetsLoad(this);
    115121
    116122  catDict.free();
     
    161167  delete form;
    162168  delete optContent;
     169  delete viewerPrefs;
    163170  metadata.free();
    164171  structTreeRoot.free();
    165172  outline.free();
    166173  acroForm.free();
     174  viewerPreferences.free();
    167175}
    168176
     
    231239    xref->getCatalog(&catDict);
    232240
    233     Object pagesDictRef;
    234     if (catDict.dictLookupNF("Pages", &pagesDictRef)->isRef() &&
    235         pagesDictRef.getRefNum() >= 0 &&
    236         pagesDictRef.getRefNum() < xref->getNumObjects()) {
    237       pagesRef = pagesDictRef.getRef();
    238       pagesDictRef.free();
     241    if (catDict.isDict()) {
     242      Object pagesDictRef;
     243      if (catDict.dictLookupNF("Pages", &pagesDictRef)->isRef() &&
     244          pagesDictRef.getRefNum() >= 0 &&
     245          pagesDictRef.getRefNum() < xref->getNumObjects()) {
     246        pagesRef = pagesDictRef.getRef();
     247        pagesDictRef.free();
     248      } else {
     249        error(-1, "Catalog dictionary does not contain a valid \"Pages\" entry");
     250        pagesDictRef.free();
     251        catDict.free();
     252        return gFalse;
     253      }
    239254    } else {
    240        error(-1, "Catalog dictionary does not contain a valid \"Pages\" entry");
    241        pagesDictRef.free();
    242        return gFalse;
     255      error(-1, "Could not find catalog dictionary");
     256      catDict.free();
     257      return gFalse;
    243258    }
    244259
     
    441456}
    442457
    443 EmbFile *Catalog::embeddedFile(int i)
     458FileSpec *Catalog::embeddedFile(int i)
    444459{
    445460    Object efDict;
    446461    Object obj;
    447462    obj = getEmbeddedFileNameTree()->getValue(i);
    448     EmbFile *embeddedFile = 0;
     463    FileSpec *embeddedFile = 0;
    449464    if (obj.isRef()) {
    450         GooString desc(getEmbeddedFileNameTree()->getName(i));
    451         embeddedFile = new EmbFile(obj.fetch(xref, &efDict), &desc);
    452         efDict.free();
     465      Object fsDict;
     466      embeddedFile = new FileSpec(obj.fetch(xref, &fsDict));
     467      fsDict.free();
    453468    } else {
    454         Object null;
    455         embeddedFile = new EmbFile(&null);
     469      Object null;
     470      embeddedFile = new FileSpec(&null);
    456471    }
    457472    return embeddedFile;
     
    460475GooString *Catalog::getJS(int i)
    461476{
    462   Object obj = getJSNameTree()->getValue(i);
    463   if (obj.isRef()) {
    464     Ref r = obj.getRef();
    465     obj.free();
    466     xref->fetch(r.num, r.gen, &obj);
    467   }
     477  Object obj;
     478  // getJSNameTree()->getValue(i) returns a shallow copy of the object so we
     479  // do not need to free it
     480  getJSNameTree()->getValue(i).fetch(xref, &obj);
    468481
    469482  if (!obj.isDict()) {
     
    732745}
    733746
    734 EmbFile::EmbFile(Object *efDict, GooString *description)
    735 {
    736   m_name = 0;
    737   m_description = 0;
    738   if (description)
    739     m_description = description->copy();
    740   m_size = -1;
    741   m_createDate = 0;
    742   m_modDate = 0;
    743   m_checksum = 0;
    744   m_mimetype = 0;
    745   if (efDict->isDict()) {
    746     Object fileSpec;
    747     Object fileDesc;
    748     Object paramDict;
    749     Object paramObj;
    750     Object obj2;
    751     Stream *efStream = NULL;
    752     // efDict matches Table 3.40 in the PDF1.6 spec
    753     efDict->dictLookup("F", &fileSpec);
    754     if (fileSpec.isString()) {
    755       m_name = new GooString(fileSpec.getString());
    756     }
    757     fileSpec.free();
    758 
    759     // the logic here is that the description from the name
    760     // dictionary is used if we don't have a more specific
    761     // description - see the Note: on page 157 of the PDF1.6 spec
    762     efDict->dictLookup("Desc", &fileDesc);
    763     if (fileDesc.isString()) {
    764       delete m_description;
    765       m_description = new GooString(fileDesc.getString());
    766     } else {
    767       efDict->dictLookup("Description", &fileDesc);
    768       if (fileDesc.isString()) {
    769         delete m_description;
    770         m_description = new GooString(fileDesc.getString());
    771       }
    772     }
    773     fileDesc.free();
    774 
    775     efDict->dictLookup("EF", &obj2);
    776     if (obj2.isDict()) {
    777       // This gives us the raw data stream bytes
    778 
    779       obj2.dictLookup("F", &m_objStr);
    780       if (m_objStr.isStream()) {
    781         efStream = m_objStr.getStream();
    782 
    783         // dataDict corresponds to Table 3.41 in the PDF1.6 spec.
    784         Dict *dataDict = efStream->getDict();
    785 
    786         // subtype is normally the mimetype
    787         Object subtypeName;
    788         if (dataDict->lookup("Subtype", &subtypeName)->isName()) {
    789           m_mimetype = new GooString(subtypeName.getName());
    790         }
    791         subtypeName.free();
    792 
    793         // paramDict corresponds to Table 3.42 in the PDF1.6 spec
    794         Object paramDict;
    795         dataDict->lookup( "Params", &paramDict );
    796         if (paramDict.isDict()) {
    797           paramDict.dictLookup("ModDate", &paramObj);
    798           if (paramObj.isString()) {
    799             m_modDate = new GooString(paramObj.getString());
    800           }
    801           paramObj.free();
    802           paramDict.dictLookup("CreationDate", &paramObj);
    803           if (paramObj.isString()) {
    804             m_createDate = new GooString(paramObj.getString());
    805           }
    806           paramObj.free();
    807           paramDict.dictLookup("Size", &paramObj);
    808           if (paramObj.isInt()) {
    809             m_size = paramObj.getInt();
    810           }
    811           paramObj.free();
    812           paramDict.dictLookup("CheckSum", &paramObj);
    813           if (paramObj.isString()) {
    814             m_checksum = new GooString(paramObj.getString());
    815           }
    816           paramObj.free();
    817         }
    818         paramDict.free();
    819       }
    820     }
    821     obj2.free();
    822   }
    823   if (!m_name)
    824     m_name = new GooString();
    825   if (!m_description)
    826     m_description = new GooString();
    827   if (!m_createDate)
    828     m_createDate = new GooString();
    829   if (!m_modDate)
    830     m_modDate = new GooString();
    831   if (!m_checksum)
    832     m_checksum = new GooString();
    833   if (!m_mimetype)
    834     m_mimetype = new GooString();
    835 }
    836 
    837747int Catalog::getNumPages()
    838748{
     
    842752
    843753    xref->getCatalog(&catDict);
     754    if (!catDict.isDict()) {
     755      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     756      catDict.free();
     757      return 0;
     758    }
    844759    catDict.dictLookup("Pages", &pagesDict);
    845760    catDict.free();
     
    962877}
    963878
     879ViewerPreferences *Catalog::getViewerPreferences()
     880{
     881  if (!viewerPrefs) {
     882    if (viewerPreferences.isDict()) {
     883      viewerPrefs = new ViewerPreferences(viewerPreferences.getDict());
     884    }
     885  }
     886
     887  return viewerPrefs;
     888}
     889
    964890Object *Catalog::getNames()
    965891{
  • trunk/poppler/mypoppler/poppler/Catalog.h

    r470 r497  
    1515//
    1616// Copyright (C) 2005 Kristian HÞgsberg <krh@redhat.com>
    17 // Copyright (C) 2005, 2007, 2009, 2010 Albert Astals Cid <aacid@kde.org>
     17// Copyright (C) 2005, 2007, 2009-2011 Albert Astals Cid <aacid@kde.org>
    1818// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
    1919// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
    2020// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
    21 // Copyright (C) 2008 Pino Toscano <pino@kde.org>
     21// Copyright (C) 2008, 2011 Pino Toscano <pino@kde.org>
    2222// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
    2323//
     
    3333#pragma interface
    3434#endif
     35
     36#include "Object.h"
    3537
    3638#include <vector>
     
    4547class Form;
    4648class OCGs;
     49class ViewerPreferences;
     50class FileSpec;
    4751
    4852//------------------------------------------------------------------------
     
    5559  ~NameTree();
    5660  void init(XRef *xref, Object *tree);
    57   void parse(Object *tree);
    5861  GBool lookup(GooString *name, Object *obj);
    5962  int numEntries() { return length; };
    60   // iterator accessor
     63  // iterator accessor, note it returns a shallow copy, do not free the object
    6164  Object getValue(int i);
    6265  GooString *getName(int i);
     
    7275  };
    7376
     77  void parse(Object *tree);
    7478  void addEntry(Entry *entry);
    7579
     
    8286};
    8387
    84 class EmbFile {
    85 public:
    86   EmbFile(GooString *name, GooString *description,
    87           int size,
    88           GooString *createDate,
    89           GooString *modDate, GooString *checksum,
    90           GooString *mimetype,
    91           Object objStr) :
    92     m_name(name),
    93     m_description(description),
    94     m_size(size),
    95     m_createDate(createDate),
    96     m_modDate(modDate),
    97     m_checksum(checksum),
    98     m_mimetype(mimetype)
    99   {
    100     objStr.copy(&m_objStr);
    101   }
    102   EmbFile(Object *efDict, GooString *description = 0);
    103 
    104   ~EmbFile()
    105   {
    106     delete m_name;
    107     delete m_description;
    108     delete m_modDate;
    109     delete m_createDate;
    110     delete m_checksum;
    111     delete m_mimetype;
    112     m_objStr.free();
    113   }
    114 
    115   GooString *name() { return m_name; }
    116   GooString *description() { return m_description; }
    117   int size() { return m_size; }
    118   GooString *modDate() { return m_modDate; }
    119   GooString *createDate() { return m_createDate; }
    120   GooString *checksum() { return m_checksum; }
    121   GooString *mimeType() { return m_mimetype; }
    122   Object &streamObject() { return m_objStr; }
    123   bool isOk() { return m_objStr.isStream(); }
    124 
    125 private:
    126   GooString *m_name;
    127   GooString *m_description;
    128   int m_size;
    129   GooString *m_createDate;
    130   GooString *m_modDate;
    131   GooString *m_checksum;
    132   GooString *m_mimetype;
    133   Object m_objStr;
    134 };
    135 
    13688//------------------------------------------------------------------------
    13789// Catalog
     
    183135
    184136  // Get the i'th file embedded (at the Document level) in the document
    185   EmbFile *embeddedFile(int i);
     137  FileSpec *embeddedFile(int i);
    186138
    187139  // Get the number of javascript scripts
     
    202154
    203155  Form* getForm();
     156
     157  ViewerPreferences *getViewerPreferences();
    204158
    205159  enum PageMode {
     
    241195  std::vector<int> *kidsIdxList;
    242196  Form *form;
     197  ViewerPreferences *viewerPrefs;
    243198  int numPages;                 // number of pages
    244199  int pagesSize;                // size of pages array
     
    253208  Object outline;               // outline dictionary
    254209  Object acroForm;              // AcroForm dictionary
     210  Object viewerPreferences;     // ViewerPreference dictionary
    255211  OCGs *optContent;             // Optional Content groups
    256212  GBool ok;                     // true if catalog is valid
  • trunk/poppler/mypoppler/poppler/CharCodeToUnicode.h

    r257 r497  
    1818// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
    1919// Copyright (C) 2007 Koji Otani <sho@bbr.jp>
    20 // Copyright (C) 2008 Albert Astals Cid <aacid@kde.org>
     20// Copyright (C) 2008, 2011 Albert Astals Cid <aacid@kde.org>
    2121//
    2222// To see a description of the changes please see the Changelog file that
     
    3434#include "poppler-config.h"
    3535#include "CharTypes.h"
     36#include "goo/gtypes.h"
    3637
    3738#if MULTITHREADED
     
    4041
    4142struct CharCodeToUnicodeString;
     43class GooString;
    4244
    4345//------------------------------------------------------------------------
  • trunk/poppler/mypoppler/poppler/CompactFontTables.h

    r257 r497  
    44//
    55// Copyright 1999-2003 Glyph & Cog, LLC
     6//
     7//========================================================================
     8
     9//========================================================================
     10//
     11// Modified under the Poppler project - http://poppler.freedesktop.org
     12//
     13// All changes made under the Poppler project to this file are licensed
     14// under GPL version 2 or later
     15//
     16// Copyright (C) 2011 Albert Astals Cid <aacid@kde.org>
     17//
     18// To see a description of the changes please see the Changelog file that
     19// came with your tarball or type make ChangeLog if you are building from git
    620//
    721//========================================================================
     
    923#ifndef COMPACTFONTINFO_H
    1024#define COMPACTFONTINFO_H
     25
     26#include "goo/gtypes.h"
    1127
    1228static char *type1CStdStrings[391] = {
  • trunk/poppler/mypoppler/poppler/CurlCachedFile.cc

    r470 r497  
    66//
    77// Copyright 2009 Stefan Thomas <thomas@eload24.com>
    8 // Copyright 2010 Hib Eris <hib@hiberis.nl>
     8// Copyright 2010, 2011 Hib Eris <hib@hiberis.nl>
    99// Copyright 2010 Albert Astals Cid <aacid@kde.org>
    1010//
     
    3939CurlCachedFileLoader::init(GooString *urlA, CachedFile *cachedFileA)
    4040{
    41   long code = NULL;
    4241  double contentLength = -1;
     42  long code = 0;
    4343  size_t size;
    4444
     
    5353  curl_easy_perform(curl);
    5454  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
    55   curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
     55  if (code) {
     56     curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
     57     size = contentLength;
     58  } else {
     59     error(-1, "Failed to get size of '%s'.", url->getCString());
     60     size = -1;
     61  }
    5662  curl_easy_reset(curl);
    57 
    58   size = contentLength;
    5963
    6064  return size;
  • trunk/poppler/mypoppler/poppler/DCTStream.cc

    r470 r497  
    1010// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
    1111// Copyright 2011 Daiki Ueno <ueno@unixuser.org>
     12// Copyright 2011 Tomas Hoger <thoger@redhat.com>
    1213//
    1314//========================================================================
     
    142143  }
    143144
    144   if (!setjmp(err.setjmp_buffer)) {
    145     jpeg_read_header(&cinfo, TRUE);
    146 
     145  if (!setjmp(err.setjmp_buffer) && jpeg_read_header(&cinfo, TRUE) != JPEG_SUSPENDED)
     146  {
    147147    // figure out color transform
    148148    if (colorXform == -1 && !cinfo.saw_Adobe_marker) {
  • trunk/poppler/mypoppler/poppler/DCTStream.h

    r470 r497  
    77// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
    88// Copyright 2005 Martin Kretzschmar <martink@gnome.org>
    9 // Copyright 2005-2007, 2009, 2010 Albert Astals Cid <aacid@kde.org>
     9// Copyright 2005-2007, 2009-2011 Albert Astals Cid <aacid@kde.org>
    1010// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
    1111// Copyright 2011 Daiki Ueno <ueno@unixuser.org>
     
    1515#ifndef DCTSTREAM_H
    1616#define DCTSTREAM_H
    17 #include <config.h>
    1817
    1918#ifdef USE_GCC_PRAGMAS
     
    2625#endif
    2726
     27#include "poppler-config.h"
    2828#include <stdio.h>
    2929#include <stdlib.h>
     
    3737#include "goo/gmem.h"
    3838#include "goo/gfile.h"
    39 #include "poppler-config.h"
    4039#include "Error.h"
    4140#include "Object.h"
     
    7069  virtual GooString *getPSFilter(int psLevel, char *indent);
    7170  virtual GBool isBinary(GBool last = gTrue);
    72   Stream *getRawStream() { return str; }
    7371
    7472private:
  • trunk/poppler/mypoppler/poppler/FileSpec.cc

    r277 r497  
    2525
    2626#include "FileSpec.h"
     27
     28EmbFile::EmbFile(Object *efStream)
     29{
     30  m_size = -1;
     31  m_createDate = NULL;
     32  m_modDate = NULL;
     33  m_checksum = NULL;
     34  m_mimetype = NULL;
     35
     36  efStream->copy(&m_objStr);
     37
     38  if (efStream->isStream()) {
     39    // dataDict corresponds to Table 3.41 in the PDF1.6 spec.
     40    Dict *dataDict = efStream->streamGetDict();
     41
     42    // subtype is normally the mimetype
     43    Object subtypeName;
     44    if (dataDict->lookup("Subtype", &subtypeName)->isName()) {
     45      m_mimetype = new GooString(subtypeName.getName());
     46    }
     47    subtypeName.free();
     48
     49    // paramDict corresponds to Table 3.42 in the PDF1.6 spec
     50    Object paramDict;
     51    if (dataDict->lookup("Params", &paramDict)->isDict()) {
     52      Object paramObj;
     53      if (paramDict.dictLookup("ModDate", &paramObj)->isString())
     54        m_modDate = new GooString(paramObj.getString());
     55      paramObj.free();
     56
     57      if (paramDict.dictLookup("CreationDate", &paramObj)->isString())
     58        m_createDate = new GooString(paramObj.getString());
     59      paramObj.free();
     60
     61      if (paramDict.dictLookup("Size", &paramObj)->isInt())
     62        m_size = paramObj.getInt();
     63      paramObj.free();
     64
     65      if (paramDict.dictLookup("CheckSum", &paramObj)->isString())
     66        m_checksum = new GooString(paramObj.getString());
     67      paramObj.free();
     68    }
     69    paramDict.free();
     70  }
     71}
     72
     73EmbFile::~EmbFile()
     74{
     75  delete m_createDate;
     76  delete m_modDate;
     77  delete m_checksum;
     78  delete m_mimetype;
     79  m_objStr.free();
     80}
     81
     82FileSpec::FileSpec(Object *fileSpecA)
     83{
     84  ok = gTrue;
     85  fileName = NULL;
     86  platformFileName = NULL;
     87  embFile = NULL;
     88  desc = NULL;
     89  fileSpecA->copy(&fileSpec);
     90
     91  Object obj1;
     92  if (!getFileSpecName(fileSpecA, &obj1)) {
     93    ok = gFalse;
     94    obj1.free();
     95    error(-1, "Invalid FileSpec");
     96    return;
     97  }
     98
     99  fileName = obj1.getString()->copy();
     100  obj1.free();
     101
     102  if (fileSpec.isDict()) {
     103    if (fileSpec.dictLookup("EF", &obj1)->isDict()) {
     104      if (!obj1.dictLookupNF("F", &fileStream)->isRef()) {
     105        ok = gFalse;
     106        fileStream.free();
     107        error(-1, "Invalid FileSpec: Embedded file stream is not an indirect reference");
     108        obj1.free();
     109        return;
     110      }
     111    }
     112    obj1.free();
     113  }
     114
     115  if (fileSpec.dictLookup("Desc", &obj1)->isString())
     116    desc = obj1.getString()->copy();
     117  obj1.free();
     118}
     119
     120FileSpec::~FileSpec()
     121{
     122  fileSpec.free();
     123  fileStream.free();
     124  delete fileName;
     125  delete platformFileName;
     126  delete embFile;
     127  delete desc;
     128}
     129
     130EmbFile *FileSpec::getEmbeddedFile()
     131{
     132  if (embFile)
     133    return embFile;
     134
     135  Object obj1;
     136  XRef *xref = fileSpec.getDict()->getXRef();
     137  embFile = new EmbFile(fileStream.fetch(xref, &obj1));
     138  obj1.free();
     139
     140  return embFile;
     141}
     142
     143GooString *FileSpec::getFileNameForPlatform()
     144{
     145  if (platformFileName)
     146    return platformFileName;
     147
     148  Object obj1;
     149  if (getFileSpecNameForPlatform(&fileSpec, &obj1))
     150    platformFileName = obj1.getString()->copy();
     151  obj1.free();
     152
     153  return platformFileName;
     154}
    27155
    28156GBool getFileSpecName (Object *fileSpec, Object *fileName)
  • trunk/poppler/mypoppler/poppler/FileSpec.h

    r257 r497  
    1616#define FILE_SPEC_H
    1717
    18 #include "goo/gtypes.h"
     18#ifdef USE_GCC_PRAGMAS
     19#pragma interface
     20#endif
     21
    1922#include "Object.h"
     23
     24class EmbFile {
     25public:
     26  EmbFile(Object *efStream);
     27  ~EmbFile();
     28
     29  int size() { return m_size; }
     30  GooString *modDate() { return m_modDate; }
     31  GooString *createDate() { return m_createDate; }
     32  GooString *checksum() { return m_checksum; }
     33  GooString *mimeType() { return m_mimetype; }
     34  Stream *stream() { return isOk() ? m_objStr.getStream() : NULL; }
     35  GBool isOk() { return m_objStr.isStream(); }
     36
     37private:
     38  int m_size;
     39  GooString *m_createDate;
     40  GooString *m_modDate;
     41  GooString *m_checksum;
     42  GooString *m_mimetype;
     43  Object m_objStr;
     44};
     45
     46class FileSpec {
     47public:
     48  FileSpec(Object *fileSpec);
     49  ~FileSpec();
     50
     51  GBool isOk() { return ok; }
     52
     53  GooString *getFileName() const { return fileName; }
     54  GooString *getFileNameForPlatform();
     55  GooString *getDescription() const { return desc; }
     56  EmbFile *getEmbeddedFile();
     57
     58private:
     59  GBool ok;
     60
     61  Object fileSpec;
     62
     63  GooString *fileName;         // F, UF, DOS, Mac, Unix
     64  GooString *platformFileName;
     65  Object fileStream;           // Ref to F entry in UF
     66  EmbFile *embFile;
     67  GooString *desc;             // Desc
     68};
    2069
    2170GBool getFileSpecName (Object *fileSpec, Object *fileName);
  • trunk/poppler/mypoppler/poppler/FlateStream.h

    r470 r497  
    44//
    55// Copyright (C) 2005, Jeff Muizelaar <jeff@infidigm.net>
    6 // Copyright (C) 2010, Albert Astals Cid <aacid@kde.org>
     6// Copyright (C) 2010, 2011, Albert Astals Cid <aacid@kde.org>
    77//
    88// This file is under the GPLv2 or later license
     
    1212#ifndef FLATESTREAM_H
    1313#define FLATESTREAM_H
    14 #include <config.h>
    1514
    1615#ifdef USE_GCC_PRAGMAS
     
    2322#endif
    2423
     24#include "poppler-config.h"
    2525#include <stdio.h>
    2626#include <stdlib.h>
     
    3333#include "goo/gmem.h"
    3434#include "goo/gfile.h"
    35 #include "poppler-config.h"
    3635#include "Error.h"
    3736#include "Object.h"
  • trunk/poppler/mypoppler/poppler/FontInfo.cc

    r470 r497  
    1111// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
    1212// Copyright (C) 2010 Thomas Freitag <Thomas.Freitag@alfa.de>
     13// Copyright (C) 2011 Carlos Garcia Campos <carlosgc@gnome.org>
    1314//
    1415// To see a description of the changes please see the Changelog file that
     
    7475      scanFonts(resDict, result);
    7576    }
    76     annots = new Annots(doc->getXRef(), doc->getCatalog(), page->getAnnots(&obj1));
    77     obj1.free();
     77    annots = page->getAnnots(doc->getCatalog());
    7878    for (int i = 0; i < annots->getNumAnnots(); ++i) {
    7979      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
     
    8686      obj1.free();
    8787    }
    88     delete annots;
    8988  }
    9089
  • trunk/poppler/mypoppler/poppler/FontInfo.h

    r470 r497  
    44//
    55// Copyright (C) 2005 Kristian HÞgsberg <krh@redhat.com>
    6 // Copyright (C) 2005-2008, 2010 Albert Astals Cid <aacid@kde.org>
     6// Copyright (C) 2005-2008, 2010, 2011 Albert Astals Cid <aacid@kde.org>
    77// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
    88// Copyright (C) 2009 Pino Toscano <pino@kde.org>
     
    2424#define FONT_INFO_H
    2525
     26#include "Object.h"
    2627#include "goo/gtypes.h"
    2728#include "goo/GooList.h"
     29
     30class GfxFont;
     31class PDFDoc;
    2832
    2933class FontInfo {
  • trunk/poppler/mypoppler/poppler/Form.cc

    r470 r497  
    66//
    77// Copyright 2006-2008 Julien Rebetez <julienr@svn.gnome.org>
    8 // Copyright 2007-2010 Albert Astals Cid <aacid@kde.org>
    9 // Copyright 2007-2008 Carlos Garcia Campos <carlosgc@gnome.org>
     8// Copyright 2007-2011 Albert Astals Cid <aacid@kde.org>
     9// Copyright 2007-2008, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
    1010// Copyright 2007 Adrian Johnson <ajohnson@redneon.com>
    1111// Copyright 2007 Iñigo Martínez <inigomartinez@gmail.com>
    12 // Copyright 2008 Pino Toscano <pino@kde.org>
     12// Copyright 2008, 2011 Pino Toscano <pino@kde.org>
    1313// Copyright 2008 Michael Vrable <mvrable@cs.ucsd.edu>
    1414// Copyright 2009 Matthias Drochner <M.Drochner@fz-juelich.de>
     
    3333#include "Array.h"
    3434#include "Dict.h"
     35#include "Gfx.h"
    3536#include "Form.h"
    3637#include "XRef.h"
     
    3839#include "Annot.h"
    3940#include "Catalog.h"
     41#include "Link.h"
    4042
    4143//return a newly allocated char* containing an UTF16BE string of size length
     
    6264FormWidget::FormWidget(XRef *xrefA, Object *aobj, unsigned num, Ref aref, FormField *fieldA)
    6365{
    64   Object obj1, obj2;
    6566  ref = aref;
    66   double t;
    6767  ID = 0;
    68   defaultsLoaded = gFalse;
    69   fontSize = 0.0;
    70   modified = gFalse;
    7168  childNum = num;
    7269  xref = xrefA;
     
    7471  type = formUndef;
    7572  field = fieldA;
    76   Dict *dict = obj.getDict();
    77   fullyQualifiedName = NULL;
    78 
    79   if (dict->lookup("T", &obj1)->isString()) {
    80     partialName = obj1.getString()->copy();
    81   } else {
    82     partialName = NULL;
    83   }
    84   obj1.free();
    85 
    86   if(dict->lookup("TM", &obj1)->isString()) {
    87     mappingName = obj1.getString()->copy();
    88   } else {
    89     mappingName = NULL;
    90   }
    91   obj1.free();
    92 
    93   if (!dict->lookup("Rect", &obj1)->isArray()) {
    94     error(-1, "Annotation rectangle is wrong type");
    95     goto err2;
    96   }
    97   if (!obj1.arrayGet(0, &obj2)->isNum()) {
    98     error(-1, "Bad annotation rectangle");
    99     goto err1;
    100   }
    101   x1 = obj2.getNum();
    102   obj2.free();
    103   if (!obj1.arrayGet(1, &obj2)->isNum()) {
    104     error(-1, "Bad annotation rectangle");
    105     goto err1;
    106   }
    107   y1 = obj2.getNum();
    108   obj2.free();
    109   if (!obj1.arrayGet(2, &obj2)->isNum()) {
    110     error(-1, "Bad annotation rectangle");
    111     goto err1;
    112   }
    113   x2 = obj2.getNum();
    114   obj2.free();
    115   if (!obj1.arrayGet(3, &obj2)->isNum()) {
    116     error(-1, "Bad annotation rectangle");
    117     goto err1;
    118   }
    119   y2 = obj2.getNum();
    120   obj2.free();
    121   obj1.free();
    122   //swap coords if needed
    123   if (x1 > x2) {
    124     t = x1;
    125     x1 = x2;
    126     x2 = t;
    127   }
    128   if (y1 > y2) {
    129     t = y1;
    130     y1 = y2;
    131     y2 = t;
    132   }
    133  
    134   err1:
    135     obj2.free(); 
    136   err2:
    137     obj1.free();
     73  widget = NULL;
    13874}
    13975
    14076FormWidget::~FormWidget()
    14177{
    142   delete partialName;
    143   delete mappingName;
    144   delete fullyQualifiedName;
     78  if (widget)
     79    widget->decRefCnt();
    14580  obj.free ();
    14681}
    14782
     83#ifdef DEBUG_FORMS
     84void FormWidget::print(int indent) {
     85  printf ("%*s+ (%d %d): [widget]\n", indent, "", ref.num, ref.gen);
     86}
     87#endif
     88
     89void FormWidget::createWidgetAnnotation(Catalog *catalog) {
     90  if (widget)
     91    return;
     92
     93  Object obj1;
     94  obj1.initRef(ref.num, ref.gen);
     95  widget = new AnnotWidget(xref, obj.getDict(), catalog, &obj1, field);
     96  obj1.free();
     97}
     98
     99GBool FormWidget::inRect(double x, double y) const {
     100  return widget ? widget->inRect(x, y) : gFalse;
     101}
     102
     103void FormWidget::getRect(double *x1, double *y1, double *x2, double *y2) const {
     104  if (widget)
     105    widget->getRect(x1, y1, x2, y2);
     106}
     107
     108double FormWidget::getFontSize() const {
     109  return widget ? widget->getFontSize() : 0.;
     110}
     111
    148112bool FormWidget::isReadOnly() const
    149113{
    150114  return field->isReadOnly();
     115}
     116
     117GBool FormWidget::isModified() const {
     118  return field->isModified();
    151119}
    152120
     
    162130}
    163131
    164 void FormWidget::updateField (const char *key, Object *value)
    165 {
    166   Object *obj1;
    167   Ref ref1;
    168   Object obj2;
    169 
    170   if (obj.getDict()->lookup ("FT", &obj2)->isName ()) {
    171     // It's a composed (annot + field) dict
    172     obj1 = &obj;
    173     ref1 = ref;
    174   } else {
    175     // It's an annot dict, we have to modify the Field (parent) dict
    176     obj1 = field->getObj ();
    177     ref1 = field->getRef ();
    178   }
    179   obj2.free ();
    180 
    181   obj1->getDict ()->set (const_cast<char*>(key), value);
    182   //notify the xref about the update
    183   xref->setModifiedObject(obj1, ref1);
    184 }
    185 
    186 GooString* FormWidget::getFullyQualifiedName() {
    187   Object obj1, obj2;
    188   Object parent;
    189   GooString *parent_name;
    190   GooString *full_name;
    191 
    192   if (fullyQualifiedName)
    193     return fullyQualifiedName;
    194 
    195   full_name = new GooString();
    196 
    197   obj.copy(&obj1);
    198   while (obj1.dictLookup("Parent", &parent)->isDict()) {
    199     if (parent.dictLookup("T", &obj2)->isString()) {
    200       parent_name = obj2.getString();
    201 
    202       if (parent_name->hasUnicodeMarker()) {
    203         parent_name->del(0, 2); // Remove the unicode BOM
    204         full_name->insert(0, "\0.", 2); // 2-byte unicode period
    205       } else {
    206         full_name->insert(0, '.'); // 1-byte ascii period
    207       }
    208 
    209       full_name->insert(0, parent_name);
    210       obj2.free();
    211     }
    212     obj1.free();
    213     parent.copy(&obj1);
    214     parent.free();
    215   }
    216   obj1.free();
    217   parent.free();
    218 
    219   if (partialName) {
    220     full_name->append(partialName);
    221   } else {
    222     int len = full_name->getLength();
    223     // Remove the last period
    224     if (len > 0)
    225       full_name->del(len - 1, 1);
    226   }
    227 
    228   fullyQualifiedName = full_name;
    229   return fullyQualifiedName;
     132GooString *FormWidget::getPartialName() const {
     133  return field->getPartialName();
     134}
     135
     136GooString *FormWidget::getAlternateUiName() const {
     137  return field->getAlternateUiName();
     138}
     139
     140GooString *FormWidget::getMappingName() const {
     141  return field->getMappingName();
     142}
     143
     144GooString *FormWidget::getFullyQualifiedName() {
     145  return field->getFullyQualifiedName();
     146}
     147
     148LinkAction *FormWidget::getActivationAction() {
     149  return widget ? widget->getAction() : NULL;
    230150}
    231151
     
    236156  parent = static_cast<FormFieldButton*>(field);
    237157  onStr = NULL;
    238   state = gFalse;
    239158  siblingsID = NULL;
    240159  numSiblingsID = 0;
     160
     161  Object obj1, obj2;
     162
     163  // Find the name of the ON state in the AP dictionnary
     164  // The reference say the Off state, if it existe, _must_ be stored in the AP dict under the name /Off
     165  // The "on" state may be stored under any other name
     166  if (obj.dictLookup("AP", &obj1)->isDict()) {
     167    if (obj1.dictLookup("N", &obj2)->isDict()) {
     168      for (int i = 0; i < obj2.dictGetLength(); i++) {
     169        char *key = obj2.dictGetKey(i);
     170        if (strcmp (key, "Off") != 0) {
     171          onStr = new GooString (key);
     172          break;
     173        }
     174      }
     175    }
     176    obj2.free();
     177  }
     178  obj1.free();
     179}
     180
     181char *FormWidgetButton::getOnStr() {
     182  if (onStr)
     183    return onStr->getCString();
     184
     185  // 12.7.4.2.3 Check Boxes
     186  //  Yes should be used as the name for the on state
     187  return parent->getButtonType() == formButtonCheck ? (char *)"Yes" : NULL;
    241188}
    242189
     
    253200}
    254201
    255 void FormWidgetButton::setState (GBool astate, GBool calledByParent)
     202void FormWidgetButton::setAppearanceState(char *state) {
     203  if (!widget)
     204    return;
     205  widget->setAppearanceState(state);
     206}
     207
     208void FormWidgetButton::setState (GBool astate)
    256209{
    257210  //pushButtons don't have state
    258211  if (parent->getButtonType() == formButtonPush)
    259212    return;
    260   //the state modification may be denied by the parent. e.g we don't want to let the user put all combo boxes to false
    261   if (!calledByParent) { //avoid infinite recursion
    262     modified = gTrue;
    263     if (!parent->setState(childNum, astate)) {
    264       return;
    265     }
    266   }
    267   state = astate;
    268  
    269   //update appearance
    270   char *offStr = "Off";
    271   Object obj1;
    272   obj1.initName(state?getOnStr():offStr);
    273   updateField ("V", &obj1);
    274 
    275   obj1.initName(state?getOnStr():offStr);
    276   //modify the Appearance State entry as well
    277   obj.getDict()->set("AS", &obj1);
    278   //notify the xref about the update
    279   xref->setModifiedObject(&obj, ref);
    280 }
    281 
    282 void FormWidgetButton::loadDefaults ()
    283 {
    284   if (defaultsLoaded)
     213
     214  // Silently return if can't set ON state
     215  if (astate && !onStr)
    285216    return;
    286217
    287   defaultsLoaded = gTrue;
    288 
    289   Dict *dict = obj.getDict();
    290   Object obj1;
    291 
    292   //pushButtons don't have state