home *** CD-ROM | disk | FTP | other *** search
- //========================================================================
- //
- // GfxFont.cc
- //
- // Copyright 1996 Derek B. Noonburg
- //
- //========================================================================
- //
- // Ported to EPOC by Sander van der Wal
- //
- // $Log: GfxFont.cpp $
- // Revision 1.4 2000-09-24 21:10:09+02 svdwal
- // Memory leak fixed
- //
- // Revision 1.3 2000-09-21 14:51:12+02 svdwal
- // Some xpdf 0.91 bugfixes added
- //
- // Revision 1.2 2000-09-17 13:38:23+02 svdwal
- // Ported
- //
-
- #ifdef __GNUC__
- #pragma implementation
- #endif
-
- #ifdef __E32DEF_H__
- #include <e32def.h> // remove warning about NULL redefinition
- #endif
-
- #include "GString.h"
- #include "gmem.h"
- #include "gfile.h"
-
- #include "config.h"
- #include "Object.h"
- #include "Array.h"
- #include "Dict.h"
- #include "Error.h"
- #include "FontFile.h"
- #include "Stream.h"
- #include "GfxFont.h"
-
- #if JAPANESE_SUPPORT
- #include "Japan12CMapInfo.h"
- #endif
-
- #include "PDFGlobal.h"
- #include "Pdf.rsg"
- #include "PROFILE.h"
-
-
- //------------------------------------------------------------------------
-
- static int CDECL cmpWidthExcep(const void *w1, const void *w2);
- static int CDECL cmpWidthExcepV(const void *w1, const void *w2);
-
- //------------------------------------------------------------------------
-
- static const Gushort* const defCharWidths[12] = {
- courierWidths,
- courierObliqueWidths,
- courierBoldWidths,
- courierBoldObliqueWidths,
- helveticaWidths,
- helveticaObliqueWidths,
- helveticaBoldWidths,
- helveticaBoldObliqueWidths,
- timesRomanWidths,
- timesItalicWidths,
- timesBoldWidths,
- timesBoldItalicWidths
- };
-
- //------------------------------------------------------------------------
- // GfxFont
- //------------------------------------------------------------------------
-
- GfxFont::GfxFont() {}
-
- void GfxFont::ConstructL(char *tag1, Ref id1, Dict *fontDict) {
- BuiltinFont *builtinFont;
- RAutoObject obj1, obj2;
- int missingWidth;
- char *name2, *p;
-
- // get font tag and ID
- tag = GString::NewL(tag1);
- id = id1;
-
- // get base font name
- name = NULL;
- fontDict->lookupL("BaseFont", &obj1);
- if (obj1.isName())
- name = GString::NewL(obj1.getName());
- obj1.free();
-
- // get font type
- fontDict->lookupL("Subtype", &obj1);
- if (obj1.isName("Type1"))
- type = fontType1;
- else if (obj1.isName("Type1C"))
- type = fontType1C;
- else if (obj1.isName("Type3"))
- type = fontType3;
- else if (obj1.isName("TrueType"))
- type = fontTrueType;
- else if (obj1.isName("Type0"))
- type = fontType0;
- else
- type = fontUnknownType;
- obj1.free();
- is16 = gFalse;
-
- // is it a built-in font?
- builtinFont = NULL;
- if (name && (type == fontType1)) {
- BuiltinFont (&builtinFonts)[14] = Global().GfxFont.builtinFonts;
- for (register int i = 0; i < numBuiltinFonts; ++i) {
- if (!strcmp(builtinFonts[i].name, name->getCString())) {
- builtinFont = &builtinFonts[i];
- break;
- }
- }
- }
-
- // assume Times-Roman forby default (for substitution purposes)
- flags = fontSerif;
-
- // Newer Adobe tools are using Base14-compatible TrueType fonts
- // without embedding them, so munge the names into the equivalent
- // PostScript names. This is a kludge -- it would be nice if Adobe
- // followed their own spec.
- if (type == fontTrueType) {
- p = name->getCString();
- name2 = NULL;
- if (!strncmp(p, "Arial", 5)) {
- if (!strcmp(p+5, ",Bold")) {
- name2 = "Helvetica-Bold";
- } else if (!strcmp(p+5, "Italic")) {
- name2 = "Helvetica-Oblique";
- } else if (!strcmp(p+5, "BoldItalic")) {
- name2 = "Helvetica-BoldOblique";
- } else {
- name2 = "Helvetica";
- }
- } else if (!strncmp(p, "TimesNewRoman", 13)) {
- if (!strcmp(p+5, ",Bold")) {
- name2 = "Times-Bold";
- } else if (!strcmp(p+5, "Italic")) {
- name2 = "Times-Italic";
- } else if (!strcmp(p+5, "BoldItalic")) {
- name2 = "Times-BoldItalic";
- } else {
- name2 = "Times-Roman";
- }
- } else if (!strncmp(p, "CourierNew", 10)) {
- if (!strcmp(p+5, ",Bold")) {
- name2 = "Courier-Bold";
- } else if (!strcmp(p+5, "Italic")) {
- name2 = "Courier-Oblique";
- } else if (!strcmp(p+5, "BoldItalic")) {
- name2 = "Courier-BoldOblique";
- } else {
- name2 = "Courier";
- }
- }
- if (name2) {
- delete name;
- name = 0;
- name = GString::NewL(name2);
- }
- }
-
- // get info from font descriptor
- embFontName = NULL;
- embFontID.num = -1;
- embFontID.gen = -1;
- missingWidth = 0;
- fontDict->lookupL("FontDescriptor", &obj1);
- if (obj1.isDict()) {
-
- // get flags
- obj1.dictLookupL("Flags", &obj2);
- if (obj2.isInt())
- flags = obj2.getInt();
- obj2.free();
-
- // get name
- obj1.dictLookupL("FontName", &obj2);
- if (obj2.isName())
- embFontName = GString::NewL(obj2.getName());
- obj2.free();
-
- // look for embedded font file
- if (type == fontType1) {
- obj1.dictLookupNFL("FontFile", &obj2);
- if (obj2.isRef())
- embFontID = obj2.getRef();
- obj2.free();
- }
- if (embFontID.num == -1 && type == fontTrueType) {
- obj1.dictLookupNFL("FontFile2", &obj2);
- if (obj2.isRef())
- embFontID = obj2.getRef();
- obj2.free();
- }
- if (embFontID.num == -1) {
- obj1.dictLookupNFL("FontFile3", &obj2);
- if (obj2.isRef()) {
- RAutoObject obj3, obj4;
- embFontID = obj2.getRef();
- obj2.fetchL(&obj3);
- if (obj3.isStream()) {
- obj3.streamGetDict()->lookupL("Subtype", &obj4);
- if (obj4.isName("Type1"))
- type = fontType1;
- else if (obj4.isName("Type1C"))
- type = fontType1C;
- else if (obj4.isName("Type3"))
- type = fontType3;
- else if (obj4.isName("TrueType"))
- type = fontTrueType;
- else if (obj4.isName("Type0"))
- type = fontType0;
- obj4.free();
- }
- obj3.free();
- }
- obj2.free();
- }
-
- // look for MissingWidth
- obj1.dictLookupL("MissingWidth", &obj2);
- if (obj2.isInt()) {
- missingWidth = obj2.getInt();
- }
- obj2.free();
- }
- obj1.free();
-
- // look for an external font file
- extFontFile = NULL;
- if (type == fontType1 && name)
- findExtFontFile();
-
- // get font matrix
- fontMat[0] = fontMat[3] = 1;
- fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0;
- if (fontDict->lookupL("FontMatrix", &obj1)->isArray()) {
- for (register int i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) {
- if (obj1.arrayGetL(i, &obj2)->isNum())
- fontMat[i] = obj2.getNum();
- obj2.free();
- }
- }
- obj1.free();
-
- // get encoding and character widths
- if (type == fontType0)
- getType0EncAndWidths(fontDict);
- else
- getEncAndWidths(fontDict, builtinFont, missingWidth);
- }
-
- GfxFont::~GfxFont() {
- delete tag;
- delete name;
- if (!is16)
- delete encoding;
- delete embFontName;
- delete extFontFile;
- if (is16) {
- User::Free(widths16.exceps);
- User::Free(widths16.excepsV);
- }
- }
-
- double GfxFont::getWidth(GString *s) {
-
- PROFILE_START(GFXFONT__GETWIDTH);
-
- double w = 0;
-
- w = 0;
- int len = s->getLength();
- for (int i = 0; i < len; ++i)
- w += widths[s->getChar(i) & 0xff];
-
- PROFILE_STOP(GFXFONT__GETWIDTH);
-
- return w;
- }
-
- double GfxFont::getWidth16(int c) {
- double w;
- int a, b, m;
-
- w = widths16.defWidth;
- a = -1;
- b = widths16.numExceps;
- // invariant: widths16.exceps[a].last < c < widths16.exceps[b].first
- while (b - a > 1) {
- m = (a + b) / 2;
- if (widths16.exceps[m].last < c) {
- a = m;
- } else if (c < widths16.exceps[m].first) {
- b = m;
- } else {
- w = widths16.exceps[m].width;
- break;
- }
- }
- return w;
- }
-
- double GfxFont::getHeight16(int c) {
- double h;
- int a, b, m;
-
- h = widths16.defHeight;
- a = -1;
- b = widths16.numExcepsV;
- // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first
- while (b - a > 1) {
- m = (a + b) / 2;
- if (widths16.excepsV[m].last < c) {
- a = m;
- } else if (c < widths16.excepsV[m].first) {
- b = m;
- } else {
- h = widths16.excepsV[m].height;
- break;
- }
- }
- return h;
- }
-
- double GfxFont::getOriginX16(int c) {
- double vx;
- int a, b, m;
-
- vx = widths16.defWidth / 2;
- a = -1;
- b = widths16.numExcepsV;
- // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first
- while (b - a > 1) {
- m = (a + b) / 2;
- if (widths16.excepsV[m].last < c) {
- a = m;
- } else if (c < widths16.excepsV[m].first) {
- b = m;
- } else {
- vx = widths16.excepsV[m].vx;
- break;
- }
- }
- return vx;
- }
-
- double GfxFont::getOriginY16(int c) {
- double vy;
- int a, b, m;
-
- vy = widths16.defVY;
- a = -1;
- b = widths16.numExcepsV;
- // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first
- while (b - a > 1) {
- m = (a + b) / 2;
- if (widths16.excepsV[m].last < c) {
- a = m;
- } else if (c < widths16.excepsV[m].first) {
- b = m;
- } else {
- vy = widths16.excepsV[m].vy;
- break;
- }
- }
- return vy;
- }
-
- void GfxFont::getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont,
- int missingWidth) {
- RAutoObject obj1, obj2;
- FontFile *fontFile;
-
- // Encodings start with a base encoding, which can come from
- // (in order of priority):
- // 1. FontDict.Encoding or FontDict.Encoding.BaseEncoding
- // - MacRoman / WinAnsi / Standard
- // 2. embedded font file
- // 3. default:
- // - builtin --> builtin encoding
- // - TrueType --> MacRomanEncoding
- // - others --> StandardEncoding
- // and then add a list of differences from
- // FontDict.Encoding.Differences.
-
- // check FontDict for base encoding
- encoding = NULL;
- fontDict->lookupL("Encoding", &obj1);
- if (obj1.isDict()) {
- obj1.dictLookupL("BaseEncoding", &obj2);
- if (obj2.isName()) {
- if (obj2.isName("MacRomanEncoding")) {
- encoding = Global().GfxFont.macRomanEncoding->copyL();
- } else if (obj2.isName("WinAnsiEncoding")) {
- encoding = Global().GfxFont.winAnsiEncoding->copyL();
- } else if (obj2.isName("StandardEncoding")) {
- encoding = Global().GfxFont.standardEncoding->copyL();
- }
- }
- obj2.free();
- } else if (obj1.isName("MacRomanEncoding")) {
- encoding = Global().GfxFont.macRomanEncoding->copyL();
- } else if (obj1.isName("WinAnsiEncoding")) {
- encoding = Global().GfxFont.winAnsiEncoding->copyL();
- } else if (obj1.isName("StandardEncoding")) {
- encoding = Global().GfxFont.standardEncoding->copyL();
- }
- obj1.free();
-
- // check embedded or external font file for base encoding
- if ((type == fontType1 || type == fontType1C) &&
- (extFontFile || embFontID.num >= 0)) {
- int len;
- char *buf = extFontFile ? readExtFontFileL(&len) : readEmbFontFileL(&len);
- if (buf) {
- CleanupStack::PushL(buf);
- if (type == fontType1)
- fontFile = Type1FontFile::NewLC(buf, len);
- else
- fontFile = Type1CFontFile::NewLC(buf, len);
-
- if (fontFile->getName()) {
- delete embFontName;
- embFontName=0;
- embFontName = GString::NewL(fontFile->getName());
- }
- if (!encoding)
- encoding = fontFile->getEncoding(gTrue);
- CleanupStack::PopAndDestroy(); // delete fontFile;
- CleanupStack::Pop(); // buf
- User::Free(buf);
- }
- }
-
- // get default base encoding
- if (!encoding) {
- if (builtinFont)
- encoding = builtinFont->encoding->copyL();
- else if (type == fontTrueType)
- encoding = Global().GfxFont.macRomanEncoding->copyL();
- else
- encoding = Global().GfxFont.standardEncoding->copyL();
- }
-
- // merge differences into encoding
- fontDict->lookupL("Encoding", &obj1);
- if (obj1.isDict()) {
- obj1.dictLookupL("Differences", &obj2);
- if (obj2.isArray()) {
- RAutoObject obj3;
- int code = 0;
- for (int i = 0; i < obj2.arrayGetLength(); ++i) {
- obj2.arrayGetL(i, &obj3);
- if (obj3.isInt()) {
- code = obj3.getInt();
- } else if (obj3.isName()) {
- if (code < 256)
- encoding->addChar(code, copyStringL(obj3.getName()));
- ++code;
- } else {
- error(-1, R_WRONG_TYPE_IN_FONT_ENCODING_RESOURCE_DIFFERENCES___S_, obj3.getTypeName());
- }
- obj3.free();
- }
- }
- obj2.free();
- }
- obj1.free();
-
- // get character widths
- if (builtinFont)
- makeWidths(fontDict, builtinFont->encoding, builtinFont->widths, missingWidth);
- else
- makeWidths(fontDict, NULL, NULL, missingWidth);
- }
-
- void GfxFont::findExtFontFile() {
- #if 0
- char **path;
- FILE *f;
- for (path = fontPath; *path; ++path) {
- extFontFile = appendToPath(new(ELeave) GString(*path), name->getCString());
- f = fopen(extFontFile->getCString(), "rb");
- if (!f) {
- extFontFile->append(".pfb");
- f = fopen(extFontFile->getCString(), "rb");
- }
- if (!f) {
- extFontFile->del(extFontFile->getLength() - 4, 4);
- extFontFile->append(".pfa");
- f = fopen(extFontFile->getCString(), "rb");
- }
- if (f) {
- fclose(f);
- break;
- }
- delete extFontFile;
- extFontFile = NULL;
- }
- #else
- extFontFile = NULL;
- #endif
- }
-
- char *GfxFont::readExtFontFileL(int* /*len*/){
- #if 0
- TText8 *buf = 0;
- RFs session;
- CleanupClosePushL(session);
-
- RFile f;
- CleanupClosePushL(f);
-
- session.Connect();
-
- TInt err = f.Open(session, *extFontFile, EFileStream|EFileRead);
- if (err) {
- if (err != KErrNoMemory)
- error(-1, R_INTERNAL__EXTERNAL_FONT_FILE_VANISHED, extFontFile->Ptr());
- User::Leave(err);
- }
- User::LeaveIfError(f.Size(*len));
- buf = (TText8 *)User::AllocLC(*len);
- err = f.Read(TPtr8(buf, *len, *len));
- if (err) {
- error(-1, R_ERROR_READING_EXTERNAL_FONT_FILE);
- User::Leave(err);
- }
-
- CleanupStack::PopAndDestroy(2); // f, session
- return (char*) buf;
- #else
- return 0;
- #endif
- }
-
- char *GfxFont::readEmbFontFileL(int *len) {
- char *buf;
- RAutoObject obj1, obj2;
- Stream *str;
- int c;
- int size, i;
-
- obj1.initRef(embFontID.num, embFontID.gen);
- obj1.fetchL(&obj2);
- if (!obj2.isStream()) {
- error(-1, R_EMBEDDED_FONT_FILE_IS_NOT_A_STREAM);
- obj2.free();
- obj1.free();
- embFontID.num = -1;
- return NULL;
- }
- str = obj2.getStream();
-
- i = 0;
- size = 4096;
- buf = (char*) User::AllocLC(size);
- str->reset();
- while ((c = str->getChar()) != EOF) {
- if (i == size) {
- size += 4096;
- buf = (char *)User::ReAllocL(buf, size);
- }
- buf[i++] = (char)c;
- }
- *len = i;
- CleanupStack::Pop(); // buf
- obj2.free();
- obj1.free();
-
- return buf;
- }
-
- void GfxFont::makeWidths(Dict *fontDict, FontEncoding *builtinEncoding,
- Gushort *builtinWidths, int missingWidth) {
- register int code, code2;
- register const char *charName;
-
- // initialize all widths
- double m = missingWidth * 0.001;
- for (code = 0; code < 256; ++code) {
- widths[code] = m;
- }
-
- // use widths from built-in font
- if (builtinEncoding) {
- code2 = 0; // to make gcc happy
- for (code = 0; code < 256; ++code) {
- charName = encoding->getCharName(code);
- if (charName) {
- code2 = builtinEncoding->getCharCode(charName);
- if (code2 >= 0)
- widths[code] = builtinWidths[code2] * 0.001;
- }
- }
- }
- else {
- // get widths from font dict
- RAutoObject obj1, obj2;
- int firstChar, lastChar;
- fontDict->lookupL("FirstChar", &obj1);
- firstChar = obj1.isInt() ? obj1.getInt() : 0;
- obj1.free();
- fontDict->lookupL("LastChar", &obj1);
- lastChar = obj1.isInt() ? obj1.getInt() : 255;
- obj1.free();
- double mult;
- if (type == fontType3)
- mult = fontMat[0];
- else
- mult = 0.001;
- fontDict->lookupL("Widths", &obj1);
- if (obj1.isArray()) {
- for (code = firstChar; code <= lastChar; ++code) {
- obj1.arrayGetL(code - firstChar, &obj2);
- if (obj2.isNum())
- widths[code] = obj2.getNum() * mult;
- obj2.free();
- }
- } else {
-
- // couldn't find widths -- use defaults
- #if 0 //~
- //~ certain PDF generators apparently don't include widths
- //~ for Arial and TimesNewRoman -- and this error message
- //~ is a nuisance
- error(-1, "No character widths resource for non-builtin font");
- #endif
- int index;
- if (isFixedWidth())
- index = 0;
- else if (isSerif())
- index = 8;
- else
- index = 4;
- if (isBold())
- index += 2;
- if (isItalic())
- index += 1;
- const Gushort *defWidths = defCharWidths[index];
- code2 = 0; // to make gcc happy
- for (code = 0; code < 256; ++code) {
- widths[code] = 0;
- charName = encoding->getCharName(code);
- if (charName) {
- code2 = Global().GfxFont.standardEncoding->getCharCode(charName);
- if (code2 >= 0)
- widths[code] = defWidths[code2] * 0.001;
- }
- }
- }
- obj1.free();
- }
- }
-
- void GfxFont::getType0EncAndWidths(Dict *fontDict) {
- RAutoObject obj1, obj2, obj3, obj4, obj5;
- int excepsSize;
- int i, j, k, n;
-
- widths16.exceps = NULL;
- widths16.excepsV = NULL;
-
- // get the CIDFont
- fontDict->lookupL("DescendantFonts", &obj1);
- if (!obj1.isArray() || obj1.arrayGetLength() != 1) {
- error(-1, R_BAD_DESCENDANTFONTS_ENTRY_FOR_TYPE_0_FONT);
- goto err1;
- }
- obj1.arrayGetL(0, &obj2);
- if (!obj2.isDict()) {
- error(-1, R_BAD_DESCENDANT_FONT_OF_TYPE_0_FONT);
- goto err2;
- }
-
- // get font info
- obj2.dictLookupL("CIDSystemInfo", &obj3);
- if (!obj3.isDict()) {
- error(-1, R_BAD_CIDSYSTEMINFO_IN_TYPE_0_FONT_DESCENDANT);
- goto err3;
- }
- obj3.dictLookupL("Registry", &obj4);
- obj3.dictLookupL("Ordering", &obj5);
- if (obj4.isString() && obj5.isString()) {
- if (obj4.getString()->cmp("Adobe") == 0 &&
- obj5.getString()->cmp("Japan1") == 0) {
- #if JAPANESE_SUPPORT
- is16 = gTrue;
- enc16.charSet = font16AdobeJapan12;
- #else
- error(-1, R_PDF_WAS_COMPILED_WITHOUT_JAPANESE_FONT_SUPPORT);
- goto err4;
- #endif
- } else {
- error(-1, R_UNKNOWN_TYPE_0_CHARACTER_SET___S__S,
- obj4.getString()->getCString(), obj5.getString()->getCString());
- goto err4;
- }
- } else {
- error(-1, R_UNKNOWN_TYPE_0_CHARACTER_SET);
- goto err4;
- }
- obj5.free();
- obj4.free();
- obj3.free();
-
- // get default char width
- obj2.dictLookupL("DW", &obj3);
- if (obj3.isInt())
- widths16.defWidth = obj3.getInt() * 0.001;
- else
- widths16.defWidth = 1.0;
- obj3.free();
-
- // get default char metrics for vertical font
- obj2.dictLookupL("DW2", &obj3);
- widths16.defVY = 0.880;
- widths16.defHeight = -1;
- if (obj3.isArray() && obj3.arrayGetLength() == 2) {
- obj3.arrayGetL(0, &obj4);
- if (obj4.isInt()) {
- widths16.defVY = obj4.getInt() * 0.001;
- }
- obj4.free();
- obj3.arrayGetL(1, &obj4);
- if (obj4.isInt()) {
- widths16.defHeight = obj4.getInt() * 0.001;
- }
- obj4.free();
- }
- obj3.free();
-
- // get char width exceptions
- widths16.exceps = NULL;
- widths16.numExceps = 0;
- obj2.dictLookupL("W", &obj3);
- if (obj3.isArray()) {
- RAutoObject obj6, obj7, obj8;
- excepsSize = 0;
- k = 0;
- i = 0;
- while (i+1 < obj3.arrayGetLength()) {
- obj3.arrayGetL(i, &obj4);
- obj3.arrayGetL(i+1, &obj5);
- if (obj4.isInt() && obj5.isInt()) {
- obj3.arrayGetL(i+2, &obj6);
- if (!obj6.isNum()) {
- error(-1, R_BAD_WIDTHS_ARRAY_IN_TYPE_0_FONT);
- obj6.free();
- obj5.free();
- obj4.free();
- break;
- }
- if (k == excepsSize) {
- excepsSize += 16;
- widths16.exceps = (GfxFontWidthExcep *)
- User::ReAllocL(widths16.exceps, excepsSize * sizeof(GfxFontWidthExcep));
- }
- widths16.exceps[k].first = obj4.getInt();
- widths16.exceps[k].last = obj5.getInt();
- widths16.exceps[k].width = obj6.getNum() * 0.001;
- obj6.free();
- ++k;
- i += 3;
- } else if (obj4.isInt() && obj5.isArray()) {
- if (k + obj5.arrayGetLength() >= excepsSize) {
- excepsSize = (k + obj5.arrayGetLength() + 15) & ~15;
- widths16.exceps = (GfxFontWidthExcep *)
- User::ReAllocL(widths16.exceps, excepsSize * sizeof(GfxFontWidthExcep));
- }
- n = obj4.getInt();
- for (j = 0; j < obj5.arrayGetLength(); ++j) {
- obj5.arrayGetL(j, &obj6);
- if (!obj6.isNum()) {
- error(-1, R_BAD_WIDTHS_ARRAY_IN_TYPE_0_FONT);
- obj6.free();
- break;
- }
- widths16.exceps[k].first = widths16.exceps[k].last = n++;
- widths16.exceps[k].width = obj6.getNum() * 0.001;
- obj6.free();
- ++k;
- }
- i += 2;
- } else {
- error(-1, R_BAD_WIDTHS_ARRAY_IN_TYPE_0_FONT);
- obj6.free();
- obj5.free();
- obj4.free();
- break;
- }
- obj5.free();
- obj4.free();
- }
- widths16.numExceps = k;
- if (k > 0)
- qsort(widths16.exceps, k, sizeof(GfxFontWidthExcep), &cmpWidthExcep);
- }
- obj3.free();
-
- // get char metric exceptions for vertical font
- widths16.excepsV = NULL;
- widths16.numExcepsV = 0;
- obj2.dictLookupL("W2", &obj3);
- if (obj3.isArray()) {
- RAutoObject obj6, obj7, obj8;
- excepsSize = 0;
- k = 0;
- i = 0;
- while (i+1 < obj3.arrayGetLength()) {
- obj3.arrayGetL(i, &obj4);
- obj3.arrayGetL(i+1, &obj5);
- if (obj4.isInt() && obj5.isInt()) {
- obj3.arrayGetL(i+2, &obj6);
- obj3.arrayGetL(i+3, &obj7);
- obj3.arrayGetL(i+4, &obj8);
- if (!obj6.isNum() || !obj7.isNum() || !obj8.isNum()) {
- error(-1, R_BAD_WIDTHS__W2__ARRAY_IN_TYPE_0_FONT);
- obj8.free();
- obj7.free();
- obj6.free();
- obj5.free();
- obj4.free();
- break;
- }
- if (k == excepsSize) {
- excepsSize += 16;
- widths16.excepsV = (GfxFontWidthExcepV *)
- User::ReAllocL(widths16.excepsV, excepsSize * sizeof(GfxFontWidthExcepV));
- }
- widths16.excepsV[k].first = obj4.getInt();
- widths16.excepsV[k].last = obj5.getInt();
- widths16.excepsV[k].height = obj6.getNum() * 0.001;
- widths16.excepsV[k].vx = obj7.getNum() * 0.001;
- widths16.excepsV[k].vy = obj8.getNum() * 0.001;
- obj8.free();
- obj7.free();
- obj6.free();
- ++k;
- i += 5;
- } else if (obj4.isInt() && obj5.isArray()) {
- if (k + obj5.arrayGetLength() / 3 >= excepsSize) {
- excepsSize = (k + obj5.arrayGetLength() / 3 + 15) & ~15;
- widths16.excepsV = (GfxFontWidthExcepV *)
- User::ReAllocL(widths16.excepsV, excepsSize * sizeof(GfxFontWidthExcepV));
- }
- n = obj4.getInt();
- for (j = 0; j < obj5.arrayGetLength(); j += 3) {
- obj5.arrayGetL(j, &obj6);
- obj5.arrayGetL(j+1, &obj7);
- obj5.arrayGetL(j+1, &obj8);
- if (!obj6.isNum() || !obj7.isNum() || !obj8.isNum()) {
- error(-1, R_BAD_WIDTHS__W2__ARRAY_IN_TYPE_0_FONT);
- obj6.free();
- break;
- }
- widths16.excepsV[k].first = widths16.exceps[k].last = n++;
- widths16.excepsV[k].height = obj6.getNum() * 0.001;
- widths16.excepsV[k].vx = obj7.getNum() * 0.001;
- widths16.excepsV[k].vy = obj8.getNum() * 0.001;
- obj8.free();
- obj7.free();
- obj6.free();
- ++k;
- }
- i += 2;
- } else {
- error(-1, R_BAD_WIDTHS_ARRAY_IN_TYPE_0_FONT);
- obj5.free();
- obj4.free();
- break;
- }
- obj5.free();
- obj4.free();
- }
- widths16.numExcepsV = k;
- if (k > 0) {
- qsort(widths16.excepsV, k, sizeof(GfxFontWidthExcepV), &cmpWidthExcepV);
- }
- }
- obj3.free();
-
- obj2.free();
- obj1.free();
-
- // get encoding (CMap)
- fontDict->lookupL("Encoding", &obj1);
- if (!obj1.isName()) {
- error(-1, R_BAD_ENCODING_FOR_TYPE_0_FONT);
- goto err1;
- }
- #if JAPANESE_SUPPORT
- if (enc16.charSet == font16AdobeJapan12) {
- for (i = 0; gfxJapan12Tab[i].name; ++i) {
- if (!strcmp(obj1.getName(), gfxJapan12Tab[i].name))
- break;
- }
- if (!gfxJapan12Tab[i].name) {
- error(-1, R_UNKNOWN_ENCODING_FOR_ADOBE_JAPAN1_2_FONT,
- obj1.getName());
- goto err1;
- }
- enc16.enc = gfxJapan12Tab[i].enc;
- }
- #endif
- obj1.free();
-
- return;
-
- err4:
- obj5.free();
- obj4.free();
- err3:
- obj3.free();
- err2:
- obj2.free();
- err1:
- obj1.free();
- //~ fix this --> add 16-bit font support to FontFile
- encoding = new(ELeave) FontEncoding();
- encoding->ConstructL();
- makeWidths(fontDict, NULL, NULL, 0);
- }
-
- static int CDECL cmpWidthExcep(const void *w1, const void *w2) {
- return ((GfxFontWidthExcep *)w1)->first - ((GfxFontWidthExcep *)w2)->first;
- }
-
- static int CDECL cmpWidthExcepV(const void *w1, const void *w2) {
- return ((GfxFontWidthExcepV *)w1)->first - ((GfxFontWidthExcepV *)w2)->first;
- }
-
- //------------------------------------------------------------------------
- // GfxFontDict
- //------------------------------------------------------------------------
-
- GfxFontDict::GfxFontDict() {}
-
- void GfxFontDict::ConstructL(Dict *fontDict) {
- int i;
- RAutoObject obj1, obj2;
-
- numFonts = 0; // fontDict->getLength();
- fonts = (GfxFont **)User::AllocL(fontDict->getLength() * sizeof(GfxFont *));
- // if zeroed cleanup in the destructor works
- // Mem::FillZ(fonts, numFonts * sizeof(GfxFont *));
- for (i = 0; i < fontDict->getLength(); ++i) {
- // zero entry so that it can be safely cleaned up
- fonts[i] = 0;
- numFonts++;
- fontDict->getValNFL(i, &obj1);
- obj1.fetchL(&obj2);
- if (obj1.isRef() && obj2.isDict()) {
- fonts[i] = new(ELeave) GfxFont();
- fonts[i]->ConstructL(fontDict->getKey(i), obj1.getRef(), obj2.getDict());
- } else {
- error(-1, R_FONT_RESOURCE_IS_NOT_A_DICTIONARY);
- }
-
- obj1.free();
- obj2.free();
- }
- }
-
- GfxFontDict::~GfxFontDict() {
- int i;
-
- if (fonts) {
- for (i = 0; i < numFonts; ++i)
- delete fonts[i];
- }
- User::Free(fonts);
- }
-
- GfxFont *GfxFontDict::lookup(char *tag) {
- int i;
-
- for (i = 0; i < numFonts; ++i) {
- if (fonts[i]->matches(tag))
- return fonts[i];
- }
- return NULL;
- }
-
- #ifdef __SYMBIAN32__
-
- // Initialise global data
-
- FontInfoGlobal::FontInfoGlobal()
- {
- standardEncoding = 0;
- symbolEncoding = 0;
- zapfDingbatsEncoding = 0;
- macRomanEncoding = 0;
- winAnsiEncoding = 0;
- }
-
- TInt FontInfoGlobal::Construct()
- {
- standardEncoding = new FontEncoding();
- if (!standardEncoding)
- return KErrNoMemory;
- standardEncoding->Construct(standardEncodingNames, standardEncodingSize);
-
- symbolEncoding = new FontEncoding();
- if (!symbolEncoding)
- return KErrNoMemory;
- symbolEncoding->Construct(symbolEncodingNames, symbolEncodingSize);
-
- zapfDingbatsEncoding = new FontEncoding();
- if (!zapfDingbatsEncoding)
- return KErrNoMemory;
- zapfDingbatsEncoding->Construct(zapfDingbatsEncodingNames, zapfDingbatsEncodingSize);
-
- macRomanEncoding = new FontEncoding();
- if (!macRomanEncoding)
- return KErrNoMemory;
- macRomanEncoding->Construct(macRomanEncodingNames, macRomanEncodingSize);
-
- winAnsiEncoding = new FontEncoding();
- if (!winAnsiEncoding)
- return KErrNoMemory;
- winAnsiEncoding->Construct((const char**)winAnsiEncodingNames, winAnsiEncodingSize);
-
- builtinFonts[ 0] = BuiltinFont("Courier", (Gushort *)courierWidths, standardEncoding);
- builtinFonts[ 1] = BuiltinFont("Courier-Bold", (Gushort *)courierBoldWidths, standardEncoding);
- builtinFonts[ 2] = BuiltinFont("Courier-BoldOblique", (Gushort *)courierBoldObliqueWidths, standardEncoding);
- builtinFonts[ 3] = BuiltinFont("Courier-Oblique", (Gushort *)courierObliqueWidths, standardEncoding);
- builtinFonts[ 4] = BuiltinFont("Helvetica", (Gushort *)helveticaWidths, standardEncoding);
- builtinFonts[ 5] = BuiltinFont("Helvetica-Bold", (Gushort *)helveticaBoldWidths, standardEncoding);
- builtinFonts[ 6] = BuiltinFont("Helvetica-BoldOblique", (Gushort *)helveticaBoldObliqueWidths, standardEncoding);
- builtinFonts[ 7] = BuiltinFont("Helvetica-Oblique", (Gushort *)helveticaObliqueWidths, standardEncoding);
- builtinFonts[ 8] = BuiltinFont("Symbol", (Gushort *)symbolWidths, symbolEncoding);
- builtinFonts[ 9] = BuiltinFont("Times-Bold", (Gushort *)timesBoldWidths, standardEncoding);
- builtinFonts[10] = BuiltinFont("Times-BoldItalic", (Gushort *)timesBoldItalicWidths, standardEncoding);
- builtinFonts[11] = BuiltinFont("Times-Italic", (Gushort *)timesItalicWidths, standardEncoding);
- builtinFonts[12] = BuiltinFont("Times-Roman", (Gushort *)timesRomanWidths, standardEncoding);
- builtinFonts[13] = BuiltinFont("ZapfDingbats", (Gushort *)zapfDingbatsWidths, zapfDingbatsEncoding);
-
- return KErrNone;
- };
-
-
- FontInfoGlobal::~FontInfoGlobal()
- {
- delete standardEncoding;
- delete symbolEncoding;
- delete zapfDingbatsEncoding;
- delete macRomanEncoding;
- delete winAnsiEncoding;
- }
-
- #endif